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. Reviewed-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
parent
3a2f94045e
commit
f37d9bbb4d
@ -2051,3 +2051,65 @@ cogl_matrix_is_identity (const CoglMatrix *matrix)
|
|||||||
else
|
else
|
||||||
return memcmp (matrix, identity, sizeof (float) * 16) == 0;
|
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);
|
||||||
|
}
|
||||||
|
@ -193,6 +193,62 @@ cogl_matrix_scale (CoglMatrix *matrix,
|
|||||||
float sy,
|
float sy,
|
||||||
float sz);
|
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.
|
||||||
|
*
|
||||||
|
* 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>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>
|
||||||
|
*
|
||||||
|
* Since: 1.8
|
||||||
|
* Stability: unstable
|
||||||
|
*/
|
||||||
|
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:
|
* cogl_matrix_frustum:
|
||||||
* @matrix: A 4x4 transformation matrix
|
* @matrix: A 4x4 transformation matrix
|
||||||
|
@ -424,6 +424,7 @@ cogl_matrix_free
|
|||||||
cogl_matrix_frustum
|
cogl_matrix_frustum
|
||||||
cogl_matrix_ortho
|
cogl_matrix_ortho
|
||||||
cogl_matrix_perspective
|
cogl_matrix_perspective
|
||||||
|
cogl_matrix_look_at
|
||||||
cogl_matrix_multiply
|
cogl_matrix_multiply
|
||||||
cogl_matrix_rotate
|
cogl_matrix_rotate
|
||||||
cogl_matrix_translate
|
cogl_matrix_translate
|
||||||
|
Loading…
Reference in New Issue
Block a user