From: Christophe Sadoine <chris@indefini.org>
authorChristophe Sadoine <chris@indefini.org>
Fri, 31 Aug 2012 07:05:48 +0000 (07:05 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Fri, 31 Aug 2012 07:05:48 +0000 (07:05 +0000)
Subject: [E-devel] [patch] A function to rotate an evas map with a
quaternion

So this is a patch to rotate an evas map with a quaternion.
You can use this to avoid gimbal lock... for example in the elementary
evas map 3d test, if you put the Rot y angle to 90 then Rot x and Rot
z will do the same rotation...

SVN revision: 75920

legacy/evas/AUTHORS
legacy/evas/ChangeLog
legacy/evas/NEWS
legacy/evas/src/lib/Evas.h
legacy/evas/src/lib/canvas/evas_map.c

index 82f644e..ae614e5 100644 (file)
@@ -36,3 +36,4 @@ Hyoyoung Chang <hyoyoung@gmail.com>
 Jérôme Pinot <ngc891@gmail.com>
 Rafael Antognolli <antognolli@profusion.mobi>
 Daniel Zaoui <daniel.zaoui@samsung.com>
+Christophe Sadoine <chris@indefini.org>
index 55240bc..afb3fa6 100644 (file)
 2012-08-30  Carsten Haitzler (The Rasterman)
 
         1.7.0 release
+
+2012-08-31  Christophe Sadoine
+
+       * Added a function: evas_map_util_quat_rotate().
index 4455de4..2dcb6a2 100644 (file)
@@ -1,3 +1,12 @@
+Evas 1.8.0
+
+Changes since Evas 1.7.0:
+-------------------------
+
+Improvements:
+
+   * Function to rotate an evas map with a quaternion: evas_map_util_quat_rotate().
+
 Evas 1.7.0
 
 Changes since Evas 1.2.0:
index 7a64071..9f82a94 100644 (file)
@@ -4753,6 +4753,30 @@ EAPI void            evas_map_util_zoom(Evas_Map *m, double zoomx, double zoomy,
 EAPI void            evas_map_util_3d_rotate(Evas_Map *m, double dx, double dy, double dz, Evas_Coord cx, Evas_Coord cy, Evas_Coord cz);
 
 /**
+ * Rotate the map in 3D using a unit quaternion.
+ *
+ * This will rotate in 3D using a unit quaternion. Like with
+ * evas_map_util_3d_rotate() you provide a center point 
+ * to rotate around (in 3D).
+ *
+ * @param m map to change.
+ * @param qx the x component of the imaginary part of the quaternion.
+ * @param qy the y component of the imaginary part of the quaternion.
+ * @param qz the z component of the imaginary part of the quaternion.
+ * @param qw the w component of the real part of the quaternion.
+ * @param cx rotation's center x.
+ * @param cy rotation's center y.
+ * @param cz rotation's center z.
+ *
+ * @warning Rotations can be done using a unit quaternion. Thus, this
+ * function expects a unit quaternion (i.e. qx² + qy² + qz² + qw² == 1).
+ * If this is not the case the behavior is undefined.
+ *
+ * @since 1.8
+ */
+EAPI void            evas_map_util_quat_rotate(Evas_Map *m, double qx, double qy, double qz, double qw, double cx, double cy, double cz);
+
+/**
  * Perform lighting calculations on the given Map
  *
  * This is used to apply lighting calculations (from a single light source)
index 779f967..ee6a4c8 100644 (file)
@@ -896,6 +896,49 @@ evas_map_util_3d_rotate(Evas_Map *m, double dx, double dy, double dz,
 }
 
 EAPI void
+evas_map_util_quat_rotate(Evas_Map *m, double qx, double qy, double qz,
+                          double qw, double cx, double cy, double cz)
+{
+   MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
+   return;
+   MAGIC_CHECK_END();
+
+   Evas_Map_Point *p, *p_end;
+
+   p = m->points;
+   p_end = p + m->count;
+
+   for (; p < p_end; p++)
+     {
+       double x, y, z, uvx, uvy, uvz, uuvx, uuvy, uuvz;
+
+       x = p->x - cx;
+       y = p->y - cy;
+       z = p->z - cz;
+
+       uvx = qy * z - qz * y;
+       uvy = qz * x - qx * z;
+       uvz = qx * y - qy * x;
+
+       uuvx = qy * uvz - qz * uvy;
+       uuvy = qz * uvx - qx * uvz;
+       uuvz = qx * uvy - qy * uvx;
+
+       uvx *= (2.0f * qw);
+       uvy *= (2.0f * qw);
+       uvz *= (2.0f * qw);
+
+       uuvx *= 2.0f;
+       uuvy *= 2.0f;
+       uuvz *= 2.0f;
+
+       p->px = p->x = cx + x + uvx + uuvx;
+       p->py = p->y = cy + y + uvy + uuvy;
+       p->z = cz + z + uvz + uuvz;
+     }
+}
+
+EAPI void
 evas_map_util_3d_lighting(Evas_Map *m,
                           Evas_Coord lx, Evas_Coord ly, Evas_Coord lz,
                           int lr, int lg, int lb, int ar, int ag, int ab)