/*==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 .
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 plAGMasterMod.h
\brief The animation class for the AniGraph animation system
\ingroup Avatar
\ingroup AniGraph
*/
#ifndef PLAGMASTERMOD_INC
#define PLAGMASTERMOD_INC
/////////////////////////////////////////////////////////////////////////////////////////
//
// INCLUDES
//
/////////////////////////////////////////////////////////////////////////////////////////
#include "pnModifier/plModifier.h"
#include "plAGChannel.h"
#include "plAvDefs.h"
#include "pnKeyedObject/plMsgForwarder.h"
// templates
#include "hsStlUtils.h"
#include "hsStlSortUtils.h"
class plAGModifier;
class plAGAnimInstance;
class plAGAnim;
class plATCAnim;
class plAGMasterSDLModifier;
////////////////
//
// PLAGMASTERMOD
//
////////////////
/** \class plAGMasterMod
A modifier which can apply animations to scene objects.
Works together with a plAGModifier, which can apply animation to a
single scene object. A master modifier hooks up to a family of
ag modifiers to do its job.
An animation (plAGAnim) can have many different channels, but the
user can just pass it to a single master mod to apply it to all the
channels owned by that master. The master will take care of hooking
each channel up to an ag modifier.
The goal is to make an animation a conceptually (and practically) simple
object to work with, whether or not it has multiple channels.
\sa plAGAnim, plAGAnimInstance, plAGModifier
*/
class plAGMasterMod : public plModifier
{
friend class plAGMasterSDLModifier;
public:
/** Default constructor. Primarily for use by the class factory. */
plAGMasterMod();
/** Free the name and any other miscellany. */
virtual ~plAGMasterMod();
/** Find an individual plAGModifier of the given name under our control. */
plAGModifier * GetChannelMod(const char * name, hsBool dontCache = false) const;
/** \name Managing Animations */
// \{
// AGANIM PROTOCOL
/** Attach the given animation object with the given blend factor.
If there's no animation already attached to blend with, the
animation will be attached at full strength. */
plAGAnimInstance *AttachAnimationBlended(plAGAnim *anim, hsScalar blendFactor = 0,
UInt16 blendPriority = kAGMedBlendPriority,
hsBool cache = false);
/** Look up the given animation by name and attach it
with the given blend factor. */
plAGAnimInstance *AttachAnimationBlended(const char *name, hsScalar blendFactor = 0,
UInt16 blendPriority = kAGMedBlendPriority,
hsBool cache = false);
/** Play a simple anim (one that doesn't affect root) once and auto detach.
Intended for Zandi's facial animations that run seperate from the behaviors. */
void PlaySimpleAnim(const char *name);
/** Detach the given animation instance. Does nothing
if the instance is not managed by this master mod. */
void DetachAnimation(plAGAnimInstance *instance);
void DetachAllAnimations();
/** Detach the given animation by name. Searches for
any instances derived from animations with the
given name and removes them. */
void DetachAnimation(const char *name);
// \}
/** Print the current animation stack to the console.
Will list all the animations and their blend strengths.
Animations later in the list will mask animations earlier
in the list. */
void DumpCurrentAnims(const char *header);
/** Find and return any animation instances with the
given name on this master modifer. */
plAGAnimInstance *FindAnimInstance(const char *name);
/** Return the Ith animation instance, based on blend
order. Of dubious utility, but, y'know. */
plAGAnimInstance *GetAnimInstance(int i);
/** Attach the animation if it's not already attached. If
it is attached, return the instance.
Note that if it's attached by this function, it
will be on top of the stack, but if it was already
attached, it could be anywhere, including buried under
a bunch of other animations. If it's important that it be
on top of the stack, you may need to detach it first. */
plAGAnimInstance *FindOrAttachInstance(const char *name, hsScalar blendFactor);
/** Return the number of animations available. */
int GetNumAnimations();
/** Return the number of animations that are privately
owned by this modifier.
Animations may be either shared in a general pool,
or privately owned by a mastermod. */
int GetNumPrivateAnimations();
int GetNumATCAnimations();
plAGAnimInstance *GetATCAnimInstance(int i);
/** Apply all our animations to all our parts.
\param timeNow is the current world time
\param elapsed is the time since the previous frame */
void ApplyAnimations(double timeNow, hsScalar elapsed);
/** Runs through our anims and applies them, without
processing fades. This is used when we load in anim
state from the server, and need to advance it to a
certain point before enabling callbacks */
void AdvanceAnimsToTime(double time);
/** Change the connectivity in the graph so that inactive animations are bypassed.
The original connectivity information is kept, so if the activity of different
animations is changed (such as by changing blend biases or adding new animations,
the graph can be compiled again to the correct state. */
void Compile(double time);
/** We've done something that invalidates the cached connectivity in the graph.
Mark this for fixup. */
void SetNeedCompile(bool needCompile);
/** List the animationg graph to stdOut, with a ASCII representation of the tree
structure. Done by recursively dumping the graph; some types of nodes will have
more output information than others.
*/
void DumpAniGraph(const char *channel, bool optimized, double time);
/** Set whether or not this is the "group master" so grouped animations will only have
one member getting/setting sdl animation state in order to synch the anims
*/
void SetIsGrouped(bool grouped);
void SetIsGroupMaster(bool master, plMsgForwarder* msgForwarder);
// PLASMA PROTOCOL
virtual int GetNumTargets() const { return fTarget ? 1 : 0; }
virtual plSceneObject* GetTarget(int w) const { /* hsAssert(w < GetNumTargets(), "Bad target"); */ return fTarget; }
virtual void AddTarget(plSceneObject * object);
virtual void RemoveTarget(plSceneObject * object);
hsBool MsgReceive(plMessage* msg);
virtual void Write(hsStream *stream, hsResMgr *mgr);
virtual void Read(hsStream * stream, hsResMgr *mgr);
hsBool HasRunningAnims();
hsBool DirtySynchState(const char* SDLStateName, UInt32 synchFlags);
CLASSNAME_REGISTER( plAGMasterMod );
GETINTERFACE_ANY( plAGMasterMod, plModifier );
protected:
// -- methods --
plAGModifier * ICacheChannelMod(plAGModifier *mod) const;
plAGModifier * IFindChannelMod(const plSceneObject *obj, const char *name) const;
virtual hsBool IEval(double secs, hsScalar del, UInt32 dirty);
virtual void IApplyDynamic() {}; // dummy function required by base class
// Find markers in an anim for environment effects (footsteps)
virtual void ISetupMarkerCallbacks(plATCAnim *anim, plAnimTimeConvert *atc) {}
// -- members
plSceneObject* fTarget;
// a map from channel names to ag modifiers within our domain
typedef std::map plChannelModMap;
plChannelModMap fChannelMods;
// instances which are currently attached to this master
typedef std::vector plInstanceVector;
plInstanceVector fAnimInstances; // animation instances
// animations which are owned exclusively by this master
typedef std::vector plAnimVector;
plAnimVector fPrivateAnims;
// animations that require AnimTimeConvert state to be synched
plInstanceVector fATCAnimInstances;
hsBool fFirstEval;
hsBool fNeedEval;
void IRegForEval(hsBool val);
// SDL modifier which sends/recvs dynamics state
plAGMasterSDLModifier *fAGMasterSDLMod;
bool fNeedCompile;
bool fIsGrouped;
bool fIsGroupMaster;
plMsgForwarder* fMsgForwarder;
enum {
kPrivateAnim,
kPublicAnim,
};
};
#endif // PLAGMASTERMOD_INC