You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
294 lines
11 KiB
294 lines
11 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, Inc. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
Additional permissions under GNU GPL version 3 section 7 |
|
|
|
If you modify this Program, or any covered work, by linking or |
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
(or a modified version of those libraries), |
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
licensors of this Program grant you additional |
|
permission to convey the resulting work. Corresponding Source for a |
|
non-source form of such a combination shall include the source code for |
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
work. |
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
or by snail mail at: |
|
Cyan Worlds, Inc. |
|
14617 N Newport Hwy |
|
Mead, WA 99021 |
|
|
|
*==LICENSE==*/ |
|
/** \file plAGAnimInstance.h |
|
\brief The animation class for the AniGraph animation system |
|
|
|
\ingroup Avatar |
|
\ingroup AniGraph |
|
*/ |
|
|
|
#ifndef PLAGANIMINSTANCE_INC |
|
#define PLAGANIMINSTANCE_INC |
|
|
|
// disable warning C4503: dcorated name length exceeded, name was truncated |
|
// disable warning C4786: symbol greater than 255 characters, |
|
#pragma warning(disable: 4503 4786) |
|
|
|
// templates |
|
#include "hsStlUtils.h" |
|
#include "hsStlSortUtils.h" |
|
|
|
// local |
|
#include "plScalarChannel.h" |
|
|
|
// other |
|
#include "plInterp/plAnimTimeConvert.h" |
|
|
|
// declarations |
|
class plAGChannel; |
|
class plAGAnim; |
|
class plAGMasterMod; |
|
class plAGChannelApplicator; |
|
class plOneShotCallbacks; |
|
|
|
///////////////// |
|
// PLAGANIMINSTANCE |
|
///////////////// |
|
/** \class plAGAnimInstance |
|
Whenever we attach an animation to a scene object hierarchy, we |
|
create an activation record -- a plAGAnimInstance -- that remembers |
|
all the ephemeral state associated with animation |
|
Since animations have many channels and may involve blend operations, |
|
one of the primary responsibilities of this class is to keep track of |
|
all the animation node graphs that were created by the invocation of |
|
this animation. |
|
*/ |
|
class plAGAnimInstance { |
|
public: |
|
/** Used for the fade commands to select what to fade. */ |
|
enum |
|
{ |
|
kFadeBlend, /// Fade the blend strength |
|
kFadeAmp, /// Fade the amplitude |
|
} FadeType; |
|
|
|
/** Default constructor. */ |
|
plAGAnimInstance(); |
|
|
|
/** Construct from an animation and a master modifier. |
|
This attaches the animation channels to the channels of |
|
the master modifier and creates all the bookkeeping structures |
|
necessary to undo it later. */ |
|
plAGAnimInstance(plAGAnim * anim, plAGMasterMod * master, hsScalar blend, UInt16 blendPriority, hsBool cache, bool useAmplitude); |
|
|
|
/** Destructor. Removes the animation from the scene objects it's attached to. */ |
|
virtual ~plAGAnimInstance(); |
|
|
|
/** Returns the animation that this instance mediates. */ |
|
const plAGAnim * GetAnimation() { return fAnimation; }; |
|
|
|
/** Returns the timeconvert object that controls the progress of time |
|
in this animation. */ |
|
plAnimTimeConvert *GetTimeConvert() { return fTimeConvert; } |
|
|
|
/** Set the speed of the animation. This is expressed as a fraction of |
|
the speed with which the animation was defined. */ |
|
void SetSpeed(hsScalar speed) { if (fTimeConvert) fTimeConvert->SetSpeed(speed); }; |
|
|
|
// \{ |
|
/** |
|
The current blend factor of the animation. This indicates the |
|
priority of this animation as opposed to other animations which |
|
were attached before it. Conceptually it may help to think of this |
|
as a layer in an stack of animations, where the blend value is the |
|
'opacity' of this animation relative to the ones below it. |
|
1.0 represents full strength. |
|
You may use values higher than 1.0, but this has not |
|
yet been seen to have any practical utility whatsoever. Note that |
|
even if an animation has a blend strength of 1.0, it may have another |
|
animation on top/downstream from it that is masking it completely. */ |
|
hsScalar SetBlend(hsScalar blend); |
|
hsScalar GetBlend(); |
|
// \} |
|
|
|
/** Set the strength of the animation with respect to its 0th frame. |
|
This can be used to dampen the motion of the animation. |
|
Animations must be designed to use this: frame 0 of the animation |
|
must be a reasonable "default pose" as it will be blended with the |
|
current frame of the animation to produce the result. */ |
|
hsScalar SetAmplitude(hsScalar amp); |
|
/** Get the current strength of the animation. */ |
|
hsScalar GetAmplitude(); |
|
|
|
/** Make this animation loop (or not.) Note that the instance can loop |
|
or not without regard to whether the plAGAnim it is based on loops. */ |
|
void SetLoop(hsBool status); |
|
|
|
/** Interpret and respond to an animation command message. /sa plAnimCmdMsg */ |
|
hsBool HandleCmd(plAnimCmdMsg *msg); |
|
|
|
/** Start playback of the animation. You may optionally provide the a world |
|
time, which is needed for synchronizing the animation's timeline |
|
with the global timeline. If timeNow is -1 (the default,) the system |
|
time will be polled */ |
|
void Start(double worldTimeNow = -1); |
|
|
|
/** Stop playback of the animation. */ |
|
void Stop(); |
|
|
|
/** Move the playback head of the animation to a specific time. |
|
Note that this time is in animation local time, not global time. |
|
The "jump" parameter specifies whether or not to fire callbacks |
|
that occur between the current time and the target time. */ |
|
void SetCurrentTime(hsScalar newLocalTime, hsBool jump = false); |
|
|
|
/** Move the playback head by the specified relative amount within |
|
the animation. This may cause looping. If the beginning or end |
|
of the animation is reached an looping is not on, the movement |
|
will pin. |
|
\param jump if true, don't look for callbacks between old time and TRACKED_NEW */ |
|
void SeekRelative(hsScalar delta, hsBool jump); |
|
|
|
/** Gradually fade the blend strength or amplitude of the animation. |
|
\param goal is the desired blend strength |
|
\param rate is in blend units per second |
|
\type is either kFadeBlend or kFadeAmp */ |
|
void Fade(hsScalar goal, hsScalar rate, UInt8 type = kFadeBlend); |
|
|
|
/** Fade the animation and detach it after the fade is complete. |
|
Extremely useful for situations where the controlling logic |
|
is terminating immediately but you want the animation to fade |
|
out gradually. |
|
\deprecated |
|
*/ |
|
void FadeAndDetach(hsScalar goal, hsScalar rate); |
|
|
|
/** Has the animation terminated of natural causes? |
|
Primarily used to see if an animation has played all the |
|
way to the end, but will also return true if the animation |
|
was stopped with a stop command */ |
|
hsBool IsFinished(); |
|
|
|
/** Is the animation playback head positioned at the end. */ |
|
hsBool IsAtEnd(); |
|
|
|
/** Get the name of the underlying animation. */ |
|
const char * GetName(); |
|
|
|
/** Remove all channels from the master mode and remove us from |
|
our master modifier. |
|
Destructs the object! */ |
|
void Detach(); |
|
|
|
/** Remove all the instance's channels from the modifiers they're attached to. |
|
Typically called by the master mod prior to destructing the instance. */ |
|
void DetachChannels(); |
|
|
|
/** Prune any unused branches out of the animation graph; add any |
|
newly active branches back in. */ |
|
void Optimize(); |
|
|
|
/** Convert the given world time to local animation time. |
|
May include the effects of looping or wraparound. |
|
If the local time passes the end of the animation, the returned |
|
time will be pinned appropriately. */ |
|
double WorldToAnimTime(double foo) { return (fTimeConvert ? fTimeConvert->WorldToAnimTimeNoUpdate(foo) : 0); }; |
|
|
|
/** Attach a sequence of callback messages to the animation instance. |
|
Messages are each associated with a specific (local) time |
|
in the animation and will be sent when playback passes that time. */ |
|
void AttachCallbacks(plOneShotCallbacks *callbacks); |
|
|
|
void ProcessFade(hsScalar elapsed); // process any outstanding fades |
|
void SearchForGlobals(); // Util function to setup SDL channels |
|
protected: |
|
/** Set up bookkeeping for a fade. */ |
|
void ISetupFade(hsScalar goal, hsScalar rate, bool detach, UInt8 type); |
|
|
|
void IRegisterDetach(const char *channelName, plAGChannel *channel); |
|
|
|
const plAGAnim * fAnimation; |
|
plAGMasterMod * fMaster; |
|
|
|
std::map<char *, plAGChannelApplicator *, stringISorter> fChannels; |
|
|
|
typedef std::multimap<const char *, plAGChannel *> plDetachMap; |
|
plDetachMap fManualDetachChannels; |
|
|
|
std::vector<plAGChannel*> fCleanupChannels; |
|
std::vector<plScalarSDLChannel*> fSDLChannels; |
|
|
|
plScalarConstant fBlend; // blend factor vs. previous animations |
|
plScalarConstant fAmplitude; // for animation scaling |
|
|
|
// Each activation gets its own timeline. |
|
plAnimTimeConvert *fTimeConvert; |
|
|
|
hsBool fFadeBlend; /// we are fading the blend |
|
hsScalar fFadeBlendGoal; /// what blend level we're trying to reach |
|
hsScalar fFadeBlendRate; /// how fast are we fading in blend units per second (1 blend unit = full) |
|
hsBool fFadeDetach; /// detach after fade is finished? (only used for blend fades) |
|
|
|
hsBool fFadeAmp; /// we are fading the amplitude |
|
hsScalar fFadeAmpGoal; /// amplitude we're trying to reach |
|
hsScalar fFadeAmpRate; /// how faster we're fading in blend units per second |
|
|
|
hsScalar ICalcFade(hsBool &fade, hsScalar curVal, hsScalar goal, hsScalar rate, hsScalar elapsed); |
|
|
|
}; |
|
|
|
//#ifdef _DEBUG |
|
//#define TRACK_AG_ALLOCS // for now, automatically track AG allocations in debug |
|
//#endif |
|
#ifdef TRACK_AG_ALLOCS |
|
|
|
extern const char *gGlobalAnimName; |
|
extern const char *gGlobalChannelName; |
|
|
|
void RegisterAGAlloc(plAGChannel *object, const char *chanName, const char *animName, UInt16 classIndex); |
|
void UnRegisterAGAlloc(plAGChannel *object); |
|
void DumpAGAllocs(); |
|
|
|
#endif // TRACK_AG_ALLOCS |
|
|
|
#endif // PLAGANIMINSTANCE_INC |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|