1 /* Copyright (C) 2016 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
19 * Mesh object with texture and skinning information
22 #ifndef INCLUDED_MODEL
23 #define INCLUDED_MODEL
27 #include "graphics/Texture.h"
28 #include "graphics/Material.h"
29 #include "graphics/MeshManager.h"
30 #include "graphics/ModelAbstract.h"
35 class CSkeletonAnimDef
;
36 class CSkeletonAnimManager
;
39 #define MODELFLAG_CASTSHADOWS (1<<0)
40 #define MODELFLAG_NOLOOPANIMATION (1<<1)
41 #define MODELFLAG_SILHOUETTE_DISPLAY (1<<2)
42 #define MODELFLAG_SILHOUETTE_OCCLUDER (1<<3)
43 #define MODELFLAG_IGNORE_LOS (1<<4)
45 ///////////////////////////////////////////////////////////////////////////////
46 // CModel: basically, a mesh object - holds the texturing and skinning
47 // information for a model in game
48 class CModel
: public CModelAbstract
55 Prop() : m_MinHeight(0.f
), m_MaxHeight(0.f
), m_Point(0), m_Model(0), m_ObjectEntry(0), m_Hidden(false), m_Selectable(true) {}
61 * Location of the prop point within its parent model, relative to either a bone in the parent model or to the
62 * parent model's origin. See the documentation for @ref SPropPoint for more details.
65 const SPropPoint
* m_Point
;
68 * Pointer to the model associated with this prop. Note that the transform matrix held by this model is the full object-to-world
69 * space transform, taking into account all parent model positioning (see @ref CModel::ValidatePosition for positioning logic).
70 * @see CModel::ValidatePosition
72 CModelAbstract
* m_Model
;
73 CObjectEntry
* m_ObjectEntry
;
75 bool m_Hidden
; ///< Should this prop be temporarily removed from rendering?
76 bool m_Selectable
; /// < should this prop count in the selection size?
81 CModel(CSkeletonAnimManager
& skeletonAnimManager
, CSimulation2
& simulation
);
87 virtual CModel
* ToCModel()
92 // setup model from given geometry
93 bool InitModel(const CModelDefPtr
& modeldef
);
94 // update this model's state; 'time' is the absolute time since the start of the animation, in MS
95 void UpdateTo(float time
);
97 // get the model's geometry data
98 const CModelDefPtr
& GetModelDef() { return m_pModelDef
; }
100 // set the model's material
101 void SetMaterial(const CMaterial
&material
);
102 // set the model's player ID, recursively through props
103 void SetPlayerID(player_id_t id
);
104 // set the models mod color
105 virtual void SetShadingColor(const CColor
& color
);
106 // get the model's material
107 CMaterial
& GetMaterial() { return m_Material
; }
109 // set the given animation as the current animation on this model
110 bool SetAnimation(CSkeletonAnim
* anim
, bool once
= false);
112 // get the currently playing animation, if any
113 CSkeletonAnim
* GetAnimation() const { return m_Anim
; }
115 // set the animation state to be the same as from another; both models should
116 // be compatible types (same type of skeleton)
117 void CopyAnimationFrom(CModel
* source
);
120 void SetFlags(int flags
) { m_Flags
=flags
; }
122 int GetFlags() const { return m_Flags
; }
123 // add object flags, recursively through props
124 void AddFlagsRec(int flags
);
125 // remove shadow casting and receiving, recursively through props
126 // TODO: replace with more generic shader define + flags setting
127 void RemoveShadowsRec();
129 // recurse down tree setting dirty bits
130 virtual void SetDirtyRec(int dirtyflags
) {
131 SetDirty(dirtyflags
);
132 for (size_t i
=0;i
<m_Props
.size();i
++) {
133 m_Props
[i
].m_Model
->SetDirtyRec(dirtyflags
);
137 virtual void SetTerrainDirty(ssize_t i0
, ssize_t j0
, ssize_t i1
, ssize_t j1
)
139 for (size_t i
= 0; i
< m_Props
.size(); ++i
)
140 m_Props
[i
].m_Model
->SetTerrainDirty(i0
, j0
, i1
, j1
);
143 virtual void SetEntityVariable(const std::string
& name
, float value
)
145 for (size_t i
= 0; i
< m_Props
.size(); ++i
)
146 m_Props
[i
].m_Model
->SetEntityVariable(name
, value
);
149 // --- WORLD/OBJECT SPACE BOUNDS -----------------------------------------------------------------
151 /// Overridden to calculate both the world-space and object-space bounds of this model, and stores the result in
152 /// m_Bounds and m_ObjectBounds, respectively.
153 virtual void CalcBounds();
155 /// Returns the object-space bounds for this model, excluding its children.
156 const CBoundingBoxAligned
& GetObjectBounds()
158 RecalculateBoundsIfNecessary(); // recalculates both object-space and world-space bounds if necessary
159 return m_ObjectBounds
;
162 virtual const CBoundingBoxAligned
GetWorldBoundsRec(); // reimplemented here
164 /// Auxiliary method; calculates object space bounds of this model, based solely on vertex positions, and stores
165 /// the result in m_ObjectBounds. Called by CalcBounds (instead of CalcAnimatedObjectBounds) if it has been determined
166 /// that the object-space bounds are static.
167 void CalcStaticObjectBounds();
169 /// Auxiliary method; calculate object-space bounds encompassing all vertex positions for given animation, and stores
170 /// the result in m_ObjectBounds. Called by CalcBounds (instead of CalcStaticBounds) if it has been determined that the
171 /// object-space bounds need to take animations into account.
172 void CalcAnimatedObjectBounds(CSkeletonAnimDef
* anim
,CBoundingBoxAligned
& result
);
174 // --- SELECTION BOX/BOUNDS ----------------------------------------------------------------------
176 /// Reimplemented here since proper models should participate in selection boxes.
177 virtual const CBoundingBoxAligned
GetObjectSelectionBoundsRec();
180 * Set transform of this object.
182 * @note In order to ensure that all child props are updated properly,
183 * you must call ValidatePosition().
185 virtual void SetTransform(const CMatrix3D
& transform
);
188 * Return whether this is a skinned/skeletal model. If it is, Get*BoneMatrices()
189 * will return valid non-NULL arrays.
191 bool IsSkinned() { return (m_BoneMatrices
!= NULL
); }
193 // return the models bone matrices; 16-byte aligned for SSE reads
194 const CMatrix3D
* GetAnimatedBoneMatrices() {
195 ENSURE(m_PositionValid
);
196 return m_BoneMatrices
;
200 * Load raw animation frame animation from given file, and build an
201 * animation specific to this model.
202 * @param pathname animation file to load
203 * @param name animation name (e.g. "idle")
204 * @param ID specific ID of the animation, to sync with props
205 * @param frequency influences the random choices
206 * @param speed animation speed as a factor of the default animation speed
207 * @param actionpos offset of 'action' event, in range [0, 1]
208 * @param actionpos2 offset of 'action2' event, in range [0, 1]
209 * @param sound offset of 'sound' event, in range [0, 1]
210 * @return new animation, or NULL on error
212 CSkeletonAnim
* BuildAnimation(const VfsPath
& pathname
, const CStr
& name
, const CStr
& ID
, int frequency
, float speed
, float actionpos
, float actionpos2
, float soundpos
);
215 * Add a prop to the model on the given point.
217 void AddProp(const SPropPoint
* point
, CModelAbstract
* model
, CObjectEntry
* objectentry
, float minHeight
= 0.f
, float maxHeight
= 0.f
, bool selectable
= true);
220 * Add a prop to the model on the given point, and treat it as the ammo prop.
221 * The prop will be hidden by default.
223 void AddAmmoProp(const SPropPoint
* point
, CModelAbstract
* model
, CObjectEntry
* objectentry
);
226 * Show the ammo prop (if any), and hide any other props on that prop point.
231 * Hide the ammo prop (if any), and show any other props on that prop point.
236 * Find the first prop used for ammo, by this model or its own props.
238 CModelAbstract
* FindFirstAmmoProp();
241 std::vector
<Prop
>& GetProps() { return m_Props
; }
242 const std::vector
<Prop
>& GetProps() const { return m_Props
; }
244 // return a clone of this model
245 virtual CModelAbstract
* Clone() const;
248 * Ensure that both the transformation and the bone
249 * matrices are correct for this model and all its props.
251 virtual void ValidatePosition();
254 * Mark this model's position and bone matrices,
255 * and all props' positions as invalid.
257 virtual void InvalidatePosition();
260 // delete anything allocated by the model
263 // Needed for terrain aligned props
264 CSimulation2
& m_Simulation
;
269 CMaterial m_Material
;
270 // pointer to the model's raw 3d data
271 CModelDefPtr m_pModelDef
;
272 // object space bounds of model - accounts for bounds of all possible animations
273 // that can play on a model. Not always up-to-date - currently CalcBounds()
274 // updates it when necessary.
275 CBoundingBoxAligned m_ObjectBounds
;
276 // animation currently playing on this model, if any
277 CSkeletonAnim
* m_Anim
;
278 // time (in MS) into the current animation
282 * Current state of all bones on this model; null if associated modeldef isn't skeletal.
283 * Props may attach to these bones by means of the SPropPoint::m_BoneIndex field; in this case their
284 * transformation matrix held is relative to the bone transformation (see @ref SPropPoint and
285 * @ref CModel::ValidatePosition).
289 CMatrix3D
* m_BoneMatrices
;
290 // list of current props on model
291 std::vector
<Prop
> m_Props
;
294 * The prop point to which the ammo prop is attached, or NULL if none
296 const SPropPoint
* m_AmmoPropPoint
;
299 * If m_AmmoPropPoint is not NULL, then the index in m_Props of the ammo prop
301 size_t m_AmmoLoadedProp
;
303 // manager object which can load animations for us
304 CSkeletonAnimManager
& m_SkeletonAnimManager
;