forked from 0ad/0ad
Ykkrosh
fa45d214b3
Moved COLLADA-loading code into separate class, since it now handles both PMD and PSA. Desingletonised CSkeletonAnimManager, moved into CGameView. Made Atlas load its icons with buffered IO, for possible efficiency. This was SVN commit r4934.
211 lines
6.3 KiB
C++
211 lines
6.3 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Name: Model.h
|
|
// Author: Rich Cross
|
|
// Contact: rich@wildfiregames.com
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef _MODEL_H
|
|
#define _MODEL_H
|
|
|
|
#include <vector>
|
|
|
|
#include "Texture.h"
|
|
#include "MeshManager.h"
|
|
#include "RenderableObject.h"
|
|
#include "Material.h"
|
|
#include "ps/Overlay.h"
|
|
struct SPropPoint;
|
|
class CObjectEntry;
|
|
class CSkeletonAnim;
|
|
class CSkeletonAnimDef;
|
|
class CSkeletonAnimManager;
|
|
|
|
#define MODELFLAG_CASTSHADOWS (1<<0)
|
|
#define MODELFLAG_NOLOOPANIMATION (1<<1)
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CModel: basically, a mesh object - holds the texturing and skinning
|
|
// information for a model in game
|
|
class CModel : public CRenderableObject, boost::noncopyable
|
|
{
|
|
friend class CUnitAnimation;
|
|
// HACK - we should probably move the rest of this class's animation state
|
|
// into the animation class, then it wouldn't need friend access
|
|
|
|
public:
|
|
struct Prop {
|
|
Prop() : m_Point(0), m_Model(0), m_ObjectEntry(0) {}
|
|
|
|
SPropPoint* m_Point;
|
|
CModel* m_Model;
|
|
CObjectEntry* m_ObjectEntry;
|
|
};
|
|
|
|
public:
|
|
// constructor
|
|
CModel(CSkeletonAnimManager& skeletonAnimManager);
|
|
// destructor
|
|
~CModel();
|
|
|
|
// setup model from given geometry
|
|
bool InitModel(CModelDefPtr modeldef);
|
|
// calculate the world space bounds of this model
|
|
void CalcBounds();
|
|
// update this model's state; 'time' is the time since the last update, in MS
|
|
void Update(float time);
|
|
// returns true if Update(time) will require a new animation (due to the
|
|
// current one ending)
|
|
bool NeedsNewAnim(float time) const;
|
|
|
|
// get the model's geometry data
|
|
CModelDefPtr GetModelDef() { return m_pModelDef; }
|
|
|
|
// set the model's texture
|
|
void SetTexture(const CTexture& tex) { m_Texture=tex; }
|
|
// set the model's material
|
|
void SetMaterial(const CMaterial &material);
|
|
// set the model's player ID, recursively through props. CUnit::SetPlayerID
|
|
// should normally be used instead.
|
|
void SetPlayerID(int id);
|
|
// set the model's player colour
|
|
void SetPlayerColor(CColor& colour);
|
|
// set the models mod color
|
|
void SetShadingColor(CColor& colour);
|
|
// get the model's texture
|
|
CTexture* GetTexture() { return &m_Texture; }
|
|
// get the models material
|
|
CMaterial &GetMaterial() { return m_Material; }
|
|
// get the model's texture
|
|
CColor GetShadingColor() { return m_ShadingColor; }
|
|
|
|
// set the given animation as the current animation on this model
|
|
bool SetAnimation(CSkeletonAnim* anim, bool once = false, float speed = 1000.0f, CSkeletonAnim* next = NULL);
|
|
|
|
// get the currently playing animation, if any
|
|
CSkeletonAnim* GetAnimation() const { return m_Anim; }
|
|
|
|
// set the animation state to be the same as from another; both models should
|
|
// be compatible types (same type of skeleton)
|
|
void CopyAnimationFrom(CModel* source);
|
|
|
|
// set object flags
|
|
void SetFlags(u32 flags) { m_Flags=flags; }
|
|
// get object flags
|
|
u32 GetFlags() const { return m_Flags; }
|
|
|
|
// recurse down tree setting dirty bits
|
|
void SetDirtyRec(u32 dirtyflags) {
|
|
SetDirty(dirtyflags);
|
|
for (size_t i=0;i<m_Props.size();i++) {
|
|
m_Props[i].m_Model->SetDirtyRec(dirtyflags);
|
|
}
|
|
}
|
|
|
|
// calculate object space bounds of this model, based solely on vertex positions
|
|
void CalcObjectBounds();
|
|
// calculate bounds encompassing all vertex positions for given animation
|
|
void CalcAnimatedObjectBound(CSkeletonAnimDef* anim,CBound& result);
|
|
|
|
/**
|
|
* Set transform of this object.
|
|
*
|
|
* @note In order to ensure that all child props are updated properly,
|
|
* you must call ValidatePosition().
|
|
*/
|
|
void SetTransform(const CMatrix3D& transform);
|
|
|
|
/**
|
|
* Return whether this is a skinned/skeletal model. If it is, Get*BoneMatrices()
|
|
* will return valid non-NULL arrays.
|
|
*/
|
|
bool IsSkinned() { return (m_BoneMatrices != NULL); }
|
|
|
|
// return the models bone matrices
|
|
const CMatrix3D* GetAnimatedBoneMatrices() {
|
|
debug_assert(m_PositionValid);
|
|
return m_BoneMatrices;
|
|
}
|
|
const CMatrix3D* GetInverseBindBoneMatrices() {
|
|
return m_InverseBindBoneMatrices;
|
|
}
|
|
|
|
// load raw animation frame animation from given file, and build a
|
|
// animation specific to this model
|
|
CSkeletonAnim* BuildAnimation(const char* filename, const char* name, float speed, double actionpos, double actionpos2);
|
|
|
|
// add a prop to the model on the given point
|
|
void AddProp(SPropPoint* point, CModel* model, CObjectEntry* objectentry);
|
|
// remove a prop from the given point
|
|
void RemoveProp(SPropPoint* point);
|
|
// return prop list
|
|
std::vector<Prop>& GetProps() { return m_Props; }
|
|
const std::vector<Prop>& GetProps() const { return m_Props; }
|
|
|
|
// return a clone of this model
|
|
CModel* Clone() const;
|
|
|
|
/**
|
|
* Ensure that both the transformation and the bone
|
|
* matrices are correct for this model and all its props.
|
|
*/
|
|
void ValidatePosition();
|
|
|
|
private:
|
|
// delete anything allocated by the model
|
|
void ReleaseData();
|
|
|
|
/**
|
|
* Mark this model's position and bone matrices,
|
|
* and all props' positions as invalid.
|
|
*/
|
|
void InvalidatePosition();
|
|
|
|
/**
|
|
* If non-null, m_Parent points to the model that we
|
|
* are attached to.
|
|
*/
|
|
CModel* m_Parent;
|
|
|
|
// object flags
|
|
u32 m_Flags;
|
|
// texture used by model
|
|
CTexture m_Texture;
|
|
// model's material
|
|
CMaterial m_Material;
|
|
// pointer to the model's raw 3d data
|
|
CModelDefPtr m_pModelDef;
|
|
// object space bounds of model - accounts for bounds of all possible animations
|
|
// that can play on a model. Not always up-to-date - currently CalcBounds()
|
|
// updates it when necessary.
|
|
CBound m_ObjectBounds;
|
|
// animation currently playing on this model, if any
|
|
CSkeletonAnim* m_Anim;
|
|
// animation to switch back to when the current one finishes
|
|
CSkeletonAnim* m_NextAnim;
|
|
// rate at which the animation should play
|
|
float m_AnimSpeed;
|
|
// time (in MS) into the current animation
|
|
float m_AnimTime;
|
|
// current state of all bones on this model; null if associated modeldef isn't skeletal
|
|
CMatrix3D* m_BoneMatrices;
|
|
// inverse matrices for the bind pose's bones; null if not skeletal
|
|
CMatrix3D* m_InverseBindBoneMatrices;
|
|
// list of current props on model
|
|
std::vector<Prop> m_Props;
|
|
|
|
/**
|
|
* true if both transform and and bone matrices are valid.
|
|
*/
|
|
bool m_PositionValid;
|
|
|
|
// modulating color
|
|
CColor m_ShadingColor;
|
|
|
|
// manager object which can load animations for us
|
|
CSkeletonAnimManager& m_SkeletonAnimManager;
|
|
};
|
|
|
|
#endif
|