llcoordframe.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:19k
源码类别:

游戏引擎

开发平台:

C++ Builder

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