paysages: Added strafing with mouse and keys for 3d explorer.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@242 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-01-27 16:01:34 +00:00 committed by ThunderK
parent 42bbb32b7a
commit c57adf47f2
4 changed files with 188 additions and 13 deletions

View file

@ -1,20 +1,147 @@
#include "widgetwanderer.h" #include "widgetwanderer.h"
#include <QGLWidget> #include <QGLWidget>
#include <QKeyEvent>
#include "../lib_paysages/scenery.h" #include "../lib_paysages/scenery.h"
WidgetWanderer::WidgetWanderer(QWidget *parent, CameraDefinition* camera): WidgetWanderer::WidgetWanderer(QWidget *parent, CameraDefinition* camera):
QGLWidget(parent) QGLWidget(parent)
{ {
setMinimumSize(400, 300); setMinimumSize(400, 300);
setFocusPolicy(Qt::StrongFocus);
this->camera = camera; cameraCopyDefinition(camera, &this->camera);
this->terrain = terrainCreateDefinition(); this->terrain = terrainCreateDefinition();
sceneryGetTerrain(&terrain); sceneryGetTerrain(&terrain);
this->water = waterCreateDefinition(); this->water = waterCreateDefinition();
sceneryGetWater(&water); sceneryGetWater(&water);
last_mouse_x = 0;
last_mouse_y = 0;
}
void WidgetWanderer::keyPressEvent(QKeyEvent* event)
{
double factor;
if (event->modifiers() & Qt::ShiftModifier)
{
factor = 0.1;
}
else if (event->modifiers() & Qt::ControlModifier)
{
factor = 10.0;
}
else
{
factor = 1.0;
}
if (event->key() == Qt::Key_Up)
{
cameraStrafeForward(&camera, 0.1 * factor);
updateGL();
}
else if (event->key() == Qt::Key_Down)
{
cameraStrafeForward(&camera, -0.1 * factor);
updateGL();
}
else if (event->key() == Qt::Key_Right)
{
cameraStrafeRight(&camera, 0.1 * factor);
updateGL();
}
else if (event->key() == Qt::Key_Left)
{
cameraStrafeRight(&camera, -0.1 * factor);
updateGL();
}
else if (event->key() == Qt::Key_PageUp)
{
cameraStrafeUp(&camera, 0.1 * factor);
updateGL();
}
else if (event->key() == Qt::Key_PageDown)
{
cameraStrafeUp(&camera, -0.1 * factor);
updateGL();
}
else
{
QGLWidget::keyPressEvent(event);
}
}
void WidgetWanderer::mousePressEvent(QMouseEvent* event)
{
last_mouse_x = event->x();
last_mouse_y = event->y();
event->ignore();
}
void WidgetWanderer::mouseMoveEvent(QMouseEvent* event)
{
double factor;
if (event->modifiers() & Qt::ShiftModifier)
{
factor = 0.01;
}
else if (event->modifiers() & Qt::ControlModifier)
{
factor = 1.0;
}
else
{
factor = 0.1;
}
factor *= 0.2;
if (event->buttons() & Qt::LeftButton)
{
cameraStrafeRight(&camera, (double)(last_mouse_x - event->x()) * factor);
cameraStrafeUp(&camera, (double)(event->y() - last_mouse_y) * factor);
updateGL();
event->accept();
}
else
{
event->ignore();
}
last_mouse_x = event->x();
last_mouse_y = event->y();
}
void WidgetWanderer::wheelEvent(QWheelEvent* event)
{
double factor;
if (event->modifiers() & Qt::ShiftModifier)
{
factor = 0.01;
}
else if (event->modifiers() & Qt::ControlModifier)
{
factor = 1.0;
}
else
{
factor = 0.1;
}
factor *= 0.1;
if (event->orientation() == Qt::Vertical)
{
cameraStrafeForward(&camera, (double)event->delta() * factor);
updateGL();
}
event->accept();
} }
void WidgetWanderer::initializeGL() void WidgetWanderer::initializeGL()
@ -36,7 +163,6 @@ void WidgetWanderer::resizeGL(int w, int h)
static inline void _pushTerrainVertex(TerrainDefinition* terrain, double x, double z) static inline void _pushTerrainVertex(TerrainDefinition* terrain, double x, double z)
{ {
glVertex3f(x, terrainGetHeight(terrain, x, z), z); glVertex3f(x, terrainGetHeight(terrain, x, z), z);
//glVertex3f(x, 1.0, z);
} }
void WidgetWanderer::paintGL() void WidgetWanderer::paintGL()
@ -45,7 +171,7 @@ void WidgetWanderer::paintGL()
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
gluLookAt(camera->location.x, camera->location.y, camera->location.z, camera->target.x, camera->target.y, camera->target.z, camera->up.x, camera->up.y, camera->up.z); gluLookAt(camera.location.x, camera.location.y, camera.location.z, camera.target.x, camera.target.y, camera.target.z, camera.up.x, camera.up.y, camera.up.z);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -54,6 +180,7 @@ void WidgetWanderer::paintGL()
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
glDepthMask(true);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glLineWidth(1.0); glLineWidth(1.0);
@ -72,15 +199,6 @@ void WidgetWanderer::paintGL()
{ {
for (z = -50.0; z < 50.0; z += step) for (z = -50.0; z < 50.0; z += step)
{ {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_QUADS);
_pushTerrainVertex(&terrain, x, z);
_pushTerrainVertex(&terrain, x, z + step);
_pushTerrainVertex(&terrain, x + step, z + step);
_pushTerrainVertex(&terrain, x + step, z);
glEnd();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glColor3f(0.0, 0.5, 0.0); glColor3f(0.0, 0.5, 0.0);
glBegin(GL_QUADS); glBegin(GL_QUADS);
@ -89,6 +207,17 @@ void WidgetWanderer::paintGL()
_pushTerrainVertex(&terrain, x + step, z + step); _pushTerrainVertex(&terrain, x + step, z + step);
_pushTerrainVertex(&terrain, x + step, z); _pushTerrainVertex(&terrain, x + step, z);
glEnd(); glEnd();
glEnable(GL_LINE_SMOOTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_QUADS);
_pushTerrainVertex(&terrain, x, z);
_pushTerrainVertex(&terrain, x, z + step);
_pushTerrainVertex(&terrain, x + step, z + step);
_pushTerrainVertex(&terrain, x + step, z);
glEnd();
glDisable(GL_LINE_SMOOTH);
} }
} }
} }

