From c57adf47f254ab85505058c0566b7a362cd269ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Fri, 27 Jan 2012 16:01:34 +0000 Subject: [PATCH] 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 --- gui_qt/widgetwanderer.cpp | 153 +++++++++++++++++++++++++++++++++++--- gui_qt/widgetwanderer.h | 10 ++- lib_paysages/camera.c | 33 ++++++++ lib_paysages/camera.h | 5 ++ 4 files changed, 188 insertions(+), 13 deletions(-) diff --git a/gui_qt/widgetwanderer.cpp b/gui_qt/widgetwanderer.cpp index 8bc9282..87748d5 100644 --- a/gui_qt/widgetwanderer.cpp +++ b/gui_qt/widgetwanderer.cpp @@ -1,20 +1,147 @@ #include "widgetwanderer.h" #include +#include #include "../lib_paysages/scenery.h" WidgetWanderer::WidgetWanderer(QWidget *parent, CameraDefinition* camera): QGLWidget(parent) { setMinimumSize(400, 300); + setFocusPolicy(Qt::StrongFocus); - this->camera = camera; + cameraCopyDefinition(camera, &this->camera); this->terrain = terrainCreateDefinition(); sceneryGetTerrain(&terrain); this->water = waterCreateDefinition(); 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() @@ -36,7 +163,6 @@ void WidgetWanderer::resizeGL(int w, int h) static inline void _pushTerrainVertex(TerrainDefinition* terrain, double x, double z) { glVertex3f(x, terrainGetHeight(terrain, x, z), z); - //glVertex3f(x, 1.0, z); } void WidgetWanderer::paintGL() @@ -45,7 +171,7 @@ void WidgetWanderer::paintGL() glMatrixMode(GL_MODELVIEW); 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); @@ -54,6 +180,7 @@ void WidgetWanderer::paintGL() glEnable(GL_CULL_FACE); glDepthFunc(GL_LEQUAL); + glDepthMask(true); glEnable(GL_DEPTH_TEST); glLineWidth(1.0); @@ -72,15 +199,6 @@ void WidgetWanderer::paintGL() { 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); glColor3f(0.0, 0.5, 0.0); glBegin(GL_QUADS); @@ -89,6 +207,17 @@ void WidgetWanderer::paintGL() _pushTerrainVertex(&terrain, x + step, z + step); _pushTerrainVertex(&terrain, x + step, z); 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); } } } diff --git a/gui_qt/widgetwanderer.h b/gui_qt/widgetwanderer.h index f11270e..ca574c4 100644 --- a/gui_qt/widgetwanderer.h +++ b/gui_qt/widgetwanderer.h @@ -13,14 +13,22 @@ public: WidgetWanderer(QWidget* parent, CameraDefinition* camera); protected: + void keyPressEvent(QKeyEvent* event); + void mousePressEvent(QMouseEvent* event); + void mouseMoveEvent(QMouseEvent* event); + void wheelEvent(QWheelEvent* event); + void initializeGL(); void resizeGL(int w, int h); void paintGL(); private: - CameraDefinition* camera; + CameraDefinition camera; TerrainDefinition terrain; WaterDefinition water; + + int last_mouse_x; + int last_mouse_y; }; #endif diff --git a/lib_paysages/camera.c b/lib_paysages/camera.c index d7888e2..7cf6d93 100644 --- a/lib_paysages/camera.c +++ b/lib_paysages/camera.c @@ -86,6 +86,39 @@ void cameraSetAngle(CameraDefinition* camera, double angle) /* 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) { point = m4Transform(camera->project, v3Sub(point, camera->location)); diff --git a/lib_paysages/camera.h b/lib_paysages/camera.h index 1549741..eb7fb9c 100644 --- a/lib_paysages/camera.h +++ b/lib_paysages/camera.h @@ -29,6 +29,11 @@ void cameraValidateDefinition(CameraDefinition* definition); 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 cameraStrafeForward(CameraDefinition* camera, double value); +void cameraStrafeRight(CameraDefinition* camera, double value); +void cameraStrafeUp(CameraDefinition* camera, double value); + Vector3 cameraProject(CameraDefinition* camera, Vector3 point); Vector3 cameraUnproject(CameraDefinition* camera, Vector3 point); void cameraProjectToFragment(CameraDefinition* camera, double x, double y, double z, RenderFragment* result);