414 lines
17 KiB
C++
414 lines
17 KiB
C++
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CryEngine Source code
|
|
//
|
|
// File:CryCharInstance.h
|
|
// Declaration of CryCharInstance class
|
|
//
|
|
// History:
|
|
// August 16, 2002: Created by Sergiy Migdalskiy <sergiy@crytek.de>
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
#ifndef _CRY_CHAR_INSTANCE_HEADER_
|
|
#define _CRY_CHAR_INSTANCE_HEADER_
|
|
|
|
struct CryEngineDecalInfo;
|
|
struct CryParticleSpawnInfo;
|
|
|
|
#include <ICryAnimation.h>
|
|
#include "CryModel.h"
|
|
#include "CryCharBody.h"
|
|
#include "IBindable.h"
|
|
#include "CryCharInstanceRenderParams.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
struct AnimData;
|
|
|
|
class CryCharManager;
|
|
|
|
class CryCharInstanceBase: public ICryCharInstance
|
|
{
|
|
public:
|
|
~CryCharInstanceBase()
|
|
{
|
|
DetachAll();
|
|
}
|
|
struct StatObjBind
|
|
{
|
|
IBindable* pObj;
|
|
unsigned nBone;
|
|
unsigned nFlags;
|
|
StatObjBind(IBindable* obj, unsigned bone,unsigned flags):
|
|
pObj(obj), nBone(bone), nFlags(flags) {assert (pObj);}
|
|
};
|
|
typedef std::vector<StatObjBind*> BindArray;
|
|
BindArray m_arrBinds;
|
|
|
|
// detaches all objects from bones; returns the nubmer of bindings deleted
|
|
unsigned DetachAll();
|
|
|
|
// detach all bindings to the given bone; returns the nubmer of bindings deleted
|
|
unsigned DetachAllFromBone(unsigned nBone);
|
|
|
|
// attaches the object to the given bone. The returned value is the handle of the binding,
|
|
// that can be used to examine the binding and delete it
|
|
ObjectBindingHandle AttachToBone (IBindable*pObj, unsigned nBone, unsigned nFlags = 0);
|
|
|
|
// detaches the given binding; if it returns false, the binding handle is invalid
|
|
// the binding becomes invalid immediately after detach
|
|
bool Detach (ObjectBindingHandle nHandle);
|
|
|
|
// checks if the given binding is valid
|
|
bool IsBindingValid (ObjectBindingHandle nHandle);
|
|
|
|
void PreloadResources ( float fDistance, float fTime, int nFlags );
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Implementation of ICryCharInstance interface, the main interface
|
|
// in the Animation module
|
|
class CryCharInstance : public CryCharInstanceBase, protected CryCharInstanceRenderParams
|
|
{
|
|
public:
|
|
// Releases this instance.
|
|
virtual void Release()
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
CryCharBody *GetBody()
|
|
{
|
|
return m_pCryCharBody;
|
|
}
|
|
|
|
//! Returns the model interface
|
|
virtual ICryCharModel* GetModel();
|
|
|
|
virtual void Draw(const SRendParams & RendParams,const Vec3& t);
|
|
//there must be only one function
|
|
//! Render object ( register render elements into renderer )
|
|
virtual void Render(const struct SRendParams & rParams, const Vec3& t, int nLodLevel);
|
|
|
|
//! marks all LODs as needed to be reskinned
|
|
virtual void ForceReskin ();
|
|
|
|
//! returns the leaf buffer materials in this character (as they are used in the renderer)
|
|
virtual const list2<CMatInfo>*getLeafBufferMaterials();
|
|
|
|
|
|
//! Interface for the renderer - returns the CDLight describing the light in this character;
|
|
//! returns NULL if there's no light with such index
|
|
//! ICryCharInstance owns this light. This light may be destructed without notice upon next call to
|
|
//! any other function but GetLight(). Nobody may every modify it.
|
|
const CDLight* GetBoundLight (int nIndex);
|
|
|
|
//! Draw the character shadow volumes into the stencil buffer using a set of specified
|
|
//! rendering parameters
|
|
virtual void RenderShadowVolumes(const SRendParams *rParams, int nLimitLOD = 0);
|
|
|
|
virtual const char * GetShaderTemplateName();
|
|
|
|
virtual bool SetShaderTemplateName(const char *TemplName, int Id, const char *ShaderName=0,IMatInfo *pCustomMaterial=0,unsigned nFlags = 0);
|
|
//! Sets shader template for rendering
|
|
virtual bool SetShaderTemplate(int nTemplate, const char *TemplName, const char *ShaderName, bool bOnlyRegister=false, int * pnNewTemplateId=NULL);
|
|
|
|
|
|
virtual void SetShaderFloat(const char *Name, float fVal, const char *ShaderName=NULL);
|
|
//! Sets color parameter
|
|
virtual void SetColor(float fR, float fG, float fB, float fA);
|
|
|
|
virtual const Vec3d GetCenter();
|
|
virtual const float GetRadius();
|
|
virtual void GetBBox(Vec3d& Mins, Vec3d& Maxs);
|
|
|
|
virtual bool SetAnimationFrame(const char * szString, int nFrame);
|
|
virtual ICryBone * GetBoneByName(const char * szName);
|
|
|
|
// Attaches a static object to the bone (given the bone name) or detaches previous object from the bone.
|
|
virtual ObjectBindingHandle AttachObjectToBone(IBindable * pWeaponModel, const char * szBoneName, bool bUseRelativeToDefPoseMatrix, unsigned nFlags);
|
|
|
|
// returns the number of bindings; valid until the next attach/detach operation
|
|
virtual size_t GetBindingCount();
|
|
|
|
// fills the given array with GetBindingCount() pointers to IBindable
|
|
virtual void EnumBindables(IBindable** pResult);
|
|
|
|
//! attach a light to a bone
|
|
virtual LightHandle AttachLight (CDLight* pDLight, unsigned nBone, bool bCopyLight = false);
|
|
//! detach the light from the bone
|
|
virtual void DetachLight (CDLight* pDLight);
|
|
|
|
//! Attach a light (copying the light actually) to the bone
|
|
//! Returns the handle identifying the light. With this handle, you can either
|
|
//! Retrieve the light information or detach it.
|
|
virtual LightHandle AttachLight (const CDLight& rDLight, const char* szBoneName);
|
|
//! Detaches the light by the handle retuned by AttachLight
|
|
virtual void DetachLight (LightHandle nHandle);
|
|
//! Returns the light by the light handle; returns NULL if no such light found
|
|
virtual CDLight* GetLight(LightHandle nHandle);
|
|
//! Returns the light handle if the light is attached; returns invalid handle, if this light is not attached
|
|
//! NOTE: if your light was attached with copying, then you won't get the handle for the original light pointer
|
|
//! because the original light might have been attached several times and have several pointers in this case
|
|
virtual LightHandle GetLightHandle (CDLight* pLight);
|
|
|
|
// virtual bool BindStatObjToBone(IBindable * pStatObj, const char * szBoneName);
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// StartAnimation:
|
|
// Searchs for the animation in animations list and starts palying it.
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
virtual bool StartAnimation (const char* szAnimName, const struct CryCharAnimationParams& Params);
|
|
|
|
//! Start the specified by parameters morph target
|
|
virtual void StartMorph (const char* szMorphTarget,const CryCharMorphParams& params);
|
|
|
|
//! Start the morph target
|
|
virtual void StartMorph (int nMorphTargetId, const CryCharMorphParams& params);
|
|
|
|
//! Finds the morph with the given id and sets its relative time.
|
|
//! Returns false if the operation can't be performed (no morph)
|
|
virtual bool SetMorphTime (int nMorphTargetId, float fTime);
|
|
|
|
//! Stops the animation at the specified layer. Returns true if there was some animation on that layer, and false otherwise
|
|
virtual bool StopAnimation (int nLayer);
|
|
|
|
virtual bool StopMorph (int nMorphTargetId);
|
|
virtual void StopAllMorphs();
|
|
//! freezes all currently playing morphs at the point they're at
|
|
virtual void FreezeAllMorphs();
|
|
|
|
|
|
//! Enables/Disables the Default Idle Animation restart.
|
|
//! If this feature is enabled, then the last looped animation will be played back after the current (non-loop) animation is finished.
|
|
//! Only those animations started with the flag bTreatAsDefaultIdleAnimation == true will be taken into account
|
|
virtual void EnableLastIdleAnimationRestart (unsigned nLayer, bool bEnable = true);
|
|
|
|
// Checks if the animation with the given name exists, returns true if it does
|
|
virtual bool IsAnimationPresent(const char* szAnimName);
|
|
|
|
|
|
virtual const char * GetCurAnimation();
|
|
|
|
//! Returns the current animation in the layer or -1 if no animation is being played
|
|
//! in this layer (or if there's no such layer)
|
|
virtual int GetCurrentAnimation (unsigned nLayer);
|
|
|
|
virtual void ResetAnimations();
|
|
|
|
// calculates the mask ANDed with the frame id that's used to determine whether to skin the character on this frame or not.
|
|
int GetUpdateFrequencyMask(Vec3d vPos, float fRadius);
|
|
virtual void Update(Vec3d vPos, float fRadius, unsigned uFlags); // processes animations and recalc bones
|
|
//! Updates the bones and the bounding box. Should be called if animation update
|
|
//! cycle in EntityUpdate has already passed but you need the result of new animatmions
|
|
//! started after Update right now.
|
|
virtual void ForceUpdate();
|
|
|
|
virtual void UpdatePhysics( float fScale=1.0f ); // updates model physics (if any); is separate from Update
|
|
|
|
virtual void SetFlags(int nFlags) { m_nFlags=nFlags; }
|
|
virtual int GetFlags() { return m_nFlags; }
|
|
|
|
//! Enables receiving OnStart/OnEnd of all animations from this character instance
|
|
//! THe specified sink also receives the additional animation events specified through AddAnimationEvent interface
|
|
virtual void AddAnimationEventSink(ICharInstanceSink * pCharInstanceSink);
|
|
|
|
//! Counterpart to AddAnimationEventSink
|
|
virtual void RemoveAnimationEventSink(ICharInstanceSink * pCharInstanceSink);
|
|
|
|
//! Deletes all animation events
|
|
virtual void RemoveAllAnimationEvents();
|
|
|
|
|
|
//! Enables receiving OnStart/OnEnd of specified animation from this character instance
|
|
//! The specified sink also receives the additional animation events specified through AddAnimationEvent interface for this animation
|
|
virtual void AddAnimationEventSink(const char* szAnimName, ICharInstanceSink * pCharInstanceSink);
|
|
|
|
//! Counterpart to the AddAnimationEventSink
|
|
virtual void RemoveAnimationEventSink(const char* szAnimName, ICharInstanceSink * pCharInstanceSink);
|
|
|
|
//! Adds an animation event; whenever the character plays the specified frame of the specified animation,
|
|
//! it calls back the animation event sinkreceiving OnEvent notification of specified animation for all instances using this model
|
|
virtual bool AddAnimationEvent(const char * szAnimName, int nFrameID, AnimSinkEventData UserData);
|
|
|
|
//! Deletes the animation event; from now on the sink won't be receiving the animation this event
|
|
virtual bool RemoveAnimationEvent (const char* szAnimName, int nFrameID, AnimSinkEventData UserData);
|
|
|
|
//! Enable object animation time update. If the bUpdate flag is false, subsequent calls to Update will not animate the character
|
|
virtual void EnableTimeUpdate (bool bUpdate);
|
|
|
|
//! Set the current time of the given layer, in seconds
|
|
virtual void SetLayerTime (int nLayer, float fTimeSeconds);
|
|
virtual float GetLayerTime (int nLayer);
|
|
|
|
// sets the given aniimation to the given layer as the default
|
|
void SetDefaultIdleAnimation(unsigned nLayer, const char* szAnimName);
|
|
|
|
CryCharInstance (CryCharBody * pBody);
|
|
~CryCharInstance ();
|
|
|
|
// FOR TEST ONLY enables/disables StartAnimation* calls; puts warning into the log if StartAnimation* is called while disabled
|
|
void EnableStartAnimation (bool bEnable) ;
|
|
|
|
//Executes a per-character script command
|
|
bool ExecScriptCommand (int nCommand, void* pParams, void* pResult);
|
|
private:
|
|
|
|
void Create(const char * fname, CryCharBody * _pCryCharBody);
|
|
|
|
const Vec3d & GetSpitFirePos() { return m_v3pvSpitFirePosTranslated; }
|
|
|
|
//! Return the length of the given animation in seconds; 0 if no such animation found
|
|
virtual void SetAnimationSpeed(float speed) { m_fAnimSpeedScale = speed; }
|
|
virtual float GetAnimationSpeed() { return m_fAnimSpeedScale; }
|
|
virtual void SetAnimationSpeed(int nLayer, float fSpeed);
|
|
//! Set morph speed scale
|
|
//! Finds the morph target with the given id, sets its morphing speed and returns true;
|
|
//! if there's no such morph target currently playing, returns false
|
|
virtual bool SetMorphSpeed (int nMorphTargetId, float fSpeed);
|
|
|
|
virtual void BuildPhysicalEntity(IPhysicalEntity *pent,float mass,int surface_idx,float stiffness_scale,int nLod=0);
|
|
virtual IPhysicalEntity *CreateCharacterPhysics(IPhysicalEntity *pHost, float mass,int surface_idx,float stiffness_scale, int nLod=0);
|
|
virtual int CreateAuxilaryPhysics(IPhysicalEntity *pHost, int nLod=0);
|
|
virtual void SynchronizeWithPhysicalEntity(IPhysicalEntity *pent,const Vec3& posMaster,const Quat& qMaster);
|
|
virtual IPhysicalEntity *RelinquishCharacterPhysics();
|
|
virtual void SetCharacterPhysParams(float mass,int surface_idx);
|
|
virtual IPhysicalEntity *GetCharacterPhysics();
|
|
virtual IPhysicalEntity *GetCharacterPhysics(const char *pRootBoneName);
|
|
virtual IPhysicalEntity *GetCharacterPhysics(int iAuxPhys);
|
|
virtual void DestroyCharacterPhysics(int iMode=0);
|
|
|
|
virtual void SetLimbIKGoal(int limbid, vectorf ptgoal=vectorf(1E10f,0,0), int ik_flags=0, float addlen=0, vectorf goal_normal=vectorf(zero));
|
|
virtual vectorf GetLimbEndPos(int limbid);
|
|
|
|
virtual void AddImpact(int partid, vectorf point,vectorf impact);
|
|
virtual int TranslatePartIdToDeadBody(int partid);
|
|
|
|
virtual bool IsAnimStopped();
|
|
|
|
virtual vectorf GetOffset();
|
|
virtual void SetOffset(vectorf offset);
|
|
|
|
// Spawn decal on the character
|
|
virtual void CreateDecal(CryEngineDecalInfo& Decal);
|
|
|
|
//! cleans up all decals in this character
|
|
virtual void ClearDecals();
|
|
|
|
|
|
private:
|
|
CryCharBody_AutoPtr m_pCryCharBody;
|
|
CryModelState *m_pModelState;
|
|
|
|
protected:
|
|
// the time of the last animation update call.
|
|
// This is the time returned by ITimer::GetCurrTime()
|
|
// If it's <=0, it means that update was never called
|
|
float m_fLastAnimUpdateTime;
|
|
|
|
// This is the scale factor that affects the animation speed of the character.
|
|
// All the animations are played with the constant real-time speed multiplied by this factor.
|
|
// So, 0 means still animations (stuck at some frame), 1 - normal, 2 - twice as fast, 0.5 - twice slower than normal.
|
|
float m_fAnimSpeedScale;
|
|
|
|
|
|
char m_sShaderTemplateName[2][64];
|
|
unsigned m_nShaderTemplateFlags;
|
|
|
|
|
|
// m_matTranRotMatrix is implemented in a dangerous way - this should be changed
|
|
|
|
Matrix44 m_matTranRotMatrix; //!< this matrix is updated during rendering and only valid right after rendering
|
|
|
|
// the animation currently being played
|
|
char m_sCurAnimation[32];
|
|
|
|
Vec3d m_v3pvSpitFirePos, m_v3pvSpitFirePosTranslated;
|
|
|
|
//bool m_bFirstUpdate; // prevent big fFrameTime at editor startup
|
|
|
|
CLeafBuffer * GetLeafBuffer();
|
|
// Matrix m_matAttachedObjectMatrix;
|
|
|
|
// checks for possible memory corruptions in this object and its children
|
|
void SelfValidate ()const;
|
|
public:
|
|
virtual Vec3d GetTPVWeaponHelper(const char * szHelperName, ObjectBindingHandle hInfo);
|
|
virtual bool GetTPVWeaponHelperMatrix(const char * szHelperName, ObjectBindingHandle nHandle, Matrix44& matOut);
|
|
//! Returns position of specified helper ( exported into cgf file )
|
|
//! Actually returns the given bone's position
|
|
//! Default implementation: 000
|
|
virtual Vec3d GetHelperPos(const char * szHelperName);
|
|
//! Returns the matrix of the specified helper ( exported into cgf file )
|
|
//! Actually returns the given bone's matrix
|
|
virtual const Matrix44 * GetHelperMatrixByName(const char * szHelperName);
|
|
|
|
virtual void SetTwiningMode(AnimTwinMode eTwinMode);
|
|
virtual int GetDamageTableValue(int nId);
|
|
|
|
// int nDynLightMask= RendParams.nDLightMask;
|
|
// int nTemplID = RendParams.nShaderTemplate;
|
|
void DrawBoundObjects(const SRendParams & rRendParams, Matrix44 &inmatTranRotMatrix, int nLOD);
|
|
|
|
virtual bool IsCharacterActive();
|
|
|
|
// notifies the renderer that the character will soon be rendered
|
|
void PreloadResources ( float fDistance, float fTime, int nFlags);
|
|
|
|
// Returns true if this character was created from the file the path refers to.
|
|
// If this is true, then there's no need to reload the character if you need to change its model to this one.
|
|
virtual bool IsModelFileEqual (const char* szFileName);
|
|
|
|
void ValidateBoundObjects();
|
|
|
|
//! Sets up particle spawning. After this funtion is called, every subsequenc frame,
|
|
//! During the character deformation, particles will be spawned in the given characteristics.
|
|
//! The returned handle is to be used to stop particle spawning
|
|
//! -1 means invalid handle value (couldn't add the particle spawn task, or not implemented)
|
|
virtual int AddParticleEmitter(ParticleParams& rParticleInfo, const CryParticleSpawnInfo& rSpawnInfo);
|
|
|
|
//! Stops particle spawning started with StartParticleSpawn that returned the parameter
|
|
//! Returns true if the particle spawn was stopped, or false if the handle is invalid
|
|
//! -1 means remove all particle emitters
|
|
virtual bool RemoveParticleEmitter (int nHandle);
|
|
|
|
//! Sets the character scale relative to the model
|
|
virtual void SetScale (const Vec3d& vScale);
|
|
|
|
void GetMemoryUsage(ICrySizer* pSizer)const;
|
|
// adds a submesh, returns handle to it which can be used to delete the submesh
|
|
// submesh is created either visible or invisible
|
|
// submesh creation/destruction is heavy operations, so the clients must use they rarely,
|
|
// and set visible/invisible when they need to turn them on/off
|
|
// But creating many submeshes is memory-consuming so the number of them must be kept low at all times
|
|
ICryCharSubmesh* NewSubmesh (ICryCharModel* pModel, bool bVisible = false);
|
|
|
|
// adds submesh to the specified slot; replaces submesh if there's some there
|
|
ICryCharSubmesh* NewSubmesh (unsigned nSlot, ICryCharModel* pModel, bool bVisible = false);
|
|
|
|
// removes submesh from the character
|
|
void RemoveSubmesh (ICryCharSubmesh* pSubmesh);
|
|
void RemoveSubmesh (unsigned nSlot);
|
|
|
|
// enumeration of submeshes
|
|
size_t NumSubmeshes();
|
|
|
|
ICryCharSubmesh* GetSubmesh(unsigned i);
|
|
|
|
ICryCharFxTrail* NewFxTrail (unsigned nSlot, const struct CryCharFxTrailParams&);
|
|
void RemoveFxTrail(unsigned nSlot);
|
|
|
|
protected:
|
|
CryCharManager* m_pManager;
|
|
|
|
bool m_bEnableStartAnimation;
|
|
|
|
#ifdef _DEBUG
|
|
// the last frame angles (orientation for this instance)
|
|
Vec3d m_vLastAngles, m_vLastPos;
|
|
#endif
|
|
};
|
|
|
|
|
|
#endif |