PageRenderTime 24ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcharacter/lljoint.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 562 lines | 321 code | 88 blank | 153 comment | 37 complexity | 3e4df5466e602246ddef2933a4bb1013 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lljoint.cpp
  3. * @brief Implementation of LLJoint class.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. //-----------------------------------------------------------------------------
  27. // Header Files
  28. //-----------------------------------------------------------------------------
  29. #include "linden_common.h"
  30. #include "lljoint.h"
  31. #include "llmath.h"
  32. S32 LLJoint::sNumUpdates = 0;
  33. S32 LLJoint::sNumTouches = 0;
  34. //-----------------------------------------------------------------------------
  35. // LLJoint()
  36. // Class Constructor
  37. //-----------------------------------------------------------------------------
  38. LLJoint::LLJoint()
  39. {
  40. mName = "unnamed";
  41. mParent = NULL;
  42. mXform.setScaleChildOffset(TRUE);
  43. mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
  44. mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
  45. mUpdateXform = TRUE;
  46. mJointNum = -1;
  47. touch();
  48. mResetAfterRestoreOldXform = false;
  49. }
  50. //-----------------------------------------------------------------------------
  51. // LLJoint()
  52. // Class Constructor
  53. //-----------------------------------------------------------------------------
  54. LLJoint::LLJoint(const std::string &name, LLJoint *parent)
  55. {
  56. mName = "unnamed";
  57. mParent = NULL;
  58. mXform.setScaleChildOffset(TRUE);
  59. mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
  60. mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
  61. mUpdateXform = FALSE;
  62. mJointNum = 0;
  63. setName(name);
  64. if (parent)
  65. {
  66. parent->addChild( this );
  67. }
  68. touch();
  69. }
  70. //-----------------------------------------------------------------------------
  71. // ~LLJoint()
  72. // Class Destructor
  73. //-----------------------------------------------------------------------------
  74. LLJoint::~LLJoint()
  75. {
  76. if (mParent)
  77. {
  78. mParent->removeChild( this );
  79. }
  80. removeAllChildren();
  81. }
  82. //-----------------------------------------------------------------------------
  83. // setup()
  84. //-----------------------------------------------------------------------------
  85. void LLJoint::setup(const std::string &name, LLJoint *parent)
  86. {
  87. setName(name);
  88. if (parent)
  89. {
  90. parent->addChild( this );
  91. }
  92. }
  93. //-----------------------------------------------------------------------------
  94. // touch()
  95. // Sets all dirty flags for all children, recursively.
  96. //-----------------------------------------------------------------------------
  97. void LLJoint::touch(U32 flags)
  98. {
  99. if ((flags | mDirtyFlags) != mDirtyFlags)
  100. {
  101. sNumTouches++;
  102. mDirtyFlags |= flags;
  103. U32 child_flags = flags;
  104. if (flags & ROTATION_DIRTY)
  105. {
  106. child_flags |= POSITION_DIRTY;
  107. }
  108. for (child_list_t::iterator iter = mChildren.begin();
  109. iter != mChildren.end(); ++iter)
  110. {
  111. LLJoint* joint = *iter;
  112. joint->touch(child_flags);
  113. }
  114. }
  115. }
  116. //-----------------------------------------------------------------------------
  117. // getRoot()
  118. //-----------------------------------------------------------------------------
  119. LLJoint *LLJoint::getRoot()
  120. {
  121. if ( getParent() == NULL )
  122. {
  123. return this;
  124. }
  125. return getParent()->getRoot();
  126. }
  127. //-----------------------------------------------------------------------------
  128. // findJoint()
  129. //-----------------------------------------------------------------------------
  130. LLJoint *LLJoint::findJoint( const std::string &name )
  131. {
  132. if (name == getName())
  133. return this;
  134. for (child_list_t::iterator iter = mChildren.begin();
  135. iter != mChildren.end(); ++iter)
  136. {
  137. LLJoint* joint = *iter;
  138. LLJoint *found = joint->findJoint(name);
  139. if (found)
  140. {
  141. return found;
  142. }
  143. }
  144. return NULL;
  145. }
  146. //--------------------------------------------------------------------
  147. // addChild()
  148. //--------------------------------------------------------------------
  149. void LLJoint::addChild(LLJoint* joint)
  150. {
  151. if (joint->mParent)
  152. joint->mParent->removeChild(joint);
  153. mChildren.push_back(joint);
  154. joint->mXform.setParent(&mXform);
  155. joint->mParent = this;
  156. joint->touch();
  157. }
  158. //--------------------------------------------------------------------
  159. // removeChild()
  160. //--------------------------------------------------------------------
  161. void LLJoint::removeChild(LLJoint* joint)
  162. {
  163. child_list_t::iterator iter = std::find(mChildren.begin(), mChildren.end(), joint);
  164. if (iter != mChildren.end())
  165. {
  166. mChildren.erase(iter);
  167. joint->mXform.setParent(NULL);
  168. joint->mParent = NULL;
  169. joint->touch();
  170. }
  171. }
  172. //--------------------------------------------------------------------
  173. // removeAllChildren()
  174. //--------------------------------------------------------------------
  175. void LLJoint::removeAllChildren()
  176. {
  177. for (child_list_t::iterator iter = mChildren.begin();
  178. iter != mChildren.end();)
  179. {
  180. child_list_t::iterator curiter = iter++;
  181. LLJoint* joint = *curiter;
  182. mChildren.erase(curiter);
  183. joint->mXform.setParent(NULL);
  184. joint->mParent = NULL;
  185. joint->touch();
  186. }
  187. }
  188. //--------------------------------------------------------------------
  189. // getPosition()
  190. //--------------------------------------------------------------------
  191. const LLVector3& LLJoint::getPosition()
  192. {
  193. return mXform.getPosition();
  194. }
  195. //--------------------------------------------------------------------
  196. // setPosition()
  197. //--------------------------------------------------------------------
  198. void LLJoint::setPosition( const LLVector3& pos )
  199. {
  200. // if (mXform.getPosition() != pos)
  201. {
  202. mXform.setPosition(pos);
  203. touch(MATRIX_DIRTY | POSITION_DIRTY);
  204. }
  205. }
  206. //--------------------------------------------------------------------
  207. // setPosition()
  208. //--------------------------------------------------------------------
  209. void LLJoint::setDefaultFromCurrentXform( void )
  210. {
  211. mDefaultXform = mXform;
  212. touch(MATRIX_DIRTY | POSITION_DIRTY);
  213. }
  214. //--------------------------------------------------------------------
  215. // storeCurrentXform()
  216. //--------------------------------------------------------------------
  217. void LLJoint::storeCurrentXform( const LLVector3& pos )
  218. {
  219. mOldXform = mXform;
  220. mResetAfterRestoreOldXform = true;
  221. setPosition( pos );
  222. }
  223. //--------------------------------------------------------------------
  224. // restoreOldXform()
  225. //--------------------------------------------------------------------
  226. void LLJoint::restoreOldXform( void )
  227. {
  228. mResetAfterRestoreOldXform = false;
  229. mXform = mOldXform;
  230. }
  231. //--------------------------------------------------------------------
  232. // restoreOldXform()
  233. //--------------------------------------------------------------------
  234. void LLJoint::restoreToDefaultXform( void )
  235. {
  236. mXform = mDefaultXform;
  237. setPosition( mXform.getPosition() );
  238. }
  239. //--------------------------------------------------------------------
  240. // getWorldPosition()
  241. //--------------------------------------------------------------------
  242. LLVector3 LLJoint::getWorldPosition()
  243. {
  244. updateWorldPRSParent();
  245. return mXform.getWorldPosition();
  246. }
  247. //-----------------------------------------------------------------------------
  248. // getLastWorldPosition()
  249. //-----------------------------------------------------------------------------
  250. LLVector3 LLJoint::getLastWorldPosition()
  251. {
  252. return mXform.getWorldPosition();
  253. }
  254. //--------------------------------------------------------------------
  255. // setWorldPosition()
  256. //--------------------------------------------------------------------
  257. void LLJoint::setWorldPosition( const LLVector3& pos )
  258. {
  259. if (mParent == NULL)
  260. {
  261. this->setPosition( pos );
  262. return;
  263. }
  264. LLMatrix4 temp_matrix = getWorldMatrix();
  265. temp_matrix.mMatrix[VW][VX] = pos.mV[VX];
  266. temp_matrix.mMatrix[VW][VY] = pos.mV[VY];
  267. temp_matrix.mMatrix[VW][VZ] = pos.mV[VZ];
  268. LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix();
  269. LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert();
  270. temp_matrix *= invParentWorldMatrix;
  271. LLVector3 localPos( temp_matrix.mMatrix[VW][VX],
  272. temp_matrix.mMatrix[VW][VY],
  273. temp_matrix.mMatrix[VW][VZ] );
  274. setPosition( localPos );
  275. }
  276. //--------------------------------------------------------------------
  277. // mXform.getRotation()
  278. //--------------------------------------------------------------------
  279. const LLQuaternion& LLJoint::getRotation()
  280. {
  281. return mXform.getRotation();
  282. }
  283. //--------------------------------------------------------------------
  284. // setRotation()
  285. //--------------------------------------------------------------------
  286. void LLJoint::setRotation( const LLQuaternion& rot )
  287. {
  288. if (rot.isFinite())
  289. {
  290. // if (mXform.getRotation() != rot)
  291. {
  292. mXform.setRotation(rot);
  293. touch(MATRIX_DIRTY | ROTATION_DIRTY);
  294. }
  295. }
  296. }
  297. //--------------------------------------------------------------------
  298. // getWorldRotation()
  299. //--------------------------------------------------------------------
  300. LLQuaternion LLJoint::getWorldRotation()
  301. {
  302. updateWorldPRSParent();
  303. return mXform.getWorldRotation();
  304. }
  305. //-----------------------------------------------------------------------------
  306. // getLastWorldRotation()
  307. //-----------------------------------------------------------------------------
  308. LLQuaternion LLJoint::getLastWorldRotation()
  309. {
  310. return mXform.getWorldRotation();
  311. }
  312. //--------------------------------------------------------------------
  313. // setWorldRotation()
  314. //--------------------------------------------------------------------
  315. void LLJoint::setWorldRotation( const LLQuaternion& rot )
  316. {
  317. if (mParent == NULL)
  318. {
  319. this->setRotation( rot );
  320. return;
  321. }
  322. LLMatrix4 temp_mat(rot);
  323. LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix();
  324. parentWorldMatrix.mMatrix[VW][VX] = 0;
  325. parentWorldMatrix.mMatrix[VW][VY] = 0;
  326. parentWorldMatrix.mMatrix[VW][VZ] = 0;
  327. LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert();
  328. temp_mat *= invParentWorldMatrix;
  329. setRotation(LLQuaternion(temp_mat));
  330. }
  331. //--------------------------------------------------------------------
  332. // getScale()
  333. //--------------------------------------------------------------------
  334. const LLVector3& LLJoint::getScale()
  335. {
  336. return mXform.getScale();
  337. }
  338. //--------------------------------------------------------------------
  339. // setScale()
  340. //--------------------------------------------------------------------
  341. void LLJoint::setScale( const LLVector3& scale )
  342. {
  343. // if (mXform.getScale() != scale)
  344. {
  345. mXform.setScale(scale);
  346. touch();
  347. }
  348. }
  349. //--------------------------------------------------------------------
  350. // getWorldMatrix()
  351. //--------------------------------------------------------------------
  352. const LLMatrix4 &LLJoint::getWorldMatrix()
  353. {
  354. updateWorldMatrixParent();
  355. return mXform.getWorldMatrix();
  356. }
  357. //--------------------------------------------------------------------
  358. // setWorldMatrix()
  359. //--------------------------------------------------------------------
  360. void LLJoint::setWorldMatrix( const LLMatrix4& mat )
  361. {
  362. llinfos << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << llendl;
  363. // extract global translation
  364. LLVector3 trans( mat.mMatrix[VW][VX],
  365. mat.mMatrix[VW][VY],
  366. mat.mMatrix[VW][VZ] );
  367. // extract global rotation
  368. LLQuaternion rot( mat );
  369. setWorldPosition( trans );
  370. setWorldRotation( rot );
  371. }
  372. //-----------------------------------------------------------------------------
  373. // updateWorldMatrixParent()
  374. //-----------------------------------------------------------------------------
  375. void LLJoint::updateWorldMatrixParent()
  376. {
  377. if (mDirtyFlags & MATRIX_DIRTY)
  378. {
  379. LLJoint *parent = getParent();
  380. if (parent)
  381. {
  382. parent->updateWorldMatrixParent();
  383. }
  384. updateWorldMatrix();
  385. }
  386. }
  387. //-----------------------------------------------------------------------------
  388. // updateWorldPRSParent()
  389. //-----------------------------------------------------------------------------
  390. void LLJoint::updateWorldPRSParent()
  391. {
  392. if (mDirtyFlags & (ROTATION_DIRTY | POSITION_DIRTY))
  393. {
  394. LLJoint *parent = getParent();
  395. if (parent)
  396. {
  397. parent->updateWorldPRSParent();
  398. }
  399. mXform.update();
  400. mDirtyFlags &= ~(ROTATION_DIRTY | POSITION_DIRTY);
  401. }
  402. }
  403. //-----------------------------------------------------------------------------
  404. // updateWorldMatrixChildren()
  405. //-----------------------------------------------------------------------------
  406. void LLJoint::updateWorldMatrixChildren()
  407. {
  408. if (!this->mUpdateXform) return;
  409. if (mDirtyFlags & MATRIX_DIRTY)
  410. {
  411. updateWorldMatrix();
  412. }
  413. for (child_list_t::iterator iter = mChildren.begin();
  414. iter != mChildren.end(); ++iter)
  415. {
  416. LLJoint* joint = *iter;
  417. joint->updateWorldMatrixChildren();
  418. }
  419. }
  420. //-----------------------------------------------------------------------------
  421. // updateWorldMatrix()
  422. //-----------------------------------------------------------------------------
  423. void LLJoint::updateWorldMatrix()
  424. {
  425. if (mDirtyFlags & MATRIX_DIRTY)
  426. {
  427. sNumUpdates++;
  428. mXform.updateMatrix(FALSE);
  429. mDirtyFlags = 0x0;
  430. }
  431. }
  432. //--------------------------------------------------------------------
  433. // getSkinOffset()
  434. //--------------------------------------------------------------------
  435. const LLVector3 &LLJoint::getSkinOffset()
  436. {
  437. return mSkinOffset;
  438. }
  439. //--------------------------------------------------------------------
  440. // setSkinOffset()
  441. //--------------------------------------------------------------------
  442. void LLJoint::setSkinOffset( const LLVector3& offset )
  443. {
  444. mSkinOffset = offset;
  445. }
  446. //-----------------------------------------------------------------------------
  447. // clampRotation()
  448. //-----------------------------------------------------------------------------
  449. void LLJoint::clampRotation(LLQuaternion old_rot, LLQuaternion new_rot)
  450. {
  451. LLVector3 main_axis(1.f, 0.f, 0.f);
  452. for (child_list_t::iterator iter = mChildren.begin();
  453. iter != mChildren.end(); ++iter)
  454. {
  455. LLJoint* joint = *iter;
  456. if (joint->isAnimatable())
  457. {
  458. main_axis = joint->getPosition();
  459. main_axis.normVec();
  460. // only care about first animatable child
  461. break;
  462. }
  463. }
  464. // 2003.03.26 - This code was just using up cpu cycles. AB
  465. // LLVector3 old_axis = main_axis * old_rot;
  466. // LLVector3 new_axis = main_axis * new_rot;
  467. // for (S32 i = 0; i < mConstraintSilhouette.count() - 1; i++)
  468. // {
  469. // LLVector3 vert1 = mConstraintSilhouette[i];
  470. // LLVector3 vert2 = mConstraintSilhouette[i + 1];
  471. // figure out how to clamp rotation to line on 3-sphere
  472. // }
  473. }
  474. // End