GNOME Bugzilla – Bug 655228
Bugs in cogl-quaternion library functions cogl_quaternion_init_from_array and cogl_quaternion_get_rotation_axis.
Last modified: 2011-07-27 17:28:38 UTC
The Quaternion library function cogl_quaternion_init_from_array is passing a pointer to the wrong structure member to memcpy. ------------------------------------------------------------------------------ diff --git a/cogl/cogl-quaternion.c b/cogl/cogl-quaternion.c index ff59720..d7592a2 100644 --- a/cogl/cogl-quaternion.c +++ b/cogl/cogl-quaternion.c @@ -122,5 +122,5 @@ cogl_quaternion_init_from_array (CoglQuaternion *quaternion, const float *array) { - memcpy (&quaternion->x, array, sizeof (float) * 4); + memcpy (&quaternion->w, array, sizeof (float) * 4); } ------------------------------------------------------------------------------ /* Reproducing cogl_quaternion_init_from_array bug */ #include <stdlib.h> #include <assert.h> #include <math.h> #include <cogl/cogl.h> #define FEQUALS(x,y) (fabs((x)-(y))<0.001f) int main (int argc, char **argv) { CoglQuaternion quat; float vals[4] = { 1.0f, 2.0f, 3.0f, 4.0f }; cogl_quaternion_init_from_array (&quat, vals); assert (FEQUALS (quat.w, 1.0f)); return EXIT_SUCCESS; } ------------------------------------------------------------------------------ Additionally this paragraph of the C99 standard: 6.7.2.1:13 ".. There may be unnamed padding within a structure object, .." Would suggest that the method of memcpy-ing the array of floats into the structure produces non-portable behavior. Initializing each of the members separately as the alternative solution: ------------------------------------------------------------------------------ diff --git a/cogl/cogl-quaternion.c b/cogl/cogl-quaternion.c index ff59720..9403fc7 100644 --- a/cogl/cogl-quaternion.c +++ b/cogl/cogl-quaternion.c @@ -122,5 +122,8 @@ cogl_quaternion_init_from_array (CoglQuaternion *quaternion, const float *array) { - memcpy (&quaternion->x, array, sizeof (float) * 4); + quaternion->w = array[0]; + quaternion->x = array[1]; + quaternion->y = array[2]; + quaternion->z = array[3]; } ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ The Quaternion library function cogl_quaternion_get_rotation_axis might be broken. Seems the intent is use of equation equivalent to http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q57 However, only the 'x' component is set. ------------------------------------------------------------------------------ diff --git a/cogl/cogl-quaternion.c b/cogl/cogl-quaternion.c index ff59720..7ec4d4e 100644 --- a/cogl/cogl-quaternion.c +++ b/cogl/cogl-quaternion.c @@ -390,6 +390,6 @@ cogl_quaternion_get_rotation_axis (const CoglQuaternion *quaternion, vector->x = quaternion->x * one_over_sin_angle_over_2; - vector->x = quaternion->x * one_over_sin_angle_over_2; - vector->x = quaternion->x * one_over_sin_angle_over_2; + vector->y = quaternion->y * one_over_sin_angle_over_2; + vector->z = quaternion->z * one_over_sin_angle_over_2; }
thanks a lot for finding and detailing these issues. I've landed a patch in master that resolves these issues in the ways you suggested: b8b37f6c41a768 regards