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.
- Implement light multi-sampling (mainly for skydome).
- All Save and Load methods should have same signature : void ...Save(FILE*, ...*).

View file

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

View file

@ -125,6 +125,7 @@ void WidgetWanderer::mouseMoveEvent(QMouseEvent* event)
else if (event->buttons() & Qt::RightButton)
{
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();
event->accept();
}
@ -265,6 +266,8 @@ static void _renderTerrain(TerrainDefinition* terrain, CameraDefinition* camera,
void WidgetWanderer::paintGL()
{
cameraValidateDefinition(&_current_camera, 1);
glMatrixMode(GL_MODELVIEW);
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);

View file

@ -8,6 +8,7 @@
#include "shared/globals.h"
#include "shared/constants.h"
#include "shared/functions.h"
#include "scenery.h"
void cameraInit()
{
@ -16,29 +17,33 @@ void cameraInit()
void cameraSave(FILE* f, CameraDefinition* camera)
{
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)
{
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 definition;
definition.location.x = -1.0;
definition.location.x = 0.0;
definition.location.y = 0.0;
definition.location.z = 0.0;
definition.target.x = 0.0;
definition.target.y = 0.0;
definition.target.z = 0.0;
definition.yaw = 0.0;
definition.pitch = 0.0;
definition.roll = 0.0;
cameraValidateDefinition(&definition);
cameraValidateDefinition(&definition, 0);
return definition;
}
@ -50,16 +55,66 @@ void cameraDeleteDefinition(CameraDefinition* definition)
void cameraCopyDefinition(CameraDefinition* source, CameraDefinition* destination)
{
*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.y = 1.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);
}
@ -69,68 +124,91 @@ void cameraSetLocation(CameraDefinition* camera, double x, double y, double z)
camera->location.y = y;
camera->location.z = z;
cameraValidateDefinition(camera);
cameraValidateDefinition(camera, 0);
}
void cameraSetTarget(CameraDefinition* camera, double x, double y, double z)
{
camera->target.x = x;
camera->target.y = y;
camera->target.z = z;
Vector3 forward, target;
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)
{
Vector3 move;
camera->location = v3Add(camera->location, v3Scale(camera->forward, value));
move = v3Scale(v3Normalize(v3Sub(camera->target, camera->location)), value);
camera->location = v3Add(camera->location, move);
camera->target = v3Add(camera->target, move);
cameraValidateDefinition(camera);
cameraValidateDefinition(camera, 0);
}
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);
camera->location = v3Add(camera->location, move);
camera->target = v3Add(camera->target, move);
cameraValidateDefinition(camera);
cameraValidateDefinition(camera, 0);
}
void cameraStrafeUp(CameraDefinition* camera, double value)
{
Vector3 move;
camera->location = v3Add(camera->location, v3Scale(camera->up, value));
move = v3Scale(v3Normalize(camera->up), value);
camera->location = v3Add(camera->location, move);
camera->target = v3Add(camera->target, move);
cameraValidateDefinition(camera);
cameraValidateDefinition(camera, 0);
}
void cameraRotateYaw(CameraDefinition* camera, double value)
{
Matrix4 m;
Vector3 v;
camera->yaw += value;
v = v3Sub(camera->target, camera->location);
m = m4NewRotateAxis(value, camera->up);
v = m4MultPoint(m, v);
cameraValidateDefinition(camera, 0);
}
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)

View file

@ -8,11 +8,22 @@
extern "C" {
#endif
/* Definition of a 3D scene camera.
*
* Don't modify this structure directly, use the provided functions.
*/
typedef struct
{
Vector3 location;
double yaw;
double pitch;
double roll;
Vector3 target;
Vector3 forward;
Vector3 right;
Vector3 up;
Matrix4 project;
Matrix4 unproject;
} CameraDefinition;
@ -24,16 +35,18 @@ void cameraLoad(FILE* f, CameraDefinition* camera);
CameraDefinition cameraCreateDefinition();
void cameraDeleteDefinition(CameraDefinition* definition);
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 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 cameraStrafeRight(CameraDefinition* camera, double value);
void cameraStrafeUp(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 cameraUnproject(CameraDefinition* camera, Vector3 point);

View file

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