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.
|
- 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*, ...*).
|
||||||
|
|
|
@ -48,7 +48,7 @@ void FormRender::applyConfig()
|
||||||
|
|
||||||
void FormRender::configChangeEvent()
|
void FormRender::configChangeEvent()
|
||||||
{
|
{
|
||||||
cameraValidateDefinition(&_camera);
|
cameraValidateDefinition(&_camera, 1);
|
||||||
BaseForm::configChangeEvent();
|
BaseForm::configChangeEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
definition->project = m4Mult(m4NewPerspective(1.57, 1.333333, 1.0, 1000.0), m4NewLookAt(VECTOR_ZERO, v3Sub(definition->target, definition->location), definition->up));
|
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, 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;
|
|
||||||
|
|
||||||
cameraValidateDefinition(camera);
|
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, 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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue