paysages : WIP.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@559 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
9a4cf159ee
commit
48ce97e4cb
8 changed files with 224 additions and 59 deletions
|
@ -6,6 +6,7 @@
|
|||
#include <math.h>
|
||||
#include <GL/glu.h>
|
||||
#include "tools.h"
|
||||
#include "rendering/scenery.h"
|
||||
|
||||
#define HEIGHTMAP_RESOLUTION 256
|
||||
|
||||
|
@ -27,6 +28,13 @@ QGLWidget(parent)
|
|||
|
||||
_dirty = true;
|
||||
|
||||
_water = true;
|
||||
_wireframe = true;
|
||||
WaterDefinition* water_definition = (WaterDefinition*) WaterDefinitionClass.create();
|
||||
sceneryGetWater(water_definition);
|
||||
_water_height = water_definition->height;
|
||||
WaterDefinitionClass.destroy(water_definition);
|
||||
|
||||
_average_frame_time = 0.0;
|
||||
|
||||
_last_brush_action = 0;
|
||||
|
@ -38,10 +46,12 @@ QGLWidget(parent)
|
|||
_current_camera = cameraCreateDefinition();
|
||||
_top_camera = cameraCreateDefinition();
|
||||
_temp_camera = cameraCreateDefinition();
|
||||
_zoom = 50.0;
|
||||
|
||||
Vector3 camera_location = {0.0, 80.0, 20.0};
|
||||
Vector3 camera_location = {0.0, 80.0, 10.0};
|
||||
cameraSetLocation(_current_camera, camera_location);
|
||||
cameraSetTarget(_current_camera, VECTOR_ZERO);
|
||||
cameraSetZoomToTarget(_top_camera, _zoom);
|
||||
cameraCopyDefinition(_current_camera, _top_camera);
|
||||
|
||||
_brush_x = 0.0;
|
||||
|
@ -132,6 +142,25 @@ void WidgetHeightMap::revert()
|
|||
updateGL();
|
||||
}
|
||||
|
||||
void WidgetHeightMap::wheelEvent(QWheelEvent* event)
|
||||
{
|
||||
if (event->orientation() == Qt::Vertical)
|
||||
{
|
||||
_zoom -= 0.05 * (double) event->delta();
|
||||
if (_zoom < 10.0)
|
||||
{
|
||||
_zoom = 10.0;
|
||||
}
|
||||
else if (_zoom > 70.0)
|
||||
{
|
||||
_zoom = 70.0;
|
||||
}
|
||||
|
||||
cameraSetZoomToTarget(_top_camera, _zoom);
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void WidgetHeightMap::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
_last_mouse_x = event->x();
|
||||
|
@ -228,7 +257,7 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
|
|||
}
|
||||
|
||||
// Move camera
|
||||
if (cameraTransitionToAnother(_current_camera, _top_camera, 0.1))
|
||||
if (cameraTransitionToAnother(_current_camera, _top_camera, 0.8))
|
||||
{
|
||||
updateGL();
|
||||
}
|
||||
|
@ -293,8 +322,8 @@ void WidgetHeightMap::initializeGL()
|
|||
//glCullFace(GL_BACK);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glDepthFunc(GL_LESS);
|
||||
glDepthMask(true);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthMask(GL_TRUE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
@ -421,6 +450,52 @@ void WidgetHeightMap::paintGL()
|
|||
glEnd();
|
||||
}
|
||||
|
||||
// Wireframe
|
||||
if (_wireframe)
|
||||
{
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4f(0.8, 0.0, 0.0, 0.1);
|
||||
for (int z = 0; z < rz; z++)
|
||||
{
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int x = 0; x < rx; x++)
|
||||
{
|
||||
_VertexInfo* vertex = _vertices + z * rx + x;
|
||||
glVertex3f(vertex->point.x - tx, vertex->point.y, vertex->point.z - tz);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
for (int x = 0; x < rx; x++)
|
||||
{
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int z = 0; z < rz; z++)
|
||||
{
|
||||
_VertexInfo* vertex = _vertices + z * rx + x;
|
||||
glVertex3f(vertex->point.x - tx, vertex->point.y, vertex->point.z - tz);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
glEnable(GL_LIGHTING);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
// Water
|
||||
if (_water)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4f(0.2, 0.3, 0.7, 0.7);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(camera_target.x - 500.0, _water_height, camera_target.z - 500.0);
|
||||
glVertex3f(camera_target.x - 500.0, _water_height, camera_target.z + 500.0);
|
||||
glVertex3f(camera_target.x + 500.0, _water_height, camera_target.z + 500.0);
|
||||
glVertex3f(camera_target.x + 500.0, _water_height, camera_target.z - 500.0);
|
||||
glEnd();
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
// Time stats
|
||||
frame_time = 0.001 * (double) start_time.msecsTo(QTime::currentTime());
|
||||
_average_frame_time = _average_frame_time * 0.8 + frame_time * 0.2;
|
||||
|
|
|
@ -46,6 +46,7 @@ protected:
|
|||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
|
||||
void timerEvent(QTimerEvent* event);
|
||||
|
||||
|
@ -64,6 +65,10 @@ private:
|
|||
bool _dirty;
|
||||
qint64 _memory_stats;
|
||||
|
||||
double _water_height;
|
||||
bool _water;
|
||||
bool _wireframe;
|
||||
|
||||
double _average_frame_time;
|
||||
|
||||
int _last_brush_action;
|
||||
|
@ -75,6 +80,7 @@ private:
|
|||
CameraDefinition* _top_camera;
|
||||
CameraDefinition* _temp_camera;
|
||||
CameraDefinition* _current_camera;
|
||||
double _zoom;
|
||||
|
||||
double _brush_x;
|
||||
double _brush_z;
|
||||
|
|
|
@ -8,24 +8,21 @@
|
|||
|
||||
struct CameraDefinition
|
||||
{
|
||||
/* Definition */
|
||||
Vector3 location;
|
||||
double yaw;
|
||||
double pitch;
|
||||
VectorSpherical direction;
|
||||
double roll;
|
||||
|
||||
/* Projection info */
|
||||
double width;
|
||||
double height;
|
||||
CameraPerspective perspective;
|
||||
|
||||
/* Auto updated */
|
||||
Vector3 target;
|
||||
Vector3 forward;
|
||||
Vector3 right;
|
||||
Vector3 up;
|
||||
|
||||
double width;
|
||||
double height;
|
||||
CameraPerspective perspective;
|
||||
double yfov;
|
||||
double xratio;
|
||||
double znear;
|
||||
double zfar;
|
||||
|
||||
Matrix4 project;
|
||||
Matrix4 unproject;
|
||||
};
|
||||
|
@ -33,16 +30,18 @@ struct CameraDefinition
|
|||
void cameraSave(PackStream* stream, CameraDefinition* camera)
|
||||
{
|
||||
v3Save(stream, &camera->location);
|
||||
packWriteDouble(stream, &camera->yaw);
|
||||
packWriteDouble(stream, &camera->pitch);
|
||||
packWriteDouble(stream, &camera->direction.r);
|
||||
packWriteDouble(stream, &camera->direction.phi);
|
||||
packWriteDouble(stream, &camera->direction.theta);
|
||||
packWriteDouble(stream, &camera->roll);
|
||||
}
|
||||
|
||||
void cameraLoad(PackStream* stream, CameraDefinition* camera)
|
||||
{
|
||||
v3Load(stream, &camera->location);
|
||||
packReadDouble(stream, &camera->yaw);
|
||||
packReadDouble(stream, &camera->pitch);
|
||||
packReadDouble(stream, &camera->direction.r);
|
||||
packReadDouble(stream, &camera->direction.phi);
|
||||
packReadDouble(stream, &camera->direction.theta);
|
||||
packReadDouble(stream, &camera->roll);
|
||||
|
||||
cameraValidateDefinition(camera, 0);
|
||||
|
@ -57,16 +56,17 @@ CameraDefinition* cameraCreateDefinition()
|
|||
definition->location.x = 0.0;
|
||||
definition->location.y = 0.0;
|
||||
definition->location.z = 0.0;
|
||||
definition->yaw = 0.0;
|
||||
definition->pitch = 0.0;
|
||||
definition->direction.phi = 0.0;
|
||||
definition->direction.theta = 0.0;
|
||||
definition->direction.r = 1.0;
|
||||
definition->roll = 0.0;
|
||||
|
||||
definition->width = 1.0;
|
||||
definition->height = 1.0;
|
||||
definition->yfov = 1.57;
|
||||
definition->xratio = 1.0;
|
||||
definition->znear = 1.0;
|
||||
definition->zfar = 1000.0;
|
||||
definition->perspective.yfov = 1.57;
|
||||
definition->perspective.xratio = 1.0;
|
||||
definition->perspective.znear = 1.0;
|
||||
definition->perspective.zfar = 1000.0;
|
||||
|
||||
cameraValidateDefinition(definition, 0);
|
||||
|
||||
|
@ -131,15 +131,15 @@ void cameraValidateDefinition(CameraDefinition* definition, int check_above)
|
|||
definition->up.y = 1.0;
|
||||
definition->up.z = 0.0;
|
||||
|
||||
rotation = m4NewRotateEuler(definition->yaw, definition->pitch, definition->roll);
|
||||
rotation = m4NewRotateEuler(definition->direction.phi, definition->direction.theta, 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->target = v3Add(definition->location, v3FromSpherical(definition->direction));
|
||||
|
||||
definition->project = m4Mult(m4NewPerspective(definition->yfov, definition->xratio, definition->znear, definition->zfar), m4NewLookAt(definition->location, definition->target, definition->up));
|
||||
definition->project = m4Mult(m4NewPerspective(definition->perspective.yfov, definition->perspective.xratio, definition->perspective.znear, definition->perspective.zfar), m4NewLookAt(definition->location, definition->target, definition->up));
|
||||
definition->unproject = m4Inverse(definition->project);
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ double cameraGetRoll(CameraDefinition* camera)
|
|||
|
||||
Vector3 cameraGetDirection(CameraDefinition* camera)
|
||||
{
|
||||
return camera->forward;
|
||||
return v3FromSpherical(camera->direction);
|
||||
}
|
||||
|
||||
Vector3 cameraGetDirectionNormalized(CameraDefinition* camera)
|
||||
|
@ -175,6 +175,7 @@ Vector3 cameraGetDirectionNormalized(CameraDefinition* camera)
|
|||
|
||||
VectorSpherical cameraGetDirectionSpherical(CameraDefinition* camera)
|
||||
{
|
||||
return camera->direction;
|
||||
}
|
||||
|
||||
CameraPerspective cameraGetPerspective(CameraDefinition* camera)
|
||||
|
@ -204,27 +205,8 @@ void cameraSetTarget(CameraDefinition* camera, Vector3 target)
|
|||
{
|
||||
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
|
||||
{
|
||||
/* Guess angles */
|
||||
VectorSpherical spherical = v3ToSpherical(forward);
|
||||
camera->yaw = spherical.phi;
|
||||
camera->pitch = spherical.theta;
|
||||
}
|
||||
camera->direction = v3ToSpherical(forward);
|
||||
|
||||
cameraValidateDefinition(camera, 0);
|
||||
}
|
||||
|
@ -242,6 +224,14 @@ void cameraSetRoll(CameraDefinition* camera, double angle)
|
|||
cameraValidateDefinition(camera, 0);
|
||||
}
|
||||
|
||||
void cameraSetZoomToTarget(CameraDefinition* camera, double zoom)
|
||||
{
|
||||
camera->direction.r = zoom;
|
||||
camera->location = v3Add(camera->target, v3Scale(v3FromSpherical(camera->direction), -1.0));
|
||||
|
||||
cameraValidateDefinition(camera, 0);
|
||||
}
|
||||
|
||||
void cameraStrafeForward(CameraDefinition* camera, double value)
|
||||
{
|
||||
camera->location = v3Add(camera->location, v3Scale(camera->forward, value));
|
||||
|
@ -265,14 +255,14 @@ void cameraStrafeUp(CameraDefinition* camera, double value)
|
|||
|
||||
void cameraRotateYaw(CameraDefinition* camera, double value)
|
||||
{
|
||||
camera->yaw += value;
|
||||
camera->direction.phi += value;
|
||||
|
||||
cameraValidateDefinition(camera, 0);
|
||||
}
|
||||
|
||||
void cameraRotatePitch(CameraDefinition* camera, double value)
|
||||
{
|
||||
camera->pitch += value;
|
||||
camera->direction.theta += value;
|
||||
|
||||
cameraValidateDefinition(camera, 0);
|
||||
}
|
||||
|
@ -288,7 +278,7 @@ void cameraSetRenderSize(CameraDefinition* camera, int width, int height)
|
|||
{
|
||||
camera->width = (double)width;
|
||||
camera->height = (double)height;
|
||||
camera->xratio = camera->width / camera->height;
|
||||
camera->perspective.xratio = camera->width / camera->height;
|
||||
|
||||
cameraValidateDefinition(camera, 0);
|
||||
}
|
||||
|
@ -408,12 +398,36 @@ int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, do
|
|||
projected = cameraProject(camera, center);
|
||||
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
||||
|
||||
return xmin <= camera->width && xmax >= 0.0 && ymin <= camera->height && ymax >= 0.0 && zmax >= camera->znear;
|
||||
return xmin <= camera->width && xmax >= 0.0 && ymin <= camera->height && ymax >= 0.0 && zmax >= camera->perspective.znear;
|
||||
}
|
||||
|
||||
int cameraTransitionToAnother(CameraDefinition* current, CameraDefinition* wanted, double factor)
|
||||
{
|
||||
current->location.z += factor;
|
||||
cameraValidateDefinition(current, 0);
|
||||
return 1;
|
||||
double dx, dy, dz, dr, dphi, dtheta, droll;
|
||||
|
||||
dx = wanted->location.x - current->location.x;
|
||||
dy = wanted->location.y - current->location.y;
|
||||
dz = wanted->location.z - current->location.z;
|
||||
dr = wanted->direction.r - current->direction.r;
|
||||
dphi = wanted->direction.phi - current->direction.phi;
|
||||
dtheta = wanted->direction.theta - current->direction.theta;
|
||||
droll = wanted->roll - current->roll;
|
||||
|
||||
if (fabs(dx) < 0.000001 && fabs(dy) < 0.000001 && fabs(dz) < 0.000001 && fabs(dr) < 0.000001 && fabs(dphi) < 0.000001 && fabs(dtheta) < 0.000001 && fabs(droll) < 0.000001)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
current->location.x += dx * factor;
|
||||
current->location.y += dy * factor;
|
||||
current->location.z += dz * factor;
|
||||
current->direction.r += dr * factor;
|
||||
current->direction.phi += dphi * factor;
|
||||
current->direction.theta += dtheta * factor;
|
||||
current->roll += droll * factor;
|
||||
|
||||
cameraValidateDefinition(current, 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ void cameraSetLocationCoords(CameraDefinition* camera, double x, double y, doubl
|
|||
void cameraSetTarget(CameraDefinition* camera, Vector3 target);
|
||||
void cameraSetTargetCoords(CameraDefinition* camera, double x, double y, double z);
|
||||
void cameraSetRoll(CameraDefinition* camera, double angle);
|
||||
void cameraSetZoomToTarget(CameraDefinition* camera, double zoom);
|
||||
|
||||
void cameraStrafeForward(CameraDefinition* camera, double value);
|
||||
void cameraStrafeRight(CameraDefinition* camera, double value);
|
||||
|
|
|
@ -105,9 +105,21 @@ Vector3 v3Cross(Vector3 v1, Vector3 v2)
|
|||
VectorSpherical v3ToSpherical(Vector3 v)
|
||||
{
|
||||
VectorSpherical result;
|
||||
result.phi = euclidGet2DAngle(v.x, v.z);
|
||||
|
||||
result.phi = euclidGet2DAngle(v.x, -v.z);
|
||||
result.theta = euclidGet2DAngle(sqrt(v.x * v.x + v.z * v.z), v.y);
|
||||
if (v.y < 0.0)
|
||||
{
|
||||
result.theta -= 2.0 * M_PI;
|
||||
}
|
||||
result.r = v3Norm(v);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector3 v3FromSpherical(VectorSpherical v)
|
||||
{
|
||||
Vector3 result = {v.r * cos(v.phi) * cos(v.theta), v.r * sin(v.theta), -v.r * sin(v.phi) * cos(v.theta)};
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ Vector3 v3Normalize(Vector3 v);
|
|||
double v3Dot(Vector3 v1, Vector3 v2);
|
||||
Vector3 v3Cross(Vector3 v1, Vector3 v2);
|
||||
VectorSpherical v3ToSpherical(Vector3 v);
|
||||
Vector3 v3FromSpherical(VectorSpherical v);
|
||||
|
||||
void m4Save(PackStream* stream, Matrix4* m);
|
||||
void m4Load(PackStream* stream, Matrix4* m);
|
||||
|
|
|
@ -13,7 +13,7 @@ START_TEST(test_camera_definition)
|
|||
cameraSetTargetCoords(cam, 0.0, 0.0, 0.0);
|
||||
|
||||
_checkVector(cameraGetLocation(cam), 0.0, 1.0, 1.0);
|
||||
_checkVector(cameraGetTarget(cam), 0.0, 1.0, 1.0);
|
||||
_checkVector(cameraGetTarget(cam), 0.0, 0.0, 0.0);
|
||||
|
||||
cameraDeleteDefinition(cam);
|
||||
}
|
||||
|
|
|
@ -66,10 +66,66 @@ START_TEST(test_vectors_spherical)
|
|||
VectorSpherical v2;
|
||||
|
||||
/* Test conversion to spherical */
|
||||
v1.x = 0.0;
|
||||
v1.y = 0.0;
|
||||
v1.z = 0.0;
|
||||
v2 = v3ToSpherical(v1);
|
||||
ck_assert_double_eq(v2.r, 0.0);
|
||||
ck_assert_double_eq(v2.phi, 0.0);
|
||||
ck_assert_double_eq(v2.theta, 0.0);
|
||||
|
||||
v1.x = 1.0;
|
||||
v1.y = 0.0;
|
||||
v1.z = 0.0;
|
||||
v2 = v3ToSpherical(v1);
|
||||
ck_assert_double_eq(v2.r, 1.0);
|
||||
ck_assert_double_eq(v2.phi, 0.0);
|
||||
ck_assert_double_eq(v2.theta, 0.0);
|
||||
|
||||
v1.x = -1.0;
|
||||
v1.y = 0.0;
|
||||
v1.z = 0.0;
|
||||
v2 = v3ToSpherical(v1);
|
||||
ck_assert_double_eq(v2.r, 1.0);
|
||||
ck_assert_double_eq(v2.phi, M_PI);
|
||||
ck_assert_double_eq(v2.theta, 0.0);
|
||||
|
||||
v1.x = 0.0;
|
||||
v1.y = 1.0;
|
||||
v1.z = 0.0;
|
||||
v2 = v3ToSpherical(v1);
|
||||
ck_assert_double_eq(v2.r, 1.0);
|
||||
ck_assert_double_eq(v2.phi, 0.0);
|
||||
ck_assert_double_eq(v2.theta, M_PI_2);
|
||||
|
||||
v1.x = 0.0;
|
||||
v1.y = -1.0;
|
||||
v1.z = 0.0;
|
||||
v2 = v3ToSpherical(v1);
|
||||
ck_assert_double_eq(v2.r, 1.0);
|
||||
ck_assert_double_eq(v2.phi, 0.0);
|
||||
ck_assert_double_eq(v2.theta, -M_PI_2);
|
||||
|
||||
v1.x = 0.0;
|
||||
v1.y = 0.0;
|
||||
v1.z = 1.0;
|
||||
v2 = v3ToSpherical(v1);
|
||||
ck_assert_double_eq(v2.r, 1.0);
|
||||
ck_assert_double_eq(v2.phi, 3.0 * M_PI_2);
|
||||
ck_assert_double_eq(v2.theta, 0.0);
|
||||
|
||||
v1.x = 0.0;
|
||||
v1.y = 0.0;
|
||||
v1.z = -1.0;
|
||||
v2 = v3ToSpherical(v1);
|
||||
ck_assert_double_eq(v2.r, 1.0);
|
||||
ck_assert_double_eq(v2.phi, M_PI_2);
|
||||
ck_assert_double_eq(v2.theta, 0.0);
|
||||
|
||||
v1.x = v1.y = v1.z = 0.5;
|
||||
v2 = v3ToSpherical(v1);
|
||||
ck_assert_double_eq(v2.r, sqrt(0.5 * 0.5 + 0.5 * 0.5 + 0.5 * 0.5));
|
||||
ck_assert_double_eq(v2.phi, M_PI_4);
|
||||
ck_assert_double_eq(v2.phi, 7.0 * M_PI_4);
|
||||
ck_assert_double_eq(v2.theta, M_PI_2 - 0.955316618125);
|
||||
}
|
||||
END_TEST
|
||||
|
|
Loading…
Reference in a new issue