View file

@ -13,14 +13,22 @@ public:
WidgetWanderer(QWidget* parent, CameraDefinition* camera); WidgetWanderer(QWidget* parent, CameraDefinition* camera);
protected: protected:
void keyPressEvent(QKeyEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void wheelEvent(QWheelEvent* event);
void initializeGL(); void initializeGL();
void resizeGL(int w, int h); void resizeGL(int w, int h);
void paintGL(); void paintGL();
private: private:
CameraDefinition* camera; CameraDefinition camera;
TerrainDefinition terrain; TerrainDefinition terrain;
WaterDefinition water; WaterDefinition water;
int last_mouse_x;
int last_mouse_y;
}; };
#endif #endif

View file

@ -86,6 +86,39 @@ void cameraSetAngle(CameraDefinition* camera, double angle)
/* TODO */ /* TODO */
} }
void cameraStrafeForward(CameraDefinition* camera, double value)
{
Vector3 move;
move = v3Scale(v3Normalize(v3Sub(camera->target, camera->location)), value);
camera->location = v3Add(camera->location, move);
camera->target = v3Add(camera->target, move);
cameraValidateDefinition(camera);
}
void cameraStrafeRight(CameraDefinition* camera, double value)
{
Vector3 move;
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);
}
void cameraStrafeUp(CameraDefinition* camera, double value)
{
Vector3 move;
move = v3Scale(v3Normalize(camera->up), value);
camera->location = v3Add(camera->location, move);
camera->target = v3Add(camera->target, move);
cameraValidateDefinition(camera);
}
Vector3 cameraProject(CameraDefinition* camera, Vector3 point) Vector3 cameraProject(CameraDefinition* camera, Vector3 point)
{ {
point = m4Transform(camera->project, v3Sub(point, camera->location)); point = m4Transform(camera->project, v3Sub(point, camera->location));

View file

@ -29,6 +29,11 @@ void cameraValidateDefinition(CameraDefinition* definition);
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 cameraSetAngle(CameraDefinition* camera, double angle);
void cameraStrafeForward(CameraDefinition* camera, double value);
void cameraStrafeRight(CameraDefinition* camera, double value);
void cameraStrafeUp(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);
void cameraProjectToFragment(CameraDefinition* camera, double x, double y, double z, RenderFragment* result); void cameraProjectToFragment(CameraDefinition* camera, double x, double y, double z, RenderFragment* result);