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