paysages: Camera support for roll (WIP).

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@248 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-01-29 11:34:49 +00:00 committed by ThunderK
parent 210b3d5e4c
commit e5365091aa
6 changed files with 155 additions and 61 deletions

2
TODO
View file

@ -1,3 +1,5 @@
- Clouds are lighted without filtering from ground (clouds lighted at night !)
- Camera should respect ratio aspect of render area.
- All noises should use the same entropy pool (saved separately), and avoid reallocs. - All noises should use the same entropy pool (saved separately), and avoid reallocs.
- Implement light multi-sampling (mainly for skydome). - Implement light multi-sampling (mainly for skydome).
- All Save and Load methods should have same signature : void ...Save(FILE*, ...*). - All Save and Load methods should have same signature : void ...Save(FILE*, ...*).

View file

@ -48,7 +48,7 @@ void FormRender::applyConfig()
void FormRender::configChangeEvent() void FormRender::configChangeEvent()
{ {
cameraValidateDefinition(&_camera); cameraValidateDefinition(&_camera, 1);
BaseForm::configChangeEvent(); BaseForm::configChangeEvent();
} }

View file

@ -125,6 +125,7 @@ void WidgetWanderer::mouseMoveEvent(QMouseEvent* event)
else if (event->buttons() & Qt::RightButton) else if (event->buttons() & Qt::RightButton)
{ {
cameraRotateYaw(&_current_camera, (double)(event->x() - last_mouse_x) * factor * 0.1); cameraRotateYaw(&_current_camera, (double)(event->x() - last_mouse_x) * factor * 0.1);
cameraRotatePitch(&_current_camera, (double)(event->y() - last_mouse_y) * factor * 0.1);
updateGL(); updateGL();
event->accept(); event->accept();
} }
@ -265,6 +266,8 @@ static void _renderTerrain(TerrainDefinition* terrain, CameraDefinition* camera,
void WidgetWanderer::paintGL() void WidgetWanderer::paintGL()
{ {
cameraValidateDefinition(&_current_camera, 1);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
gluLookAt(_current_camera.location.x, _current_camera.location.y, _current_camera.location.z, _current_camera.target.x, _current_camera.target.y, _current_camera.target.z, _current_camera.up.x, _current_camera.up.y, _current_camera.up.z); gluLookAt(_current_camera.location.x, _current_camera.location.y, _current_camera.location.z, _current_camera.target.x, _current_camera.target.y, _current_camera.target.z, _current_camera.up.x, _current_camera.up.y, _current_camera.up.z);

View file

@ -8,6 +8,7 @@
#include "shared/globals.h" #include "shared/globals.h"
#include "shared/constants.h" #include "shared/constants.h"
#include "shared/functions.h" #include "shared/functions.h"
#include "scenery.h"
void cameraInit() void cameraInit()
{ {
@ -16,29 +17,33 @@ void cameraInit()
void cameraSave(FILE* f, CameraDefinition* camera) void cameraSave(FILE* f, CameraDefinition* camera)
{ {
v3Save(camera->location, f); v3Save(camera->location, f);
v3Save(camera->target, f); toolsSaveDouble(f, camera->yaw);
toolsSaveDouble(f, camera->pitch);
toolsSaveDouble(f, camera->roll);
} }
void cameraLoad(FILE* f, CameraDefinition* camera) void cameraLoad(FILE* f, CameraDefinition* camera)
{ {
camera->location = v3Load(f); camera->location = v3Load(f);
camera->target = v3Load(f); camera->yaw = toolsLoadDouble(f);
camera->pitch = toolsLoadDouble(f);
camera->roll = toolsLoadDouble(f);
cameraValidateDefinition(camera); cameraValidateDefinition(camera, 0);
} }
CameraDefinition cameraCreateDefinition() CameraDefinition cameraCreateDefinition()
{ {
CameraDefinition definition; CameraDefinition definition;
definition.location.x = -1.0; definition.location.x = 0.0;
definition.location.y = 0.0; definition.location.y = 0.0;
definition.location.z = 0.0; definition.location.z = 0.0;
definition.target.x = 0.0; definition.yaw = 0.0;
definition.target.y = 0.0; definition.pitch = 0.0;
definition.target.z = 0.0; definition.roll = 0.0;
cameraValidateDefinition(&definition); cameraValidateDefinition(&definition, 0);
return definition; return definition;
} }
@ -50,16 +55,66 @@ void cameraDeleteDefinition(CameraDefinition* definition)
void cameraCopyDefinition(CameraDefinition* source, CameraDefinition* destination) void cameraCopyDefinition(CameraDefinition* source, CameraDefinition* destination)
{ {
*destination = *source; *destination = *source;
cameraValidateDefinition(destination, 0);
} }
void cameraValidateDefinition(CameraDefinition* definition) void cameraValidateDefinition(CameraDefinition* definition, int check_above)
{ {
/* TODO Recompute up vector */ WaterDefinition water;
TerrainDefinition terrain;
double water_height, terrain_height, diff;
Vector3 move;
Matrix4 rotation;
if (check_above)
{
water = waterCreateDefinition();
sceneryGetWater(&water);
water_height = water.height + 0.5;
waterDeleteDefinition(&water);
terrain = terrainCreateDefinition();
sceneryGetTerrain(&terrain);
terrain_height = terrainGetHeight(&terrain, definition->location.x, definition->location.z) + 0.5;
terrainDeleteDefinition(&terrain);
if (definition->location.y < water_height || definition->location.y < terrain_height)
{
if (water_height > terrain_height)
{
diff = water_height - definition->location.y;
}
else
{
diff = terrain_height - definition->location.y;
}
move.x = move.z = 0.0;
move.y = diff;
definition->location = v3Add(definition->location, move);
}
}
definition->forward.x = 1.0;
definition->forward.y = 0.0;
definition->forward.z = 0.0;
definition->right.x = 0.0;
definition->right.y = 0.0;
definition->right.z = 1.0;
definition->up.x = 0.0; definition->up.x = 0.0;
definition->up.y = 1.0; definition->up.y = 1.0;
definition->up.z = 0.0; definition->up.z = 0.0;
rotation = m4NewRotateEuler(definition->yaw, definition->pitch, definition->roll);
definition->forward = m4MultPoint(rotation, definition->forward);
definition->right = m4MultPoint(rotation, definition->right);
definition->up = m4MultPoint(rotation, definition->up);
definition->target = v3Add(definition->location, definition->forward);
definition->project = m4Mult(m4NewPerspective(1.57, 1.333333, 1.0, 1000.0), m4NewLookAt(VECTOR_ZERO, v3Sub(definition->target, definition->location), definition->up)); definition->project = m4Mult(m4NewPerspective(1.57, 1.333333, 1.0, 1000.0), m4NewLookAt(VECTOR_ZERO, definition->forward, definition->up));
definition->unproject = m4Inverse(definition->project); definition->unproject = m4Inverse(definition->project);
} }
@ -69,68 +124,91 @@ void cameraSetLocation(CameraDefinition* camera, double x, double y, double z)
camera->location.y = y; camera->location.y = y;
camera->location.z = z; camera->location.z = z;
cameraValidateDefinition(camera); cameraValidateDefinition(camera, 0);
} }
void cameraSetTarget(CameraDefinition* camera, double x, double y, double z) void cameraSetTarget(CameraDefinition* camera, double x, double y, double z)
{ {
camera->target.x = x; Vector3 forward, target;
camera->target.y = y;
camera->target.z = z; target.x = x;
target.y = y;
target.z = z;
forward = v3Sub(target, camera->location);
if (v3Norm(forward) < 0.0000001)
{
return;
}
forward = v3Normalize(forward);
if (fabs(forward.x) < 0.0000001 && fabs(forward.z) < 0.0000001)
{
/* Forward vector is vertical */
if (forward.y > 0.0)
{
camera->pitch = M_PI_2;
}
else if (forward.y > 0.0)
{
camera->pitch = -M_PI_2;
}
}
else
{
/* TODO Guess angles */
}
cameraValidateDefinition(camera); cameraValidateDefinition(camera, 0);
} }
void cameraSetAngle(CameraDefinition* camera, double angle) void cameraSetRoll(CameraDefinition* camera, double angle)
{ {
/* TODO */ camera->roll = angle;
cameraValidateDefinition(camera, 0);
} }
void cameraStrafeForward(CameraDefinition* camera, double value) void cameraStrafeForward(CameraDefinition* camera, double value)
{ {
Vector3 move; camera->location = v3Add(camera->location, v3Scale(camera->forward, value));
move = v3Scale(v3Normalize(v3Sub(camera->target, camera->location)), value); cameraValidateDefinition(camera, 0);
camera->location = v3Add(camera->location, move);
camera->target = v3Add(camera->target, move);
cameraValidateDefinition(camera);
} }
void cameraStrafeRight(CameraDefinition* camera, double value) void cameraStrafeRight(CameraDefinition* camera, double value)
{ {
Vector3 move; camera->location = v3Add(camera->location, v3Scale(camera->right, value));
move = v3Scale(v3Normalize(v3Cross(v3Sub(camera->target, camera->location), camera->up)), value); cameraValidateDefinition(camera, 0);
camera->location = v3Add(camera->location, move);
camera->target = v3Add(camera->target, move);
cameraValidateDefinition(camera);
} }
void cameraStrafeUp(CameraDefinition* camera, double value) void cameraStrafeUp(CameraDefinition* camera, double value)
{ {
Vector3 move; camera->location = v3Add(camera->location, v3Scale(camera->up, value));
move = v3Scale(v3Normalize(camera->up), value); cameraValidateDefinition(camera, 0);
camera->location = v3Add(camera->location, move);
camera->target = v3Add(camera->target, move);
cameraValidateDefinition(camera);
} }
void cameraRotateYaw(CameraDefinition* camera, double value) void cameraRotateYaw(CameraDefinition* camera, double value)
{ {
Matrix4 m; camera->yaw += value;
Vector3 v;
v = v3Sub(camera->target, camera->location); cameraValidateDefinition(camera, 0);
m = m4NewRotateAxis(value, camera->up); }
v = m4MultPoint(m, v);
camera->target = v3Add(camera->location, v); void cameraRotatePitch(CameraDefinition* camera, double value)
{
camera->pitch += value;
cameraValidateDefinition(camera); cameraValidateDefinition(camera, 0);
}
void cameraRotateRoll(CameraDefinition* camera, double value)
{
camera->roll += value;
cameraValidateDefinition(camera, 0);
} }
Vector3 cameraProject(CameraDefinition* camera, Vector3 point) Vector3 cameraProject(CameraDefinition* camera, Vector3 point)

View file

@ -8,11 +8,22 @@
extern "C" { extern "C" {
#endif #endif
/* Definition of a 3D scene camera.
*
* Don't modify this structure directly, use the provided functions.
*/
typedef struct typedef struct
{ {
Vector3 location; Vector3 location;
double yaw;
double pitch;
double roll;
Vector3 target; Vector3 target;
Vector3 forward;
Vector3 right;
Vector3 up; Vector3 up;
Matrix4 project; Matrix4 project;
Matrix4 unproject; Matrix4 unproject;
} CameraDefinition; } CameraDefinition;
@ -24,16 +35,18 @@ void cameraLoad(FILE* f, CameraDefinition* camera);
CameraDefinition cameraCreateDefinition(); CameraDefinition cameraCreateDefinition();
void cameraDeleteDefinition(CameraDefinition* definition); void cameraDeleteDefinition(CameraDefinition* definition);
void cameraCopyDefinition(CameraDefinition* source, CameraDefinition* destination); void cameraCopyDefinition(CameraDefinition* source, CameraDefinition* destination);
void cameraValidateDefinition(CameraDefinition* definition); void cameraValidateDefinition(CameraDefinition* definition, int check_above);
void cameraSetLocation(CameraDefinition* camera, double x, double y, double z); void cameraSetLocation(CameraDefinition* camera, double x, double y, double z);
void cameraSetTarget(CameraDefinition* camera, double x, double y, double z); void cameraSetTarget(CameraDefinition* camera, double x, double y, double z);
void cameraSetAngle(CameraDefinition* camera, double angle); void cameraSetRoll(CameraDefinition* camera, double angle);
void cameraStrafeForward(CameraDefinition* camera, double value); void cameraStrafeForward(CameraDefinition* camera, double value);
void cameraStrafeRight(CameraDefinition* camera, double value); void cameraStrafeRight(CameraDefinition* camera, double value);
void cameraStrafeUp(CameraDefinition* camera, double value); void cameraStrafeUp(CameraDefinition* camera, double value);
void cameraRotateYaw(CameraDefinition* camera, double value); void cameraRotateYaw(CameraDefinition* camera, double value);
void cameraRotatePitch(CameraDefinition* camera, double value);
void cameraRotateRoll(CameraDefinition* camera, double value);
Vector3 cameraProject(CameraDefinition* camera, Vector3 point); Vector3 cameraProject(CameraDefinition* camera, Vector3 point);
Vector3 cameraUnproject(CameraDefinition* camera, Vector3 point); Vector3 cameraUnproject(CameraDefinition* camera, Vector3 point);

View file

@ -58,27 +58,21 @@ void sceneryLoadFromFile(char* filepath)
/* TODO Use intermediary definitions ? */ /* TODO Use intermediary definitions ? */
atmosphereLoad(f, &_atmosphere); atmosphereLoad(f, &_atmosphere);
atmosphereValidateDefinition(&_atmosphere);
cameraLoad(f, &_camera); cameraLoad(f, &_camera);
cameraValidateDefinition(&_camera);
cloudsLoad(f, &_clouds); cloudsLoad(f, &_clouds);
cloudsValidateDefinition(&_clouds);
lightingLoad(f, &_lighting); lightingLoad(f, &_lighting);
lightingValidateDefinition(&_lighting);
skyLoad(f, &_sky); skyLoad(f, &_sky);
skyValidateDefinition(&_sky);
terrainLoad(f, &_terrain); terrainLoad(f, &_terrain);
terrainValidateDefinition(&_terrain);
texturesLoad(f, &_textures); texturesLoad(f, &_textures);
texturesValidateDefinition(&_textures);
waterLoad(f, &_water); waterLoad(f, &_water);
atmosphereValidateDefinition(&_atmosphere);
cameraValidateDefinition(&_camera, 0);
cloudsValidateDefinition(&_clouds);
lightingValidateDefinition(&_lighting);
skyValidateDefinition(&_sky);
terrainValidateDefinition(&_terrain);
texturesValidateDefinition(&_textures);
waterValidateDefinition(&_water); waterValidateDefinition(&_water);
fclose(f); fclose(f);
@ -98,7 +92,7 @@ void sceneryGetAtmosphere(AtmosphereDefinition* atmosphere)
void scenerySetCamera(CameraDefinition* camera) void scenerySetCamera(CameraDefinition* camera)
{ {
cameraCopyDefinition(camera, &_camera); cameraCopyDefinition(camera, &_camera);
cameraValidateDefinition(&_camera); cameraValidateDefinition(&_camera, 1);
} }
void sceneryGetCamera(CameraDefinition* camera) void sceneryGetCamera(CameraDefinition* camera)
@ -146,6 +140,8 @@ void scenerySetTerrain(TerrainDefinition* terrain)
{ {
terrainCopyDefinition(terrain, &_terrain); terrainCopyDefinition(terrain, &_terrain);
terrainValidateDefinition(&_terrain); terrainValidateDefinition(&_terrain);
cameraValidateDefinition(&_camera, 1);
} }
void sceneryGetTerrain(TerrainDefinition* terrain) void sceneryGetTerrain(TerrainDefinition* terrain)
@ -168,6 +164,8 @@ void scenerySetWater(WaterDefinition* water)
{ {
waterCopyDefinition(water, &_water); waterCopyDefinition(water, &_water);
waterValidateDefinition(&_water); waterValidateDefinition(&_water);
cameraValidateDefinition(&_camera, 1);
} }
void sceneryGetWater(WaterDefinition* water) void sceneryGetWater(WaterDefinition* water)