[cogl/wip/rib/master-next: 12/12] matrix: Add cogl_matrix_look_at
- From: Robert Bragg <rbragg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/rib/master-next: 12/12] matrix: Add cogl_matrix_look_at
- Date: Thu, 11 Aug 2011 14:34:17 +0000 (UTC)
commit 474ce951b47e128e623115c8b39b159e04622101
Author: Robert Bragg <robert linux intel com>
Date: Sat Jul 9 02:43:17 2011 +0100
matrix: Add cogl_matrix_look_at
Similar to the widely used gluLookAt API, this adds a CoglMatrix utility
for setting up a view transform in terms of positioning a camera/eye
position that points to a given object position aligned to a given
world-up vector.
cogl/cogl-matrix.c | 62 ++++++++++++++++++++
cogl/cogl-matrix.h | 52 ++++++++++++++++
.../cogl-2.0-experimental-sections.txt | 1 +
3 files changed, 115 insertions(+), 0 deletions(-)
---
diff --git a/cogl/cogl-matrix.c b/cogl/cogl-matrix.c
index 4ceece7..7941bb6 100644
--- a/cogl/cogl-matrix.c
+++ b/cogl/cogl-matrix.c
@@ -2051,3 +2051,65 @@ cogl_matrix_is_identity (const CoglMatrix *matrix)
else
return memcmp (matrix, identity, sizeof (float) * 16) == 0;
}
+
+void
+cogl_matrix_look_at (CoglMatrix *matrix,
+ float eye_position_x,
+ float eye_position_y,
+ float eye_position_z,
+ float object_x,
+ float object_y,
+ float object_z,
+ float world_up_x,
+ float world_up_y,
+ float world_up_z)
+{
+ CoglMatrix tmp;
+ CoglVector3 forward;
+ CoglVector3 side;
+ CoglVector3 up;
+
+ /* Get a unit viewing direction vector */
+ cogl_vector3_init (&forward,
+ object_x - eye_position_x,
+ object_y - eye_position_y,
+ object_z - eye_position_z);
+ cogl_vector3_normalize (&forward);
+
+ cogl_vector3_init (&up, world_up_x, world_up_y, world_up_z);
+
+ /* Take the sideways direction as being perpendicular to the viewing
+ * direction and the word up vector. */
+ cogl_vector3_cross_product (&side, &forward, &up);
+ cogl_vector3_normalize (&side);
+
+ /* Now we have unit sideways and forward-direction vectors calculate
+ * a new mutually perpendicular up vector. */
+ cogl_vector3_cross_product (&up, &side, &forward);
+
+ tmp.xx = side.x;
+ tmp.yx = side.y;
+ tmp.zx = side.z;
+ tmp.wx = 0;
+
+ tmp.xy = up.x;
+ tmp.yy = up.y;
+ tmp.zy = up.z;
+ tmp.wy = 0;
+
+ tmp.xz = -forward.x;
+ tmp.yz = -forward.y;
+ tmp.zz = -forward.z;
+ tmp.wz = 0;
+
+ tmp.xw = 0;
+ tmp.yw = 0;
+ tmp.zw = 0;
+ tmp.ww = 1;
+
+ cogl_matrix_translate (&tmp, -eye_position_x, -eye_position_y, -eye_position_z);
+
+ tmp.flags = (MAT_FLAG_GENERAL_3D | MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE);
+
+ cogl_matrix_multiply (matrix, matrix, &tmp);
+}
diff --git a/cogl/cogl-matrix.h b/cogl/cogl-matrix.h
index a2c2385..63827b9 100644
--- a/cogl/cogl-matrix.h
+++ b/cogl/cogl-matrix.h
@@ -193,6 +193,58 @@ cogl_matrix_scale (CoglMatrix *matrix,
float sy,
float sz);
+#define cogl_matrix_look_at cogl_matrix_look_at_EXP
+/**
+ * cogl_matrix_look_at:
+ * @matrix: A 4x4 transformation matrix
+ * @eye_position_x: The X coordinate to look from
+ * @eye_position_y: The Y coordinate to look from
+ * @eye_position_z: The Z coordinate to look from
+ * @object_x: The X coordinate of the object to look at
+ * @object_y: The Y coordinate of the object to look at
+ * @object_z: The Z coordinate of the object to look at
+ * @world_up_x: The X component of the world's up direction vector
+ * @world_up_y: The Y component of the world's up direction vector
+ * @world_up_z: The Z component of the world's up direction vector
+ *
+ * Applies a view transform @matrix that positions the camera at
+ * the coordinate (@eye_position_x, @eye_position_y, @eye_position_z)
+ * looking towards an object at the coordinate (@object_x, @object_y,
+ * @object_z). The top of the camera is aligned to the given world up
+ * vector, which is normally simply (0, 1, 0) to map up to the
+ * positive direction of the y axis.
+ *
+ * <note>You should never look directly along the world-up
+ * vector.</note>
+ *
+ * <note>It is assumed you are using a typical projection matrix where
+ * your origin maps to the center of your viewport.</note>
+ *
+ * <note>Almost always when you use this function it should be the first
+ * transform applied to a new modelview transform</note>
+ *
+ * <note>Because there is a lot of missleading documentation online for
+ * gluLookAt regarding the up vector we want to try and be a bit clearer here.
+ *
+ * The up vector should simply be relative to your world coordinates
+ * and does not need to change as you move the eye and object positions.
+ * Many online sources may claim that the up vector needs to be perpendicular
+ * to the vector between the eye and object position (partly because the
+ * man page is somewhat missleading) but that is not necessary for this
+ * function.</note>
+ */
+void
+cogl_matrix_look_at (CoglMatrix *matrix,
+ float eye_position_x,
+ float eye_position_y,
+ float eye_position_z,
+ float object_x,
+ float object_y,
+ float object_z,
+ float world_up_x,
+ float world_up_y,
+ float world_up_z);
+
/**
* cogl_matrix_frustum:
* @matrix: A 4x4 transformation matrix
diff --git a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt
index 6c0809c..35f4d63 100644
--- a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt
+++ b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt
@@ -424,6 +424,7 @@ cogl_matrix_free
cogl_matrix_frustum
cogl_matrix_ortho
cogl_matrix_perspective
+cogl_matrix_look_at
cogl_matrix_multiply
cogl_matrix_rotate
cogl_matrix_translate
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]