aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcharacter/lleditingmotion.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcharacter/lleditingmotion.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r--linden/indra/llcharacter/lleditingmotion.cpp253
1 files changed, 253 insertions, 0 deletions
diff --git a/linden/indra/llcharacter/lleditingmotion.cpp b/linden/indra/llcharacter/lleditingmotion.cpp
new file mode 100644
index 0000000..66608f8
--- /dev/null
+++ b/linden/indra/llcharacter/lleditingmotion.cpp
@@ -0,0 +1,253 @@
1/**
2 * @file lleditingmotion.cpp
3 * @brief Implementation of LLEditingMotion class.
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28//-----------------------------------------------------------------------------
29// Header Files
30//-----------------------------------------------------------------------------
31#include "linden_common.h"
32
33#include "lleditingmotion.h"
34#include "llcharacter.h"
35#include "llhandmotion.h"
36#include "llcriticaldamp.h"
37
38//-----------------------------------------------------------------------------
39// Constants
40//-----------------------------------------------------------------------------
41const LLQuaternion EDIT_MOTION_WRIST_ROTATION(F_PI_BY_TWO * 0.7f, LLVector3(1.0f, 0.0f, 0.0f));
42const F32 TARGET_LAG_HALF_LIFE = 0.1f; // half-life of IK targeting
43const F32 TORSO_LAG_HALF_LIFE = 0.2f;
44const F32 MAX_TIME_DELTA = 2.f; //max two seconds a frame for calculating interpolation
45
46S32 LLEditingMotion::sHandPose = LLHandMotion::HAND_POSE_RELAXED_R;
47S32 LLEditingMotion::sHandPosePriority = 3;
48
49//-----------------------------------------------------------------------------
50// LLEditingMotion()
51// Class Constructor
52//-----------------------------------------------------------------------------
53LLEditingMotion::LLEditingMotion( const LLUUID &id) : LLMotion(id)
54{
55 mCharacter = NULL;
56
57 // create kinematic chain
58 mParentJoint.addChild( &mShoulderJoint );
59 mShoulderJoint.addChild( &mElbowJoint );
60 mElbowJoint.addChild( &mWristJoint );
61
62 mName = "editing";
63}
64
65
66//-----------------------------------------------------------------------------
67// ~LLEditingMotion()
68// Class Destructor
69//-----------------------------------------------------------------------------
70LLEditingMotion::~LLEditingMotion()
71{
72}
73
74//-----------------------------------------------------------------------------
75// LLEditingMotion::onInitialize(LLCharacter *character)
76//-----------------------------------------------------------------------------
77LLMotion::LLMotionInitStatus LLEditingMotion::onInitialize(LLCharacter *character)
78{
79 // save character for future use
80 mCharacter = character;
81
82 // make sure character skeleton is copacetic
83 if (!mCharacter->getJoint("mShoulderLeft") ||
84 !mCharacter->getJoint("mElbowLeft") ||
85 !mCharacter->getJoint("mWristLeft"))
86 {
87 llwarns << "Invalid skeleton for editing motion!" << llendl;
88 return STATUS_FAILURE;
89 }
90
91 // get the shoulder, elbow, wrist joints from the character
92 mParentState.setJoint( mCharacter->getJoint("mShoulderLeft")->getParent() );
93 mShoulderState.setJoint( mCharacter->getJoint("mShoulderLeft") );
94 mElbowState.setJoint( mCharacter->getJoint("mElbowLeft") );
95 mWristState.setJoint( mCharacter->getJoint("mWristLeft") );
96 mTorsoState.setJoint( mCharacter->getJoint("mTorso"));
97
98 if ( ! mParentState.getJoint() )
99 {
100 llinfos << getName() << ": Can't get parent joint." << llendl;
101 return STATUS_FAILURE;
102 }
103
104 mWristOffset = LLVector3(0.0f, 0.2f, 0.0f);
105
106 // add joint states to the pose
107 mShoulderState.setUsage(LLJointState::ROT);
108 mElbowState.setUsage(LLJointState::ROT);
109 mTorsoState.setUsage(LLJointState::ROT);
110 mWristState.setUsage(LLJointState::ROT);
111 addJointState( &mShoulderState );
112 addJointState( &mElbowState );
113 addJointState( &mTorsoState );
114 addJointState( &mWristState );
115
116 // propagate joint positions to kinematic chain
117 mParentJoint.setPosition( mParentState.getJoint()->getWorldPosition() );
118 mShoulderJoint.setPosition( mShoulderState.getJoint()->getPosition() );
119 mElbowJoint.setPosition( mElbowState.getJoint()->getPosition() );
120 mWristJoint.setPosition( mWristState.getJoint()->getPosition() + mWristOffset );
121
122 // propagate current joint rotations to kinematic chain
123 mParentJoint.setRotation( mParentState.getJoint()->getWorldRotation() );
124 mShoulderJoint.setRotation( mShoulderState.getJoint()->getRotation() );
125 mElbowJoint.setRotation( mElbowState.getJoint()->getRotation() );
126
127 // connect the ikSolver to the chain
128 mIKSolver.setPoleVector( LLVector3( -1.0f, 1.0f, 0.0f ) );
129 // specifying the elbow's axis will prevent bad IK for the more
130 // singular configurations, but the axis is limb-specific -- Leviathan
131 mIKSolver.setBAxis( LLVector3( -0.682683f, 0.0f, -0.730714f ) );
132 mIKSolver.setupJoints( &mShoulderJoint, &mElbowJoint, &mWristJoint, &mTarget );
133
134 return STATUS_SUCCESS;
135}
136
137//-----------------------------------------------------------------------------
138// LLEditingMotion::onActivate()
139//-----------------------------------------------------------------------------
140BOOL LLEditingMotion::onActivate()
141{
142 // propagate joint positions to kinematic chain
143 mParentJoint.setPosition( mParentState.getJoint()->getWorldPosition() );
144 mShoulderJoint.setPosition( mShoulderState.getJoint()->getPosition() );
145 mElbowJoint.setPosition( mElbowState.getJoint()->getPosition() );
146 mWristJoint.setPosition( mWristState.getJoint()->getPosition() + mWristOffset );
147
148 // propagate current joint rotations to kinematic chain
149 mParentJoint.setRotation( mParentState.getJoint()->getWorldRotation() );
150 mShoulderJoint.setRotation( mShoulderState.getJoint()->getRotation() );
151 mElbowJoint.setRotation( mElbowState.getJoint()->getRotation() );
152
153 return TRUE;
154}
155
156//-----------------------------------------------------------------------------
157// LLEditingMotion::onUpdate()
158//-----------------------------------------------------------------------------
159BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask)
160{
161 LLVector3 focus_pt;
162 LLVector3* pointAtPt = (LLVector3*)mCharacter->getAnimationData("PointAtPoint");
163
164
165 BOOL result = TRUE;
166
167 if (!pointAtPt)
168 {
169 focus_pt = mLastSelectPt;
170 result = FALSE;
171 }
172 else
173 {
174 focus_pt = *pointAtPt;
175 mLastSelectPt = focus_pt;
176 }
177
178 focus_pt += mCharacter->getCharacterPosition();
179
180 // propagate joint positions to kinematic chain
181 mParentJoint.setPosition( mParentState.getJoint()->getWorldPosition() );
182 mShoulderJoint.setPosition( mShoulderState.getJoint()->getPosition() );
183 mElbowJoint.setPosition( mElbowState.getJoint()->getPosition() );
184 mWristJoint.setPosition( mWristState.getJoint()->getPosition() + mWristOffset );
185
186 // propagate current joint rotations to kinematic chain
187 mParentJoint.setRotation( mParentState.getJoint()->getWorldRotation() );
188 mShoulderJoint.setRotation( mShoulderState.getJoint()->getRotation() );
189 mElbowJoint.setRotation( mElbowState.getJoint()->getRotation() );
190
191 // update target position from character
192 LLVector3 target = focus_pt - mParentJoint.getPosition();
193 F32 target_dist = target.normVec();
194
195 LLVector3 edit_plane_normal(1.f / F_SQRT2, 1.f / F_SQRT2, 0.f);
196 edit_plane_normal.normVec();
197
198 edit_plane_normal.rotVec(mTorsoState.getJoint()->getWorldRotation());
199
200 F32 dot = edit_plane_normal * target;
201
202 if (dot < 0.f)
203 {
204 target = target + (edit_plane_normal * (dot * 2.f));
205 target.mV[VZ] += clamp_rescale(dot, 0.f, -1.f, 0.f, 5.f);
206 target.normVec();
207 }
208
209 target = target * target_dist;
210 if (!target.isFinite())
211 {
212 llerrs << "Non finite target in editing motion with target distance of " << target_dist <<
213 " and focus point " << focus_pt << llendl;
214 }
215
216 mTarget.setPosition( target + mParentJoint.getPosition());
217
218// llinfos << "Point At: " << mTarget.getPosition() << llendl;
219
220 // update the ikSolver
221 if (!mTarget.getPosition().isExactlyZero())
222 {
223 LLQuaternion shoulderRot = mShoulderJoint.getRotation();
224 LLQuaternion elbowRot = mElbowJoint.getRotation();
225 mIKSolver.solve();
226
227 // use blending...
228 F32 slerp_amt = LLCriticalDamp::getInterpolant(TARGET_LAG_HALF_LIFE);
229 shoulderRot = slerp(slerp_amt, mShoulderJoint.getRotation(), shoulderRot);
230 elbowRot = slerp(slerp_amt, mElbowJoint.getRotation(), elbowRot);
231
232 // now put blended values back into joints
233 llassert(shoulderRot.isFinite());
234 llassert(elbowRot.isFinite());
235 mShoulderState.setRotation(shoulderRot);
236 mElbowState.setRotation(elbowRot);
237 mWristState.setRotation(LLQuaternion::DEFAULT);
238 }
239
240 mCharacter->setAnimationData("Hand Pose", &sHandPose);
241 mCharacter->setAnimationData("Hand Pose Priority", &sHandPosePriority);
242 return result;
243}
244
245//-----------------------------------------------------------------------------
246// LLEditingMotion::onDeactivate()
247//-----------------------------------------------------------------------------
248void LLEditingMotion::onDeactivate()
249{
250}
251
252
253// End