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

游戏引擎

开发平台:

C++ Builder

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