Files
GTASource/game/task/Physics/TaskNMPose.h
T
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

200 lines
6.0 KiB
C++

// Filename : TaskNMPose.h
// Description: Natural Motion pose class (FSM version)
#ifndef INC_TASKNMPOSE_H_
#define INC_TASKNMPOSE_H_
// --- Include Files ------------------------------------------------------------
// Game headers
#include "Task/System/Task.h"
#include "Task\System\TaskTypes.h"
#include "Task/Physics/TaskNM.h"
#include "Task/Physics/TaskNMRelax.h"
#include "Network/General/NetworkUtil.h"
// ------------------------------------------------------------------------------
//
// Task info for CTaskNMPose
//
class CClonedNMPoseInfo : public CSerialisedFSMTaskInfo
{
public:
CClonedNMPoseInfo(const fwMvClipSetId &clipSetId, const fwMvClipId &clipId, float fStiffness, float fStiffnessDamping, int iStiffnessMask, bool bPlayClip);
CClonedNMPoseInfo();
~CClonedNMPoseInfo() {}
virtual s32 GetTaskInfoType( ) const {return INFO_TYPE_NM_POSE;}
// the clone task is created by the CTaskNMControl clone task
virtual bool AutoCreateCloneTask(CPed* UNUSED_PARAM(pPed)) { return false; }
virtual CTaskFSMClone *CreateCloneFSMTask();
void Serialise(CSyncDataBase& serialiser)
{
CSerialisedFSMTaskInfo::Serialise(serialiser);
bool bPlayClip = m_bPlayClip;
bool bHasClip = m_bHasClip;
bool bHasStiffness = m_bHasStiffness;
bool bHasDamping = m_bHasDamping;
SERIALISE_BOOL(serialiser, bPlayClip , "Play clip");
SERIALISE_BOOL(serialiser, bHasClip);
if (bHasClip || serialiser.GetIsMaximumSizeSerialiser())
{
SERIALISE_ANIMATION_CLIP(serialiser, m_clipSetId, m_clipId, "Animation");
}
SERIALISE_BOOL(serialiser, bHasStiffness);
if (bHasStiffness || serialiser.GetIsMaximumSizeSerialiser())
{
SERIALISE_PACKED_UNSIGNED_FLOAT(serialiser, m_fStiffness, 30.0f, SIZEOF_STIFFNESS, "Stiffness");
}
SERIALISE_BOOL(serialiser, bHasDamping);
if (bHasDamping || serialiser.GetIsMaximumSizeSerialiser())
{
SERIALISE_PACKED_UNSIGNED_FLOAT(serialiser, m_fStiffnessDamping, 30.0f, SIZEOF_STIFFNESS_DAMPING, "Damping");
}
if (bHasStiffness || bHasDamping || serialiser.GetIsMaximumSizeSerialiser())
{
u32 stiffnessMask = (u32) m_iStiffnessMask;
SERIALISE_UNSIGNED(serialiser, stiffnessMask, SIZEOF_STIFFNESS_MASK, "Stiffness mask");
m_iStiffnessMask = (u8) stiffnessMask;
}
m_bPlayClip = bPlayClip;
m_bHasClip = bHasClip;
m_bHasStiffness = bHasStiffness;
m_bHasDamping = bHasDamping;
}
private:
CClonedNMPoseInfo(const CClonedNMPoseInfo &);
CClonedNMPoseInfo &operator=(const CClonedNMPoseInfo &);
static const unsigned int SIZEOF_STIFFNESS = 16;
static const unsigned int SIZEOF_STIFFNESS_DAMPING = 16;
static const unsigned int SIZEOF_STIFFNESS_MASK = 8;
fwMvClipSetId m_clipSetId;
fwMvClipId m_clipId;
float m_fStiffness;
float m_fStiffnessDamping;
u8 m_iStiffnessMask;
bool m_bPlayClip : 1;
bool m_bHasClip : 1;
bool m_bHasStiffness : 1;
bool m_bHasDamping : 1;
};
//
// Task CTaskNMPose
//
#define NM_POSE_NUM_BODY_PARTS (8)
#define NM_POSE_DEFAULT_STIFFNESS (12.0f)
#define NM_POSE_DEFAULT_DAMPING (1.0f)
class CTaskNMPose : public CTaskNMBehaviour
{
public:
// Used for setting specific stiffness and damping per body part
enum ePoseBodyMask
{
CLAVICLES = BIT(0),
LEFT_ARM = BIT(1),
RIGHT_ARM = BIT(2),
SPINE = BIT(3),
HEAD = BIT(4), // inc. Neck
WRISTS = BIT(5),
LEFT_LEG = BIT(6),
RIGHT_LEG = BIT(7),
FULL_BODY = CLAVICLES | LEFT_ARM | RIGHT_ARM | SPINE | HEAD | WRISTS | LEFT_LEG | RIGHT_LEG
};
CTaskNMPose(u32 nMinTime, u32 nMaxTime, const fwMvClipSetId &clipSetId = CLIP_SET_ID_INVALID, const fwMvClipId &clipId = CLIP_ID_INVALID, float fStiffness = NM_POSE_DEFAULT_STIFFNESS, float fStiffnessDamping = NM_POSE_DEFAULT_DAMPING, int iStiffnessMask = FULL_BODY, bool bPlayClip = true);
~CTaskNMPose();
float GetClipPhase() const { return m_fPhase; }
void SetClipPhase(float fPhase){m_fPhase = fPhase; }
bool HasPlayedFullClipPhase() { return m_bHasPlayedFullPhase; }
// Specify an clip for the NM pose to drive to.
// If the clip id specified is CLIP_ID_INVALID then the ragdoll is driven to a skeleton generated by the clip blender
fwMvClipId GetClipId() const { return m_clipId; }
void SetClipId(const fwMvClipId &clipId) { m_clipId = clipId; }
fwMvClipSetId GetClipSet() const { return m_clipSetId; }
void SetClipSetId(const fwMvClipSetId &clipSetId) { m_clipSetId = clipSetId; }
// Functions to set the stiffness and damping arrays.
// Only the values in the array corresponding to the ones
// int the poseBodyMask are set
// This allows stiffness and damping to be set per body part
/** Damping is in range 0-3 .
* Default is 1
*/
void SetDamping(float fDamping, int poseBodyMask);
/** Stiffness is in range 6..16
* Default is 12
*/
void SetStiffness(float fStiffness, int poseBodyMask);
////////////////////////
// CTaskSimple functions
#if !__FINAL
virtual atString GetName() const {return atString("NMPose");}
#endif
virtual aiTask* Copy() const;
virtual int GetTaskTypeInternal() const {return CTaskTypes::TASK_NM_POSE;}
///////////////////////////
// CTaskNMBehaviour functions
protected:
virtual void StartBehaviour(CPed* pPed);
virtual void ControlBehaviour(CPed* pPed);
virtual bool FinishConditions(CPed* pPed);
////////////////////////
// CTaskFSMClone functions
virtual CTaskInfo* CreateQueriableState() const
{
return rage_new CClonedNMPoseInfo(m_clipSetId, m_clipId, m_fStiffness, m_fDamping, m_mask, m_bPlayClip);
}
//////////////////////////
// Local functions and data
private:
void PostNMMessagesForStiffness(CPed* pPed);
const char* GetNMMaskStrFromBodyPartIndex(int iBodyPartIndex);
fwMvClipId m_clipId;
fwMvClipSetId m_clipSetId;
float m_fPhase;
bool m_bPlayClip;
bool m_bHasPlayedFullPhase;
bool m_bStiffnessValuesChanged;
float m_fStiffness;
float m_fDamping;
u32 m_mask;
// For specifying stiffness and damping per body part
// These are ordered in same sequence as the ePoseBodyMask
float m_fBodyPartStiffness[NM_POSE_NUM_BODY_PARTS];
float m_fBodyPartDamping[NM_POSE_NUM_BODY_PARTS];
};
#endif // ! INC_TASKNMPOSE_H_