PageRenderTime 26ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcharacter/lleditingmotion.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 258 lines | 142 code | 45 blank | 71 comment | 6 complexity | 5e0c8d947e74db69613ec68e8690ca25 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lleditingmotion.cpp
  3. * @brief Implementation of LLEditingMotion 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 "lleditingmotion.h"
  31. #include "llcharacter.h"
  32. #include "llhandmotion.h"
  33. #include "llcriticaldamp.h"
  34. //-----------------------------------------------------------------------------
  35. // Constants
  36. //-----------------------------------------------------------------------------
  37. const LLQuaternion EDIT_MOTION_WRIST_ROTATION(F_PI_BY_TWO * 0.7f, LLVector3(1.0f, 0.0f, 0.0f));
  38. const F32 TARGET_LAG_HALF_LIFE = 0.1f; // half-life of IK targeting
  39. const F32 TORSO_LAG_HALF_LIFE = 0.2f;
  40. const F32 MAX_TIME_DELTA = 2.f; //max two seconds a frame for calculating interpolation
  41. S32 LLEditingMotion::sHandPose = LLHandMotion::HAND_POSE_RELAXED_R;
  42. S32 LLEditingMotion::sHandPosePriority = 3;
  43. //-----------------------------------------------------------------------------
  44. // LLEditingMotion()
  45. // Class Constructor
  46. //-----------------------------------------------------------------------------
  47. LLEditingMotion::LLEditingMotion( const LLUUID &id) : LLMotion(id)
  48. {
  49. mCharacter = NULL;
  50. // create kinematic chain
  51. mParentJoint.addChild( &mShoulderJoint );
  52. mShoulderJoint.addChild( &mElbowJoint );
  53. mElbowJoint.addChild( &mWristJoint );
  54. mName = "editing";
  55. mParentState = new LLJointState;
  56. mShoulderState = new LLJointState;
  57. mElbowState = new LLJointState;
  58. mWristState = new LLJointState;
  59. mTorsoState = new LLJointState;
  60. }
  61. //-----------------------------------------------------------------------------
  62. // ~LLEditingMotion()
  63. // Class Destructor
  64. //-----------------------------------------------------------------------------
  65. LLEditingMotion::~LLEditingMotion()
  66. {
  67. }
  68. //-----------------------------------------------------------------------------
  69. // LLEditingMotion::onInitialize(LLCharacter *character)
  70. //-----------------------------------------------------------------------------
  71. LLMotion::LLMotionInitStatus LLEditingMotion::onInitialize(LLCharacter *character)
  72. {
  73. // save character for future use
  74. mCharacter = character;
  75. // make sure character skeleton is copacetic
  76. if (!mCharacter->getJoint("mShoulderLeft") ||
  77. !mCharacter->getJoint("mElbowLeft") ||
  78. !mCharacter->getJoint("mWristLeft"))
  79. {
  80. llwarns << "Invalid skeleton for editing motion!" << llendl;
  81. return STATUS_FAILURE;
  82. }
  83. // get the shoulder, elbow, wrist joints from the character
  84. mParentState->setJoint( mCharacter->getJoint("mShoulderLeft")->getParent() );
  85. mShoulderState->setJoint( mCharacter->getJoint("mShoulderLeft") );
  86. mElbowState->setJoint( mCharacter->getJoint("mElbowLeft") );
  87. mWristState->setJoint( mCharacter->getJoint("mWristLeft") );
  88. mTorsoState->setJoint( mCharacter->getJoint("mTorso"));
  89. if ( ! mParentState->getJoint() )
  90. {
  91. llinfos << getName() << ": Can't get parent joint." << llendl;
  92. return STATUS_FAILURE;
  93. }
  94. mWristOffset = LLVector3(0.0f, 0.2f, 0.0f);
  95. // add joint states to the pose
  96. mShoulderState->setUsage(LLJointState::ROT);
  97. mElbowState->setUsage(LLJointState::ROT);
  98. mTorsoState->setUsage(LLJointState::ROT);
  99. mWristState->setUsage(LLJointState::ROT);
  100. addJointState( mShoulderState );
  101. addJointState( mElbowState );
  102. addJointState( mTorsoState );
  103. addJointState( mWristState );
  104. // propagate joint positions to kinematic chain
  105. mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() );
  106. mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() );
  107. mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() );
  108. mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset );
  109. // propagate current joint rotations to kinematic chain
  110. mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() );
  111. mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() );
  112. mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() );
  113. // connect the ikSolver to the chain
  114. mIKSolver.setPoleVector( LLVector3( -1.0f, 1.0f, 0.0f ) );
  115. // specifying the elbow's axis will prevent bad IK for the more
  116. // singular configurations, but the axis is limb-specific -- Leviathan
  117. mIKSolver.setBAxis( LLVector3( -0.682683f, 0.0f, -0.730714f ) );
  118. mIKSolver.setupJoints( &mShoulderJoint, &mElbowJoint, &mWristJoint, &mTarget );
  119. return STATUS_SUCCESS;
  120. }
  121. //-----------------------------------------------------------------------------
  122. // LLEditingMotion::onActivate()
  123. //-----------------------------------------------------------------------------
  124. BOOL LLEditingMotion::onActivate()
  125. {
  126. // propagate joint positions to kinematic chain
  127. mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() );
  128. mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() );
  129. mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() );
  130. mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset );
  131. // propagate current joint rotations to kinematic chain
  132. mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() );
  133. mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() );
  134. mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() );
  135. return TRUE;
  136. }
  137. //-----------------------------------------------------------------------------
  138. // LLEditingMotion::onUpdate()
  139. //-----------------------------------------------------------------------------
  140. BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask)
  141. {
  142. LLVector3 focus_pt;
  143. LLVector3* pointAtPt = (LLVector3*)mCharacter->getAnimationData("PointAtPoint");
  144. BOOL result = TRUE;
  145. if (!pointAtPt)
  146. {
  147. focus_pt = mLastSelectPt;
  148. result = FALSE;
  149. }
  150. else
  151. {
  152. focus_pt = *pointAtPt;
  153. mLastSelectPt = focus_pt;
  154. }
  155. focus_pt += mCharacter->getCharacterPosition();
  156. // propagate joint positions to kinematic chain
  157. mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() );
  158. mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() );
  159. mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() );
  160. mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset );
  161. // propagate current joint rotations to kinematic chain
  162. mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() );
  163. mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() );
  164. mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() );
  165. // update target position from character
  166. LLVector3 target = focus_pt - mParentJoint.getPosition();
  167. F32 target_dist = target.normVec();
  168. LLVector3 edit_plane_normal(1.f / F_SQRT2, 1.f / F_SQRT2, 0.f);
  169. edit_plane_normal.normVec();
  170. edit_plane_normal.rotVec(mTorsoState->getJoint()->getWorldRotation());
  171. F32 dot = edit_plane_normal * target;
  172. if (dot < 0.f)
  173. {
  174. target = target + (edit_plane_normal * (dot * 2.f));
  175. target.mV[VZ] += clamp_rescale(dot, 0.f, -1.f, 0.f, 5.f);
  176. target.normVec();
  177. }
  178. target = target * target_dist;
  179. if (!target.isFinite())
  180. {
  181. llerrs << "Non finite target in editing motion with target distance of " << target_dist <<
  182. " and focus point " << focus_pt << llendl;
  183. }
  184. mTarget.setPosition( target + mParentJoint.getPosition());
  185. // llinfos << "Point At: " << mTarget.getPosition() << llendl;
  186. // update the ikSolver
  187. if (!mTarget.getPosition().isExactlyZero())
  188. {
  189. LLQuaternion shoulderRot = mShoulderJoint.getRotation();
  190. LLQuaternion elbowRot = mElbowJoint.getRotation();
  191. mIKSolver.solve();
  192. // use blending...
  193. F32 slerp_amt = LLCriticalDamp::getInterpolant(TARGET_LAG_HALF_LIFE);
  194. shoulderRot = slerp(slerp_amt, mShoulderJoint.getRotation(), shoulderRot);
  195. elbowRot = slerp(slerp_amt, mElbowJoint.getRotation(), elbowRot);
  196. // now put blended values back into joints
  197. llassert(shoulderRot.isFinite());
  198. llassert(elbowRot.isFinite());
  199. mShoulderState->setRotation(shoulderRot);
  200. mElbowState->setRotation(elbowRot);
  201. mWristState->setRotation(LLQuaternion::DEFAULT);
  202. }
  203. mCharacter->setAnimationData("Hand Pose", &sHandPose);
  204. mCharacter->setAnimationData("Hand Pose Priority", &sHandPosePriority);
  205. return result;
  206. }
  207. //-----------------------------------------------------------------------------
  208. // LLEditingMotion::onDeactivate()
  209. //-----------------------------------------------------------------------------
  210. void LLEditingMotion::onDeactivate()
  211. {
  212. }
  213. // End