PageRenderTime 66ms CodeModel.GetById 2ms app.highlight 53ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcharacter/llpose.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 567 lines | 365 code | 71 blank | 131 comment | 60 complexity | e4336015c98eca10c63f1a70e4653200 MD5 | raw file
  1/** 
  2 * @file llpose.cpp
  3 * @brief Implementation of LLPose 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 "llpose.h"
 33
 34#include "llmotion.h"
 35#include "llmath.h"
 36#include "llstl.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(const LLPointer<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(const LLPointer<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		mAdditiveBlends[i] = FALSE;
187	}
188}
189
190LLJointStateBlender::~LLJointStateBlender()
191{
192	
193}
194
195//-----------------------------------------------------------------------------
196// addJointState()
197//-----------------------------------------------------------------------------
198BOOL LLJointStateBlender::addJointState(const LLPointer<LLJointState>& joint_state, S32 priority, BOOL additive_blend)
199{
200	llassert(joint_state);
201
202	if (!joint_state->getJoint())
203		// this joint state doesn't point to an actual joint, so we don't care about applying it
204		return FALSE;
205
206	for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++)
207	{
208		if (mJointStates[i].isNull())
209		{
210			mJointStates[i] = joint_state;
211			mPriorities[i] = priority;
212			mAdditiveBlends[i] = additive_blend;
213			return TRUE;
214		} 
215		else if (priority > mPriorities[i])
216		{
217			// we're at a higher priority than the current joint state in this slot
218			// so shift everyone over
219			// previous joint states (newer motions) with same priority should stay in place
220			for (S32 j = JSB_NUM_JOINT_STATES - 1; j > i; j--)
221			{
222				mJointStates[j] = mJointStates[j - 1];
223				mPriorities[j] = mPriorities[j - 1];
224				mAdditiveBlends[j] = mAdditiveBlends[j - 1];
225			}
226			// now store ourselves in this slot
227			mJointStates[i] = joint_state;
228			mPriorities[i] = priority;
229			mAdditiveBlends[i] = additive_blend;
230			return TRUE;
231		}
232	}
233
234	return FALSE;
235}
236
237//-----------------------------------------------------------------------------
238// blendJointStates()
239//-----------------------------------------------------------------------------
240void LLJointStateBlender::blendJointStates(BOOL apply_now)
241{
242	// we need at least one joint to blend
243	// if there is one, it will be in slot zero according to insertion logic
244	// instead of resetting joint state to default, just leave it unchanged from last frame
245	if (mJointStates[0].isNull())
246	{
247		return;
248	}
249
250	LLJoint* target_joint = apply_now ? mJointStates[0]->getJoint() : &mJointCache;
251
252	const S32 POS_WEIGHT = 0;
253	const S32 ROT_WEIGHT = 1;
254	const S32 SCALE_WEIGHT = 2;
255
256	F32				sum_weights[3];
257	U32				sum_usage = 0;
258
259	LLVector3		blended_pos = target_joint->getPosition();
260	LLQuaternion	blended_rot = target_joint->getRotation();
261	LLVector3		blended_scale = target_joint->getScale();
262
263	LLVector3		added_pos;
264	LLQuaternion	added_rot;
265	LLVector3		added_scale;
266
267	//S32				joint_state_index;
268
269	sum_weights[POS_WEIGHT] = 0.f;
270	sum_weights[ROT_WEIGHT] = 0.f;
271	sum_weights[SCALE_WEIGHT] = 0.f;
272
273	for(S32 joint_state_index = 0; 
274		joint_state_index < JSB_NUM_JOINT_STATES && mJointStates[joint_state_index].notNull();
275		joint_state_index++)
276	{
277		LLJointState* jsp = mJointStates[joint_state_index];
278		U32 current_usage = jsp->getUsage();
279		F32 current_weight = jsp->getWeight();
280
281		if (current_weight == 0.f)
282		{
283			continue;
284		}
285
286		if (mAdditiveBlends[joint_state_index])
287		{
288			if(current_usage & LLJointState::POS)
289			{
290				F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]);
291
292				// add in pos for this jointstate modulated by weight
293				added_pos += jsp->getPosition() * (new_weight_sum - sum_weights[POS_WEIGHT]);
294			}
295
296			if(current_usage & LLJointState::SCALE)
297			{
298				F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]);
299
300				// add in scale for this jointstate modulated by weight
301				added_scale += jsp->getScale() * (new_weight_sum - sum_weights[SCALE_WEIGHT]);
302			}
303
304			if (current_usage & LLJointState::ROT)
305			{
306				F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]);
307
308				// add in rotation for this jointstate modulated by weight
309				added_rot = nlerp((new_weight_sum - sum_weights[ROT_WEIGHT]), added_rot, jsp->getRotation()) * added_rot;
310			}
311		}
312		else
313		{
314			// blend two jointstates together
315		
316			// blend position
317			if(current_usage & LLJointState::POS)
318			{
319				if(sum_usage & LLJointState::POS)
320				{
321					F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]);
322
323					// blend positions from both
324					blended_pos = lerp(jsp->getPosition(), blended_pos, sum_weights[POS_WEIGHT] / new_weight_sum);
325					sum_weights[POS_WEIGHT] = new_weight_sum;
326				} 
327				else
328				{
329					// copy position from current
330					blended_pos = jsp->getPosition();
331					sum_weights[POS_WEIGHT] = current_weight;
332				}
333			}
334			
335			// now do scale
336			if(current_usage & LLJointState::SCALE)
337			{
338				if(sum_usage & LLJointState::SCALE)
339				{
340					F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]);
341
342					// blend scales from both
343					blended_scale = lerp(jsp->getScale(), blended_scale, sum_weights[SCALE_WEIGHT] / new_weight_sum);
344					sum_weights[SCALE_WEIGHT] = new_weight_sum;
345				} 
346				else
347				{
348					// copy scale from current
349					blended_scale = jsp->getScale();
350					sum_weights[SCALE_WEIGHT] = current_weight;
351				}
352			}
353
354			// rotation
355			if (current_usage & LLJointState::ROT)
356			{
357				if(sum_usage & LLJointState::ROT)
358				{
359					F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]);
360
361					// blend rotations from both
362					blended_rot = nlerp(sum_weights[ROT_WEIGHT] / new_weight_sum, jsp->getRotation(), blended_rot);
363					sum_weights[ROT_WEIGHT] = new_weight_sum;
364				} 
365				else
366				{
367					// copy rotation from current
368					blended_rot = jsp->getRotation();
369					sum_weights[ROT_WEIGHT] = current_weight;
370				}
371			}
372
373			// update resulting usage mask
374			sum_usage = sum_usage | current_usage;
375		}
376	}
377
378	if (!added_scale.isFinite())
379	{
380		added_scale.clearVec();
381	}
382
383	if (!blended_scale.isFinite())
384	{
385		blended_scale.setVec(1,1,1);
386	}
387
388	// apply transforms
389	target_joint->setPosition(blended_pos + added_pos);
390	target_joint->setScale(blended_scale + added_scale);
391	target_joint->setRotation(added_rot * blended_rot);
392
393	if (apply_now)
394	{
395		// now clear joint states
396		for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++)
397		{
398			mJointStates[i] = NULL;
399		}
400	}
401}
402
403//-----------------------------------------------------------------------------
404// interpolate()
405//-----------------------------------------------------------------------------
406void LLJointStateBlender::interpolate(F32 u)
407{
408	// only interpolate if we have a joint state
409	if (!mJointStates[0])
410	{
411		return;
412	}
413	LLJoint* target_joint = mJointStates[0]->getJoint();
414
415	if (!target_joint)
416	{
417		return;
418	}
419
420	target_joint->setPosition(lerp(target_joint->getPosition(), mJointCache.getPosition(), u));
421	target_joint->setScale(lerp(target_joint->getScale(), mJointCache.getScale(), u));
422	target_joint->setRotation(nlerp(u, target_joint->getRotation(), mJointCache.getRotation()));
423}
424
425//-----------------------------------------------------------------------------
426// clear()
427//-----------------------------------------------------------------------------
428void LLJointStateBlender::clear()
429{
430	// now clear joint states
431	for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++)
432	{
433		mJointStates[i] = NULL;
434	}
435}
436
437//-----------------------------------------------------------------------------
438// resetCachedJoint()
439//-----------------------------------------------------------------------------
440void LLJointStateBlender::resetCachedJoint()
441{
442	if (!mJointStates[0])
443	{
444		return;
445	}
446	LLJoint* source_joint = mJointStates[0]->getJoint();
447	mJointCache.setPosition(source_joint->getPosition());
448	mJointCache.setScale(source_joint->getScale());
449	mJointCache.setRotation(source_joint->getRotation());
450}
451
452//-----------------------------------------------------------------------------
453// LLPoseBlender
454//-----------------------------------------------------------------------------
455
456LLPoseBlender::LLPoseBlender()
457	: mNextPoseSlot(0)
458{
459}
460
461LLPoseBlender::~LLPoseBlender()
462{
463	for_each(mJointStateBlenderPool.begin(), mJointStateBlenderPool.end(), DeletePairedPointer());
464}
465
466//-----------------------------------------------------------------------------
467// addMotion()
468//-----------------------------------------------------------------------------
469BOOL LLPoseBlender::addMotion(LLMotion* motion)
470{
471	LLPose* pose = motion->getPose();
472
473	for(LLJointState* jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState())
474	{
475		LLJoint *jointp = jsp->getJoint();
476		LLJointStateBlender* joint_blender;
477		if (mJointStateBlenderPool.find(jointp) == mJointStateBlenderPool.end())
478		{
479			// this is the first time we are animating this joint
480			// so create new jointblender and add it to our pool
481			joint_blender = new LLJointStateBlender();
482			mJointStateBlenderPool[jointp] = joint_blender;
483		}
484		else
485		{
486			joint_blender = mJointStateBlenderPool[jointp];
487		}
488
489		if (jsp->getPriority() == LLJoint::USE_MOTION_PRIORITY)
490		{
491			joint_blender->addJointState(jsp, motion->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
492		}
493		else
494		{
495			joint_blender->addJointState(jsp, jsp->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
496		}
497
498		// add it to our list of active blenders
499		if (std::find(mActiveBlenders.begin(), mActiveBlenders.end(), joint_blender) == mActiveBlenders.end())
500		{
501			mActiveBlenders.push_front(joint_blender);
502		}
503	}
504	return TRUE;
505}
506
507//-----------------------------------------------------------------------------
508// blendAndApply()
509//-----------------------------------------------------------------------------
510void LLPoseBlender::blendAndApply()
511{
512	for (blender_list_t::iterator iter = mActiveBlenders.begin();
513		 iter != mActiveBlenders.end(); )
514	{
515		LLJointStateBlender* jsbp = *iter++;
516		jsbp->blendJointStates();
517	}
518
519	// we're done now so there are no more active blenders for this frame
520	mActiveBlenders.clear();
521}
522
523//-----------------------------------------------------------------------------
524// blendAndCache()
525//-----------------------------------------------------------------------------
526void LLPoseBlender::blendAndCache(BOOL reset_cached_joints)
527{
528	for (blender_list_t::iterator iter = mActiveBlenders.begin();
529		 iter != mActiveBlenders.end(); ++iter)
530	{
531		LLJointStateBlender* jsbp = *iter;
532		if (reset_cached_joints)
533		{
534			jsbp->resetCachedJoint();
535		}
536		jsbp->blendJointStates(FALSE);
537	}
538}
539
540//-----------------------------------------------------------------------------
541// interpolate()
542//-----------------------------------------------------------------------------
543void LLPoseBlender::interpolate(F32 u)
544{
545	for (blender_list_t::iterator iter = mActiveBlenders.begin();
546		 iter != mActiveBlenders.end(); ++iter)
547	{
548		LLJointStateBlender* jsbp = *iter;
549		jsbp->interpolate(u);
550	}
551}
552
553//-----------------------------------------------------------------------------
554// clearBlenders()
555//-----------------------------------------------------------------------------
556void LLPoseBlender::clearBlenders()
557{
558	for (blender_list_t::iterator iter = mActiveBlenders.begin();
559		 iter != mActiveBlenders.end(); ++iter)
560	{
561		LLJointStateBlender* jsbp = *iter;
562		jsbp->clear();
563	}
564
565	mActiveBlenders.clear();
566}
567