Fix infinite loop detection when placing players randomly on the newer random map...
[0ad.git] / source / graphics / Model.h
blob8bf254fb873c2b39c43786b7fc3741f3d354c2a8
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
25 #include <vector>
27 #include "graphics/Texture.h"
28 #include "graphics/Material.h"
29 #include "graphics/MeshManager.h"
30 #include "graphics/ModelAbstract.h"
32 struct SPropPoint;
33 class CObjectEntry;
34 class CSkeletonAnim;
35 class CSkeletonAnimDef;
36 class CSkeletonAnimManager;
37 class CSimulation2;
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
50 NONCOPYABLE(CModel);
52 public:
53 struct Prop
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) {}
57 float m_MinHeight;
58 float m_MaxHeight;
60 /**
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.
63 * @see SPropPoint
65 const SPropPoint* m_Point;
67 /**
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?
79 public:
80 // constructor
81 CModel(CSkeletonAnimManager& skeletonAnimManager, CSimulation2& simulation);
82 // destructor
83 ~CModel();
86 /// Dynamic cast
87 virtual CModel* ToCModel()
89 return this;
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);
119 // set object flags
120 void SetFlags(int flags) { m_Flags=flags; }
121 // get object 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.
228 void ShowAmmoProp();
231 * Hide the ammo prop (if any), and show any other props on that prop point.
233 void HideAmmoProp();
236 * Find the first prop used for ammo, by this model or its own props.
238 CModelAbstract* FindFirstAmmoProp();
240 // return prop list
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();
259 private:
260 // delete anything allocated by the model
261 void ReleaseData();
263 // Needed for terrain aligned props
264 CSimulation2& m_Simulation;
266 // object flags
267 int m_Flags;
268 // model's material
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
279 float m_AnimTime;
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).
287 * @see SPropPoint
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;
307 #endif