libmoldeo (Moldeo 1.0 Core)  1.0
libmoldeo is the group of objects and functions that executes the basic operations of Moldeo 1.0 Platform.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
moArcBall.h
Go to the documentation of this file.
1 
18 /*************************************************************/
19 
20 #ifndef _ArcBall_h
21 #define _ArcBall_h
22 
23 #include "moTypes.h"
24 
25 // 8<--Snip here if you have your own math types/funcs-->8
26 
27 //Only support assertions in debug builds
28 
29 
30 //Math types derived from the KempoApi tMath library
31  typedef union LIBMOLDEO_API Tuple2f_t
32  {
33  struct
34  {
35  GLfloat X, Y;
36  } s;
37 
38  GLfloat T[2];
39  } Tuple2fT; //A generic 2-element tuple that is represented by single-precision floating point x,y coordinates.
40 
41  typedef union LIBMOLDEO_API Tuple3f_t
42  {
43  struct
44  {
45  GLfloat X, Y, Z;
46  } s;
47 
48  GLfloat T[3];
49  } Tuple3fT; //A generic 3-element tuple that is represented by single precision-floating point x,y,z coordinates.
50 
51  typedef union LIBMOLDEO_API Tuple4f_t
52  {
53  struct
54  {
55  GLfloat X, Y, Z, W;
56  } s;
57 
58  GLfloat T[4];
59  } Tuple4fT; //A 4-element tuple represented by single-precision floating point x,y,z,w coordinates.
60 
61  typedef union LIBMOLDEO_API Matrix3f_t
62  {
63  struct
64  {
65  //column major
66  union { GLfloat M00; GLfloat XX; GLfloat SX; }; //XAxis.X and Scale X
67  union { GLfloat M10; GLfloat XY; }; //XAxis.Y
68  union { GLfloat M20; GLfloat XZ; }; //XAxis.Z
69  union { GLfloat M01; GLfloat YX; }; //YAxis.X
70  union { GLfloat M11; GLfloat YY; GLfloat SY; }; //YAxis.Y and Scale Y
71  union { GLfloat M21; GLfloat YZ; }; //YAxis.Z
72  union { GLfloat M02; GLfloat ZX; }; //ZAxis.X
73  union { GLfloat M12; GLfloat ZY; }; //ZAxis.Y
74  union { GLfloat M22; GLfloat ZZ; GLfloat SZ; }; //ZAxis.Z and Scale Z
75  } s;
76  GLfloat M[9];
77  } Matrix3fT; //A single precision floating point 3 by 3 matrix.
78 
79  typedef union LIBMOLDEO_API Matrix4f_t
80  {
81  struct
82  {
83  //column major
84  union { GLfloat M00; GLfloat XX; GLfloat SX; }; //XAxis.X and Scale X
85  union { GLfloat M10; GLfloat XY; }; //XAxis.Y
86  union { GLfloat M20; GLfloat XZ; }; //XAxis.Z
87  union { GLfloat M30; GLfloat XW; }; //XAxis.W
88  union { GLfloat M01; GLfloat YX; }; //YAxis.X
89  union { GLfloat M11; GLfloat YY; GLfloat SY; }; //YAxis.Y and Scale Y
90  union { GLfloat M21; GLfloat YZ; }; //YAxis.Z
91  union { GLfloat M31; GLfloat YW; }; //YAxis.W
92  union { GLfloat M02; GLfloat ZX; }; //ZAxis.X
93  union { GLfloat M12; GLfloat ZY; }; //ZAxis.Y
94  union { GLfloat M22; GLfloat ZZ; GLfloat SZ; }; //ZAxis.Z and Scale Z
95  union { GLfloat M32; GLfloat ZW; }; //ZAxis.W
96  union { GLfloat M03; GLfloat TX; }; //Trans.X
97  union { GLfloat M13; GLfloat TY; }; //Trans.Y
98  union { GLfloat M23; GLfloat TZ; }; //Trans.Z
99  union { GLfloat M33; GLfloat TW; GLfloat SW; }; //Trans.W and Scale W
100  } s;
101  GLfloat M[16];
102  } Matrix4fT; //A single precision floating point 4 by 4 matrix.
103 
104 
105 //"Inherited" types
106 #define Point2fT Tuple2fT //A 2 element point that is represented by single precision floating point x,y coordinates.
107 
108 #define Quat4fT Tuple4fT //A 4 element unit quaternion represented by single precision floating point x,y,z,w coordinates.
109 
110 #define Vector2fT Tuple2fT //A 2-element vector that is represented by single-precision floating point x,y coordinates.
111 #define Vector3fT Tuple3fT //A 3-element vector that is represented by single-precision floating point x,y,z coordinates.
112 
113 //Custom math, or speed overrides
114 #define FuncSqrt sqrtf
115 
116 //utility macros
117 //assuming IEEE-754(GLfloat), which i believe has max precision of 7 bits
118 # define Epsilon 1.0e-5
119 
120 //Math functions
121 
126  inline
127  static void Point2fAdd(Point2fT* NewObj, const Tuple2fT* t1)
128  {
130 
131  NewObj->s.X += t1->s.X;
132  NewObj->s.Y += t1->s.Y;
133  }
134 
139  inline
140  static void Point2fSub(Point2fT* NewObj, const Tuple2fT* t1)
141  {
143 
144  NewObj->s.X -= t1->s.X;
145  NewObj->s.Y -= t1->s.Y;
146  }
147 
153  inline
154  static void Vector3fCross(Vector3fT* NewObj, const Vector3fT* v1, const Vector3fT* v2)
155  {
156  Vector3fT Result; //safe not to initialize
157 
159 
160  // store on stack once for aliasing-safty
161  // i.e. safe when a.cross(a, b)
162 
163  Result.s.X =(v1->s.Y * v2->s.Z) -(v1->s.Z * v2->s.Y);
164  Result.s.Y =(v1->s.Z * v2->s.X) -(v1->s.X * v2->s.Z);
165  Result.s.Z =(v1->s.X * v2->s.Y) -(v1->s.Y * v2->s.X);
166 
167  //copy result back
168  *NewObj = Result;
169  }
170 
175  inline
176  static GLfloat Vector3fDot(const Vector3fT* NewObj, const Vector3fT* v1)
177  {
179 
180  return (NewObj->s.X * v1->s.X) +
181  (NewObj->s.Y * v1->s.Y) +
182  (NewObj->s.Z * v1->s.Z);
183  }
184 
189  inline
190  static GLfloat Vector3fLengthSquared(const Vector3fT* NewObj)
191  {
193 
194  return (NewObj->s.X * NewObj->s.X) +
195  (NewObj->s.Y * NewObj->s.Y) +
196  (NewObj->s.Z * NewObj->s.Z);
197  }
198 
203  inline
204  static GLfloat Vector3fLength(const Vector3fT* NewObj)
205  {
207 
208  return FuncSqrt(Vector3fLengthSquared(NewObj));
209  }
210 
211  inline
212  static void Matrix3fSetZero(Matrix3fT* NewObj)
213  {
214  NewObj->s.M00 = NewObj->s.M01 = NewObj->s.M02 =
215  NewObj->s.M10 = NewObj->s.M11 = NewObj->s.M12 =
216  NewObj->s.M20 = NewObj->s.M21 = NewObj->s.M22 = 0.0f;
217  }
218 
222  inline
223  static void Matrix3fSetIdentity(Matrix3fT* NewObj)
224  {
225  Matrix3fSetZero(NewObj);
226 
227  //then set diagonal as 1
228  NewObj->s.M00 =
229  NewObj->s.M11 =
230  NewObj->s.M22 = 1.0f;
231  }
232 
238  //$hack this can be optimized some(if s == 0)
239  inline
240  static void Matrix3fSetRotationFromQuat4f(Matrix3fT* NewObj, const Quat4fT* q1)
241  {
242  GLfloat n, s;
243  GLfloat xs, ys, zs;
244  GLfloat wx, wy, wz;
245  GLfloat xx, xy, xz;
246  GLfloat yy, yz, zz;
247 
249 
250  n =(q1->s.X * q1->s.X) +(q1->s.Y * q1->s.Y) +(q1->s.Z * q1->s.Z) +(q1->s.W * q1->s.W);
251  s =(n > 0.0f) ?(2.0f / n) : 0.0f;
252 
253  xs = q1->s.X * s; ys = q1->s.Y * s; zs = q1->s.Z * s;
254  wx = q1->s.W * xs; wy = q1->s.W * ys; wz = q1->s.W * zs;
255  xx = q1->s.X * xs; xy = q1->s.X * ys; xz = q1->s.X * zs;
256  yy = q1->s.Y * ys; yz = q1->s.Y * zs; zz = q1->s.Z * zs;
257 
258  NewObj->s.XX = 1.0f -(yy + zz); NewObj->s.YX = xy - wz; NewObj->s.ZX = xz + wy;
259  NewObj->s.XY = xy + wz; NewObj->s.YY = 1.0f -(xx + zz); NewObj->s.ZY = yz - wx;
260  NewObj->s.XZ = xz - wy; NewObj->s.YZ = yz + wx; NewObj->s.ZZ = 1.0f -(xx + yy);
261  }
262 
268  inline
269  static void Matrix3fMulMatrix3f(Matrix3fT* NewObj, const Matrix3fT* m1)
270  {
271  Matrix3fT Result; //safe not to initialize
272 
274 
275  // alias-safe way.
276  Result.s.M00 =(NewObj->s.M00 * m1->s.M00) +(NewObj->s.M01 * m1->s.M10) +(NewObj->s.M02 * m1->s.M20);
277  Result.s.M01 =(NewObj->s.M00 * m1->s.M01) +(NewObj->s.M01 * m1->s.M11) +(NewObj->s.M02 * m1->s.M21);
278  Result.s.M02 =(NewObj->s.M00 * m1->s.M02) +(NewObj->s.M01 * m1->s.M12) +(NewObj->s.M02 * m1->s.M22);
279 
280  Result.s.M10 =(NewObj->s.M10 * m1->s.M00) +(NewObj->s.M11 * m1->s.M10) +(NewObj->s.M12 * m1->s.M20);
281  Result.s.M11 =(NewObj->s.M10 * m1->s.M01) +(NewObj->s.M11 * m1->s.M11) +(NewObj->s.M12 * m1->s.M21);
282  Result.s.M12 =(NewObj->s.M10 * m1->s.M02) +(NewObj->s.M11 * m1->s.M12) +(NewObj->s.M12 * m1->s.M22);
283 
284  Result.s.M20 =(NewObj->s.M20 * m1->s.M00) +(NewObj->s.M21 * m1->s.M10) +(NewObj->s.M22 * m1->s.M20);
285  Result.s.M21 =(NewObj->s.M20 * m1->s.M01) +(NewObj->s.M21 * m1->s.M11) +(NewObj->s.M22 * m1->s.M21);
286  Result.s.M22 =(NewObj->s.M20 * m1->s.M02) +(NewObj->s.M21 * m1->s.M12) +(NewObj->s.M22 * m1->s.M22);
287 
288  //copy result back to this
289  *NewObj = Result;
290  }
291 
292  inline
293  static void Matrix4fSetRotationScaleFromMatrix4f(Matrix4fT* NewObj, const Matrix4fT* m1)
294  {
295  //assert(NewObj && m1);
296 
297  NewObj->s.XX = m1->s.XX; NewObj->s.YX = m1->s.YX; NewObj->s.ZX = m1->s.ZX;
298  NewObj->s.XY = m1->s.XY; NewObj->s.YY = m1->s.YY; NewObj->s.ZY = m1->s.ZY;
299  NewObj->s.XZ = m1->s.XZ; NewObj->s.YZ = m1->s.YZ; NewObj->s.ZZ = m1->s.ZZ;
300  }
301 
309  inline
310  static GLfloat Matrix4fSVD(const Matrix4fT* NewObj, Matrix3fT* rot3, Matrix4fT* rot4)
311  {
312  GLfloat s, n;
313 
314  //assert(NewObj);
315 
316  // this is a simple svd.
317  // Not complete but fast and reasonable.
318  // See comment in Matrix3d.
319 
320  s = FuncSqrt(
321  ((NewObj->s.XX * NewObj->s.XX) +(NewObj->s.XY * NewObj->s.XY) +(NewObj->s.XZ * NewObj->s.XZ) +
322  (NewObj->s.YX * NewObj->s.YX) +(NewObj->s.YY * NewObj->s.YY) +(NewObj->s.YZ * NewObj->s.YZ) +
323  (NewObj->s.ZX * NewObj->s.ZX) +(NewObj->s.ZY * NewObj->s.ZY) +(NewObj->s.ZZ * NewObj->s.ZZ) ) / 3.0f );
324 
325  if(rot3) //if pointer not null
326  {
327  //this->getRotationScale(rot3);
328  rot3->s.XX = NewObj->s.XX; rot3->s.XY = NewObj->s.XY; rot3->s.XZ = NewObj->s.XZ;
329  rot3->s.YX = NewObj->s.YX; rot3->s.YY = NewObj->s.YY; rot3->s.YZ = NewObj->s.YZ;
330  rot3->s.ZX = NewObj->s.ZX; rot3->s.ZY = NewObj->s.ZY; rot3->s.ZZ = NewObj->s.ZZ;
331 
332  // zero-div may occur.
333 
334  n = 1.0f / FuncSqrt((NewObj->s.XX * NewObj->s.XX) +
335  (NewObj->s.XY * NewObj->s.XY) +
336  (NewObj->s.XZ * NewObj->s.XZ) );
337  rot3->s.XX *= n;
338  rot3->s.XY *= n;
339  rot3->s.XZ *= n;
340 
341  n = 1.0f / FuncSqrt((NewObj->s.YX * NewObj->s.YX) +
342  (NewObj->s.YY * NewObj->s.YY) +
343  (NewObj->s.YZ * NewObj->s.YZ) );
344  rot3->s.YX *= n;
345  rot3->s.YY *= n;
346  rot3->s.YZ *= n;
347 
348  n = 1.0f / FuncSqrt((NewObj->s.ZX * NewObj->s.ZX) +
349  (NewObj->s.ZY * NewObj->s.ZY) +
350  (NewObj->s.ZZ * NewObj->s.ZZ) );
351  rot3->s.ZX *= n;
352  rot3->s.ZY *= n;
353  rot3->s.ZZ *= n;
354  }
355 
356  if(rot4) //if pointer not null
357  {
358  if(rot4 != NewObj)
359  {
360  Matrix4fSetRotationScaleFromMatrix4f(rot4, NewObj); // private method
361  }
362 
363  // zero-div may occur.
364 
365  n = 1.0f / FuncSqrt((NewObj->s.XX * NewObj->s.XX) +
366  (NewObj->s.XY * NewObj->s.XY) +
367  (NewObj->s.XZ * NewObj->s.XZ) );
368  rot4->s.XX *= n;
369  rot4->s.XY *= n;
370  rot4->s.XZ *= n;
371 
372  n = 1.0f / FuncSqrt((NewObj->s.YX * NewObj->s.YX) +
373  (NewObj->s.YY * NewObj->s.YY) +
374  (NewObj->s.YZ * NewObj->s.YZ) );
375  rot4->s.YX *= n;
376  rot4->s.YY *= n;
377  rot4->s.YZ *= n;
378 
379  n = 1.0f / FuncSqrt((NewObj->s.ZX * NewObj->s.ZX) +
380  (NewObj->s.ZY * NewObj->s.ZY) +
381  (NewObj->s.ZZ * NewObj->s.ZZ) );
382  rot4->s.ZX *= n;
383  rot4->s.ZY *= n;
384  rot4->s.ZZ *= n;
385  }
386 
387  return s;
388  }
389 
390  inline
391  static void Matrix4fSetRotationScaleFromMatrix3f(Matrix4fT* NewObj, const Matrix3fT* m1)
392  {
393  //assert(NewObj && m1);
394 
395  NewObj->s.XX = m1->s.XX; NewObj->s.YX = m1->s.YX; NewObj->s.ZX = m1->s.ZX;
396  NewObj->s.XY = m1->s.XY; NewObj->s.YY = m1->s.YY; NewObj->s.ZY = m1->s.ZY;
397  NewObj->s.XZ = m1->s.XZ; NewObj->s.YZ = m1->s.YZ; NewObj->s.ZZ = m1->s.ZZ;
398  }
399 
400  inline
401  static void Matrix4fMulRotationScale(Matrix4fT* NewObj, GLfloat scale)
402  {
403  //assert(NewObj);
404 
405  NewObj->s.XX *= scale; NewObj->s.YX *= scale; NewObj->s.ZX *= scale;
406  NewObj->s.XY *= scale; NewObj->s.YY *= scale; NewObj->s.ZY *= scale;
407  NewObj->s.XZ *= scale; NewObj->s.YZ *= scale; NewObj->s.ZZ *= scale;
408  }
409 
420  inline
421  static void Matrix4fSetRotationFromMatrix3f(Matrix4fT* NewObj, const Matrix3fT* m1)
422  {
423  GLfloat scale;
424 
425  //assert(NewObj && m1);
426 
427  scale = Matrix4fSVD(NewObj, NULL, NULL);
428 
429  Matrix4fSetRotationScaleFromMatrix3f(NewObj, m1);
430  Matrix4fMulRotationScale(NewObj, scale);
431  }
432 
433 // 8<--Snip here if you have your own math types/funcs-->8
434 
436 
439  typedef class LIBMOLDEO_API ArcBall_t
440  {
441  protected:
442  inline
443  void _mapToSphere(const Point2fT* NewPt, Vector3fT* NewVec) const;
444 
445  public:
446  //Create/Destroy
447  ArcBall_t();
448  ArcBall_t(GLfloat NewWidth, GLfloat NewHeight);
449  ~ArcBall_t() { /* nothing to do */ };
450 
451  //Set new bounds
452  inline
453  void setBounds(GLfloat NewWidth, GLfloat NewHeight)
454  {
455  //assert((NewWidth > 1.0f) &&(NewHeight > 1.0f));
456 
457  //Set adjustment factor for width/height
458  this->AdjustWidth = 1.0f /((NewWidth - 1.0f) * 0.5f);
459  this->AdjustHeight = 1.0f /((NewHeight - 1.0f) * 0.5f);
460  }
461 
462  //Mouse down
463  void click(const Point2fT* NewPt);
464 
465  //Mouse drag, calculate rotation
466  void drag(const Point2fT* NewPt, Quat4fT* NewRot);
467 
468  protected:
469  Vector3fT StVec; //Saved click vector
470  Vector3fT EnVec; //Saved drag vector
471  GLfloat AdjustWidth; //Mouse bounds width
472  GLfloat AdjustHeight; //Mouse bounds height
473 
474  } ArcBallT;
475 
476 #endif
#define Quat4fT
Definition: moArcBall.h:108
void setBounds(GLfloat NewWidth, GLfloat NewHeight)
Definition: moArcBall.h:453
GLfloat YY
Definition: moArcBall.h:89
GLfloat YZ
Definition: moArcBall.h:90
GLfloat YZ
Definition: moArcBall.h:71
GLfloat YW
Definition: moArcBall.h:91
GLfloat AdjustWidth
Definition: moArcBall.h:471
GLfloat TZ
Definition: moArcBall.h:98
union LIBMOLDEO_API Tuple3f_t Tuple3fT
union LIBMOLDEO_API Tuple4f_t Tuple4fT
GLfloat TX
Definition: moArcBall.h:96
GLfloat YX
Definition: moArcBall.h:69
GLfloat ZY
Definition: moArcBall.h:73
GLfloat XW
Definition: moArcBall.h:87
union LIBMOLDEO_API Tuple2f_t Tuple2fT
GLfloat ZW
Definition: moArcBall.h:95
#define Vector3fT
Definition: moArcBall.h:111
#define LIBMOLDEO_API
Definition: moTypes.h:180
GLfloat TW
Definition: moArcBall.h:99
GLfloat Z
Definition: moArcBall.h:45
GLfloat TY
Definition: moArcBall.h:97
GLfloat AdjustHeight
Definition: moArcBall.h:472
Vector3fT EnVec
Definition: moArcBall.h:470
GLfloat ZZ
Definition: moArcBall.h:94
#define FuncSqrt
Definition: moArcBall.h:114
GLfloat YX
Definition: moArcBall.h:88
GLfloat XX
Definition: moArcBall.h:84
GLfloat ZX
Definition: moArcBall.h:92
class LIBMOLDEO_API ArcBall_t ArcBallT
Objeto para la rotación esférica de la vista 3d.
The projection component of space.
Definition: moOGLFT.h:80
union LIBMOLDEO_API Matrix3f_t Matrix3fT
GLfloat Y
Definition: moArcBall.h:35
GLfloat ZX
Definition: moArcBall.h:72
#define Point2fT
Definition: moArcBall.h:106
GLfloat XZ
Definition: moArcBall.h:86
GLfloat ZZ
Definition: moArcBall.h:74
The Y component of space.
Definition: moOGLFT.h:78
The X component of space.
Definition: moOGLFT.h:77
GLfloat XX
Definition: moArcBall.h:66
GLfloat XY
Definition: moArcBall.h:67
GLfloat ZY
Definition: moArcBall.h:93
~ArcBall_t()
Definition: moArcBall.h:449
GLfloat XY
Definition: moArcBall.h:85
Objeto para la rotación esférica de la vista 3d.
Definition: moArcBall.h:439
GLfloat YY
Definition: moArcBall.h:70
Vector3fT StVec
Definition: moArcBall.h:469
union LIBMOLDEO_API Matrix4f_t Matrix4fT
GLfloat Z
Definition: moArcBall.h:55
GLfloat XZ
Definition: moArcBall.h:68