summaryrefslogtreecommitdiffstats
path: root/sdl/glframe.c
diff options
context:
space:
mode:
Diffstat (limited to 'sdl/glframe.c')
-rw-r--r--sdl/glframe.c302
1 files changed, 263 insertions, 39 deletions
diff --git a/sdl/glframe.c b/sdl/glframe.c
index b3dc33e..fbf8cd6 100644
--- a/sdl/glframe.c
+++ b/sdl/glframe.c
@@ -8,25 +8,26 @@
*/
#include <GL/glew.h>
+#include <stdio.h>
#include "glframe.h"
void glframe_reset(GLFrame *frame)
{
- frame->v_location[0] = 0.0f;
- frame->v_location[1] = 0.0f;
- frame->v_location[2] = 0.0f;
-
- frame->v_forward[0] = 0.0f;
- frame->v_forward[1] = 0.0f;
- frame->v_forward[2] = -1.0f;
-
- frame->v_up[0] = 0.0f;
- frame->v_up[1] = 1.0f;
- frame->v_up[2] = 0.0f;
+ frame->v_location[0] = 0.0f;
+ frame->v_location[1] = 0.0f;
+ frame->v_location[2] = 0.0f;
+
+ frame->v_forward[0] = 0.0f;
+ frame->v_forward[1] = 0.0f;
+ frame->v_forward[2] = -1.0f;
+
+ frame->v_up[0] = 0.0f;
+ frame->v_up[1] = 1.0f;
+ frame->v_up[2] = 0.0f;
}
/* get a 4x4 transformation matrix that describes the camera orientation */
-void glframe_get_camera_orientation(GLFrame *frame, M3DMatrix44f m)
+inline void glframe_get_camera_orientation(GLFrame *frame, M3DMatrix44f m)
{
M3DVector3f x, z;
@@ -60,32 +61,26 @@ void glframe_get_camera_orientation(GLFrame *frame, M3DMatrix44f m)
}
/* perform viewing or modeling transformations */
-/* some of the code is unimplemented */
-void glframe_apply_camera_transform(GLFrame *frame)
+inline void glframe_apply_camera_transform(GLFrame *frame, const int rot_only)
{
- /* XXX: rotation only, should be passed in as a parameter */
- int rot_only = 0;
-
M3DMatrix44f m;
glframe_get_camera_orientation(frame, m);
- m3dPrintMatrix44f(m);
-
glMultMatrixf(m);
- /* if rotation only, then do not do the translation */
if (!rot_only)
- glTranslatef(-frame->v_location[0], -frame->v_location[1], -frame->v_location[2]);
+ glTranslatef(-frame->v_location[0], -frame->v_location[1],
+ -frame->v_location[2]);
#if 0
- gluLookAt(v_location[0], v_location[1], v_location[2],
- v_location[0] + v_forward[0],
- v_location[1] + v_forward[1],
- v_location[2] + v_forward[2],
- v_up[0], v_up[1], v_up[2]);
+ gluLookAt(frame->v_location[0], frame->v_location[1], frame->v_location[2],
+ frame->v_location[0] + frame->v_forward[0],
+ frame->v_location[1] + frame->v_forward[1],
+ frame->v_location[2] + frame->v_forward[2],
+ frame->v_up[0], frame->v_up[1], frame->v_up[2]);
#endif
}
-void glframe_move_forward(GLFrame *frame, float delta)
+inline void glframe_move_forward(GLFrame *frame, const float delta)
{
/* move along direction of front direction */
frame->v_location[0] += frame->v_forward[0] * delta;
@@ -93,25 +88,63 @@ void glframe_move_forward(GLFrame *frame, float delta)
frame->v_location[2] += frame->v_forward[2] * delta;
}
-/* rotate left or right */
-void glframe_rotate_local_y(GLFrame *frame, float angle)
+/* move up or down */
+inline void glframe_move_up(GLFrame *frame, const float delta)
+{
+ frame->v_location[0] += frame->v_up[0] * delta;
+ frame->v_location[1] += frame->v_up[1] * delta;
+ frame->v_location[2] += frame->v_up[2] * delta;
+}
+
+/* move left or right */
+inline void glframe_move_right(GLFrame *frame, const float delta)
+{
+ M3DVector3f x;
+
+ m3dCrossProductf(x, frame->v_up, frame->v_forward);
+ frame->v_location[0] += x[0] * delta;
+ frame->v_location[1] += x[1] * delta;
+ frame->v_location[2] += x[2] * delta;
+}
+
+inline void glframe_translate_world(GLFrame *frame, const float x, const float y,
+ const float z)
+{
+ frame->v_location[0] += x;
+ frame->v_location[1] += y;
+ frame->v_location[2] += z;
+}
+
+inline void glframe_translate_local(GLFrame *frame, const float x, const float y,
+ const float z)
+{
+ glframe_move_forward(frame, z);
+ glframe_move_up(frame, y);
+ glframe_move_right(frame, x);
+}
+
+/* yaw */
+void glframe_rotate_local_y(GLFrame *frame, const float angle)
{
M3DMatrix44f rotmat;
M3DVector3f newvect;
- /* just rotate around the up vector */
/* create a rotation matrix around up vector */
- m3dRotationMatrix44f(rotmat, angle, frame->v_up[0], frame->v_up[1], frame->v_up[2]);
+ m3dRotationMatrix44f(rotmat, angle, frame->v_up[0], frame->v_up[1],
+ frame->v_up[2]);
/* rotate forward pointing vector (inlined 3x3 transform) */
- newvect[0] = rotmat[0] * frame->v_forward[0] + rotmat[4] * frame->v_forward[1] + rotmat[8] * frame->v_forward[2];
- newvect[1] = rotmat[1] * frame->v_forward[0] + rotmat[5] * frame->v_forward[1] + rotmat[9] * frame->v_forward[2];
- newvect[2] = rotmat[2] * frame->v_forward[0] + rotmat[6] * frame->v_forward[1] + rotmat[10] * frame->v_forward[2];
+ newvect[0] = rotmat[0] * frame->v_forward[0] + rotmat[4] *
+ frame->v_forward[1] + rotmat[8] * frame->v_forward[2];
+ newvect[1] = rotmat[1] * frame->v_forward[0] + rotmat[5] *
+ frame->v_forward[1] + rotmat[9] * frame->v_forward[2];
+ newvect[2] = rotmat[2] * frame->v_forward[0] + rotmat[6] *
+ frame->v_forward[1] + rotmat[10] * frame->v_forward[2];
m3dCopyVector3f(frame->v_forward, newvect);
}
-/* rotate up or down */
-void glframe_rotate_local_x(GLFrame *frame, float angle)
+/* pitch */
+void glframe_rotate_local_x(GLFrame *frame, const float angle)
{
M3DMatrix44f rotmat;
M3DVector3f newfwdvec;
@@ -130,9 +163,12 @@ void glframe_rotate_local_x(GLFrame *frame, float angle)
m3dRotationMatrix44f(rotmat, angle, x[0], x[1], x[2]);
/* rotate forward pointing vector (inlined 3x3 transform) */
- newfwdvec[0] = rotmat[0] * frame->v_forward[0] + rotmat[4] * frame->v_forward[1] + rotmat[8] * frame->v_forward[2];
- newfwdvec[1] = rotmat[1] * frame->v_forward[0] + rotmat[5] * frame->v_forward[1] + rotmat[9] * frame->v_forward[2];
- newfwdvec[2] = rotmat[2] * frame->v_forward[0] + rotmat[6] * frame->v_forward[1] + rotmat[10] * frame->v_forward[2];
+ newfwdvec[0] = rotmat[0] * frame->v_forward[0] + rotmat[4] *
+ frame->v_forward[1] + rotmat[8] * frame->v_forward[2];
+ newfwdvec[1] = rotmat[1] * frame->v_forward[0] + rotmat[5] *
+ frame->v_forward[1] + rotmat[9] * frame->v_forward[2];
+ newfwdvec[2] = rotmat[2] * frame->v_forward[0] + rotmat[6] *
+ frame->v_forward[1] + rotmat[10] * frame->v_forward[2];
/* calculate new up vector */
m3dCrossProductf(newupvec, x, newfwdvec);
@@ -141,3 +177,191 @@ void glframe_rotate_local_x(GLFrame *frame, float angle)
m3dCopyVector3f(frame->v_up, newupvec);
}
+/* roll */
+void glframe_rotate_local_z(GLFrame *frame, const float angle)
+{
+ M3DMatrix44f rotmat;
+ M3DVector3f newupvec;
+
+ m3dRotationMatrix44f(rotmat, angle, frame->v_forward[0], frame->v_forward[1],
+ frame->v_forward[2]);
+
+ /* rotate forward pointing vector (inlined 3x3 transform) */
+ newupvec[0] = rotmat[0] * frame->v_up[0] + rotmat[4] * frame->v_up[1] +
+ rotmat[8] * frame->v_up[2];
+ newupvec[1] = rotmat[1] * frame->v_up[0] + rotmat[5] * frame->v_up[1] +
+ rotmat[9] * frame->v_up[2];
+ newupvec[2] = rotmat[2] * frame->v_up[0] + rotmat[6] * frame->v_up[1] +
+ rotmat[10] * frame->v_up[2];
+ m3dCopyVector3f(frame->v_up, newupvec);
+}
+
+/* reset axes to make sure they are orthonormal, should be called occasionally
+ * if the matrix is long-lived and frequently transformed
+ */
+void gl_frame_normalize(GLFrame *frame)
+{
+ M3DVector3f x;
+
+ m3dCrossProductf(x, frame->v_up, frame->v_forward);
+
+ /* use result to recalculate forward vector */
+ m3dCrossProductf(frame->v_forward, x, frame->v_up);
+
+ /* also check for unit length */
+ m3dNormalizeVectorf(frame->v_up);
+ m3dNormalizeVectorf(frame->v_forward);
+}
+
+/* assemble the matrix */
+void glframe_get_matrix(GLFrame *frame, M3DMatrix44f m, const int rot_only)
+{
+ M3DVector3f x;
+
+ m3dCrossProductf(x, frame->v_up, frame->v_forward);
+
+ m3dSetMatrixColumn44f(m, x, 0);
+ m[3] = 0.0f;
+
+ m3dSetMatrixColumn44f(m, frame->v_up, 1);
+ m[7] = 0.0f;
+
+ m3dSetMatrixColumn44f(m, frame->v_forward, 2);
+ m[11] = 0.0f;
+
+ if (rot_only)
+ {
+ m[12] = 0.0f;
+ m[13] = 0.0f;
+ m[14] = 0.0f;
+ }
+ else
+ m3dSetMatrixColumn44f(m, frame->v_location, 3);
+
+ m[15] = 1.0f;
+}
+
+/* position as an object in the scene, this places and orients a coordinate
+ * frame for other objects besides the camera
+ */
+void gl_frame_apply_actor_transform(GLFrame *frame)
+{
+ M3DMatrix44f rotmat;
+ glframe_get_matrix(frame, rotmat, 0);
+
+ /* apply rotation to the current matrix */
+ glMultMatrixf(rotmat);
+}
+
+/* rotate in world coordinates */
+void glframe_rotate_world(GLFrame *frame, const float angle, const float x,
+ const float y, const float z)
+{
+ M3DMatrix44f rotmat;
+
+ /* create the rotation matrix */
+ m3dRotationMatrix44f(rotmat, angle, x, y, z);
+
+ M3DVector3f newvect;
+
+ newvect[0] = rotmat[0] * frame->v_up[0] + rotmat[4] *
+ frame->v_up[1] + rotmat[8] * frame->v_up[2];
+ newvect[1] = rotmat[1] * frame->v_up[0] + rotmat[5] *
+ frame->v_up[1] + rotmat[9] * frame->v_up[2];
+ newvect[2] = rotmat[2] * frame->v_up[0] + rotmat[6] *
+ frame->v_up[1] + rotmat[10] * frame->v_up[2];
+
+ m3dCopyVector3f(frame->v_up, newvect);
+
+ /* transform the forward axis */
+ newvect[0] = rotmat[0] * frame->v_forward[0] + rotmat[4] *
+ frame->v_forward[1] + rotmat[8] * frame->v_forward[2];
+ newvect[1] = rotmat[1] * frame->v_forward[0] + rotmat[5] *
+ frame->v_forward[1] + rotmat[9] * frame->v_forward[2];
+ newvect[2] = rotmat[2] * frame->v_forward[0] + rotmat[6] *
+ frame->v_forward[1] + rotmat[10] * frame->v_forward[2];
+
+ m3dCopyVector3f(frame->v_forward, newvect);
+}
+
+/* rotate around a local axis */
+void glframe_rotate_local(GLFrame *frame, const float angle, const float x,
+ const float y, const float z)
+{
+ M3DVector3f world_vec;
+ M3DVector3f local_vec;
+ m3dLoadVector3f(local_vec, x, y, z);
+
+ glframe_local_to_world(frame, local_vec, world_vec);
+ glframe_rotate_world(frame, angle, world_vec[0], world_vec[1], world_vec[2]);
+}
+
+/* convert coordinate systems, do the transformation represented by the rotation
+ * and position on the point
+ */
+void glframe_local_to_world(GLFrame *frame, const M3DVector3f local, M3DVector3f world)
+{
+ M3DMatrix44f rotmat;
+
+ glframe_get_matrix(frame, rotmat, 1);
+
+ world[0] = rotmat[0] * local[0] + rotmat[4] * local[1] + rotmat[8] * local[2];
+ world[1] = rotmat[1] * local[0] + rotmat[5] * local[1] + rotmat[9] * local[2];
+ world[2] = rotmat[2] * local[0] + rotmat[6] * local[1] + rotmat[10] * local[2];
+
+ /* translate the point */
+ world[0] += frame->v_location[0];
+ world[1] += frame->v_location[1];
+ world[2] += frame->v_location[2];
+}
+
+/* change world coordinates into "local" coordinates */
+void glframe_world_to_local(GLFrame *frame, const M3DVector3f world, M3DVector3f local)
+{
+ /* translate the origin */
+ M3DVector3f new_world;
+ new_world[0] = world[0] - frame->v_location[0];
+ new_world[1] = world[1] - frame->v_location[1];
+ new_world[2] = world[2] - frame->v_location[2];
+
+ /* create the rotation matrix based on the vectors */
+ M3DMatrix44f rotmat;
+ M3DMatrix44f invmat;
+ glframe_get_matrix(frame, rotmat, 1);
+
+ /* do the rotation based on inverted matrix */
+ if (m3dInvertMatrix44f(invmat, rotmat) == -1)
+ fprintf(stderr, "glframe: m3dInvertMatrix44f() failed\n");
+
+ local[0] = invmat[0] * new_world[0] + invmat[4] *
+ new_world[1] + invmat[8] * new_world[2];
+ local[1] = invmat[1] * new_world[0] + invmat[5] *
+ new_world[1] + invmat[9] * new_world[2];
+ local[2] = invmat[2] * new_world[0] + invmat[6] *
+ new_world[1] + invmat[10] * new_world[2];
+}
+
+/* transform a point by frame matrix */
+void glframe_transform_point(GLFrame *frame, const M3DVector3f src, M3DVector3f dst)
+{
+ M3DMatrix44f m;
+
+ /* rotate and translate */
+ glframe_get_matrix(frame, m, 0);
+
+ dst[0] = m[0] * src[0] + m[4] * src[1] + m[8] * src[2] + m[12];
+ dst[1] = m[1] * src[0] + m[5] * src[1] + m[9] * src[2] + m[13];
+ dst[2] = m[2] * src[0] + m[6] * src[1] + m[10] * src[2] + m[14];
+}
+
+/* rotate a vector by frame matrix */
+void glframe_rotate_vector(GLFrame *frame, M3DVector3f src, M3DVector3f dst)
+{
+ M3DMatrix44f m;
+ glframe_get_matrix(frame, m, 1); /* rotate only */
+
+ dst[0] = m[0] * src[0] + m[4] * src[1] + m[8] * src[2];
+ dst[1] = m[1] * src[0] + m[5] * src[1] + m[9] * src[2];
+ dst[2] = m[2] * src[0] + m[6] * src[1] + m[10] * src[2];
+}
+