Update contrib.
2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
14 * Description: AnimationTrack implementation
22 * \brief AnimationTrack implementation
25 #ifndef M3G_CORE_INCLUDE
26 # error included by m3g_core.c; do not compile separately.
29 #include "m3g_animationtrack.h"
30 #include "m3g_keyframesequence.h"
31 #include "m3g_memory.h"
34 /*----------------------------------------------------------------------
36 *--------------------------------------------------------------------*/
40 * \brief Destroys this AnimationTrack object.
42 * \param obj AnimationTrack object
44 static void m3gDestroyAnimationTrack(Object *obj)
46 AnimationTrack *animTrack = (AnimationTrack *) obj;
47 M3G_VALIDATE_OBJECT(animTrack);
49 M3G_ASSIGN_REF(animTrack->sequence, NULL);
50 M3G_ASSIGN_REF(animTrack->controller, NULL);
52 m3gDestroyObject(&animTrack->object);
57 * \brief Calculates animation track contribution.
59 * \param track AnimationTrack object
60 * \param time current world time
61 * \param accumSamples accumulated samples
62 * \param sampleInfo sample information
64 static void m3gGetContribution(const AnimationTrack *track, M3Gint time,
65 M3Gfloat *accumSamples, SampleInfo *sampleInfo)
67 if (track->controller == NULL || !m3gIsActive(track->controller, time)) {
68 sampleInfo->weight = 0;
69 sampleInfo->validity = (track->controller ?
70 m3gTimeToActivation(track->controller, time) :
72 if (sampleInfo->validity < 1)
73 sampleInfo->validity = 1;
77 M3Gfloat stackSampleVector[4];
78 Interface *m3g = M3G_INTERFACE(track);
79 M3Gint i, sampleTime, sampleValidity;
81 M3Gint sampleLength = m3gGetNumComponents(track->sequence);
84 /* Before sampling, make sure that this track has some effect
85 * on the end result */
87 weight = m3gGetWeight(track->controller);
88 sampleInfo->weight = weight;
91 sampleInfo->validity = 0x7FFFFFFF;
95 /* We use the stack-allocated sample vector by default, but
96 * the MORPH_WEIGHTS target may have more than 4 components,
97 * in which case we resort to the global temp vector. This
98 * means that the temp vector can not be used in the keyframe
99 * sampling code, but it doesn't seem likely that it would be
102 if (sampleLength > 4) {
103 sample = (M3Gfloat*) m3gAllocTemp(m3g, (M3Gsize) sampleLength * sizeof(M3Gfloat));
105 sampleInfo->validity = 0;
106 return; /* automatic out-of-memory error */
110 sample = stackSampleVector;
113 sampleTime = m3gRoundToInt(m3gGetPosition(track->controller, time));
114 sampleValidity = m3gGetSample(track->sequence, sampleTime, sample);
115 sampleInfo->validity = sampleValidity;
117 /* Only bother if there was no error in GetSample... */
119 if (sampleValidity > 0) {
121 /* Resolve the validity time of the sample */
123 sampleValidity = m3gTimeToDeactivation(track->controller, time);
124 if (sampleValidity < sampleInfo->validity) {
125 sampleInfo->validity = sampleValidity;
128 /* Add the weighted sample to the accumulated value
131 for (i = 0; i < sampleLength; ++i) {
132 accumSamples[i] = m3gAdd(accumSamples[i],
133 m3gMul(sample[i], weight));
136 if (sample != stackSampleVector) {
144 * \brief Checks animation property size.
146 * \param m3g M3G interface
147 * \param property animation property
148 * \param numComponents number of components
149 * \retval M3G_TRUE valid size for property
150 * \retval M3G_FALSE invalid size for property
152 static M3Gbool m3gIsValidSize(Interface *m3g, M3Gint property, M3Gint numComponents)
156 case M3G_ANIM_DENSITY:
157 case M3G_ANIM_FAR_DISTANCE:
158 case M3G_ANIM_FIELD_OF_VIEW:
159 case M3G_ANIM_INTENSITY:
160 case M3G_ANIM_NEAR_DISTANCE:
161 case M3G_ANIM_PICKABILITY:
162 case M3G_ANIM_SHININESS:
163 case M3G_ANIM_SPOT_ANGLE:
164 case M3G_ANIM_SPOT_EXPONENT:
165 case M3G_ANIM_VISIBILITY:
166 return (numComponents == 1);
168 return (numComponents == 2 || numComponents == 4);
170 case M3G_ANIM_AMBIENT_COLOR:
171 case M3G_ANIM_DIFFUSE_COLOR:
172 case M3G_ANIM_EMISSIVE_COLOR:
173 case M3G_ANIM_SPECULAR_COLOR:
174 return (numComponents == 3);
175 case M3G_ANIM_TRANSLATION:
176 return (numComponents == 3);
177 case M3G_ANIM_ORIENTATION:
178 return (numComponents == 4);
180 return (numComponents == 1 || numComponents == 3);
181 case M3G_ANIM_MORPH_WEIGHTS:
182 return (numComponents > 0);
184 m3gRaiseError(m3g, M3G_INVALID_ENUM);
191 * \brief Overloaded Object3D method.
193 * \param self AnimationTrack object
194 * \param references array of reference objects
195 * \return number of references
197 static M3Gint m3gAnimationTrackDoGetReferences(Object *self, Object **references)
199 AnimationTrack *track = (AnimationTrack *) self;
200 M3Gint num = m3gObjectDoGetReferences(self, references);
201 if (track->sequence != NULL) {
202 if (references != NULL)
203 references[num] = (Object *)track->sequence;
206 if (track->controller != NULL) {
207 if (references != NULL)
208 references[num] = (Object *)track->controller;
216 * \brief Overloaded Object3D method
218 static Object *m3gAnimationTrackFindID(Object *self, M3Gint userID)
220 AnimationTrack *track = (AnimationTrack *) self;
221 Object *found = m3gObjectFindID(self, userID);
223 if (!found && track->sequence != NULL) {
224 found = m3gFindID((Object*) track->sequence, userID);
226 if (!found && track->controller != NULL) {
227 found = m3gFindID((Object*) track->controller, userID);
234 * \brief Overloaded Object3D method.
236 * \param originalObj original AnimationTrack object
237 * \param cloneObj pointer to cloned AnimationTrack object
238 * \param pairs array for all object-duplicate pairs
239 * \param numPairs number of pairs
241 static M3Gbool m3gAnimationTrackDuplicate(const Object *originalObj,
246 AnimationTrack *original = (AnimationTrack *)originalObj;
247 AnimationTrack *clone =
248 (AnimationTrack *)m3gCreateAnimationTrack(originalObj->interface,
251 *cloneObj = (Object *)clone;
252 if (*cloneObj == NULL) {
256 if(m3gObjectDuplicate(originalObj, cloneObj, pairs, numPairs)) {
257 M3G_ASSIGN_REF(clone->controller, original->controller);
265 /*----------------------------------------------------------------------
266 * Virtual function table
267 *--------------------------------------------------------------------*/
269 static const ObjectVFTable m3gvf_AnimationTrack = {
270 m3gObjectApplyAnimation,
271 m3gObjectIsCompatible,
272 m3gObjectUpdateProperty,
273 m3gAnimationTrackDoGetReferences,
274 m3gAnimationTrackFindID,
275 m3gAnimationTrackDuplicate,
276 m3gDestroyAnimationTrack
280 /*----------------------------------------------------------------------
281 * Public API functions
282 *--------------------------------------------------------------------*/
285 * \brief Creates a new AnimationTrack with default values
287 * \param hInterface M3G interface
288 * \param hSequence KeyframeSequence object
289 * \param property target animation property
290 * \retval AnimationTrack new AnimationTrack object
291 * \retval NULL AnimationTrack creating failed
293 M3G_API M3GAnimationTrack m3gCreateAnimationTrack(M3GInterface hInterface,
294 M3GKeyframeSequence hSequence,
297 KeyframeSequence *sequence = (KeyframeSequence *)hSequence;
298 Interface *m3g = (Interface *) hInterface;
299 M3G_VALIDATE_INTERFACE(m3g);
301 /* Check for invalid arguments */
303 if (sequence == NULL) {
304 m3gRaiseError(m3g, M3G_NULL_POINTER);
307 if (property < M3G_ANIM_ALPHA || property > M3G_ANIM_VISIBILITY) {
308 m3gRaiseError(m3g, M3G_INVALID_ENUM);
311 if (!m3gIsValidSize(m3g, property, m3gGetNumComponents(sequence))) {
312 m3gRaiseError(m3g, M3G_INVALID_VALUE);
316 /* Allocate and initialize the object */
319 AnimationTrack *track = m3gAllocZ(m3g, sizeof(AnimationTrack));
322 M3G_ASSIGN_REF(track->sequence, sequence);
323 track->property = property;
324 m3gInitObject(&track->object, m3g, M3G_CLASS_ANIMATION_TRACK);
332 * \brief Get animation controller.
334 * \param hTrack AnimationTrack object
335 * \retval AnimationController object
337 M3G_API M3GAnimationController m3gGetController(M3GAnimationTrack hTrack)
339 AnimationTrack *track = (AnimationTrack *) hTrack;
340 M3G_VALIDATE_OBJECT(track);
342 return track->controller;
346 * \brief Get key frame sequence.
348 * \param hTrack AnimationTrack object
349 * \retval KeyframeSequence object
351 M3G_API M3GKeyframeSequence m3gGetSequence(M3GAnimationTrack hTrack)
353 AnimationTrack *track = (AnimationTrack *) hTrack;
354 M3G_VALIDATE_OBJECT(track);
356 return track->sequence;
360 * \brief Get animation target property.
362 * \param hTrack AnimationTrack object
363 * \retval target property
365 M3G_API M3Gint m3gGetTargetProperty(M3GAnimationTrack hTrack)
367 AnimationTrack *track = (AnimationTrack *) hTrack;
368 M3G_VALIDATE_OBJECT(track);
370 return track->property;
374 * \brief Set animation controller.
376 * \param hTrack AnimationTrack object
377 * \param hController AnimationController object
379 M3G_API void m3gSetController(M3GAnimationTrack hTrack,
380 M3GAnimationController hController)
382 AnimationTrack *track = (AnimationTrack *) hTrack;
383 M3G_VALIDATE_OBJECT(track);
385 M3G_ASSIGN_REF(track->controller, hController);