llcoordframe.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. /**
  2. * @file llcoordframe.cpp
  3. * @brief LLCoordFrame class implementation.
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewergpl$
  6. *
  7. * Copyright (c) 2000-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "linden_common.h"
  33. #include "llcoordframe.h"
  34. #include "llmatrix3.h"
  35. #include "llmatrix4.h"
  36. #include "llquaternion.h"
  37. LLCoordFrame::LLCoordFrame(const LLVector3& origin) noexcept
  38. : mOrigin(origin),
  39. mXAxis(1.f, 0.f, 0.f),
  40. mYAxis(0.f, 1.f, 0.f),
  41. mZAxis(0.f, 0.f, 1.f)
  42. {
  43. if (!mOrigin.isFinite())
  44. {
  45. reset();
  46. llwarns_sparse << "Non finite (1). Coordinates reset." << llendl;
  47. }
  48. }
  49. LLCoordFrame::LLCoordFrame(const LLVector3& origin,
  50. const LLVector3& direction) noexcept
  51. : mOrigin(origin)
  52. {
  53. lookDir(direction);
  54. if (!isFinite())
  55. {
  56. reset();
  57. llwarns_sparse << "Non finite (2). Coordinates reset." << llendl;
  58. }
  59. }
  60. LLCoordFrame::LLCoordFrame(const LLVector3& x_axis,
  61. const LLVector3& y_axis,
  62. const LLVector3& z_axis) noexcept
  63. : mXAxis(x_axis),
  64. mYAxis(y_axis),
  65. mZAxis(z_axis)
  66. {
  67. if (!isFinite())
  68. {
  69. reset();
  70. llwarns_sparse << "Non finite (3). Coordinates reset." << llendl;
  71. }
  72. }
  73. LLCoordFrame::LLCoordFrame(const LLVector3& origin,
  74. const LLVector3& x_axis,
  75. const LLVector3& y_axis,
  76. const LLVector3& z_axis) noexcept
  77. : mOrigin(origin),
  78. mXAxis(x_axis),
  79. mYAxis(y_axis),
  80. mZAxis(z_axis)
  81. {
  82. if (!isFinite())
  83. {
  84. reset();
  85. llwarns_sparse << "Non finite (4). Coordinates reset." << llendl;
  86. }
  87. }
  88. LLCoordFrame::LLCoordFrame(const LLVector3& origin,
  89. const LLMatrix3& rotation) noexcept
  90. : mOrigin(origin),
  91. mXAxis(rotation.mMatrix[VX]),
  92. mYAxis(rotation.mMatrix[VY]),
  93. mZAxis(rotation.mMatrix[VZ])
  94. {
  95. if (!isFinite())
  96. {
  97. reset();
  98. llwarns_sparse << "Non finite (5). Coordinates reset." << llendl;
  99. }
  100. }
  101. LLCoordFrame::LLCoordFrame(const LLQuaternion& q) noexcept
  102. {
  103. LLMatrix3 rotation_matrix(q);
  104. mXAxis.set(rotation_matrix.mMatrix[VX]);
  105. mYAxis.set(rotation_matrix.mMatrix[VY]);
  106. mZAxis.set(rotation_matrix.mMatrix[VZ]);
  107. if (!isFinite())
  108. {
  109. reset();
  110. llwarns_sparse << "Non finite (6). Coordinates reset." << llendl;
  111. }
  112. }
  113. LLCoordFrame::LLCoordFrame(const LLVector3& origin,
  114. const LLQuaternion& q) noexcept
  115. : mOrigin(origin)
  116. {
  117. LLMatrix3 rotation_matrix(q);
  118. mXAxis.set(rotation_matrix.mMatrix[VX]);
  119. mYAxis.set(rotation_matrix.mMatrix[VY]);
  120. mZAxis.set(rotation_matrix.mMatrix[VZ]);
  121. if (!isFinite())
  122. {
  123. reset();
  124. llwarns_sparse << "Non finite. Coordinates reset." << llendl;
  125. }
  126. }
  127. LLCoordFrame::LLCoordFrame(const LLMatrix4& mat) noexcept
  128. : mOrigin(mat.mMatrix[VW]),
  129. mXAxis(mat.mMatrix[VX]),
  130. mYAxis(mat.mMatrix[VY]),
  131. mZAxis(mat.mMatrix[VZ])
  132. {
  133. if (!isFinite())
  134. {
  135. reset();
  136. llwarns_sparse << "Non finite (7). Coordinates reset." << llendl;
  137. }
  138. }
  139. #if 0 // The folowing two constructors are dangerous due to implicit casting
  140. // and have been disabled - SJB
  141. LLCoordFrame::LLCoordFrame(const F32* origin, const F32* rotation) noexcept
  142. : mOrigin(origin),
  143. mXAxis(rotation + 3 * VX),
  144. mYAxis(rotation + 3 * VY),
  145. mZAxis(rotation + 3 * VZ)
  146. {
  147. if (!isFinite())
  148. {
  149. reset();
  150. llwarns_sparse << "Non finite (8). Coordinates reset." << llendl;
  151. }
  152. }
  153. LLCoordFrame::LLCoordFrame(const F32* origin_and_rotation) noexcept
  154. : mOrigin(origin_and_rotation),
  155. mXAxis(origin_and_rotation + 3 * (VX + 1)),
  156. mYAxis(origin_and_rotation + 3 * (VY + 1)),
  157. mZAxis(origin_and_rotation + 3 * (VZ + 1))
  158. {
  159. if (!isFinite())
  160. {
  161. reset();
  162. llwarns_sparse << "Non finite (9). Coordinates reset." << llendl;
  163. }
  164. }
  165. #endif
  166. void LLCoordFrame::reset()
  167. {
  168. mOrigin.clear();
  169. resetAxes();
  170. }
  171. void LLCoordFrame::resetAxes()
  172. {
  173. mXAxis.set(1.f, 0.f, 0.f);
  174. mYAxis.set(0.f, 1.f, 0.f);
  175. mZAxis.set(0.f, 0.f, 1.f);
  176. }
  177. // setOrigin() methods set mOrigin
  178. void LLCoordFrame::setOrigin(F32 x, F32 y, F32 z)
  179. {
  180. mOrigin.set(x, y, z);
  181. if (!mOrigin.isFinite())
  182. {
  183. reset();
  184. llwarns_sparse << "Non finite (1). Coordinates reset." << llendl;
  185. }
  186. }
  187. void LLCoordFrame::setOrigin(const LLVector3& new_origin)
  188. {
  189. mOrigin = new_origin;
  190. if (!mOrigin.isFinite())
  191. {
  192. reset();
  193. llwarns_sparse << "Non finite (2). Coordinates reset." << llendl;
  194. }
  195. }
  196. void LLCoordFrame::setOrigin(const F32* origin)
  197. {
  198. mOrigin.mV[VX] = *(origin + VX);
  199. mOrigin.mV[VY] = *(origin + VY);
  200. mOrigin.mV[VZ] = *(origin + VZ);
  201. if (!mOrigin.isFinite())
  202. {
  203. reset();
  204. llwarns_sparse << "Non finite (3). Coordinates reset." << llendl;
  205. }
  206. }
  207. void LLCoordFrame::setOrigin(const LLCoordFrame& frame)
  208. {
  209. mOrigin = frame.getOrigin();
  210. if (!mOrigin.isFinite())
  211. {
  212. reset();
  213. llwarns_sparse << "Non finite (4). Coordinates reset." << llendl;
  214. }
  215. }
  216. // The setAxes() methods set the axes, and assume that the arguments are
  217. // orthogonal and normalized.
  218. void LLCoordFrame::setAxes(const LLVector3& x_axis,
  219. const LLVector3& y_axis,
  220. const LLVector3& z_axis)
  221. {
  222. mXAxis = x_axis;
  223. mYAxis = y_axis;
  224. mZAxis = z_axis;
  225. if (!isFinite())
  226. {
  227. reset();
  228. llwarns_sparse << "Non finite (1). Coordinates reset." << llendl;
  229. }
  230. }
  231. void LLCoordFrame::setAxes(const LLMatrix3& rotation_matrix)
  232. {
  233. mXAxis.set(rotation_matrix.mMatrix[VX]);
  234. mYAxis.set(rotation_matrix.mMatrix[VY]);
  235. mZAxis.set(rotation_matrix.mMatrix[VZ]);
  236. if (!isFinite())
  237. {
  238. reset();
  239. llwarns_sparse << "Non finite (2). Coordinates reset." << llendl;
  240. }
  241. }
  242. void LLCoordFrame::setAxes(const LLQuaternion& q)
  243. {
  244. LLMatrix3 rotation_matrix(q);
  245. setAxes(rotation_matrix);
  246. if (!isFinite())
  247. {
  248. reset();
  249. llwarns_sparse << "Non finite (3). Coordinates reset." << llendl;
  250. }
  251. }
  252. void LLCoordFrame::setAxes(const F32* rotation_matrix)
  253. {
  254. mXAxis.mV[VX] = *(rotation_matrix + (3 * VX + VX));
  255. mXAxis.mV[VY] = *(rotation_matrix + (3 * VX + VY));
  256. mXAxis.mV[VZ] = *(rotation_matrix + (3 * VX + VZ));
  257. mYAxis.mV[VX] = *(rotation_matrix + (3 * VY + VX));
  258. mYAxis.mV[VY] = *(rotation_matrix + (3 * VY + VY));
  259. mYAxis.mV[VZ] = *(rotation_matrix + (3 * VY + VZ));
  260. mZAxis.mV[VX] = *(rotation_matrix + (3 * VZ + VX));
  261. mZAxis.mV[VY] = *(rotation_matrix + (3 * VZ + VY));
  262. mZAxis.mV[VZ] = *(rotation_matrix + (3 * VZ + VZ));
  263. if (!isFinite())
  264. {
  265. reset();
  266. llwarns_sparse << "Non finite (4). Coordinates reset." << llendl;
  267. }
  268. }
  269. void LLCoordFrame::setAxes(const LLCoordFrame& frame)
  270. {
  271. mXAxis = frame.getXAxis();
  272. mYAxis = frame.getYAxis();
  273. mZAxis = frame.getZAxis();
  274. if (!isFinite())
  275. {
  276. reset();
  277. llwarns_sparse << "Non finite (5). Coordinates reset." << llendl;
  278. }
  279. }
  280. // The translate() methods move mOrigin to a relative position
  281. void LLCoordFrame::translate(F32 x, F32 y, F32 z)
  282. {
  283. mOrigin.mV[VX] += x;
  284. mOrigin.mV[VY] += y;
  285. mOrigin.mV[VZ] += z;
  286. if (!mOrigin.isFinite())
  287. {
  288. reset();
  289. llwarns_sparse << "Non finite (1). Coordinates reset." << llendl;
  290. }
  291. }
  292. void LLCoordFrame::translate(const LLVector3& v)
  293. {
  294. mOrigin += v;
  295. if (!mOrigin.isFinite())
  296. {
  297. reset();
  298. llwarns_sparse << "Non finite (2). Coordinates reset." << llendl;
  299. }
  300. }
  301. void LLCoordFrame::translate(const F32* origin)
  302. {
  303. mOrigin.mV[VX] += *(origin + VX);
  304. mOrigin.mV[VY] += *(origin + VY);
  305. mOrigin.mV[VZ] += *(origin + VZ);
  306. if (!mOrigin.isFinite())
  307. {
  308. reset();
  309. llwarns_sparse << "Non finite (3). Coordinates reset." << llendl;
  310. }
  311. }
  312. // Rotate methods move the axes to a relative rotation
  313. void LLCoordFrame::rotate(F32 angle, F32 x, F32 y, F32 z)
  314. {
  315. LLQuaternion q(angle, LLVector3(x,y,z));
  316. rotate(q);
  317. }
  318. void LLCoordFrame::rotate(F32 angle, const LLVector3& rotation_axis)
  319. {
  320. LLQuaternion q(angle, rotation_axis);
  321. rotate(q);
  322. }
  323. void LLCoordFrame::rotate(const LLQuaternion& q)
  324. {
  325. LLMatrix3 rotation_matrix(q);
  326. rotate(rotation_matrix);
  327. }
  328. void LLCoordFrame::rotate(const LLMatrix3& rotation_matrix)
  329. {
  330. mXAxis.rotVec(rotation_matrix);
  331. mYAxis.rotVec(rotation_matrix);
  332. orthonormalize();
  333. if (!isFinite())
  334. {
  335. reset();
  336. llwarns_sparse << "Non finite. Coordinates reset." << llendl;
  337. }
  338. }
  339. void LLCoordFrame::roll(F32 angle)
  340. {
  341. LLQuaternion q(angle, mXAxis);
  342. LLMatrix3 rotation_matrix(q);
  343. rotate(rotation_matrix);
  344. if (!mYAxis.isFinite() || !mZAxis.isFinite())
  345. {
  346. reset();
  347. llwarns_sparse << "Non finite. Coordinates reset." << llendl;
  348. }
  349. }
  350. void LLCoordFrame::pitch(F32 angle)
  351. {
  352. LLQuaternion q(angle, mYAxis);
  353. LLMatrix3 rotation_matrix(q);
  354. rotate(rotation_matrix);
  355. if (!mXAxis.isFinite() || !mZAxis.isFinite())
  356. {
  357. reset();
  358. llwarns_sparse << "Non finite. Coordinates reset." << llendl;
  359. }
  360. }
  361. void LLCoordFrame::yaw(F32 angle)
  362. {
  363. LLQuaternion q(angle, mZAxis);
  364. LLMatrix3 rotation_matrix(q);
  365. rotate(rotation_matrix);
  366. if (!mXAxis.isFinite() || !mYAxis.isFinite())
  367. {
  368. reset();
  369. llwarns_sparse << "Non finite. Coordinates reset." << llendl;
  370. }
  371. }
  372. LLQuaternion LLCoordFrame::getQuaternion() const
  373. {
  374. LLQuaternion quat(mXAxis, mYAxis, mZAxis);
  375. return quat;
  376. }
  377. void LLCoordFrame::getMatrixToLocal(LLMatrix4& mat) const
  378. {
  379. mat.setFwdCol(mXAxis);
  380. mat.setLeftCol(mYAxis);
  381. mat.setUpCol(mZAxis);
  382. mat.mMatrix[3][0] = -(mOrigin * LLVector3(mat.mMatrix[0][0],
  383. mat.mMatrix[1][0],
  384. mat.mMatrix[2][0]));
  385. mat.mMatrix[3][1] = -(mOrigin * LLVector3(mat.mMatrix[0][1],
  386. mat.mMatrix[1][1],
  387. mat.mMatrix[2][1]));
  388. mat.mMatrix[3][2] = -(mOrigin * LLVector3(mat.mMatrix[0][2],
  389. mat.mMatrix[1][2],
  390. mat.mMatrix[2][2]));
  391. }
  392. void LLCoordFrame::getRotMatrixToParent(LLMatrix4& mat) const
  393. {
  394. // Note: moves into CFR
  395. mat.setFwdRow(-mYAxis);
  396. mat.setLeftRow(mZAxis);
  397. mat.setUpRow(-mXAxis);
  398. }
  399. size_t LLCoordFrame::writeOrientation(char* buffer) const
  400. {
  401. memcpy(buffer, mOrigin.mV, 3 * sizeof(F32));
  402. buffer += 3 * sizeof(F32);
  403. memcpy(buffer, mXAxis.mV, 3 * sizeof(F32));
  404. buffer += 3 * sizeof(F32);
  405. memcpy(buffer, mYAxis.mV, 3 * sizeof(F32));
  406. buffer += 3 * sizeof(F32);
  407. memcpy(buffer, mZAxis.mV, 3 * sizeof(F32));
  408. return 12 * sizeof(F32);
  409. }
  410. size_t LLCoordFrame::readOrientation(const char* buffer)
  411. {
  412. memcpy(mOrigin.mV, buffer, 3 * sizeof(F32));
  413. buffer += 3 * sizeof(F32);
  414. memcpy(mXAxis.mV, buffer, 3 * sizeof(F32));
  415. buffer += 3 * sizeof(F32);
  416. memcpy(mYAxis.mV, buffer, 3 * sizeof(F32));
  417. buffer += 3 * sizeof(F32);
  418. memcpy(mZAxis.mV, buffer, 3 * sizeof(F32));
  419. if (!isFinite())
  420. {
  421. reset();
  422. llwarns_sparse << "Non finite. Coordinates reset." << llendl;
  423. }
  424. return 12 * sizeof(F32);
  425. }
  426. // Rotation and transform vectors between reference frames
  427. LLVector3 LLCoordFrame::rotateToLocal(const LLVector3& absolute_vector) const
  428. {
  429. LLVector3 local_vector(mXAxis * absolute_vector,
  430. mYAxis * absolute_vector,
  431. mZAxis * absolute_vector);
  432. return local_vector;
  433. }
  434. LLVector4 LLCoordFrame::rotateToLocal(const LLVector4& absolute_vector) const
  435. {
  436. LLVector4 local_vector;
  437. local_vector.mV[VX] = mXAxis.mV[VX] * absolute_vector.mV[VX] +
  438. mXAxis.mV[VY] * absolute_vector.mV[VY] +
  439. mXAxis.mV[VZ] * absolute_vector.mV[VZ];
  440. local_vector.mV[VY] = mYAxis.mV[VX] * absolute_vector.mV[VX] +
  441. mYAxis.mV[VY] * absolute_vector.mV[VY] +
  442. mYAxis.mV[VZ] * absolute_vector.mV[VZ];
  443. local_vector.mV[VZ] = mZAxis.mV[VX] * absolute_vector.mV[VX] +
  444. mZAxis.mV[VY] * absolute_vector.mV[VY] +
  445. mZAxis.mV[VZ] * absolute_vector.mV[VZ];
  446. local_vector.mV[VW] = absolute_vector.mV[VW];
  447. return local_vector;
  448. }
  449. LLVector3 LLCoordFrame::rotateToAbsolute(const LLVector3& local_vector) const
  450. {
  451. LLVector3 absolute_vector;
  452. absolute_vector.mV[VX] = mXAxis.mV[VX] * local_vector.mV[VX] +
  453. mYAxis.mV[VX] * local_vector.mV[VY] +
  454. mZAxis.mV[VX] * local_vector.mV[VZ];
  455. absolute_vector.mV[VY] = mXAxis.mV[VY] * local_vector.mV[VX] +
  456. mYAxis.mV[VY] * local_vector.mV[VY] +
  457. mZAxis.mV[VY] * local_vector.mV[VZ];
  458. absolute_vector.mV[VZ] = mXAxis.mV[VZ] * local_vector.mV[VX] +
  459. mYAxis.mV[VZ] * local_vector.mV[VY] +
  460. mZAxis.mV[VZ] * local_vector.mV[VZ];
  461. return absolute_vector;
  462. }
  463. LLVector4 LLCoordFrame::rotateToAbsolute(const LLVector4& local_vector) const
  464. {
  465. LLVector4 absolute_vector;
  466. absolute_vector.mV[VX] = mXAxis.mV[VX] * local_vector.mV[VX] +
  467. mYAxis.mV[VX] * local_vector.mV[VY] +
  468. mZAxis.mV[VX] * local_vector.mV[VZ];
  469. absolute_vector.mV[VY] = mXAxis.mV[VY] * local_vector.mV[VX] +
  470. mYAxis.mV[VY] * local_vector.mV[VY] +
  471. mZAxis.mV[VY] * local_vector.mV[VZ];
  472. absolute_vector.mV[VZ] = mXAxis.mV[VZ] * local_vector.mV[VX] +
  473. mYAxis.mV[VZ] * local_vector.mV[VY] +
  474. mZAxis.mV[VZ] * local_vector.mV[VZ];
  475. absolute_vector.mV[VW] = local_vector[VW];
  476. return absolute_vector;
  477. }
  478. void LLCoordFrame::orthonormalize()
  479. {
  480. // Makes sure the axes are orthogonal and normalized.
  481. mXAxis.normalize(); // X is renormalized
  482. mYAxis -= mXAxis * (mXAxis * mYAxis); // Y remains in X-Y plane
  483. mYAxis.normalize(); // Y is normalized
  484. mZAxis = mXAxis % mYAxis; // Z = X cross Y
  485. }
  486. LLVector3 LLCoordFrame::transformToLocal(const LLVector3& absolute_vector) const
  487. {
  488. return rotateToLocal(absolute_vector - mOrigin);
  489. }
  490. LLVector4 LLCoordFrame::transformToLocal(const LLVector4& absolute_vector) const
  491. {
  492. LLVector4 local_vector(absolute_vector);
  493. local_vector.mV[VX] -= mOrigin.mV[VX];
  494. local_vector.mV[VY] -= mOrigin.mV[VY];
  495. local_vector.mV[VZ] -= mOrigin.mV[VZ];
  496. return rotateToLocal(local_vector);
  497. }
  498. LLVector3 LLCoordFrame::transformToAbsolute(const LLVector3& local_vector) const
  499. {
  500. return (rotateToAbsolute(local_vector) + mOrigin);
  501. }
  502. LLVector4 LLCoordFrame::transformToAbsolute(const LLVector4& local_vector) const
  503. {
  504. LLVector4 absolute_vector;
  505. absolute_vector = rotateToAbsolute(local_vector);
  506. absolute_vector.mV[VX] += mOrigin.mV[VX];
  507. absolute_vector.mV[VY] += mOrigin.mV[VY];
  508. absolute_vector.mV[VZ] += mOrigin.mV[VZ];
  509. return absolute_vector;
  510. }
  511. // This is how you combine a translation and rotation of a
  512. // coordinate frame to get an OpenGL transformation matrix:
  513. //
  514. // translation * rotation = transformation matrix
  515. //
  516. // (i)->
  517. // (j)| 1 0 0 0 | | a d g 0 | | a d g 0 |
  518. // | | 0 1 0 0 | * | b e h 0 | = | b e h 0 |
  519. // V | 0 0 1 0 | | c f i 0 | | c f i 0 |
  520. // |-x -y -z 1 | | 0 0 0 1 | |-(ax+by+cz) -(dx+ey+fz) -(gx+hy+iz) 1 |
  521. //
  522. // where {a,b,c} = x-axis
  523. // {d,e,f} = y-axis
  524. // {g,h,i} = z-axis
  525. // {x,y,z} = origin
  526. void LLCoordFrame::getOpenGLTranslation(F32* ogl_matrix) const
  527. {
  528. *(ogl_matrix + 0) = 1.f;
  529. *(ogl_matrix + 1) = 0.f;
  530. *(ogl_matrix + 2) = 0.f;
  531. *(ogl_matrix + 3) = 0.f;
  532. *(ogl_matrix + 4) = 0.f;
  533. *(ogl_matrix + 5) = 1.f;
  534. *(ogl_matrix + 6) = 0.f;
  535. *(ogl_matrix + 7) = 0.f;
  536. *(ogl_matrix + 8) = 0.f;
  537. *(ogl_matrix + 9) = 0.f;
  538. *(ogl_matrix + 10) = 1.f;
  539. *(ogl_matrix + 11) = 0.f;
  540. *(ogl_matrix + 12) = -mOrigin.mV[VX];
  541. *(ogl_matrix + 13) = -mOrigin.mV[VY];
  542. *(ogl_matrix + 14) = -mOrigin.mV[VZ];
  543. *(ogl_matrix + 15) = 1.f;
  544. }
  545. void LLCoordFrame::getOpenGLRotation(F32* ogl_matrix) const
  546. {
  547. *(ogl_matrix + 0) = mXAxis.mV[VX];
  548. *(ogl_matrix + 4) = mXAxis.mV[VY];
  549. *(ogl_matrix + 8) = mXAxis.mV[VZ];
  550. *(ogl_matrix + 1) = mYAxis.mV[VX];
  551. *(ogl_matrix + 5) = mYAxis.mV[VY];
  552. *(ogl_matrix + 9) = mYAxis.mV[VZ];
  553. *(ogl_matrix + 2) = mZAxis.mV[VX];
  554. *(ogl_matrix + 6) = mZAxis.mV[VY];
  555. *(ogl_matrix + 10) = mZAxis.mV[VZ];
  556. *(ogl_matrix + 3) = 0.f;
  557. *(ogl_matrix + 7) = 0.f;
  558. *(ogl_matrix + 11) = 0.f;
  559. *(ogl_matrix + 12) = 0.f;
  560. *(ogl_matrix + 13) = 0.f;
  561. *(ogl_matrix + 14) = 0.f;
  562. *(ogl_matrix + 15) = 1.f;
  563. }
  564. void LLCoordFrame::getOpenGLTransform(F32* ogl_matrix) const
  565. {
  566. *(ogl_matrix + 0) = mXAxis.mV[VX];
  567. *(ogl_matrix + 4) = mXAxis.mV[VY];
  568. *(ogl_matrix + 8) = mXAxis.mV[VZ];
  569. *(ogl_matrix + 12) = -mOrigin * mXAxis;
  570. *(ogl_matrix + 1) = mYAxis.mV[VX];
  571. *(ogl_matrix + 5) = mYAxis.mV[VY];
  572. *(ogl_matrix + 9) = mYAxis.mV[VZ];
  573. *(ogl_matrix + 13) = -mOrigin * mYAxis;
  574. *(ogl_matrix + 2) = mZAxis.mV[VX];
  575. *(ogl_matrix + 6) = mZAxis.mV[VY];
  576. *(ogl_matrix + 10) = mZAxis.mV[VZ];
  577. *(ogl_matrix + 14) = -mOrigin * mZAxis;
  578. *(ogl_matrix + 3) = 0.f;
  579. *(ogl_matrix + 7) = 0.f;
  580. *(ogl_matrix + 11) = 0.f;
  581. *(ogl_matrix + 15) = 1.f;
  582. }
  583. // at and up_direction are presumed to be normalized
  584. void LLCoordFrame::lookDir(const LLVector3& at, const LLVector3& up_direction)
  585. {
  586. // Make sure 'at' and 'up_direction' are not parallel
  587. // and that neither are zero-length vectors
  588. LLVector3 left(up_direction % at);
  589. if (left.isNull())
  590. {
  591. // tweak lookat pos so we don't get a degenerate matrix
  592. LLVector3 tempat(at[VX] + 0.01f, at[VY], at[VZ]);
  593. tempat.normalize();
  594. left = (up_direction % tempat);
  595. }
  596. left.normalize();
  597. LLVector3 up = at % left;
  598. if (at.isFinite() && left.isFinite() && up.isFinite())
  599. {
  600. setAxes(at, left, up);
  601. }
  602. }
  603. void LLCoordFrame::lookDir(const LLVector3& xuv)
  604. {
  605. lookDir(xuv, LLVector3::z_axis);
  606. }
  607. void LLCoordFrame::lookAt(const LLVector3& origin,
  608. const LLVector3& point_of_interest,
  609. const LLVector3& up_direction)
  610. {
  611. setOrigin(origin);
  612. LLVector3 at(point_of_interest - origin);
  613. at.normalize();
  614. lookDir(at, up_direction);
  615. }
  616. void LLCoordFrame::lookAt(const LLVector3& origin,
  617. const LLVector3& point_of_interest)
  618. {
  619. setOrigin(origin);
  620. LLVector3 at(point_of_interest - origin);
  621. at.normalize();
  622. lookDir(at, LLVector3::z_axis);
  623. }
  624. // Operators and friends
  625. std::ostream& operator<<(std::ostream& s, const LLCoordFrame& c)
  626. {
  627. s << "{ "
  628. << " origin = " << c.mOrigin
  629. << " x_axis = " << c.mXAxis
  630. << " y_axis = " << c.mYAxis
  631. << " z_axis = " << c.mZAxis
  632. << " }";
  633. return s;
  634. }