PageRenderTime 57ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/S19/indra/llcharacter/lljoint.cpp

https://github.com/AlexRa/Kirstens-clone
C++ | 529 lines | 298 code | 84 blank | 147 comment | 37 complexity | ca73c0d18d2fbbb95995bfb0759ec7eb MD5 | raw file
Possible License(s): GPL-2.0
  1. /**
  2. * @file lljoint.cpp
  3. * @brief Implementation of LLJoint class.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-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. //-----------------------------------------------------------------------------
  33. // Header Files
  34. //-----------------------------------------------------------------------------
  35. #include "linden_common.h"
  36. #include "lljoint.h"
  37. #include "llmath.h"
  38. S32 LLJoint::sNumUpdates = 0;
  39. S32 LLJoint::sNumTouches = 0;
  40. //-----------------------------------------------------------------------------
  41. // LLJoint()
  42. // Class Constructor
  43. //-----------------------------------------------------------------------------
  44. LLJoint::LLJoint()
  45. {
  46. mName = "unnamed";
  47. mParent = NULL;
  48. mXform.setScaleChildOffset(TRUE);
  49. mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
  50. mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
  51. mUpdateXform = TRUE;
  52. mJointNum = -1;
  53. touch();
  54. }
  55. //-----------------------------------------------------------------------------
  56. // LLJoint()
  57. // Class Constructor
  58. //-----------------------------------------------------------------------------
  59. LLJoint::LLJoint(const std::string &name, LLJoint *parent)
  60. {
  61. mName = "unnamed";
  62. mParent = NULL;
  63. mXform.setScaleChildOffset(TRUE);
  64. mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
  65. mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
  66. mJointNum = 0;
  67. setName(name);
  68. if (parent)
  69. {
  70. parent->addChild( this );
  71. }
  72. touch();
  73. }
  74. //-----------------------------------------------------------------------------
  75. // ~LLJoint()
  76. // Class Destructor
  77. //-----------------------------------------------------------------------------
  78. LLJoint::~LLJoint()
  79. {
  80. if (mParent)
  81. {
  82. mParent->removeChild( this );
  83. }
  84. removeAllChildren();
  85. }
  86. //-----------------------------------------------------------------------------
  87. // setup()
  88. //-----------------------------------------------------------------------------
  89. void LLJoint::setup(const std::string &name, LLJoint *parent)
  90. {
  91. setName(name);
  92. if (parent)
  93. {
  94. parent->addChild( this );
  95. }
  96. }
  97. //-----------------------------------------------------------------------------
  98. // touch()
  99. // Sets all dirty flags for all children, recursively.
  100. //-----------------------------------------------------------------------------
  101. void LLJoint::touch(U32 flags)
  102. {
  103. if ((flags | mDirtyFlags) != mDirtyFlags)
  104. {
  105. sNumTouches++;
  106. mDirtyFlags |= flags;
  107. U32 child_flags = flags;
  108. if (flags & ROTATION_DIRTY)
  109. {
  110. child_flags |= POSITION_DIRTY;
  111. }
  112. for (child_list_t::iterator iter = mChildren.begin();
  113. iter != mChildren.end(); ++iter)
  114. {
  115. LLJoint* joint = *iter;
  116. joint->touch(child_flags);
  117. }
  118. }
  119. }
  120. //-----------------------------------------------------------------------------
  121. // getRoot()
  122. //-----------------------------------------------------------------------------
  123. LLJoint *LLJoint::getRoot()
  124. {
  125. if ( getParent() == NULL )
  126. {
  127. return this;
  128. }
  129. return getParent()->getRoot();
  130. }
  131. //-----------------------------------------------------------------------------
  132. // findJoint()
  133. //-----------------------------------------------------------------------------
  134. LLJoint *LLJoint::findJoint( const std::string &name )
  135. {
  136. if (name == getName())
  137. return this;
  138. for (child_list_t::iterator iter = mChildren.begin();
  139. iter != mChildren.end(); ++iter)
  140. {
  141. LLJoint* joint = *iter;
  142. LLJoint *found = joint->findJoint(name);
  143. if (found)
  144. {
  145. return found;
  146. }
  147. }
  148. return NULL;
  149. }
  150. //--------------------------------------------------------------------
  151. // addChild()
  152. //--------------------------------------------------------------------
  153. void LLJoint::addChild(LLJoint* joint)
  154. {
  155. if (joint->mParent)
  156. joint->mParent->removeChild(joint);
  157. mChildren.push_back(joint);
  158. joint->mXform.setParent(&mXform);
  159. joint->mParent = this;
  160. joint->touch();
  161. }
  162. //--------------------------------------------------------------------
  163. // removeChild()
  164. //--------------------------------------------------------------------
  165. void LLJoint::removeChild(LLJoint* joint)
  166. {
  167. child_list_t::iterator iter = std::find(mChildren.begin(), mChildren.end(), joint);
  168. if (iter != mChildren.end())
  169. {
  170. mChildren.erase(iter);
  171. joint->mXform.setParent(NULL);
  172. joint->mParent = NULL;
  173. joint->touch();
  174. }
  175. }
  176. //--------------------------------------------------------------------
  177. // removeAllChildren()
  178. //--------------------------------------------------------------------
  179. void LLJoint::removeAllChildren()
  180. {
  181. for (child_list_t::iterator iter = mChildren.begin();
  182. iter != mChildren.end();)
  183. {
  184. child_list_t::iterator curiter = iter++;
  185. LLJoint* joint = *curiter;
  186. mChildren.erase(curiter);
  187. joint->mXform.setParent(NULL);
  188. joint->mParent = NULL;
  189. joint->touch();
  190. }
  191. }
  192. //--------------------------------------------------------------------
  193. // getPosition()
  194. //--------------------------------------------------------------------
  195. const LLVector3& LLJoint::getPosition()
  196. {
  197. return mXform.getPosition();
  198. }
  199. //--------------------------------------------------------------------
  200. // setPosition()
  201. //--------------------------------------------------------------------
  202. void LLJoint::setPosition( const LLVector3& pos )
  203. {
  204. // if (mXform.getPosition() != pos)
  205. {
  206. mXform.setPosition(pos);
  207. touch(MATRIX_DIRTY | POSITION_DIRTY);
  208. }
  209. }
  210. //--------------------------------------------------------------------
  211. // getWorldPosition()
  212. //--------------------------------------------------------------------
  213. LLVector3 LLJoint::getWorldPosition()
  214. {
  215. updateWorldPRSParent();
  216. return mXform.getWorldPosition();
  217. }
  218. //-----------------------------------------------------------------------------
  219. // getLastWorldPosition()
  220. //-----------------------------------------------------------------------------
  221. LLVector3 LLJoint::getLastWorldPosition()
  222. {
  223. return mXform.getWorldPosition();
  224. }
  225. //--------------------------------------------------------------------
  226. // setWorldPosition()
  227. //--------------------------------------------------------------------
  228. void LLJoint::setWorldPosition( const LLVector3& pos )
  229. {
  230. if (mParent == NULL)
  231. {
  232. this->setPosition( pos );
  233. return;
  234. }
  235. LLMatrix4 temp_matrix = getWorldMatrix();
  236. temp_matrix.mMatrix[VW][VX] = pos.mV[VX];
  237. temp_matrix.mMatrix[VW][VY] = pos.mV[VY];
  238. temp_matrix.mMatrix[VW][VZ] = pos.mV[VZ];
  239. LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix();
  240. LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert();
  241. temp_matrix *= invParentWorldMatrix;
  242. LLVector3 localPos( temp_matrix.mMatrix[VW][VX],
  243. temp_matrix.mMatrix[VW][VY],
  244. temp_matrix.mMatrix[VW][VZ] );
  245. setPosition( localPos );
  246. }
  247. //--------------------------------------------------------------------
  248. // mXform.getRotation()
  249. //--------------------------------------------------------------------
  250. const LLQuaternion& LLJoint::getRotation()
  251. {
  252. return mXform.getRotation();
  253. }
  254. //--------------------------------------------------------------------
  255. // setRotation()
  256. //--------------------------------------------------------------------
  257. void LLJoint::setRotation( const LLQuaternion& rot )
  258. {
  259. if (rot.isFinite())
  260. {
  261. // if (mXform.getRotation() != rot)
  262. {
  263. mXform.setRotation(rot);
  264. touch(MATRIX_DIRTY | ROTATION_DIRTY);
  265. }
  266. }
  267. }
  268. //--------------------------------------------------------------------
  269. // getWorldRotation()
  270. //--------------------------------------------------------------------
  271. LLQuaternion LLJoint::getWorldRotation()
  272. {
  273. updateWorldPRSParent();
  274. return mXform.getWorldRotation();
  275. }
  276. //-----------------------------------------------------------------------------
  277. // getLastWorldRotation()
  278. //-----------------------------------------------------------------------------
  279. LLQuaternion LLJoint::getLastWorldRotation()
  280. {
  281. return mXform.getWorldRotation();
  282. }
  283. //--------------------------------------------------------------------
  284. // setWorldRotation()
  285. //--------------------------------------------------------------------
  286. void LLJoint::setWorldRotation( const LLQuaternion& rot )
  287. {
  288. if (mParent == NULL)
  289. {
  290. this->setRotation( rot );
  291. return;
  292. }
  293. LLMatrix4 temp_mat(rot);
  294. LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix();
  295. parentWorldMatrix.mMatrix[VW][VX] = 0;
  296. parentWorldMatrix.mMatrix[VW][VY] = 0;
  297. parentWorldMatrix.mMatrix[VW][VZ] = 0;
  298. LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert();
  299. temp_mat *= invParentWorldMatrix;
  300. setRotation(LLQuaternion(temp_mat));
  301. }
  302. //--------------------------------------------------------------------
  303. // getScale()
  304. //--------------------------------------------------------------------
  305. const LLVector3& LLJoint::getScale()
  306. {
  307. return mXform.getScale();
  308. }
  309. //--------------------------------------------------------------------
  310. // setScale()
  311. //--------------------------------------------------------------------
  312. void LLJoint::setScale( const LLVector3& scale )
  313. {
  314. // if (mXform.getScale() != scale)
  315. {
  316. mXform.setScale(scale);
  317. touch();
  318. }
  319. }
  320. //--------------------------------------------------------------------
  321. // getWorldMatrix()
  322. //--------------------------------------------------------------------
  323. const LLMatrix4 &LLJoint::getWorldMatrix()
  324. {
  325. updateWorldMatrixParent();
  326. return mXform.getWorldMatrix();
  327. }
  328. //--------------------------------------------------------------------
  329. // setWorldMatrix()
  330. //--------------------------------------------------------------------
  331. void LLJoint::setWorldMatrix( const LLMatrix4& mat )
  332. {
  333. llinfos << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << llendl;
  334. // extract global translation
  335. LLVector3 trans( mat.mMatrix[VW][VX],
  336. mat.mMatrix[VW][VY],
  337. mat.mMatrix[VW][VZ] );
  338. // extract global rotation
  339. LLQuaternion rot( mat );
  340. setWorldPosition( trans );
  341. setWorldRotation( rot );
  342. }
  343. //-----------------------------------------------------------------------------
  344. // updateWorldMatrixParent()
  345. //-----------------------------------------------------------------------------
  346. void LLJoint::updateWorldMatrixParent()
  347. {
  348. if (mDirtyFlags & MATRIX_DIRTY)
  349. {
  350. LLJoint *parent = getParent();
  351. if (parent)
  352. {
  353. parent->updateWorldMatrixParent();
  354. }
  355. updateWorldMatrix();
  356. }
  357. }
  358. //-----------------------------------------------------------------------------
  359. // updateWorldPRSParent()
  360. //-----------------------------------------------------------------------------
  361. void LLJoint::updateWorldPRSParent()
  362. {
  363. if (mDirtyFlags & (ROTATION_DIRTY | POSITION_DIRTY))
  364. {
  365. LLJoint *parent = getParent();
  366. if (parent)
  367. {
  368. parent->updateWorldPRSParent();
  369. }
  370. mXform.update();
  371. mDirtyFlags &= ~(ROTATION_DIRTY | POSITION_DIRTY);
  372. }
  373. }
  374. //-----------------------------------------------------------------------------
  375. // updateWorldMatrixChildren()
  376. //-----------------------------------------------------------------------------
  377. void LLJoint::updateWorldMatrixChildren()
  378. {
  379. if (!this->mUpdateXform) return;
  380. if (mDirtyFlags & MATRIX_DIRTY)
  381. {
  382. updateWorldMatrix();
  383. }
  384. for (child_list_t::iterator iter = mChildren.begin();
  385. iter != mChildren.end(); ++iter)
  386. {
  387. LLJoint* joint = *iter;
  388. joint->updateWorldMatrixChildren();
  389. }
  390. }
  391. //-----------------------------------------------------------------------------
  392. // updateWorldMatrix()
  393. //-----------------------------------------------------------------------------
  394. void LLJoint::updateWorldMatrix()
  395. {
  396. if (mDirtyFlags & MATRIX_DIRTY)
  397. {
  398. sNumUpdates++;
  399. mXform.updateMatrix(FALSE);
  400. mDirtyFlags = 0x0;
  401. }
  402. }
  403. //--------------------------------------------------------------------
  404. // getSkinOffset()
  405. //--------------------------------------------------------------------
  406. const LLVector3 &LLJoint::getSkinOffset()
  407. {
  408. return mSkinOffset;
  409. }
  410. //--------------------------------------------------------------------
  411. // setSkinOffset()
  412. //--------------------------------------------------------------------
  413. void LLJoint::setSkinOffset( const LLVector3& offset )
  414. {
  415. mSkinOffset = offset;
  416. }
  417. //-----------------------------------------------------------------------------
  418. // clampRotation()
  419. //-----------------------------------------------------------------------------
  420. void LLJoint::clampRotation(LLQuaternion old_rot, LLQuaternion new_rot)
  421. {
  422. LLVector3 main_axis(1.f, 0.f, 0.f);
  423. for (child_list_t::iterator iter = mChildren.begin();
  424. iter != mChildren.end(); ++iter)
  425. {
  426. LLJoint* joint = *iter;
  427. if (joint->isAnimatable())
  428. {
  429. main_axis = joint->getPosition();
  430. main_axis.normVec();
  431. // only care about first animatable child
  432. break;
  433. }
  434. }
  435. // 2003.03.26 - This code was just using up cpu cycles. AB
  436. // LLVector3 old_axis = main_axis * old_rot;
  437. // LLVector3 new_axis = main_axis * new_rot;
  438. // for (S32 i = 0; i < mConstraintSilhouette.count() - 1; i++)
  439. // {
  440. // LLVector3 vert1 = mConstraintSilhouette[i];
  441. // LLVector3 vert2 = mConstraintSilhouette[i + 1];
  442. // figure out how to clamp rotation to line on 3-sphere
  443. // }
  444. }
  445. // End