Changeset View
Changeset View
Standalone View
Standalone View
source/graphics/Model.h
/* Copyright (C) 2021 Wildfire Games. | /* Copyright (C) 2022 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
Show All 13 Lines | |||||
#define INCLUDED_MODEL | #define INCLUDED_MODEL | ||||
#include "graphics/Material.h" | #include "graphics/Material.h" | ||||
#include "graphics/MeshManager.h" | #include "graphics/MeshManager.h" | ||||
#include "graphics/ModelAbstract.h" | #include "graphics/ModelAbstract.h" | ||||
#include <vector> | #include <vector> | ||||
struct SPropPoint; | |||||
class CObjectEntry; | |||||
class CSkeletonAnim; | class CSkeletonAnim; | ||||
class CSkeletonAnimDef; | class CSkeletonAnimDef; | ||||
class CSkeletonAnimManager; | class CSkeletonAnimManager; | ||||
class CSimulation2; | class CSimulation2; | ||||
#define MODELFLAG_CASTSHADOWS (1<<0) | #define MODELFLAG_CASTSHADOWS (1<<0) | ||||
#define MODELFLAG_NOLOOPANIMATION (1<<1) | #define MODELFLAG_NOLOOPANIMATION (1<<1) | ||||
#define MODELFLAG_SILHOUETTE_DISPLAY (1<<2) | #define MODELFLAG_SILHOUETTE_DISPLAY (1<<2) | ||||
#define MODELFLAG_SILHOUETTE_OCCLUDER (1<<3) | #define MODELFLAG_SILHOUETTE_OCCLUDER (1<<3) | ||||
#define MODELFLAG_IGNORE_LOS (1<<4) | #define MODELFLAG_IGNORE_LOS (1<<4) | ||||
#define MODELFLAG_FLOATONWATER (1<<5) | #define MODELFLAG_FLOATONWATER (1<<5) | ||||
/////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////// | ||||
// CModel: basically, a mesh object - holds the texturing and skinning | // CModel: basically, a mesh object - holds the texturing and skinning | ||||
// information for a model in game | // information for a model in game | ||||
class CModel : public CModelAbstract | class CModel : public CModelAbstract | ||||
{ | { | ||||
NONCOPYABLE(CModel); | NONCOPYABLE(CModel); | ||||
public: | |||||
struct Prop | |||||
{ | |||||
Prop() : m_MinHeight(0.f), m_MaxHeight(0.f), m_Point(0), m_Model(0), m_ObjectEntry(0), m_Hidden(false), m_Selectable(true) {} | |||||
float m_MinHeight; | |||||
float m_MaxHeight; | |||||
/** | |||||
* Location of the prop point within its parent model, relative to either a bone in the parent model or to the | |||||
* parent model's origin. See the documentation for @ref SPropPoint for more details. | |||||
* @see SPropPoint | |||||
*/ | |||||
const SPropPoint* m_Point; | |||||
/** | |||||
* Pointer to the model associated with this prop. Note that the transform matrix held by this model is the full object-to-world | |||||
* space transform, taking into account all parent model positioning (see @ref CModel::ValidatePosition for positioning logic). | |||||
* @see CModel::ValidatePosition | |||||
*/ | |||||
CModelAbstract* m_Model; | |||||
CObjectEntry* m_ObjectEntry; | |||||
bool m_Hidden; ///< Should this prop be temporarily removed from rendering? | |||||
bool m_Selectable; /// < should this prop count in the selection size? | |||||
}; | |||||
public: | public: | ||||
// constructor | // constructor | ||||
CModel(CSkeletonAnimManager& skeletonAnimManager, CSimulation2& simulation); | CModel(CSkeletonAnimManager& skeletonAnimManager, CSimulation2& simulation); | ||||
// destructor | // destructor | ||||
~CModel(); | ~CModel(); | ||||
/// Dynamic cast | /// Dynamic cast | ||||
Show All 28 Lines | public: | ||||
// set the animation state to be the same as from another; both models should | // set the animation state to be the same as from another; both models should | ||||
// be compatible types (same type of skeleton) | // be compatible types (same type of skeleton) | ||||
void CopyAnimationFrom(CModel* source); | void CopyAnimationFrom(CModel* source); | ||||
// set object flags | // set object flags | ||||
void SetFlags(int flags) { m_Flags=flags; } | void SetFlags(int flags) { m_Flags=flags; } | ||||
// get object flags | // get object flags | ||||
int GetFlags() const { return m_Flags; } | int GetFlags() const { return m_Flags; } | ||||
// add object flags, recursively through props | // Add object flags, recursively through props. | ||||
// TODO: this stops if it encounters a non-CModel prop. | |||||
void AddFlagsRec(int flags); | void AddFlagsRec(int flags); | ||||
// remove shadow casting and receiving, recursively through props | // Remove shadow casting and receiving, recursively through props | ||||
// TODO: replace with more generic shader define + flags setting | // TODO: replace with more generic shader define + flags setting. | ||||
// TODO: this stops if it encounters a non-CModel prop. | |||||
void RemoveShadowsRec(); | void RemoveShadowsRec(); | ||||
// recurse down tree setting dirty bits | |||||
virtual void SetDirtyRec(int dirtyflags) { | |||||
SetDirty(dirtyflags); | |||||
for (size_t i=0;i<m_Props.size();i++) { | |||||
m_Props[i].m_Model->SetDirtyRec(dirtyflags); | |||||
} | |||||
} | |||||
virtual void SetTerrainDirty(ssize_t i0, ssize_t j0, ssize_t i1, ssize_t j1) | |||||
{ | |||||
for (size_t i = 0; i < m_Props.size(); ++i) | |||||
m_Props[i].m_Model->SetTerrainDirty(i0, j0, i1, j1); | |||||
} | |||||
virtual void SetEntityVariable(const std::string& name, float value) | |||||
{ | |||||
for (size_t i = 0; i < m_Props.size(); ++i) | |||||
m_Props[i].m_Model->SetEntityVariable(name, value); | |||||
} | |||||
// --- WORLD/OBJECT SPACE BOUNDS ----------------------------------------------------------------- | // --- WORLD/OBJECT SPACE BOUNDS ----------------------------------------------------------------- | ||||
/// Overridden to calculate both the world-space and object-space bounds of this model, and stores the result in | /// Overridden to calculate both the world-space and object-space bounds of this model, and stores the result in | ||||
/// m_Bounds and m_ObjectBounds, respectively. | /// m_Bounds and m_ObjectBounds, respectively. | ||||
virtual void CalcBounds(); | virtual void CalcBounds(); | ||||
/// Returns the object-space bounds for this model, excluding its children. | |||||
const CBoundingBoxAligned& GetObjectBounds() | |||||
{ | |||||
RecalculateBoundsIfNecessary(); // recalculates both object-space and world-space bounds if necessary | |||||
return m_ObjectBounds; | |||||
} | |||||
virtual const CBoundingBoxAligned GetWorldBoundsRec(); // reimplemented here | |||||
/// Auxiliary method; calculates object space bounds of this model, based solely on vertex positions, and stores | /// Auxiliary method; calculates object space bounds of this model, based solely on vertex positions, and stores | ||||
/// the result in m_ObjectBounds. Called by CalcBounds (instead of CalcAnimatedObjectBounds) if it has been determined | /// the result in m_ObjectBounds. Called by CalcBounds (instead of CalcAnimatedObjectBounds) if it has been determined | ||||
/// that the object-space bounds are static. | /// that the object-space bounds are static. | ||||
void CalcStaticObjectBounds(); | void CalcStaticObjectBounds(); | ||||
/// Auxiliary method; calculate object-space bounds encompassing all vertex positions for given animation, and stores | /// Auxiliary method; calculate object-space bounds encompassing all vertex positions for given animation, and stores | ||||
/// the result in m_ObjectBounds. Called by CalcBounds (instead of CalcStaticBounds) if it has been determined that the | /// the result in m_ObjectBounds. Called by CalcBounds (instead of CalcStaticBounds) if it has been determined that the | ||||
/// object-space bounds need to take animations into account. | /// object-space bounds need to take animations into account. | ||||
void CalcAnimatedObjectBounds(CSkeletonAnimDef* anim,CBoundingBoxAligned& result); | void CalcAnimatedObjectBounds(CSkeletonAnimDef* anim,CBoundingBoxAligned& result); | ||||
// --- SELECTION BOX/BOUNDS ---------------------------------------------------------------------- | |||||
/// Reimplemented here since proper models should participate in selection boxes. | |||||
virtual const CBoundingBoxAligned GetObjectSelectionBoundsRec(); | |||||
/** | /** | ||||
* Set transform of this object. | * Set transform of this object. | ||||
* | * | ||||
* @note In order to ensure that all child props are updated properly, | * @note In order to ensure that all child props are updated properly, | ||||
* you must call ValidatePosition(). | * you must call ValidatePosition(). | ||||
*/ | */ | ||||
virtual void SetTransform(const CMatrix3D& transform); | virtual void SetTransform(const CMatrix3D& transform); | ||||
Show All 20 Lines | public: | ||||
* @param actionpos offset of 'action' event, in range [0, 1] | * @param actionpos offset of 'action' event, in range [0, 1] | ||||
* @param actionpos2 offset of 'action2' event, in range [0, 1] | * @param actionpos2 offset of 'action2' event, in range [0, 1] | ||||
* @param sound offset of 'sound' event, in range [0, 1] | * @param sound offset of 'sound' event, in range [0, 1] | ||||
* @return new animation, or NULL on error | * @return new animation, or NULL on error | ||||
*/ | */ | ||||
CSkeletonAnim* BuildAnimation(const VfsPath& pathname, const CStr& name, const CStr& ID, int frequency, float speed, float actionpos, float actionpos2, float soundpos); | CSkeletonAnim* BuildAnimation(const VfsPath& pathname, const CStr& name, const CStr& ID, int frequency, float speed, float actionpos, float actionpos2, float soundpos); | ||||
/** | /** | ||||
* Add a prop to the model on the given point. | |||||
*/ | |||||
void AddProp(const SPropPoint* point, CModelAbstract* model, CObjectEntry* objectentry, float minHeight = 0.f, float maxHeight = 0.f, bool selectable = true); | |||||
/** | |||||
* Add a prop to the model on the given point, and treat it as the ammo prop. | * Add a prop to the model on the given point, and treat it as the ammo prop. | ||||
* The prop will be hidden by default. | * The prop will be hidden by default. | ||||
*/ | */ | ||||
void AddAmmoProp(const SPropPoint* point, CModelAbstract* model, CObjectEntry* objectentry); | void AddAmmoProp(const SPropPoint* point, CModelAbstract* model, CObjectEntry* objectentry); | ||||
/** | /** | ||||
* Show the ammo prop (if any), and hide any other props on that prop point. | * Show the ammo prop (if any), and hide any other props on that prop point. | ||||
*/ | */ | ||||
void ShowAmmoProp(); | void ShowAmmoProp(); | ||||
/** | /** | ||||
* Hide the ammo prop (if any), and show any other props on that prop point. | * Hide the ammo prop (if any), and show any other props on that prop point. | ||||
*/ | */ | ||||
void HideAmmoProp(); | void HideAmmoProp(); | ||||
/** | /** | ||||
* Find the first prop used for ammo, by this model or its own props. | * Find the first prop used for ammo, by this model or its own props. | ||||
*/ | */ | ||||
CModelAbstract* FindFirstAmmoProp(); | CModelAbstract* FindFirstAmmoProp(); | ||||
// 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 | // return a clone of this model | ||||
virtual CModelAbstract* Clone() const; | virtual CModelAbstract* Clone() const; | ||||
/** | /** | ||||
* Ensure that both the transformation and the bone | * Ensure that both the transformation and the bone | ||||
* matrices are correct for this model and all its props. | * matrices are correct for this model. | ||||
*/ | */ | ||||
virtual void ValidatePosition(); | virtual void ValidatePosition(); | ||||
/** | |||||
* Mark this model's position and bone matrices, | |||||
* and all props' positions as invalid. | |||||
*/ | |||||
virtual void InvalidatePosition(); | |||||
private: | private: | ||||
// delete anything allocated by the model | // delete anything allocated by the model | ||||
void ReleaseData(); | void ReleaseData(); | ||||
// Needed for terrain aligned props | // Needed for terrain aligned props | ||||
CSimulation2& m_Simulation; | CSimulation2& m_Simulation; | ||||
// object flags | // object flags | ||||
int m_Flags; | int m_Flags; | ||||
// model's material | // model's material | ||||
CMaterial m_Material; | CMaterial m_Material; | ||||
// pointer to the model's raw 3d data | // pointer to the model's raw 3d data | ||||
CModelDefPtr m_pModelDef; | 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. | |||||
CBoundingBoxAligned m_ObjectBounds; | |||||
// animation currently playing on this model, if any | // animation currently playing on this model, if any | ||||
CSkeletonAnim* m_Anim; | CSkeletonAnim* m_Anim; | ||||
// time (in MS) into the current animation | // time (in MS) into the current animation | ||||
float m_AnimTime; | float m_AnimTime; | ||||
/** | /** | ||||
* Current state of all bones on this model; null if associated modeldef isn't skeletal. | * Current state of all bones on this model; null if associated modeldef isn't skeletal. | ||||
* Props may attach to these bones by means of the SPropPoint::m_BoneIndex field; in this case their | |||||
* transformation matrix held is relative to the bone transformation (see @ref SPropPoint and | |||||
* @ref CModel::ValidatePosition). | |||||
* | |||||
* @see SPropPoint | |||||
*/ | */ | ||||
CMatrix3D* m_BoneMatrices; | CMatrix3D* m_BoneMatrices; | ||||
// list of current props on model | |||||
std::vector<Prop> m_Props; | |||||
/** | /** | ||||
* The prop point to which the ammo prop is attached, or NULL if none | * The prop point to which the ammo prop is attached, or NULL if none | ||||
*/ | */ | ||||
const SPropPoint* m_AmmoPropPoint; | const SPropPoint* m_AmmoPropPoint; | ||||
/** | /** | ||||
* If m_AmmoPropPoint is not NULL, then the index in m_Props of the ammo prop | * If m_AmmoPropPoint is not NULL, then the index in m_Props of the ammo prop | ||||
*/ | */ | ||||
size_t m_AmmoLoadedProp; | size_t m_AmmoLoadedProp; | ||||
// manager object which can load animations for us | // manager object which can load animations for us | ||||
CSkeletonAnimManager& m_SkeletonAnimManager; | CSkeletonAnimManager& m_SkeletonAnimManager; | ||||
}; | }; | ||||
#endif | #endif |
Wildfire Games · Phabricator