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

游戏引擎

开发平台:

C++ Builder

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