Files
GTASource/game/cloth/ClothPendants.h
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

195 lines
4.3 KiB
C++

#ifndef CLOTH_PENDANTS_H
#define CLOTH_PENDANTS_H
class CEntity;
#include "Debug/Debug.h"
#include "Scene/RegdRefTypes.h"
#include "vector/vector3.h"
#define MAX_NUM_CLOTH_PENDANTS 4
class CClothPendantMethod
{
public:
enum
{
CLOTH_PENDANT_METHOD_ROTATOR=0,
CLOTH_PENDANT_METHOD_ENTITY_OFFSET
};
CClothPendantMethod(){}
virtual ~CClothPendantMethod(){}
virtual int GetType() const=0;
//Update and recompute the pendant position.
virtual void Update(const float dt, Vector3& vPendantPos)=0;
//Transform from body space to world space.
virtual void Transform(const Matrix34& mat)=0;
protected:
};
class CClothPendantMethodRotator : public CClothPendantMethod
{
public:
CClothPendantMethodRotator(const Vector3& vMotionCentre, const float fRadius, const float fAngularSpeed)
: CClothPendantMethod(),
m_vMotionCentre(vMotionCentre),
m_fRadius(fRadius),
m_fAngularSpeed(fAngularSpeed),
m_fAngle(0)
{
}
CClothPendantMethodRotator(const CClothPendantMethodRotator& src)
: m_vMotionCentre(src.m_vMotionCentre),
m_fRadius(src.m_fRadius),
m_fAngularSpeed(src.m_fAngularSpeed),
m_fAngle(0)
{
}
~CClothPendantMethodRotator()
{
}
CClothPendantMethodRotator& operator=(const CClothPendantMethodRotator& src)
{
m_vMotionCentre=src.m_vMotionCentre;
m_fRadius=src.m_fRadius;
m_fAngularSpeed=src.m_fAngularSpeed;
m_fAngle=0;
return *this;
}
virtual int GetType() const {return CLOTH_PENDANT_METHOD_ROTATOR;}
//Update and recompute the pendant position.
virtual void Update(const float dt, Vector3& vPendantPosition);
//Transform from body space to world space.
virtual void Transform(const Matrix34& mat);
private:
Vector3 m_vMotionCentre;
float m_fRadius;
float m_fAngularSpeed;
//Integrated angle.
float m_fAngle;
};
class CClothPendantMethodEntityOffset : public CClothPendantMethod
{
public:
CClothPendantMethodEntityOffset(CEntity* pEntity, const Vector3& vOffset);
CClothPendantMethodEntityOffset(const CClothPendantMethodEntityOffset& src);
~CClothPendantMethodEntityOffset();
CClothPendantMethodEntityOffset& operator=(const CClothPendantMethodEntityOffset& src);
virtual int GetType() const {return CLOTH_PENDANT_METHOD_ENTITY_OFFSET;}
//Update and recompute the pendant position.
virtual void Update(const float dt, Vector3& vPendantPos);
//Transform from body space to world space.
virtual void Transform(const Matrix34& mat);
private:
RegdEnt m_pEntity;
Vector3 m_vOffset;
Vector3 m_vPosition;
};
class CClothPendants
{
public:
friend class CCloth;
void Init()
{
m_iNumPendants=0;
m_paiParticleIds=0;
for(int i=0;i<MAX_NUM_CLOTH_PENDANTS;i++)
{
m_apMethods[i]=0;
}
}
void Shutdown()
{
m_iNumPendants=0;
m_paiParticleIds=0;
for(int i=0;i<MAX_NUM_CLOTH_PENDANTS;i++)
{
if(m_apMethods[i]) delete m_apMethods[i];
m_apMethods[i]=0;
}
}
//Initialise from archetype data.
void SetArchetypeData(const class CClothArchetype& clothArchetype);
//Transform from body space to world space.
void Transform(const Matrix34& mat)
{
for(int i=0;i<m_iNumPendants;i++)
{
Assertf(m_apMethods[i], "Null ptr to pendant method");
if(m_apMethods[i])
{
m_apMethods[i]->Transform(mat);
}
}
}
//Update all pendants and store pendant positions in an array.
void Update(const float dt, Vector3* pavPendantPositions, const int ASSERT_ONLY(iNumPendantPositions))
{
Assertf(m_iNumPendants<iNumPendantPositions, "Array of pendant positions needs to be bigger");
for(int i=0;i<m_iNumPendants;i++)
{
if(m_apMethods[i])
{
m_apMethods[i]->Update(dt,pavPendantPositions[i]);
}
}
}
//Get the number of pendants.
int GetNumPendants() const
{
return m_iNumPendants;
}
//Get the particle index of a pendant.
int GetParticleId(const int index) const
{
Assertf(index<m_iNumPendants, "Out of bounds");
Assertf(m_paiParticleIds, "Null ptr to array of particle ids");
return m_paiParticleIds[index];
}
private:
CClothPendants()
{
Init();
}
~CClothPendants()
{
Shutdown();
}
//Number of pendants.
int m_iNumPendants;
//Pointer to array of particle indices (one for each pendant).
//Particle indices belong to the archetype.
const int* m_paiParticleIds;
//Array of pointers to pendant methods (one method for each pendant).
CClothPendantMethod* m_apMethods[MAX_NUM_CLOTH_PENDANTS];
};
#endif //CLOTH_PENDANTS_H