PageRenderTime 477ms CodeModel.GetById 181ms app.highlight 112ms RepoModel.GetById 129ms app.codeStats 1ms

/indra/llcharacter/llkeyframemotion.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 459 lines | 280 code | 82 blank | 97 comment | 12 complexity | 1ef14bf26f91500f9afe613e25057154 MD5 | raw file
  1/** 
  2 * @file llkeyframemotion.h
  3 * @brief Implementation of LLKeframeMotion 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#ifndef LL_LLKEYFRAMEMOTION_H
 28#define LL_LLKEYFRAMEMOTION_H
 29
 30//-----------------------------------------------------------------------------
 31// Header files
 32//-----------------------------------------------------------------------------
 33
 34#include <string>
 35
 36#include "llassetstorage.h"
 37#include "llbboxlocal.h"
 38#include "llhandmotion.h"
 39#include "lljointstate.h"
 40#include "llmotion.h"
 41#include "llquaternion.h"
 42#include "v3dmath.h"
 43#include "v3math.h"
 44#include "llbvhconsts.h"
 45
 46class LLKeyframeDataCache;
 47class LLVFS;
 48class LLDataPacker;
 49
 50#define MIN_REQUIRED_PIXEL_AREA_KEYFRAME (40.f)
 51#define MAX_CHAIN_LENGTH (4)
 52
 53const S32 KEYFRAME_MOTION_VERSION = 1;
 54const S32 KEYFRAME_MOTION_SUBVERSION = 0;
 55
 56//-----------------------------------------------------------------------------
 57// class LLKeyframeMotion
 58//-----------------------------------------------------------------------------
 59class LLKeyframeMotion :
 60	public LLMotion
 61{
 62	friend class LLKeyframeDataCache;
 63public:
 64	// Constructor
 65	LLKeyframeMotion(const LLUUID &id);
 66
 67	// Destructor
 68	virtual ~LLKeyframeMotion();
 69
 70private:
 71	// private helper functions to wrap some asserts
 72	LLPointer<LLJointState>& getJointState(U32 index);
 73	LLJoint* getJoint(U32 index );
 74	
 75public:
 76	//-------------------------------------------------------------------------
 77	// functions to support MotionController and MotionRegistry
 78	//-------------------------------------------------------------------------
 79
 80	// static constructor
 81	// all subclasses must implement such a function and register it
 82	static LLMotion *create(const LLUUID& id);
 83
 84public:
 85	//-------------------------------------------------------------------------
 86	// animation callbacks to be implemented by subclasses
 87	//-------------------------------------------------------------------------
 88
 89	// motions must specify whether or not they loop
 90	virtual BOOL getLoop() { 
 91		if (mJointMotionList) return mJointMotionList->mLoop; 
 92		else return FALSE;
 93	}
 94
 95	// motions must report their total duration
 96	virtual F32 getDuration() { 
 97		if (mJointMotionList) return mJointMotionList->mDuration; 
 98		else return 0.f;
 99	}
100
101	// motions must report their "ease in" duration
102	virtual F32 getEaseInDuration() { 
103		if (mJointMotionList) return mJointMotionList->mEaseInDuration; 
104		else return 0.f;
105	}
106
107	// motions must report their "ease out" duration.
108	virtual F32 getEaseOutDuration() { 
109		if (mJointMotionList) return mJointMotionList->mEaseOutDuration; 
110		else return 0.f;
111	}
112
113	// motions must report their priority
114	virtual LLJoint::JointPriority getPriority() { 
115		if (mJointMotionList) return mJointMotionList->mBasePriority; 
116		else return LLJoint::LOW_PRIORITY;
117	}
118
119	virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; }
120
121	// called to determine when a motion should be activated/deactivated based on avatar pixel coverage
122	virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_KEYFRAME; }
123
124	// run-time (post constructor) initialization,
125	// called after parameters have been set
126	// must return true to indicate success and be available for activation
127	virtual LLMotionInitStatus onInitialize(LLCharacter *character);
128
129	// called when a motion is activated
130	// must return TRUE to indicate success, or else
131	// it will be deactivated
132	virtual BOOL onActivate();
133
134	// called per time step
135	// must return TRUE while it is active, and
136	// must return FALSE when the motion is completed.
137	virtual BOOL onUpdate(F32 time, U8* joint_mask);
138
139	// called when a motion is deactivated
140	virtual void onDeactivate();
141
142	virtual void setStopTime(F32 time);
143
144	static void setVFS(LLVFS* vfs) { sVFS = vfs; }
145
146	static void onLoadComplete(LLVFS *vfs,
147							   const LLUUID& asset_uuid,
148							   LLAssetType::EType type,
149							   void* user_data, S32 status, LLExtStat ext_status);
150
151public:
152	U32		getFileSize();
153	BOOL	serialize(LLDataPacker& dp) const;
154	BOOL	deserialize(LLDataPacker& dp);
155	BOOL	isLoaded() { return mJointMotionList != NULL; }
156
157
158	// setters for modifying a keyframe animation
159	void setLoop(BOOL loop);
160
161	F32 getLoopIn() {
162		return (mJointMotionList) ? mJointMotionList->mLoopInPoint : 0.f;
163	}
164
165	F32 getLoopOut() {
166		return (mJointMotionList) ? mJointMotionList->mLoopOutPoint : 0.f;
167	}
168	
169	void setLoopIn(F32 in_point);
170
171	void setLoopOut(F32 out_point);
172
173	void setHandPose(LLHandMotion::eHandPose pose) {
174		if (mJointMotionList) mJointMotionList->mHandPose = pose;
175	}
176
177	LLHandMotion::eHandPose getHandPose() { 
178		return (mJointMotionList) ? mJointMotionList->mHandPose : LLHandMotion::HAND_POSE_RELAXED;
179	}
180
181	void setPriority(S32 priority);
182
183	void setEmote(const LLUUID& emote_id);
184
185	void setEaseIn(F32 ease_in);
186
187	void setEaseOut(F32 ease_in);
188
189	F32 getLastUpdateTime() { return mLastLoopedTime; }
190
191	const LLBBoxLocal& getPelvisBBox();
192
193	static void flushKeyframeCache();
194
195protected:
196	//-------------------------------------------------------------------------
197	// JointConstraintSharedData
198	//-------------------------------------------------------------------------
199	class JointConstraintSharedData
200	{
201	public:
202		JointConstraintSharedData() :
203			mChainLength(0),
204			mEaseInStartTime(0.f), 
205			mEaseInStopTime(0.f),
206			mEaseOutStartTime(0.f),
207			mEaseOutStopTime(0.f), 
208			mUseTargetOffset(FALSE),
209			mConstraintType(CONSTRAINT_TYPE_POINT),
210			mConstraintTargetType(CONSTRAINT_TARGET_TYPE_BODY),
211			mSourceConstraintVolume(0),
212			mTargetConstraintVolume(0),
213			mJointStateIndices(NULL)
214		{ };
215		~JointConstraintSharedData() { delete [] mJointStateIndices; }
216
217		S32						mSourceConstraintVolume;
218		LLVector3				mSourceConstraintOffset;
219		S32						mTargetConstraintVolume;
220		LLVector3				mTargetConstraintOffset;
221		LLVector3				mTargetConstraintDir;
222		S32						mChainLength;
223		S32*					mJointStateIndices;
224		F32						mEaseInStartTime;
225		F32						mEaseInStopTime;
226		F32						mEaseOutStartTime;
227		F32						mEaseOutStopTime;
228		BOOL					mUseTargetOffset;
229		EConstraintType			mConstraintType;
230		EConstraintTargetType	mConstraintTargetType;
231	};
232
233	//-----------------------------------------------------------------------------
234	// JointConstraint()
235	//-----------------------------------------------------------------------------
236	class JointConstraint
237	{
238	public:
239		JointConstraint(JointConstraintSharedData* shared_data);
240		~JointConstraint();
241
242		JointConstraintSharedData*	mSharedData;
243		F32							mWeight;
244		F32							mTotalLength;
245		LLVector3					mPositions[MAX_CHAIN_LENGTH];
246		F32							mJointLengths[MAX_CHAIN_LENGTH];
247		F32							mJointLengthFractions[MAX_CHAIN_LENGTH];
248		BOOL						mActive;
249		LLVector3d					mGroundPos;
250		LLVector3					mGroundNorm;
251		LLJoint*					mSourceVolume;
252		LLJoint*					mTargetVolume;
253		F32							mFixupDistanceRMS;
254	};
255
256	void applyKeyframes(F32 time);
257
258	void applyConstraints(F32 time, U8* joint_mask);
259
260	void activateConstraint(JointConstraint* constraintp);
261
262	void initializeConstraint(JointConstraint* constraint);
263
264	void deactivateConstraint(JointConstraint *constraintp);
265
266	void applyConstraint(JointConstraint* constraintp, F32 time, U8* joint_mask);
267
268	BOOL	setupPose();
269
270public:
271	enum AssetStatus { ASSET_LOADED, ASSET_FETCHED, ASSET_NEEDS_FETCH, ASSET_FETCH_FAILED, ASSET_UNDEFINED };
272
273	enum InterpolationType { IT_STEP, IT_LINEAR, IT_SPLINE };
274
275	//-------------------------------------------------------------------------
276	// ScaleKey
277	//-------------------------------------------------------------------------
278	class ScaleKey
279	{
280	public:
281		ScaleKey() { mTime = 0.0f; }
282		ScaleKey(F32 time, const LLVector3 &scale) { mTime = time; mScale = scale; }
283
284		F32			mTime;
285		LLVector3	mScale;
286	};
287
288	//-------------------------------------------------------------------------
289	// RotationKey
290	//-------------------------------------------------------------------------
291	class RotationKey
292	{
293	public:
294		RotationKey() { mTime = 0.0f; }
295		RotationKey(F32 time, const LLQuaternion &rotation) { mTime = time; mRotation = rotation; }
296
297		F32				mTime;
298		LLQuaternion	mRotation;
299	};
300
301	//-------------------------------------------------------------------------
302	// PositionKey
303	//-------------------------------------------------------------------------
304	class PositionKey
305	{
306	public:
307		PositionKey() { mTime = 0.0f; }
308		PositionKey(F32 time, const LLVector3 &position) { mTime = time; mPosition = position; }
309
310		F32			mTime;
311		LLVector3	mPosition;
312	};
313
314	//-------------------------------------------------------------------------
315	// ScaleCurve
316	//-------------------------------------------------------------------------
317	class ScaleCurve
318	{
319	public:
320		ScaleCurve();
321		~ScaleCurve();
322		LLVector3 getValue(F32 time, F32 duration);
323		LLVector3 interp(F32 u, ScaleKey& before, ScaleKey& after);
324
325		InterpolationType	mInterpolationType;
326		S32					mNumKeys;
327		typedef std::map<F32, ScaleKey> key_map_t;
328		key_map_t 			mKeys;
329		ScaleKey			mLoopInKey;
330		ScaleKey			mLoopOutKey;
331	};
332
333	//-------------------------------------------------------------------------
334	// RotationCurve
335	//-------------------------------------------------------------------------
336	class RotationCurve
337	{
338	public:
339		RotationCurve();
340		~RotationCurve();
341		LLQuaternion getValue(F32 time, F32 duration);
342		LLQuaternion interp(F32 u, RotationKey& before, RotationKey& after);
343
344		InterpolationType	mInterpolationType;
345		S32					mNumKeys;
346		typedef std::map<F32, RotationKey> key_map_t;
347		key_map_t		mKeys;
348		RotationKey		mLoopInKey;
349		RotationKey		mLoopOutKey;
350	};
351
352	//-------------------------------------------------------------------------
353	// PositionCurve
354	//-------------------------------------------------------------------------
355	class PositionCurve
356	{
357	public:
358		PositionCurve();
359		~PositionCurve();
360		LLVector3 getValue(F32 time, F32 duration);
361		LLVector3 interp(F32 u, PositionKey& before, PositionKey& after);
362
363		InterpolationType	mInterpolationType;
364		S32					mNumKeys;
365		typedef std::map<F32, PositionKey> key_map_t;
366		key_map_t		mKeys;
367		PositionKey		mLoopInKey;
368		PositionKey		mLoopOutKey;
369	};
370
371	//-------------------------------------------------------------------------
372	// JointMotion
373	//-------------------------------------------------------------------------
374	class JointMotion
375	{
376	public:
377		PositionCurve	mPositionCurve;
378		RotationCurve	mRotationCurve;
379		ScaleCurve		mScaleCurve;
380		std::string		mJointName;
381		U32				mUsage;
382		LLJoint::JointPriority	mPriority;
383
384		void update(LLJointState* joint_state, F32 time, F32 duration);
385	};
386	
387	//-------------------------------------------------------------------------
388	// JointMotionList
389	//-------------------------------------------------------------------------
390	class JointMotionList
391	{
392	public:
393		std::vector<JointMotion*> mJointMotionArray;
394		F32						mDuration;
395		BOOL					mLoop;
396		F32						mLoopInPoint;
397		F32						mLoopOutPoint;
398		F32						mEaseInDuration;
399		F32						mEaseOutDuration;
400		LLJoint::JointPriority	mBasePriority;
401		LLHandMotion::eHandPose mHandPose;
402		LLJoint::JointPriority  mMaxPriority;
403		typedef std::list<JointConstraintSharedData*> constraint_list_t;
404		constraint_list_t		mConstraints;
405		LLBBoxLocal				mPelvisBBox;
406		// mEmoteName is a facial motion, but it's necessary to appear here so that it's cached.
407		// TODO: LLKeyframeDataCache::getKeyframeData should probably return a class containing 
408		// JointMotionList and mEmoteName, see LLKeyframeMotion::onInitialize.
409		std::string				mEmoteName; 
410	public:
411		JointMotionList();
412		~JointMotionList();
413		U32 dumpDiagInfo();
414		JointMotion* getJointMotion(U32 index) const { llassert(index < mJointMotionArray.size()); return mJointMotionArray[index]; }
415		U32 getNumJointMotions() const { return mJointMotionArray.size(); }
416	};
417
418
419protected:
420	static LLVFS*				sVFS;
421
422	//-------------------------------------------------------------------------
423	// Member Data
424	//-------------------------------------------------------------------------
425	JointMotionList*				mJointMotionList;
426	std::vector<LLPointer<LLJointState> > mJointStates;
427	LLJoint*						mPelvisp;
428	LLCharacter*					mCharacter;
429	typedef std::list<JointConstraint*>	constraint_list_t;
430	constraint_list_t				mConstraints;
431	U32								mLastSkeletonSerialNum;
432	F32								mLastUpdateTime;
433	F32								mLastLoopedTime;
434	AssetStatus						mAssetStatus;
435};
436
437class LLKeyframeDataCache
438{
439public:
440	// *FIX: implement this as an actual singleton member of LLKeyframeMotion
441	LLKeyframeDataCache(){};
442	~LLKeyframeDataCache();
443
444	typedef std::map<LLUUID, class LLKeyframeMotion::JointMotionList*> keyframe_data_map_t; 
445	static keyframe_data_map_t sKeyframeDataMap;
446
447	static void addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList*);
448	static LLKeyframeMotion::JointMotionList* getKeyframeData(const LLUUID& id);
449
450	static void removeKeyframeData(const LLUUID& id);
451
452	//print out diagnostic info
453	static void dumpDiagInfo();
454	static void clear();
455};
456
457#endif // LL_LLKEYFRAMEMOTION_H
458
459