Orientation.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /******************************************************************************
  2. Use 'Orient' to handle objects orientation.
  3. This is similar to 'Matrix', except the 'Orient' stores only 2 vectors of the orientation:
  4. 'z-forward' and 'y-up' (the 'x-right' can always be computed from 'z' and 'y')
  5. /******************************************************************************/
  6. struct Orient // Orientation
  7. {
  8. Vec dir , // direction (z - forward)
  9. perp; // perpendicular to direction (y - up )
  10. Vec cross()C {return Cross(perp, dir);} // cross (x - right )
  11. Orient& operator+=(C Orient &o);
  12. Orient& operator*=( Flt f);
  13. Orient& operator*=(C Vec &v);
  14. Orient& operator*=(C Matrix3 &m) {return mul(m);}
  15. Orient& operator/=(C Matrix3 &m) {return div(m);}
  16. Bool operator==(C Orient &o)C;
  17. Bool operator!=(C Orient &o)C;
  18. friend Orient operator* (C Orient &o, Flt f) {return Orient(o)*=f;}
  19. friend Orient operator* ( Flt f, C Orient &o) {return Orient(o)*=f;}
  20. friend Orient operator* (C Orient &o, C Matrix3 &m) {return Orient(o)*=m;}
  21. // set
  22. Orient& zero ( ); // set all vectors to zero
  23. Orient& identity( ); // set identity
  24. Orient& setDir (C Vec &dir); // set from 'dir' and calculate correct 'perp' to match it, 'dir' must be normalized
  25. Orient& fixPerp ( ); // fix perpendicular, use when 'dir' or 'perp' has changed, this method aligns 'perp' so it's perpendicular to 'dir' and normalized
  26. Bool fix ( ); // normalize and fix perpendicular, false on fail
  27. // transform
  28. Orient& mirrorX(); // mirror in X axis
  29. #if EE_PRIVATE
  30. Orient& mirrorY(); // mirror in Y axis
  31. Orient& mirrorZ(); // mirror in Z axis
  32. Orient& chs (); // change sign of all vectors
  33. Orient& rightToLeft(); // convert right to left hand coordinate system
  34. #endif
  35. Orient& rotateDir (Flt angle); // rotate along 'dir' vector, this is equal to "mul(Matrix3().setRotate(dir , angle), true)" but faster
  36. Orient& rotatePerp (Flt angle); // rotate along 'perp' vector, this is equal to "mul(Matrix3().setRotate(perp , angle), true)" but faster
  37. Orient& rotateCross(Flt angle); // rotate along 'cross' vector, this is equal to "mul(Matrix3().setRotate(cross(), angle), true)" but faster
  38. Orient& rotateX(Flt angle); // rotate along X axis, this is equal to "mul(Matrix3().setRotateX(angle), true)" but faster
  39. Orient& rotateY(Flt angle); // rotate along Y axis, this is equal to "mul(Matrix3().setRotateY(angle), true)" but faster
  40. Orient& rotateZ(Flt angle); // rotate along Z axis, this is equal to "mul(Matrix3().setRotateZ(angle), true)" but faster
  41. Orient& mul(C Matrix3 &matrix, Bool normalized=false); // transform by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  42. Orient& div(C Matrix3 &matrix, Bool normalized=false); // divide by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  43. Orient& rotateToDir(C Vec &dir ); // rotate current orientation to 'dir' vector, 'dir' must be normalized
  44. Orient& rotateToDir(C Vec &dir, Flt blend); // rotate current orientation to 'dir' vector, 'dir' must be normalized, 'blend'=how much to rotate (0=no rotation, 0.5=half rotation, 1.0=full rotation)
  45. // operations
  46. Orient& inverse( ) ; // inverse orientation
  47. void inverse(Orient &dest)C; // inverse orientation and store it in 'dest'
  48. void inverse(Matrix3 &dest)C; // inverse orientation and store it in 'dest' matrix
  49. void inverse(MatrixD3 &dest)C; // inverse orientation and store it in 'dest' matrix
  50. // io
  51. void save(MemPtr<TextNode> nodes)C; // save as text
  52. Orient() {}
  53. Orient(C Vec &dir, C Vec &perp) {T.dir=dir; T.perp=perp;}
  54. Orient(C OrientD &o);
  55. Orient(C Matrix3 &m);
  56. Orient(C MatrixD3 &m);
  57. Orient(C Quaternion &q);
  58. };
  59. /******************************************************************************/
  60. struct OrientD // Orientation (double precision)
  61. {
  62. VecD dir , // direction (z - forward)
  63. perp; // perpendicular to direction (y - up )
  64. VecD cross()C {return Cross(perp, dir);} // cross (x - right )
  65. OrientD& operator*=( Dbl f);
  66. OrientD& operator*=(C VecD &v);
  67. OrientD& operator*=(C MatrixD3 &m) {return mul(m);}
  68. OrientD& operator/=(C MatrixD3 &m) {return div(m);}
  69. Bool operator==(C OrientD &o)C;
  70. Bool operator!=(C OrientD &o)C;
  71. friend OrientD operator* (C OrientD &o, Dbl f) {return OrientD(o)*=f;}
  72. friend OrientD operator* ( Dbl f, C OrientD &o) {return OrientD(o)*=f;}
  73. friend OrientD operator* (C OrientD &o, C MatrixD3 &m) {return OrientD(o)*=m;}
  74. // set
  75. OrientD& zero ( ); // set all vectors to zero
  76. OrientD& identity( ); // set identity
  77. OrientD& setDir (C VecD &dir); // set from 'dir' and calculate correct 'perp' to match it, 'dir' must be normalized
  78. OrientD& fixPerp ( ); // fix perpendicular, use when 'dir' or 'perp' has changed, this method aligns 'perp' so it's perpendicular to 'dir' and normalized
  79. Bool fix ( ); // normalize and fix perpendicular, false on fail
  80. // transform
  81. OrientD& mirrorX(); // mirror in X axis
  82. #if EE_PRIVATE
  83. OrientD& mirrorY(); // mirror in Y axis
  84. OrientD& mirrorZ(); // mirror in Z axis
  85. OrientD& chs(); // change sign of all vectors
  86. #endif
  87. OrientD& mul(C MatrixD3 &matrix, Bool normalized=false); // transform by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  88. OrientD& div(C MatrixD3 &matrix, Bool normalized=false); // divide by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  89. // operations
  90. OrientD& inverse( ) ; // inverse orientation
  91. void inverse(OrientD &dest)C; // inverse orientation and store it in 'dest'
  92. void inverse(MatrixD3 &dest)C; // inverse orientation and store it in 'dest' matrix
  93. // io
  94. void save(MemPtr<TextNode> nodes)C; // save as text
  95. OrientD() {}
  96. OrientD(C VecD &dir, C VecD &perp) {T.dir=dir; T.perp=perp;}
  97. OrientD(C Orient &o);
  98. OrientD(C Matrix3 &m);
  99. OrientD(C MatrixD3 &m);
  100. };
  101. /******************************************************************************/
  102. STRUCT(OrientP , Orient) // Positioned Orientation
  103. //{
  104. Vec pos; // position
  105. OrientP& operator+=(C Vec &v) {pos+=v; return T;}
  106. OrientP& operator-=(C Vec &v) {pos-=v; return T;}
  107. OrientP& operator+=(C OrientP &o);
  108. OrientP& operator*=( Flt f);
  109. OrientP& operator*=(C Vec &v);
  110. OrientP& operator*=(C Matrix3 &m) {return mul(m);}
  111. OrientP& operator*=(C Matrix &m) {return mul(m);}
  112. OrientP& operator*=(C MatrixM &m) {return mul(m);}
  113. OrientP& operator/=(C Matrix3 &m) {return div(m);}
  114. OrientP& operator/=(C Matrix &m) {return div(m);}
  115. OrientP& operator/=(C MatrixM &m) {return div(m);}
  116. Bool operator==(C OrientP &o)C;
  117. Bool operator!=(C OrientP &o)C;
  118. friend OrientP operator* (C OrientP &o, Flt f) {return OrientP(o)*=f;}
  119. friend OrientP operator* ( Flt f, C OrientP &o) {return OrientP(o)*=f;}
  120. friend OrientP operator* (C OrientP &o, C Matrix3 &m) {return OrientP(o)*=m;}
  121. friend OrientP operator* (C OrientP &o, C Matrix &m) {return OrientP(o)*=m;}
  122. friend OrientP operator* (C OrientP &o, C MatrixM &m) {return OrientP(o)*=m;}
  123. // set
  124. OrientP& zero ( ); // set all vectors to zero
  125. OrientP& identity ( ); // set identity
  126. OrientP& setPosDir(C Vec &pos, C Vec &dir); // set from 'pos dir' and calculate correct 'perp' to match 'dir', 'dir' must be normalized
  127. // transform
  128. OrientP& mirrorX(); // mirror in X axis
  129. #if EE_PRIVATE
  130. OrientP& mirrorY(); // mirror in Y axis
  131. OrientP& mirrorZ(); // mirror in Z axis
  132. OrientP& rightToLeft(); // convert right to left hand coordinate system
  133. #endif
  134. OrientP& mul(C Matrix3 &matrix, Bool normalized=false); // transform by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  135. OrientP& mul(C Matrix &matrix, Bool normalized=false); // transform by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  136. OrientP& mul(C MatrixM &matrix, Bool normalized=false); // transform by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  137. OrientP& div(C Matrix3 &matrix, Bool normalized=false); // divide by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  138. OrientP& div(C Matrix &matrix, Bool normalized=false); // divide by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  139. OrientP& div(C MatrixM &matrix, Bool normalized=false); // divide by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  140. // draw
  141. void draw(C Color &color, Flt size=0.2f)C; // this can be optionally called outside of Render function, this relies on active object matrix which can be set using 'SetMatrix' function
  142. // io
  143. void save(MemPtr<TextNode> nodes)C; // save as text
  144. OrientP() {}
  145. OrientP(C Vec &pos, C Vec &dir, C Vec &perp) {T.pos=pos; T.dir=dir; T.perp=perp;}
  146. OrientP(C Orient &o);
  147. OrientP(C Matrix3 &m);
  148. OrientP(C Matrix &m);
  149. OrientP(C MatrixM &m);
  150. OrientP(C Quaternion &q);
  151. };
  152. /******************************************************************************/
  153. STRUCT(OrientM , Orient) // Positioned Orientation (mixed precision)
  154. //{
  155. VecD pos; // position
  156. OrientM& operator+=(C VecD &v) {pos+=v; return T;}
  157. OrientM& operator-=(C VecD &v) {pos-=v; return T;}
  158. OrientM& operator*=( Flt f);
  159. OrientM& operator*=(C Vec &v);
  160. OrientM& operator*=(C Matrix3 &m) {return mul(m);}
  161. OrientM& operator*=(C Matrix &m) {return mul(m);}
  162. OrientM& operator*=(C MatrixM &m) {return mul(m);}
  163. OrientM& operator/=(C Matrix3 &m) {return div(m);}
  164. OrientM& operator/=(C Matrix &m) {return div(m);}
  165. OrientM& operator/=(C MatrixM &m) {return div(m);}
  166. Bool operator==(C OrientM &o)C;
  167. Bool operator!=(C OrientM &o)C;
  168. friend OrientM operator* (C OrientM &o, Flt f) {return OrientM(o)*=f;}
  169. friend OrientM operator* ( Flt f, C OrientM &o) {return OrientM(o)*=f;}
  170. friend OrientM operator* (C OrientM &o, C Matrix3 &m) {return OrientM(o)*=m;}
  171. friend OrientM operator* (C OrientM &o, C Matrix &m) {return OrientM(o)*=m;}
  172. friend OrientM operator* (C OrientM &o, C MatrixM &m) {return OrientM(o)*=m;}
  173. // set
  174. OrientM& zero ( ); // set all vectors to zero
  175. OrientM& identity ( ); // set identity
  176. OrientM& setPosDir(C VecD &pos, C Vec &dir); // set from 'pos dir' and calculate correct 'perp' to match 'dir', 'dir' must be normalized
  177. // transform
  178. OrientM& mirrorX(); // mirror in X axis
  179. #if EE_PRIVATE
  180. OrientM& mirrorY(); // mirror in Y axis
  181. OrientM& mirrorZ(); // mirror in Z axis
  182. #endif
  183. OrientM& mul(C Matrix3 &matrix, Bool normalized=false); // transform by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  184. OrientM& mul(C Matrix &matrix, Bool normalized=false); // transform by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  185. OrientM& mul(C MatrixM &matrix, Bool normalized=false); // transform by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  186. OrientM& div(C Matrix3 &matrix, Bool normalized=false); // divide by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  187. OrientM& div(C Matrix &matrix, Bool normalized=false); // divide by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  188. OrientM& div(C MatrixM &matrix, Bool normalized=false); // divide by matrix, if 'matrix' is normalized set 'normalized' to true for more performance
  189. // draw
  190. void draw(C Color &color, Flt size=0.2f)C; // this can be optionally called outside of Render function, this relies on active object matrix which can be set using 'SetMatrix' function
  191. // io
  192. void save(MemPtr<TextNode> nodes)C; // save as text
  193. OrientM() {}
  194. OrientM(C VecD &pos, C Vec &dir, C Vec &perp) {T.pos=pos; T.dir=dir; T.perp=perp;}
  195. OrientM(C Orient &o);
  196. OrientM(C Matrix3 &m);
  197. OrientM(C Matrix &m);
  198. OrientM(C MatrixM &m);
  199. OrientM(C Quaternion &q);
  200. };
  201. /******************************************************************************/
  202. struct AxisRoll // Axis+Roll based rotation
  203. {
  204. Vec axis; // direction of this vector specifies the rotation axis, and the length of this vector specifies the rotation angle
  205. Flt roll; // roll angle, rotation along the original direction
  206. Vec4& v4() {return (Vec4&)T;} // return this in Vec4 format, this returns reference to self and not a new object!
  207. C Vec4& v4()C {return (Vec4&)T;} // return this in Vec4 format, this returns reference to self and not a new object!
  208. // get / set
  209. Bool any ( )C {return v4().any();}
  210. AxisRoll& zero( ) {axis.zero(); roll=0; return T;} // clear to zero
  211. AxisRoll& from(C Orient &start, C Orient &result); // set axis roll which transforms 'start' into 'result'
  212. // transform
  213. AxisRoll& mul (C Matrix3 &matrix); // transform by matrix
  214. AxisRoll& operator*=(C Matrix3 &matrix) {return mul(matrix);} // transform by matrix
  215. AxisRoll& operator*=( Flt f ) {axis*=f; roll*=f; return T;} // scale by 'f'
  216. };
  217. /******************************************************************************/
  218. Orient Lerp(C Orient &a, C Orient &b, Flt step); // linear interpolation, 'step'=0..1
  219. /******************************************************************************/
  220. Bool Equal(C Orient &a, C Orient &b, Flt eps=EPS );
  221. Bool Equal(C OrientD &a, C OrientD &b, Dbl eps=EPSD );
  222. Bool Equal(C OrientP &a, C OrientP &b, Flt eps=EPS , Flt pos_eps=EPS );
  223. Bool Equal(C OrientM &a, C OrientM &b, Flt eps=EPS , Dbl pos_eps=EPSD);
  224. /******************************************************************************/
  225. Orient GetAnimOrient(C Orient &orn , C Orient *parent=null ); // get animation orientation 'orn' to be displayed when having 'parent' , which is " orn / parent "
  226. Orient GetAnimOrient(C Orient &bone, C Matrix3 &bone_matrix, C Orient *parent=null, C Matrix3 *parent_matrix=null); // get animation orientation for 'bone' transformed by 'bone_matrix' to be displayed when having 'parent' transformed by 'parent_matrix', which is "(bone*bone_matrix) / (parent*parent_matrix)"
  227. Vec GetAnimPos (C OrientP &bone, C Vec &bone_pos , C Orient &bone_orn, C Orient *parent=null, C Matrix *parent_matrix=null); // get animation position for 'bone' currently set with 'bone_orn' orientation and having 'bone_pos' offset, with 'parent' transformed by 'parent_matrix'
  228. /******************************************************************************/