diff -r 000000000000 -r bde4ae8d615e os/graphics/m3g/m3gcore11/src/m3g_animationtrack.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/graphics/m3g/m3gcore11/src/m3g_animationtrack.c Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,387 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: AnimationTrack implementation +* +*/ + + +/*! + * \internal + * \file + * \brief AnimationTrack implementation + */ + +#ifndef M3G_CORE_INCLUDE +# error included by m3g_core.c; do not compile separately. +#endif + +#include "m3g_animationtrack.h" +#include "m3g_keyframesequence.h" +#include "m3g_memory.h" + + +/*---------------------------------------------------------------------- + * Internal functions + *--------------------------------------------------------------------*/ + +/*! + * \internal + * \brief Destroys this AnimationTrack object. + * + * \param obj AnimationTrack object + */ +static void m3gDestroyAnimationTrack(Object *obj) +{ + AnimationTrack *animTrack = (AnimationTrack *) obj; + M3G_VALIDATE_OBJECT(animTrack); + + M3G_ASSIGN_REF(animTrack->sequence, NULL); + M3G_ASSIGN_REF(animTrack->controller, NULL); + + m3gDestroyObject(&animTrack->object); +} + +/*! + * \internal + * \brief Calculates animation track contribution. + * + * \param track AnimationTrack object + * \param time current world time + * \param accumSamples accumulated samples + * \param sampleInfo sample information + */ +static void m3gGetContribution(const AnimationTrack *track, M3Gint time, + M3Gfloat *accumSamples, SampleInfo *sampleInfo) +{ + if (track->controller == NULL || !m3gIsActive(track->controller, time)) { + sampleInfo->weight = 0; + sampleInfo->validity = (track->controller ? + m3gTimeToActivation(track->controller, time) : + 0x7FFFFFFF); + if (sampleInfo->validity < 1) + sampleInfo->validity = 1; + return; + } + { + M3Gfloat stackSampleVector[4]; + Interface *m3g = M3G_INTERFACE(track); + M3Gint i, sampleTime, sampleValidity; + M3Gfloat weight; + M3Gint sampleLength = m3gGetNumComponents(track->sequence); + M3Gfloat *sample; + + /* Before sampling, make sure that this track has some effect + * on the end result */ + + weight = m3gGetWeight(track->controller); + sampleInfo->weight = weight; + + if (weight <= 0.0f) { + sampleInfo->validity = 0x7FFFFFFF; + return; + } + + /* We use the stack-allocated sample vector by default, but + * the MORPH_WEIGHTS target may have more than 4 components, + * in which case we resort to the global temp vector. This + * means that the temp vector can not be used in the keyframe + * sampling code, but it doesn't seem likely that it would be + * needed there. */ + + if (sampleLength > 4) { + sample = (M3Gfloat*) m3gAllocTemp(m3g, (M3Gsize) sampleLength * sizeof(M3Gfloat)); + if (!sample) { + sampleInfo->validity = 0; + return; /* automatic out-of-memory error */ + } + } + else { + sample = stackSampleVector; + } + + sampleTime = m3gRoundToInt(m3gGetPosition(track->controller, time)); + sampleValidity = m3gGetSample(track->sequence, sampleTime, sample); + sampleInfo->validity = sampleValidity; + + /* Only bother if there was no error in GetSample... */ + + if (sampleValidity > 0) { + + /* Resolve the validity time of the sample */ + + sampleValidity = m3gTimeToDeactivation(track->controller, time); + if (sampleValidity < sampleInfo->validity) { + sampleInfo->validity = sampleValidity; + } + + /* Add the weighted sample to the accumulated value + * and return */ + + for (i = 0; i < sampleLength; ++i) { + accumSamples[i] = m3gAdd(accumSamples[i], + m3gMul(sample[i], weight)); + } + } + if (sample != stackSampleVector) { + m3gFreeTemp(m3g); + } + } +} + +/*! + * \internal + * \brief Checks animation property size. + * + * \param m3g M3G interface + * \param property animation property + * \param numComponents number of components + * \retval M3G_TRUE valid size for property + * \retval M3G_FALSE invalid size for property + */ +static M3Gbool m3gIsValidSize(Interface *m3g, M3Gint property, M3Gint numComponents) +{ + switch (property) { + case M3G_ANIM_ALPHA: + case M3G_ANIM_DENSITY: + case M3G_ANIM_FAR_DISTANCE: + case M3G_ANIM_FIELD_OF_VIEW: + case M3G_ANIM_INTENSITY: + case M3G_ANIM_NEAR_DISTANCE: + case M3G_ANIM_PICKABILITY: + case M3G_ANIM_SHININESS: + case M3G_ANIM_SPOT_ANGLE: + case M3G_ANIM_SPOT_EXPONENT: + case M3G_ANIM_VISIBILITY: + return (numComponents == 1); + case M3G_ANIM_CROP: + return (numComponents == 2 || numComponents == 4); + case M3G_ANIM_COLOR: + case M3G_ANIM_AMBIENT_COLOR: + case M3G_ANIM_DIFFUSE_COLOR: + case M3G_ANIM_EMISSIVE_COLOR: + case M3G_ANIM_SPECULAR_COLOR: + return (numComponents == 3); + case M3G_ANIM_TRANSLATION: + return (numComponents == 3); + case M3G_ANIM_ORIENTATION: + return (numComponents == 4); + case M3G_ANIM_SCALE: + return (numComponents == 1 || numComponents == 3); + case M3G_ANIM_MORPH_WEIGHTS: + return (numComponents > 0); + default: + m3gRaiseError(m3g, M3G_INVALID_ENUM); + } + return M3G_FALSE; +} + +/*! + * \internal + * \brief Overloaded Object3D method. + * + * \param self AnimationTrack object + * \param references array of reference objects + * \return number of references + */ +static M3Gint m3gAnimationTrackDoGetReferences(Object *self, Object **references) +{ + AnimationTrack *track = (AnimationTrack *) self; + M3Gint num = m3gObjectDoGetReferences(self, references); + if (track->sequence != NULL) { + if (references != NULL) + references[num] = (Object *)track->sequence; + num++; + } + if (track->controller != NULL) { + if (references != NULL) + references[num] = (Object *)track->controller; + num++; + } + return num; +} + +/*! + * \internal + * \brief Overloaded Object3D method + */ +static Object *m3gAnimationTrackFindID(Object *self, M3Gint userID) +{ + AnimationTrack *track = (AnimationTrack *) self; + Object *found = m3gObjectFindID(self, userID); + + if (!found && track->sequence != NULL) { + found = m3gFindID((Object*) track->sequence, userID); + } + if (!found && track->controller != NULL) { + found = m3gFindID((Object*) track->controller, userID); + } + return found; +} + +/*! + * \internal + * \brief Overloaded Object3D method. + * + * \param originalObj original AnimationTrack object + * \param cloneObj pointer to cloned AnimationTrack object + * \param pairs array for all object-duplicate pairs + * \param numPairs number of pairs + */ +static M3Gbool m3gAnimationTrackDuplicate(const Object *originalObj, + Object **cloneObj, + Object **pairs, + M3Gint *numPairs) +{ + AnimationTrack *original = (AnimationTrack *)originalObj; + AnimationTrack *clone = + (AnimationTrack *)m3gCreateAnimationTrack(originalObj->interface, + original->sequence, + original->property); + *cloneObj = (Object *)clone; + if (*cloneObj == NULL) { + return M3G_FALSE; + } + + if(m3gObjectDuplicate(originalObj, cloneObj, pairs, numPairs)) { + M3G_ASSIGN_REF(clone->controller, original->controller); + return M3G_TRUE; + } + else { + return M3G_FALSE; + } +} + +/*---------------------------------------------------------------------- + * Virtual function table + *--------------------------------------------------------------------*/ + +static const ObjectVFTable m3gvf_AnimationTrack = { + m3gObjectApplyAnimation, + m3gObjectIsCompatible, + m3gObjectUpdateProperty, + m3gAnimationTrackDoGetReferences, + m3gAnimationTrackFindID, + m3gAnimationTrackDuplicate, + m3gDestroyAnimationTrack +}; + + +/*---------------------------------------------------------------------- + * Public API functions + *--------------------------------------------------------------------*/ + +/*! + * \brief Creates a new AnimationTrack with default values + * + * \param hInterface M3G interface + * \param hSequence KeyframeSequence object + * \param property target animation property + * \retval AnimationTrack new AnimationTrack object + * \retval NULL AnimationTrack creating failed + */ +M3G_API M3GAnimationTrack m3gCreateAnimationTrack(M3GInterface hInterface, + M3GKeyframeSequence hSequence, + M3Gint property) +{ + KeyframeSequence *sequence = (KeyframeSequence *)hSequence; + Interface *m3g = (Interface *) hInterface; + M3G_VALIDATE_INTERFACE(m3g); + + /* Check for invalid arguments */ + + if (sequence == NULL) { + m3gRaiseError(m3g, M3G_NULL_POINTER); + return NULL; + } + if (property < M3G_ANIM_ALPHA || property > M3G_ANIM_VISIBILITY) { + m3gRaiseError(m3g, M3G_INVALID_ENUM); + return NULL; + } + if (!m3gIsValidSize(m3g, property, m3gGetNumComponents(sequence))) { + m3gRaiseError(m3g, M3G_INVALID_VALUE); + return NULL; + } + + /* Allocate and initialize the object */ + + { + AnimationTrack *track = m3gAllocZ(m3g, sizeof(AnimationTrack)); + + if (track != NULL) { + M3G_ASSIGN_REF(track->sequence, sequence); + track->property = property; + m3gInitObject(&track->object, m3g, M3G_CLASS_ANIMATION_TRACK); + } + + return track; + } +} + +/*! + * \brief Get animation controller. + * + * \param hTrack AnimationTrack object + * \retval AnimationController object + */ +M3G_API M3GAnimationController m3gGetController(M3GAnimationTrack hTrack) +{ + AnimationTrack *track = (AnimationTrack *) hTrack; + M3G_VALIDATE_OBJECT(track); + + return track->controller; +} + +/*! + * \brief Get key frame sequence. + * + * \param hTrack AnimationTrack object + * \retval KeyframeSequence object + */ +M3G_API M3GKeyframeSequence m3gGetSequence(M3GAnimationTrack hTrack) +{ + AnimationTrack *track = (AnimationTrack *) hTrack; + M3G_VALIDATE_OBJECT(track); + + return track->sequence; +} + +/*! + * \brief Get animation target property. + * + * \param hTrack AnimationTrack object + * \retval target property + */ +M3G_API M3Gint m3gGetTargetProperty(M3GAnimationTrack hTrack) +{ + AnimationTrack *track = (AnimationTrack *) hTrack; + M3G_VALIDATE_OBJECT(track); + + return track->property; +} + +/*! + * \brief Set animation controller. + * + * \param hTrack AnimationTrack object + * \param hController AnimationController object + */ +M3G_API void m3gSetController(M3GAnimationTrack hTrack, + M3GAnimationController hController) +{ + AnimationTrack *track = (AnimationTrack *) hTrack; + M3G_VALIDATE_OBJECT(track); + + M3G_ASSIGN_REF(track->controller, hController); +} +