Line data Source code
1 : /* Copyright (C) 2022 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
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.
8 : *
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.
13 : *
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/>.
16 : */
17 :
18 : /*
19 : * Mesh object with texture and skinning information
20 : */
21 :
22 : #ifndef INCLUDED_MODEL
23 : #define INCLUDED_MODEL
24 :
25 : #include "graphics/Material.h"
26 : #include "graphics/MeshManager.h"
27 : #include "graphics/ModelAbstract.h"
28 :
29 : #include <vector>
30 :
31 : struct SPropPoint;
32 : class CObjectEntry;
33 : class CSkeletonAnim;
34 : class CSkeletonAnimDef;
35 : class CSimulation2;
36 :
37 : #define MODELFLAG_CASTSHADOWS (1<<0)
38 : #define MODELFLAG_NOLOOPANIMATION (1<<1)
39 : #define MODELFLAG_SILHOUETTE_DISPLAY (1<<2)
40 : #define MODELFLAG_SILHOUETTE_OCCLUDER (1<<3)
41 : #define MODELFLAG_IGNORE_LOS (1<<4)
42 : #define MODELFLAG_FLOATONWATER (1<<5)
43 : ///////////////////////////////////////////////////////////////////////////////
44 : // CModel: basically, a mesh object - holds the texturing and skinning
45 : // information for a model in game
46 : class CModel : public CModelAbstract
47 : {
48 : NONCOPYABLE(CModel);
49 :
50 : public:
51 : struct Prop
52 : {
53 0 : Prop() : m_MinHeight(0.f), m_MaxHeight(0.f), m_Point(0), m_Model(0), m_ObjectEntry(0), m_Hidden(false), m_Selectable(true) {}
54 :
55 : float m_MinHeight;
56 : float m_MaxHeight;
57 :
58 : /**
59 : * Location of the prop point within its parent model, relative to either a bone in the parent model or to the
60 : * parent model's origin. See the documentation for @ref SPropPoint for more details.
61 : * @see SPropPoint
62 : */
63 : const SPropPoint* m_Point;
64 :
65 : /**
66 : * Pointer to the model associated with this prop. Note that the transform matrix held by this model is the full object-to-world
67 : * space transform, taking into account all parent model positioning (see @ref CModel::ValidatePosition for positioning logic).
68 : * @see CModel::ValidatePosition
69 : */
70 : CModelAbstract* m_Model;
71 : CObjectEntry* m_ObjectEntry;
72 :
73 : bool m_Hidden; ///< Should this prop be temporarily removed from rendering?
74 : bool m_Selectable; /// < should this prop count in the selection size?
75 : };
76 :
77 : public:
78 : // constructor
79 : CModel(CSimulation2& simulation);
80 : // destructor
81 : ~CModel();
82 :
83 :
84 : /// Dynamic cast
85 0 : virtual CModel* ToCModel()
86 : {
87 0 : return this;
88 : }
89 :
90 : // setup model from given geometry
91 : bool InitModel(const CModelDefPtr& modeldef);
92 : // update this model's state; 'time' is the absolute time since the start of the animation, in MS
93 : void UpdateTo(float time);
94 :
95 : // get the model's geometry data
96 0 : const CModelDefPtr& GetModelDef() { return m_pModelDef; }
97 :
98 : // set the model's material
99 : void SetMaterial(const CMaterial &material);
100 : // set the model's player ID, recursively through props
101 : void SetPlayerID(player_id_t id);
102 : // set the models mod color
103 : virtual void SetShadingColor(const CColor& color);
104 : // get the model's material
105 0 : CMaterial& GetMaterial() { return m_Material; }
106 :
107 : // set the given animation as the current animation on this model
108 : bool SetAnimation(CSkeletonAnim* anim, bool once = false);
109 :
110 : // get the currently playing animation, if any
111 : CSkeletonAnim* GetAnimation() const { return m_Anim; }
112 :
113 : // set the animation state to be the same as from another; both models should
114 : // be compatible types (same type of skeleton)
115 : void CopyAnimationFrom(CModel* source);
116 :
117 : // set object flags
118 0 : void SetFlags(int flags) { m_Flags=flags; }
119 : // get object flags
120 0 : int GetFlags() const { return m_Flags; }
121 : // add object flags, recursively through props
122 : void AddFlagsRec(int flags);
123 : // remove shadow casting and receiving, recursively through props
124 : // TODO: replace with more generic shader define + flags setting
125 : void RemoveShadowsRec();
126 :
127 0 : virtual void SetTerrainDirty(ssize_t i0, ssize_t j0, ssize_t i1, ssize_t j1)
128 : {
129 0 : for (size_t i = 0; i < m_Props.size(); ++i)
130 0 : m_Props[i].m_Model->SetTerrainDirty(i0, j0, i1, j1);
131 0 : }
132 :
133 0 : virtual void SetEntityVariable(const std::string& name, float value)
134 : {
135 0 : for (size_t i = 0; i < m_Props.size(); ++i)
136 0 : m_Props[i].m_Model->SetEntityVariable(name, value);
137 0 : }
138 :
139 : // --- WORLD/OBJECT SPACE BOUNDS -----------------------------------------------------------------
140 :
141 : /// Overridden to calculate both the world-space and object-space bounds of this model, and stores the result in
142 : /// m_Bounds and m_ObjectBounds, respectively.
143 : virtual void CalcBounds();
144 :
145 : /// Returns the object-space bounds for this model, excluding its children.
146 0 : const CBoundingBoxAligned& GetObjectBounds()
147 : {
148 0 : RecalculateBoundsIfNecessary(); // recalculates both object-space and world-space bounds if necessary
149 0 : return m_ObjectBounds;
150 : }
151 :
152 : virtual const CBoundingBoxAligned GetWorldBoundsRec(); // reimplemented here
153 :
154 : /// Auxiliary method; calculates object space bounds of this model, based solely on vertex positions, and stores
155 : /// the result in m_ObjectBounds. Called by CalcBounds (instead of CalcAnimatedObjectBounds) if it has been determined
156 : /// that the object-space bounds are static.
157 : void CalcStaticObjectBounds();
158 :
159 : /// Auxiliary method; calculate object-space bounds encompassing all vertex positions for given animation, and stores
160 : /// the result in m_ObjectBounds. Called by CalcBounds (instead of CalcStaticBounds) if it has been determined that the
161 : /// object-space bounds need to take animations into account.
162 : void CalcAnimatedObjectBounds(CSkeletonAnimDef* anim,CBoundingBoxAligned& result);
163 :
164 : // --- SELECTION BOX/BOUNDS ----------------------------------------------------------------------
165 :
166 : /// Reimplemented here since proper models should participate in selection boxes.
167 : virtual const CBoundingBoxAligned GetObjectSelectionBoundsRec();
168 :
169 : /**
170 : * Set transform of this object.
171 : *
172 : * @note In order to ensure that all child props are updated properly,
173 : * you must call ValidatePosition().
174 : */
175 : virtual void SetTransform(const CMatrix3D& transform);
176 :
177 : /**
178 : * Return whether this is a skinned/skeletal model. If it is, Get*BoneMatrices()
179 : * will return valid non-NULL arrays.
180 : */
181 0 : bool IsSkinned() { return (m_BoneMatrices != NULL); }
182 :
183 : // return the models bone matrices; 16-byte aligned for SSE reads
184 0 : const CMatrix3D* GetAnimatedBoneMatrices() {
185 0 : ENSURE(m_PositionValid);
186 0 : return m_BoneMatrices;
187 : }
188 :
189 : /**
190 : * Add a prop to the model on the given point.
191 : */
192 : void AddProp(const SPropPoint* point, CModelAbstract* model, CObjectEntry* objectentry, float minHeight = 0.f, float maxHeight = 0.f, bool selectable = true);
193 :
194 : /**
195 : * Add a prop to the model on the given point, and treat it as the ammo prop.
196 : * The prop will be hidden by default.
197 : */
198 : void AddAmmoProp(const SPropPoint* point, CModelAbstract* model, CObjectEntry* objectentry);
199 :
200 : /**
201 : * Show the ammo prop (if any), and hide any other props on that prop point.
202 : */
203 : void ShowAmmoProp();
204 :
205 : /**
206 : * Hide the ammo prop (if any), and show any other props on that prop point.
207 : */
208 : void HideAmmoProp();
209 :
210 : /**
211 : * Find the first prop used for ammo, by this model or its own props.
212 : */
213 : CModelAbstract* FindFirstAmmoProp();
214 :
215 : // return prop list
216 0 : std::vector<Prop>& GetProps() { return m_Props; }
217 : const std::vector<Prop>& GetProps() const { return m_Props; }
218 :
219 : // return a clone of this model
220 : virtual CModelAbstract* Clone() const;
221 :
222 : /**
223 : * Ensure that both the transformation and the bone
224 : * matrices are correct for this model and all its props.
225 : */
226 : virtual void ValidatePosition();
227 :
228 : /**
229 : * Mark this model's position and bone matrices,
230 : * and all props' positions as invalid.
231 : */
232 : virtual void InvalidatePosition();
233 :
234 : private:
235 : // delete anything allocated by the model
236 : void ReleaseData();
237 :
238 : // Needed for terrain aligned props
239 : CSimulation2& m_Simulation;
240 :
241 : // object flags
242 : int m_Flags;
243 : // model's material
244 : CMaterial m_Material;
245 : // pointer to the model's raw 3d data
246 : CModelDefPtr m_pModelDef;
247 : // object space bounds of model - accounts for bounds of all possible animations
248 : // that can play on a model. Not always up-to-date - currently CalcBounds()
249 : // updates it when necessary.
250 : CBoundingBoxAligned m_ObjectBounds;
251 : // animation currently playing on this model, if any
252 : CSkeletonAnim* m_Anim;
253 : // time (in MS) into the current animation
254 : float m_AnimTime;
255 :
256 : /**
257 : * Current state of all bones on this model; null if associated modeldef isn't skeletal.
258 : * Props may attach to these bones by means of the SPropPoint::m_BoneIndex field; in this case their
259 : * transformation matrix held is relative to the bone transformation (see @ref SPropPoint and
260 : * @ref CModel::ValidatePosition).
261 : *
262 : * @see SPropPoint
263 : */
264 : CMatrix3D* m_BoneMatrices;
265 : // list of current props on model
266 : std::vector<Prop> m_Props;
267 :
268 : /**
269 : * The prop point to which the ammo prop is attached, or NULL if none
270 : */
271 : const SPropPoint* m_AmmoPropPoint;
272 :
273 : /**
274 : * If m_AmmoPropPoint is not NULL, then the index in m_Props of the ammo prop
275 : */
276 : size_t m_AmmoLoadedProp;
277 : };
278 :
279 : #endif
|