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:
parent
210b3d5e4c
commit
e5365091aa
6 changed files with 155 additions and 61 deletions
2
TODO
2
TODO
|
@ -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*, ...*).
|
||||
|
|
|
@ -48,7 +48,7 @@ void FormRender::applyConfig()
|
|||
|
||||
void FormRender::configChangeEvent()
|
||||
{
|
||||
cameraValidateDefinition(&_camera);
|
||||
cameraValidateDefinition(&_camera, 1);
|
||||
BaseForm::configChangeEvent();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue