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