aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcharacter/llpose.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/llpose.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 'linden/indra/llcharacter/llpose.cpp')
-rw-r--r--linden/indra/llcharacter/llpose.cpp563
1 files changed, 563 insertions, 0 deletions
diff --git a/linden/indra/llcharacter/llpose.cpp b/linden/indra/llcharacter/llpose.cpp
new file mode 100644
index 0000000..ebf6a67
--- /dev/null
+++ b/linden/indra/llcharacter/llpose.cpp
@@ -0,0 +1,563 @@
1/**
2 * @file llpose.cpp
3 * @brief Implementation of LLPose 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 "llpose.h"
34
35#include "llmotion.h"
36#include "llmath.h"
37
38//-----------------------------------------------------------------------------
39// Static
40//-----------------------------------------------------------------------------
41
42//-----------------------------------------------------------------------------
43// LLPose
44//-----------------------------------------------------------------------------
45LLPose::~LLPose()
46{
47}
48
49//-----------------------------------------------------------------------------
50// getFirstJointState()
51//-----------------------------------------------------------------------------
52LLJointState *LLPose::getFirstJointState()
53{
54 mListIter = mJointMap.begin();
55 if (mListIter == mJointMap.end())
56 {
57 return NULL;
58 }
59 else
60 {
61 return mListIter->second;
62 }
63}
64
65//-----------------------------------------------------------------------------
66// getNextJointState()
67//-----------------------------------------------------------------------------
68LLJointState *LLPose::getNextJointState()
69{
70 mListIter++;
71 if (mListIter == mJointMap.end())
72 {
73 return NULL;
74 }
75 else
76 {
77 return mListIter->second;
78 }
79}
80
81//-----------------------------------------------------------------------------
82// addJointState()
83//-----------------------------------------------------------------------------
84BOOL LLPose::addJointState(LLJointState *jointState)
85{
86 if (mJointMap.find(jointState->getJoint()->getName()) == mJointMap.end())
87 {
88 mJointMap[jointState->getJoint()->getName()] = jointState;
89 }
90 return TRUE;
91}
92
93//-----------------------------------------------------------------------------
94// removeJointState()
95//-----------------------------------------------------------------------------
96BOOL LLPose::removeJointState(LLJointState *jointState)
97{
98 mJointMap.erase(jointState->getJoint()->getName());
99 return TRUE;
100}
101
102//-----------------------------------------------------------------------------
103// removeAllJointStates()
104//-----------------------------------------------------------------------------
105BOOL LLPose::removeAllJointStates()
106{
107 mJointMap.clear();
108 return TRUE;
109}
110
111//-----------------------------------------------------------------------------
112// findJointState()
113//-----------------------------------------------------------------------------
114LLJointState* LLPose::findJointState(LLJoint *joint)
115{
116 joint_map_iterator iter = mJointMap.find(joint->getName());
117
118 if (iter == mJointMap.end())
119 {
120 return NULL;
121 }
122 else
123 {
124 return iter->second;
125 }
126}
127
128//-----------------------------------------------------------------------------
129// findJointState()
130//-----------------------------------------------------------------------------
131LLJointState* LLPose::findJointState(const std::string &name)
132{
133 joint_map_iterator iter = mJointMap.find(name);
134
135 if (iter == mJointMap.end())
136 {
137 return NULL;
138 }
139 else
140 {
141 return iter->second;
142 }
143}
144
145//-----------------------------------------------------------------------------
146// setWeight()
147//-----------------------------------------------------------------------------
148void LLPose::setWeight(F32 weight)
149{
150 joint_map_iterator iter;
151 for(iter = mJointMap.begin();
152 iter != mJointMap.end();
153 ++iter)
154 {
155 iter->second->setWeight(weight);
156 }
157 mWeight = weight;
158}
159
160//-----------------------------------------------------------------------------
161// getWeight()
162//-----------------------------------------------------------------------------
163F32 LLPose::getWeight() const
164{
165 return mWeight;
166}
167
168//-----------------------------------------------------------------------------
169// getNumJointStates()
170//-----------------------------------------------------------------------------
171S32 LLPose::getNumJointStates() const
172{
173 return (S32)mJointMap.size();
174}
175
176//-----------------------------------------------------------------------------
177// LLJointStateBlender
178//-----------------------------------------------------------------------------
179
180LLJointStateBlender::LLJointStateBlender()
181{
182 for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++)
183 {
184 mJointStates[i] = NULL;
185 mPriorities[i] = S32_MIN;
186 }
187}
188
189LLJointStateBlender::~LLJointStateBlender()
190{
191
192}
193
194//-----------------------------------------------------------------------------
195// addJointState()
196//-----------------------------------------------------------------------------
197BOOL LLJointStateBlender::addJointState(LLJointState *joint_state, S32 priority, BOOL additive_blend)
198{
199 llassert(joint_state);
200
201 if (!joint_state->getJoint())
202 // this joint state doesn't point to an actual joint, so we don't care about applying it
203 return FALSE;
204
205 for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++)
206 {
207 if (NULL == mJointStates[i])
208 {
209 mJointStates[i] = joint_state;
210 mPriorities[i] = priority;
211 mAdditiveBlends[i] = additive_blend;
212 return TRUE;
213 }
214 else if (priority > mPriorities[i])
215 {
216 // we're at a higher priority than the current joint state in this slot
217 // so shift everyone over
218 // previous joint states (newer motions) with same priority should stay in place
219 for (S32 j = JSB_NUM_JOINT_STATES - 1; j > i; j--)
220 {
221 mJointStates[j] = mJointStates[j - 1];
222 mPriorities[j] = mPriorities[j - 1];
223 mAdditiveBlends[j] = mAdditiveBlends[j - 1];
224 }
225 // now store ourselves in this slot
226 mJointStates[i] = joint_state;
227 mPriorities[i] = priority;
228 mAdditiveBlends[i] = additive_blend;
229 return TRUE;
230 }
231 }
232
233 return FALSE;
234}
235
236//-----------------------------------------------------------------------------
237// blendJointStates()
238//-----------------------------------------------------------------------------
239void LLJointStateBlender::blendJointStates(BOOL apply_now)
240{
241 // we need at least one joint to blend
242 // if there is one, it will be in slot zero according to insertion logic
243 // instead of resetting joint state to default, just leave it unchanged from last frame
244 if (NULL == mJointStates[0])
245 {
246 return;
247 }
248
249 LLJoint* target_joint = apply_now ? mJointStates[0]->getJoint() : &mJointCache;
250
251 const S32 POS_WEIGHT = 0;
252 const S32 ROT_WEIGHT = 1;
253 const S32 SCALE_WEIGHT = 2;
254
255 F32 sum_weights[3];
256 U32 sum_usage = 0;
257
258 LLVector3 blended_pos = target_joint->getPosition();
259 LLQuaternion blended_rot = target_joint->getRotation();
260 LLVector3 blended_scale = target_joint->getScale();
261
262 LLVector3 added_pos;
263 LLQuaternion added_rot;
264 LLVector3 added_scale;
265
266 //S32 joint_state_index;
267
268 sum_weights[POS_WEIGHT] = 0.f;
269 sum_weights[ROT_WEIGHT] = 0.f;
270 sum_weights[SCALE_WEIGHT] = 0.f;
271
272 for(S32 joint_state_index = 0;
273 joint_state_index < JSB_NUM_JOINT_STATES && mJointStates[joint_state_index] != NULL;
274 joint_state_index++)
275 {
276 U32 current_usage = mJointStates[joint_state_index]->getUsage();
277 F32 current_weight = mJointStates[joint_state_index]->getWeight();
278 LLJointState* jsp = mJointStates[joint_state_index];
279
280 if (current_weight == 0.f)
281 {
282 continue;
283 }
284
285 if (mAdditiveBlends[joint_state_index])
286 {
287 if(current_usage & LLJointState::POS)
288 {
289 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]);
290
291 // add in pos for this jointstate modulated by weight
292 added_pos += jsp->getPosition() * (new_weight_sum - sum_weights[POS_WEIGHT]);
293 //sum_weights[POS_WEIGHT] = new_weight_sum;
294 }
295
296 // now do scale
297 if(current_usage & LLJointState::SCALE)
298 {
299 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]);
300
301 // add in scale for this jointstate modulated by weight
302 added_scale += jsp->getScale() * (new_weight_sum - sum_weights[SCALE_WEIGHT]);
303 //sum_weights[SCALE_WEIGHT] = new_weight_sum;
304 }
305
306 if (current_usage & LLJointState::ROT)
307 {
308 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]);
309
310 // add in rotation for this jointstate modulated by weight
311 added_rot = nlerp((new_weight_sum - sum_weights[ROT_WEIGHT]), added_rot, jsp->getRotation()) * added_rot;
312 //sum_weights[ROT_WEIGHT] = new_weight_sum;
313 }
314 }
315 else
316 {
317 // blend two jointstates together
318
319 // blend position
320 if(current_usage & LLJointState::POS)
321 {
322 if(sum_usage & LLJointState::POS)
323 {
324 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]);
325
326 // blend positions from both
327 blended_pos = lerp(mJointStates[joint_state_index]->getPosition(), blended_pos, sum_weights[POS_WEIGHT] / new_weight_sum);
328 sum_weights[POS_WEIGHT] = new_weight_sum;
329 }
330 else
331 {
332 // copy position from current
333 blended_pos = mJointStates[joint_state_index]->getPosition();
334 sum_weights[POS_WEIGHT] = current_weight;
335 }
336 }
337
338 // now do scale
339 if(current_usage & LLJointState::SCALE)
340 {
341 if(sum_usage & LLJointState::SCALE)
342 {
343 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]);
344
345 // blend scales from both
346 blended_scale = lerp(mJointStates[joint_state_index]->getScale(), blended_scale, sum_weights[SCALE_WEIGHT] / new_weight_sum);
347 sum_weights[SCALE_WEIGHT] = new_weight_sum;
348 }
349 else
350 {
351 // copy scale from current
352 blended_scale = mJointStates[joint_state_index]->getScale();
353 sum_weights[SCALE_WEIGHT] = current_weight;
354 }
355 }
356
357 // rotation
358 if (current_usage & LLJointState::ROT)
359 {
360 if(sum_usage & LLJointState::ROT)
361 {
362 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]);
363
364 // blend rotations from both
365 blended_rot = nlerp(sum_weights[ROT_WEIGHT] / new_weight_sum, mJointStates[joint_state_index]->getRotation(), blended_rot);
366 sum_weights[ROT_WEIGHT] = new_weight_sum;
367 }
368 else
369 {
370 // copy rotation from current
371 blended_rot = mJointStates[joint_state_index]->getRotation();
372 sum_weights[ROT_WEIGHT] = current_weight;
373 }
374 }
375
376 // update resulting usage mask
377 sum_usage = sum_usage | current_usage;
378 }
379 }
380
381 // apply blended transforms
382 target_joint->setPosition(blended_pos);
383 target_joint->setScale(blended_scale);
384 target_joint->setRotation(blended_rot);
385
386 // apply additive transforms
387 target_joint->setPosition(target_joint->getPosition() + added_pos);
388 target_joint->setScale(target_joint->getScale() + added_scale);
389 target_joint->setRotation(added_rot * target_joint->getRotation());
390
391 if (apply_now)
392 {
393 // now clear joint states
394 for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++)
395 {
396 mJointStates[i] = NULL;
397 }
398 }
399}
400
401//-----------------------------------------------------------------------------
402// interpolate()
403//-----------------------------------------------------------------------------
404void LLJointStateBlender::interpolate(F32 u)
405{
406 // only interpolate if we have a joint state
407 if (!mJointStates[0])
408 {
409 return;
410 }
411 LLJoint* target_joint = mJointStates[0]->getJoint();
412
413 if (!target_joint)
414 {
415 return;
416 }
417
418 target_joint->setPosition(lerp(target_joint->getPosition(), mJointCache.getPosition(), u));
419 target_joint->setScale(lerp(target_joint->getScale(), mJointCache.getScale(), u));
420 target_joint->setRotation(nlerp(u, target_joint->getRotation(), mJointCache.getRotation()));
421}
422
423//-----------------------------------------------------------------------------
424// clear()
425//-----------------------------------------------------------------------------
426void LLJointStateBlender::clear()
427{
428 // now clear joint states
429 for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++)
430 {
431 mJointStates[i] = NULL;
432 }
433}
434
435//-----------------------------------------------------------------------------
436// resetCachedJoint()
437//-----------------------------------------------------------------------------
438void LLJointStateBlender::resetCachedJoint()
439{
440 if (!mJointStates[0])
441 {
442 return;
443 }
444 LLJoint* source_joint = mJointStates[0]->getJoint();
445 mJointCache.setPosition(source_joint->getPosition());
446 mJointCache.setScale(source_joint->getScale());
447 mJointCache.setRotation(source_joint->getRotation());
448}
449
450//-----------------------------------------------------------------------------
451// LLPoseBlender
452//-----------------------------------------------------------------------------
453
454LLPoseBlender::LLPoseBlender()
455{
456}
457
458LLPoseBlender::~LLPoseBlender()
459{
460 mJointStateBlenderPool.deleteAllData();
461}
462
463//-----------------------------------------------------------------------------
464// addMotion()
465//-----------------------------------------------------------------------------
466BOOL LLPoseBlender::addMotion(LLMotion* motion)
467{
468 LLPose* pose = motion->getPose();
469
470 for(LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState())
471 {
472 LLJoint *jointp = jsp->getJoint();
473 LLJointStateBlender* joint_blender;
474 if (!mJointStateBlenderPool.checkData(jointp))
475 {
476 // this is the first time we are animating this joint
477 // so create new jointblender and add it to our pool
478 joint_blender = new LLJointStateBlender();
479 mJointStateBlenderPool.addData(jointp, joint_blender);
480 } else
481 {
482 joint_blender = mJointStateBlenderPool.getData(jointp);
483 }
484
485 if (jsp->getPriority() == LLJoint::USE_MOTION_PRIORITY)
486 {
487 joint_blender->addJointState(jsp, motion->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
488 }
489 else
490 {
491 joint_blender->addJointState(jsp, jsp->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
492 }
493
494 // add it to our list of active blenders
495 if(!mActiveBlenders.checkData(joint_blender))
496 {
497 mActiveBlenders.addData(joint_blender);
498 }
499 }
500 return TRUE;
501}
502
503//-----------------------------------------------------------------------------
504// blendAndApply()
505//-----------------------------------------------------------------------------
506void LLPoseBlender::blendAndApply()
507{
508 for (LLJointStateBlender* jsbp = mActiveBlenders.getFirstData();
509 jsbp;
510 jsbp = mActiveBlenders.getNextData())
511 {
512 jsbp->blendJointStates();
513 }
514
515 // we're done now so there are no more active blenders for this frame
516 mActiveBlenders.removeAllNodes();
517}
518
519//-----------------------------------------------------------------------------
520// blendAndCache()
521//-----------------------------------------------------------------------------
522void LLPoseBlender::blendAndCache(BOOL reset_cached_joints)
523{
524 for (LLJointStateBlender* jsbp = mActiveBlenders.getFirstData();
525 jsbp;
526 jsbp = mActiveBlenders.getNextData())
527 {
528 if (reset_cached_joints)
529 {
530 jsbp->resetCachedJoint();
531 }
532 jsbp->blendJointStates(FALSE);
533 }
534}
535
536//-----------------------------------------------------------------------------
537// interpolate()
538//-----------------------------------------------------------------------------
539void LLPoseBlender::interpolate(F32 u)
540{
541 for (LLJointStateBlender* jsbp = mActiveBlenders.getFirstData();
542 jsbp;
543 jsbp = mActiveBlenders.getNextData())
544 {
545 jsbp->interpolate(u);
546 }
547}
548
549//-----------------------------------------------------------------------------
550// clearBlenders()
551//-----------------------------------------------------------------------------
552void LLPoseBlender::clearBlenders()
553{
554 for (LLJointStateBlender* jsbp = mActiveBlenders.getFirstData();
555 jsbp;
556 jsbp = mActiveBlenders.getNextData())
557 {
558 jsbp->clear();
559 }
560
561 mActiveBlenders.removeAllNodes();
562}
563