Orientation.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. Orient & Orient ::operator+=(C Orient &orn) {dir+=orn.dir; perp+=orn.perp; return T;}
  6. OrientP& OrientP::operator+=(C OrientP &orn) {dir+=orn.dir; perp+=orn.perp; pos+=orn.pos; return T;}
  7. /******************************************************************************/
  8. Orient & Orient ::operator*=(Flt f) {dir*=f; perp*=f; return T;}
  9. OrientD& OrientD::operator*=(Dbl f) {dir*=f; perp*=f; return T;}
  10. OrientP& OrientP::operator*=(Flt f) {dir*=f; perp*=f; pos*=f; return T;}
  11. OrientM& OrientM::operator*=(Flt f) {dir*=f; perp*=f; pos*=f; return T;}
  12. /******************************************************************************/
  13. Orient & Orient ::operator*=(C Vec &v) {dir*=v; perp*=v; fix(); return T;}
  14. OrientD& OrientD::operator*=(C VecD &v) {dir*=v; perp*=v; fix(); return T;}
  15. OrientP& OrientP::operator*=(C Vec &v) {dir*=v; perp*=v; pos*=v; fix(); return T;}
  16. OrientM& OrientM::operator*=(C Vec &v) {dir*=v; perp*=v; pos*=v; fix(); return T;}
  17. /******************************************************************************/
  18. Bool Orient ::operator==(C Orient &orn)C {return dir==orn.dir && perp==orn.perp;}
  19. Bool Orient ::operator!=(C Orient &orn)C {return dir!=orn.dir || perp!=orn.perp;}
  20. Bool OrientD::operator==(C OrientD &orn)C {return dir==orn.dir && perp==orn.perp;}
  21. Bool OrientD::operator!=(C OrientD &orn)C {return dir!=orn.dir || perp!=orn.perp;}
  22. Bool OrientP::operator==(C OrientP &orn)C {return dir==orn.dir && perp==orn.perp && pos==orn.pos;}
  23. Bool OrientP::operator!=(C OrientP &orn)C {return dir!=orn.dir || perp!=orn.perp || pos!=orn.pos;}
  24. Bool OrientM::operator==(C OrientM &orn)C {return dir==orn.dir && perp==orn.perp && pos==orn.pos;}
  25. Bool OrientM::operator!=(C OrientM &orn)C {return dir!=orn.dir || perp!=orn.perp || pos!=orn.pos;}
  26. /******************************************************************************/
  27. Orient& Orient::mirrorX() {CHS(dir.x); CHS(perp.x); return T;}
  28. Orient& Orient::mirrorY() {CHS(dir.y); CHS(perp.y); return T;}
  29. Orient& Orient::mirrorZ() {CHS(dir.z); CHS(perp.z); return T;}
  30. OrientD& OrientD::mirrorX() {CHS(dir.x); CHS(perp.x); return T;}
  31. OrientD& OrientD::mirrorY() {CHS(dir.y); CHS(perp.y); return T;}
  32. OrientD& OrientD::mirrorZ() {CHS(dir.z); CHS(perp.z); return T;}
  33. OrientM& OrientM::mirrorX() {CHS(dir.x); CHS(perp.x); CHS(pos.x); return T;}
  34. OrientM& OrientM::mirrorY() {CHS(dir.y); CHS(perp.y); CHS(pos.y); return T;}
  35. OrientM& OrientM::mirrorZ() {CHS(dir.z); CHS(perp.z); CHS(pos.z); return T;}
  36. OrientP& OrientP::mirrorX() {CHS(dir.x); CHS(perp.x); CHS(pos.x); return T;}
  37. OrientP& OrientP::mirrorY() {CHS(dir.y); CHS(perp.y); CHS(pos.y); return T;}
  38. OrientP& OrientP::mirrorZ() {CHS(dir.z); CHS(perp.z); CHS(pos.z); return T;}
  39. Orient & Orient ::chs() {dir.chs(); perp.chs(); return T;}
  40. OrientD& OrientD::chs() {dir.chs(); perp.chs(); return T;}
  41. Orient & Orient ::rightToLeft() {dir.rightToLeft(); perp.rightToLeft(); return T;}
  42. OrientP& OrientP::rightToLeft() {dir.rightToLeft(); perp.rightToLeft(); pos.rightToLeft(); return T;}
  43. /******************************************************************************/
  44. Orient& Orient::mul(C Matrix3 &matrix, Bool normalized)
  45. {
  46. dir *=matrix;
  47. perp*=matrix;
  48. if(!normalized){dir.normalize(); perp.normalize();}
  49. return T;
  50. }
  51. OrientD& OrientD::mul(C MatrixD3 &matrix, Bool normalized)
  52. {
  53. dir *=matrix;
  54. perp*=matrix;
  55. if(!normalized){dir.normalize(); perp.normalize();}
  56. return T;
  57. }
  58. OrientP& OrientP::mul(C Matrix3 &matrix, Bool normalized)
  59. {
  60. dir *=matrix;
  61. perp*=matrix;
  62. pos *=matrix;
  63. if(!normalized){dir.normalize(); perp.normalize();}
  64. return T;
  65. }
  66. OrientM& OrientM::mul(C Matrix3 &matrix, Bool normalized)
  67. {
  68. dir *=matrix;
  69. perp*=matrix;
  70. pos *=matrix;
  71. if(!normalized){dir.normalize(); perp.normalize();}
  72. return T;
  73. }
  74. OrientP& OrientP::mul(C Matrix &matrix, Bool normalized)
  75. {
  76. dir *=matrix.orn();
  77. perp*=matrix.orn();
  78. pos *=matrix;
  79. if(!normalized){dir.normalize(); perp.normalize();}
  80. return T;
  81. }
  82. OrientM& OrientM::mul(C Matrix &matrix, Bool normalized)
  83. {
  84. dir *=matrix.orn();
  85. perp*=matrix.orn();
  86. pos *=matrix;
  87. if(!normalized){dir.normalize(); perp.normalize();}
  88. return T;
  89. }
  90. OrientP& OrientP::mul(C MatrixM &matrix, Bool normalized)
  91. {
  92. dir *=matrix.orn();
  93. perp*=matrix.orn();
  94. pos *=matrix;
  95. if(!normalized){dir.normalize(); perp.normalize();}
  96. return T;
  97. }
  98. OrientM& OrientM::mul(C MatrixM &matrix, Bool normalized)
  99. {
  100. dir *=matrix.orn();
  101. perp*=matrix.orn();
  102. pos *=matrix;
  103. if(!normalized){dir.normalize(); perp.normalize();}
  104. return T;
  105. }
  106. /******************************************************************************/
  107. Orient& Orient::div(C Matrix3 &matrix, Bool normalized)
  108. {
  109. dir .divNormalized(matrix);
  110. perp.divNormalized(matrix);
  111. if(!normalized){dir.normalize(); perp.normalize();}
  112. return T;
  113. }
  114. OrientD& OrientD::div(C MatrixD3 &matrix, Bool normalized)
  115. {
  116. dir .divNormalized(matrix);
  117. perp.divNormalized(matrix);
  118. if(!normalized){dir.normalize(); perp.normalize();}
  119. return T;
  120. }
  121. OrientP& OrientP::div(C Matrix3 &matrix, Bool normalized)
  122. {
  123. dir .divNormalized(matrix);
  124. perp.divNormalized(matrix);
  125. if(!normalized){dir.normalize(); perp.normalize(); pos.div(matrix);}else pos.divNormalized(matrix);
  126. return T;
  127. }
  128. OrientM& OrientM::div(C Matrix3 &matrix, Bool normalized)
  129. {
  130. dir .divNormalized(matrix);
  131. perp.divNormalized(matrix);
  132. if(!normalized){dir.normalize(); perp.normalize(); pos.div(matrix);}else pos.divNormalized(matrix);
  133. return T;
  134. }
  135. OrientP& OrientP::div(C Matrix &matrix, Bool normalized)
  136. {
  137. dir .divNormalized(matrix.orn());
  138. perp.divNormalized(matrix.orn());
  139. if(!normalized){dir.normalize(); perp.normalize(); pos.div(matrix);}else pos.divNormalized(matrix);
  140. return T;
  141. }
  142. OrientM& OrientM::div(C Matrix &matrix, Bool normalized)
  143. {
  144. dir .divNormalized(matrix.orn());
  145. perp.divNormalized(matrix.orn());
  146. if(!normalized){dir.normalize(); perp.normalize(); pos.div(matrix);}else pos.divNormalized(matrix);
  147. return T;
  148. }
  149. OrientP& OrientP::div(C MatrixM &matrix, Bool normalized)
  150. {
  151. dir .divNormalized(matrix.orn());
  152. perp.divNormalized(matrix.orn());
  153. if(!normalized){dir.normalize(); perp.normalize(); pos.div(matrix);}else pos.divNormalized(matrix);
  154. return T;
  155. }
  156. OrientM& OrientM::div(C MatrixM &matrix, Bool normalized)
  157. {
  158. dir .divNormalized(matrix.orn());
  159. perp.divNormalized(matrix.orn());
  160. if(!normalized){dir.normalize(); perp.normalize(); pos.div(matrix);}else pos.divNormalized(matrix);
  161. return T;
  162. }
  163. /******************************************************************************/
  164. Orient ::Orient (C OrientD &orn) {dir=orn.dir; perp=orn.perp;}
  165. OrientD::OrientD(C Orient &orn) {dir=orn.dir; perp=orn.perp; fix();} // call 'fix' to get high precision
  166. OrientP::OrientP(C Orient &orn) {dir=orn.dir; perp=orn.perp; pos.zero();}
  167. Orient ::Orient (C Matrix3 &matrix) {dir=matrix.z; perp=matrix.y;}
  168. Orient ::Orient (C MatrixD3 &matrix) {dir=matrix.z; perp=matrix.y;}
  169. OrientD::OrientD(C Matrix3 &matrix) {dir=matrix.z; perp=matrix.y; fix();} // call 'fix' to get high precision
  170. OrientD::OrientD(C MatrixD3 &matrix) {dir=matrix.z; perp=matrix.y;}
  171. OrientP::OrientP(C Matrix3 &matrix) {dir=matrix.z; perp=matrix.y; pos.zero();}
  172. OrientP::OrientP(C Matrix &matrix) {dir=matrix.z; perp=matrix.y; pos=matrix.pos;}
  173. OrientP::OrientP(C MatrixM &matrix) {dir=matrix.z; perp=matrix.y; pos=matrix.pos;}
  174. OrientM::OrientM(C Matrix3 &matrix) {dir=matrix.z; perp=matrix.y; pos.zero();}
  175. OrientM::OrientM(C Matrix &matrix) {dir=matrix.z; perp=matrix.y; pos=matrix.pos;}
  176. OrientM::OrientM(C MatrixM &matrix) {dir=matrix.z; perp=matrix.y; pos=matrix.pos;}
  177. OrientP::OrientP(C Quaternion &q) : Orient(q), pos(VecZero) {}
  178. OrientM::OrientM(C Quaternion &q) : Orient(q), pos(0 ) {}
  179. /******************************************************************************/
  180. Orient& Orient ::zero() {dir.zero(); perp.zero(); return T;}
  181. OrientD& OrientD::zero() {dir.zero(); perp.zero(); return T;}
  182. OrientP& OrientP::zero() {dir.zero(); perp.zero(); pos.zero(); return T;}
  183. OrientM& OrientM::zero() {dir.zero(); perp.zero(); pos.zero(); return T;}
  184. /******************************************************************************/
  185. Orient & Orient ::identity() {dir.set(0, 0, 1); perp.set(0, 1, 0); return T;}
  186. OrientD& OrientD::identity() {dir.set(0, 0, 1); perp.set(0, 1, 0); return T;}
  187. OrientP& OrientP::identity() {dir.set(0, 0, 1); perp.set(0, 1, 0); pos.zero(); return T;}
  188. OrientM& OrientM::identity() {dir.set(0, 0, 1); perp.set(0, 1, 0); pos.zero(); return T;}
  189. /******************************************************************************/
  190. Orient & Orient ::setDir(C Vec &dir) {T.dir=dir; T.perp=PerpN(dir); return T;}
  191. OrientD& OrientD::setDir(C VecD &dir) {T.dir=dir; T.perp=PerpN(dir); return T;}
  192. OrientP& OrientP::setPosDir(C Vec &pos, C Vec &dir) {T.pos=pos; T.dir=dir; T.perp=PerpN(dir); return T;}
  193. OrientM& OrientM::setPosDir(C VecD &pos, C Vec &dir) {T.pos=pos; T.dir=dir; T.perp=PerpN(dir); return T;}
  194. /******************************************************************************/
  195. Orient& Orient::fixPerp()
  196. {
  197. perp=PointOnPlane(perp, dir);
  198. if(perp.normalize()<=EPS)perp=PerpN(dir); // if point on plane distance was very small, then it's very likely that due to precision issues, the vector will not be perpendicular to 'dir', so use epsilon comparison. This is very important, because we expect 'perp' to always be perpendicular to 'dir'
  199. return T;
  200. }
  201. OrientD& OrientD::fixPerp()
  202. {
  203. perp=PointOnPlane(perp, dir);
  204. if(perp.normalize()<=EPSD)perp=PerpN(dir); // if point on plane distance was very small, then it's very likely that due to precision issues, the vector will not be perpendicular to 'dir', so use epsilon comparison. This is very important, because we expect 'perp' to always be perpendicular to 'dir'
  205. return T;
  206. }
  207. Bool Orient ::fix() {if(dir.normalize()){fixPerp(); return true;} return false;}
  208. Bool OrientD::fix() {if(dir.normalize()){fixPerp(); return true;} return false;}
  209. /******************************************************************************/
  210. Orient& Orient::rotateDir(Flt angle)
  211. {
  212. if(Any(angle))
  213. {
  214. Flt cos, sin; CosSin(cos, sin, angle);
  215. perp=perp*cos - cross()*sin;
  216. }
  217. return T;
  218. }
  219. Orient& Orient::rotatePerp(Flt angle)
  220. {
  221. if(Any(angle))
  222. {
  223. Flt cos, sin; CosSin(cos, sin, angle);
  224. dir=cross()*sin + dir*cos;
  225. }
  226. return T;
  227. }
  228. Orient& Orient::rotateCross(Flt angle)
  229. {
  230. if(Any(angle))
  231. {
  232. Flt cos, sin; CosSin(cos, sin, angle);
  233. Vec _dir=T.dir;
  234. dir = dir*cos - perp*sin;
  235. perp=_dir*sin + perp*cos;
  236. }
  237. return T;
  238. }
  239. /******************************************************************************/
  240. Orient& Orient::rotateX(Flt angle)
  241. {
  242. if(Any(angle))
  243. {
  244. Flt cos, sin; CosSin(cos, sin, angle);
  245. Flt y=dir.y, z=dir.z;
  246. dir.y=y*cos - z*sin;
  247. dir.z=y*sin + z*cos;
  248. y=perp.y; z=perp.z;
  249. perp.y=y*cos - z*sin;
  250. perp.z=y*sin + z*cos;
  251. }
  252. return T;
  253. }
  254. Orient& Orient::rotateY(Flt angle)
  255. {
  256. if(Any(angle))
  257. {
  258. Flt cos, sin; CosSin(cos, sin, angle);
  259. Flt x=dir.x, z=dir.z;
  260. dir.x=x*cos + z*sin;
  261. dir.z=z*cos - x*sin;
  262. x=perp.x; z=perp.z;
  263. perp.x=x*cos + z*sin;
  264. perp.z=z*cos - x*sin;
  265. }
  266. return T;
  267. }
  268. Orient& Orient::rotateZ(Flt angle)
  269. {
  270. if(Any(angle))
  271. {
  272. Flt cos, sin; CosSin(cos, sin, angle);
  273. Flt x=dir.x, y=dir.y;
  274. dir.x=x*cos - y*sin;
  275. dir.y=y*cos + x*sin;
  276. x=perp.x; y=perp.y;
  277. perp.x=x*cos - y*sin;
  278. perp.y=y*cos + x*sin;
  279. }
  280. return T;
  281. }
  282. /******************************************************************************/
  283. Orient& Orient::rotateToDir(C Vec &dir)
  284. {
  285. T.perp*=Matrix3().setRotation(T.dir, dir);
  286. T.dir =dir;
  287. return T;
  288. }
  289. Orient& Orient::rotateToDir(C Vec &dir, Flt blend)
  290. {
  291. Matrix3 m; m.setRotation(T.dir, dir, blend);
  292. T.perp*=m;
  293. T.dir *=m;
  294. return T;
  295. }
  296. /******************************************************************************/
  297. void Orient::inverse(MatrixD3 &dest)C {OrientD(T).inverse(dest);} // use 'OrientD' to get high precision
  298. void Orient::inverse(Matrix3 &dest)C
  299. {
  300. Vec cross=T.cross();
  301. dest.x.x=cross.x;
  302. dest.x.y=perp .x;
  303. dest.x.z=dir .x;
  304. dest.y.x=cross.y;
  305. dest.y.y=perp .y;
  306. dest.y.z=dir .y;
  307. dest.z.x=cross.z;
  308. dest.z.y=perp .z;
  309. dest.z.z=dir .z;
  310. }
  311. void OrientD::inverse(MatrixD3 &dest)C
  312. {
  313. VecD cross=T.cross();
  314. dest.x.x=cross.x;
  315. dest.x.y=perp .x;
  316. dest.x.z=dir .x;
  317. dest.y.x=cross.y;
  318. dest.y.y=perp .y;
  319. dest.y.z=dir .y;
  320. dest.z.x=cross.z;
  321. dest.z.y=perp .z;
  322. dest.z.z=dir .z;
  323. }
  324. void Orient::inverse(Orient &dest)C
  325. {
  326. Vec cross=T.cross();
  327. Flt perp_z=perp.z; // remember in case 'dest' is 'this'
  328. dest.perp.x=cross.y;
  329. dest.perp.y=perp .y;
  330. dest.perp.z=dir .y;
  331. dest.dir.x=cross.z;
  332. dest.dir.y=perp_z ;
  333. dest.dir.z=dir .z;
  334. }
  335. void OrientD::inverse(OrientD &dest)C
  336. {
  337. VecD cross=T.cross();
  338. Dbl perp_z=perp.z; // remember in case 'dest' is 'this'
  339. dest.perp.x=cross.y;
  340. dest.perp.y=perp .y;
  341. dest.perp.z=dir .y;
  342. dest.dir.x=cross.z;
  343. dest.dir.y=perp_z ;
  344. dest.dir.z=dir .z;
  345. }
  346. Orient& Orient::inverse()
  347. {
  348. Vec cross=T.cross();
  349. perp.x=cross.y;
  350. dir .x=cross.z;
  351. Swap(perp.z, dir.y);
  352. return T;
  353. }
  354. OrientD& OrientD::inverse()
  355. {
  356. VecD cross=T.cross();
  357. perp.x=cross.y;
  358. dir .x=cross.z;
  359. Swap(perp.z, dir.y);
  360. return T;
  361. }
  362. /******************************************************************************/
  363. void OrientP::draw(C Color &color, Flt size)C
  364. {
  365. Vec blade_end =pos+perp*size,
  366. hilt_end =pos+dir*(size*0.30f),
  367. blade_side= dir*(size*0.08f),
  368. hilt_side=cross()*(size*0.10f);
  369. VI.color(color);
  370. VI.line (pos , blade_end);
  371. VI.line (pos-blade_side, blade_end);
  372. VI.line (pos+blade_side, blade_end);
  373. VI.line (pos+ hilt_side, hilt_end);
  374. VI.line (pos- hilt_side, hilt_end);
  375. VI.end ();
  376. }
  377. void OrientM::draw(C Color &color, Flt size)C
  378. {
  379. VecD blade_end =pos+perp*size,
  380. hilt_end =pos+dir*(size*0.30f);
  381. Vec blade_side= dir*(size*0.08f),
  382. hilt_side=cross()*(size*0.10f);
  383. VI.color(color);
  384. VI.line (pos , blade_end);
  385. VI.line (pos-blade_side, blade_end);
  386. VI.line (pos+blade_side, blade_end);
  387. VI.line (pos+ hilt_side, hilt_end);
  388. VI.line (pos- hilt_side, hilt_end);
  389. VI.end ();
  390. }
  391. /******************************************************************************/
  392. void Orient::save(MemPtr<TextNode> nodes)C
  393. {
  394. nodes.New().set("Dir" , dir );
  395. nodes.New().set("Perp", perp);
  396. }
  397. void OrientD::save(MemPtr<TextNode> nodes)C
  398. {
  399. nodes.New().set("Dir" , dir );
  400. nodes.New().set("Perp", perp);
  401. }
  402. void OrientP::save(MemPtr<TextNode> nodes)C
  403. {
  404. super::save(nodes);
  405. nodes.New().set("Pos", pos);
  406. }
  407. void OrientM::save(MemPtr<TextNode> nodes)C
  408. {
  409. super::save(nodes);
  410. nodes.New().set("Pos", pos);
  411. }
  412. /******************************************************************************/
  413. // AXIS ROLL
  414. /******************************************************************************/
  415. AxisRoll& AxisRoll::from(C Orient &start, C Orient &result)
  416. {
  417. Vec cross=Cross(start.dir, result.dir); if(Flt sin=cross.normalize())
  418. {
  419. Flt cos=Dot(start.dir, result.dir);
  420. // set axis
  421. axis=cross*ACosSin(cos, sin);
  422. // set roll
  423. Orient temp =start*Matrix3().setRotateCosSin(cross, cos, sin);
  424. Matrix3 matrix=temp;
  425. roll=AngleDelta(Angle(temp.perp, matrix), Angle(result.perp, matrix));
  426. }else
  427. {
  428. // set axis
  429. axis.zero();
  430. // set roll
  431. //Matrix3 matrix=start; roll=AngleDelta(Angle(start.perp, matrix), Angle(result.perp, matrix ));
  432. // roll=AngleDelta( PI_2, Angle(result.perp, start.cross(), start.perp )); // we don't need entire matrix, "Angle(start.perp, matrix)" gets converted to PI_2 because 'matrix' is made from 'start'
  433. roll= -Angle(result.perp, start.perp , start.cross()); // instead of calculating angle by XY, we use YX which will get rid of PI_2 offset, however we need to change sign
  434. }
  435. return T;
  436. }
  437. AxisRoll& AxisRoll::mul(C Matrix3 &matrix)
  438. {
  439. Flt length=axis.length();
  440. axis*=matrix;
  441. axis.setLength(length);
  442. return T;
  443. }
  444. /******************************************************************************/
  445. Orient Lerp(C Orient &a, C Orient &b, Flt step)
  446. {
  447. Orient o;
  448. o.dir =a.dir *Matrix3().setRotation(a.dir , b.dir , step);
  449. o.perp=a.perp*Matrix3().setRotation(a.perp, b.perp, step);
  450. o.fix();
  451. return o;
  452. }
  453. /******************************************************************************/
  454. Bool Equal(C Orient &a, C Orient &b, Flt eps ) {return Equal(a.dir, b.dir, eps) && Equal(a.perp, b.perp, eps);}
  455. Bool Equal(C OrientD &a, C OrientD &b, Dbl eps ) {return Equal(a.dir, b.dir, eps) && Equal(a.perp, b.perp, eps);}
  456. Bool Equal(C OrientP &a, C OrientP &b, Flt eps, Flt pos_eps) {return Equal(a.dir, b.dir, eps) && Equal(a.perp, b.perp, eps) && Equal(a.pos, b.pos, pos_eps);}
  457. Bool Equal(C OrientM &a, C OrientM &b, Flt eps, Dbl pos_eps) {return Equal(a.dir, b.dir, eps) && Equal(a.perp, b.perp, eps) && Equal(a.pos, b.pos, pos_eps);}
  458. /******************************************************************************/
  459. Orient GetAnimOrient(C Orient &orn, C Orient *parent)
  460. {
  461. Orient O=orn; if(parent)O.div(*parent, true); // O/=parent
  462. return O;
  463. }
  464. Orient GetAnimOrient(C Orient &bone, C Matrix3 &bone_matrix, C Orient *parent, C Matrix3 *parent_matrix)
  465. {
  466. Orient O=bone; O.mul(bone_matrix, true);
  467. if(parent && parent_matrix)
  468. {
  469. Orient transformed_parent=*parent; transformed_parent.mul(*parent_matrix, true);
  470. O.div(transformed_parent, true);
  471. }
  472. /*if(!normalized)*/{O.dir.normalize(); O.perp.normalize();}
  473. return O;
  474. }
  475. Vec GetAnimPos(C OrientP &bone, C Vec &bone_pos, C Orient &bone_orn, C Orient *parent, C Matrix *parent_matrix)
  476. {
  477. /* Following code is from "void UpdateBoneMatrix(AnimatedSkeleton &anim_skel, Int i)"
  478. bone._matrix.pos =-sbon.pos;
  479. bone._matrix.pos*=bone._matrix.orn();
  480. bone._matrix.pos+=sbon.pos;
  481. bone._matrix.pos+=(parent ? bone.pos*parent_matrix : bone.pos);
  482. bone._matrix *=parent_transform_matrix;
  483. bone._matrix =actor.matrix(); */
  484. Vec P=bone_pos;
  485. if(parent && parent_matrix)
  486. {
  487. P/=*parent_matrix;
  488. Matrix3 parent_=*parent, bone_matrix;
  489. Orient bone_orn_=bone_orn; bone_orn_.mul(parent_, true);
  490. bone.inverse(bone_matrix); bone_matrix.mul(Matrix3(bone_orn_));
  491. Vec p=-bone.pos; p*=bone_matrix; p+=bone.pos; P-=p;
  492. P/=parent_;
  493. }else
  494. {
  495. Matrix3 bone_matrix;
  496. bone.inverse(bone_matrix); bone_matrix.mul(Matrix3(bone_orn));
  497. Vec p=-bone.pos; p*=bone_matrix; p+=bone.pos; P-=p;
  498. }
  499. return P;
  500. }
  501. /******************************************************************************/
  502. }
  503. /******************************************************************************/