Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Model.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2013 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 #include "precompiled.h"
23 
24 #include "Model.h"
25 
26 #include "Decal.h"
27 #include "ModelDef.h"
28 #include "maths/Quaternion.h"
30 #include "SkeletonAnim.h"
31 #include "SkeletonAnimDef.h"
32 #include "SkeletonAnimManager.h"
33 #include "MeshManager.h"
34 #include "ObjectEntry.h"
36 #include "lib/res/h_mgr.h"
37 #include "lib/sysdep/rtl.h"
38 #include "ps/Profile.h"
39 #include "ps/CLogger.h"
40 #include "renderer/Renderer.h"
43 
44 
45 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
46 // Constructor
47 CModel::CModel(CSkeletonAnimManager& skeletonAnimManager, CSimulation2& simulation)
48  : m_Flags(0), m_Anim(NULL), m_AnimTime(0), m_Simulation(simulation),
49  m_BoneMatrices(NULL), m_AmmoPropPoint(NULL), m_AmmoLoadedProp(0),
50  m_SkeletonAnimManager(skeletonAnimManager)
51 {
52 }
53 
54 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
55 // Destructor
57 {
58  ReleaseData();
59 }
60 
61 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
62 // ReleaseData: delete anything allocated by the model
64 {
66 
67  for (size_t i = 0; i < m_Props.size(); ++i)
68  delete m_Props[i].m_Model;
69  m_Props.clear();
70 
72 }
73 
74 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
75 // InitModel: setup model from given geometry
76 bool CModel::InitModel(const CModelDefPtr& modeldef)
77 {
78  // clean up any existing data first
79  ReleaseData();
80 
81  m_pModelDef = modeldef;
82 
83  size_t numBones = modeldef->GetNumBones();
84  if (numBones != 0)
85  {
86  size_t numBlends = modeldef->GetNumBlends();
87 
88  // allocate matrices for bone transformations
89  // (one extra matrix is used for the special case of bind-shape relative weighting)
90  m_BoneMatrices = (CMatrix3D*)rtl_AllocateAligned(sizeof(CMatrix3D) * (numBones + 1 + numBlends), 16);
91  for (size_t i = 0; i < numBones + 1 + numBlends; ++i)
92  {
94  }
95  }
96 
97  m_PositionValid = true;
98 
99  return true;
100 }
101 
102 
103 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
104 // CalcBound: calculate the world space bounds of this model
106 {
107  // Need to calculate the object bounds first, if that hasn't already been done
108  if (! (m_Anim && m_Anim->m_AnimDef))
109  {
110  if (m_ObjectBounds.IsEmpty())
112  }
113  else
114  {
117  ENSURE(! m_Anim->m_ObjectBounds.IsEmpty()); // (if this happens, it'll be recalculating the bounds every time)
119  }
120 
121  // Ensure the transform is set correctly before we use it
123 
124  // Now transform the object-space bounds to world-space bounds
126 }
127 
128 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
129 // CalcObjectBounds: calculate object space bounds of this model, based solely on vertex positions
131 {
133 
134  size_t numverts=m_pModelDef->GetNumVertices();
135  SModelVertex* verts=m_pModelDef->GetVertices();
136 
137  for (size_t i=0;i<numverts;i++) {
138  m_ObjectBounds+=verts[i].m_Coords;
139  }
140 }
141 
142 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
143 // CalcAnimatedObjectBound: calculate bounds encompassing all vertex positions for given animation
145 {
146  result.SetEmpty();
147 
148  // Set the current animation on which to perform calculations (if it's necessary)
149  if (anim != m_Anim->m_AnimDef)
150  {
151  CSkeletonAnim dummyanim;
152  dummyanim.m_AnimDef=anim;
153  if (!SetAnimation(&dummyanim)) return;
154  }
155 
156  size_t numverts=m_pModelDef->GetNumVertices();
157  SModelVertex* verts=m_pModelDef->GetVertices();
158 
159  // Remove any transformations, so that we calculate the bounding box
160  // at the origin. The box is later re-transformed onto the object, without
161  // having to recalculate the size of the box.
162  CMatrix3D transform, oldtransform = GetTransform();
163  CModelAbstract* oldparent = m_Parent;
164 
165  m_Parent = 0;
166  transform.SetIdentity();
168 
169  // Following seems to stomp over the current animation time - which, unsurprisingly,
170  // introduces artefacts in the currently playing animation. Save it here and restore it
171  // at the end.
172  float AnimTime = m_AnimTime;
173 
174  // iterate through every frame of the animation
175  for (size_t j=0;j<anim->GetNumFrames();j++) {
176  m_PositionValid = false;
178 
179  // extend bounds by vertex positions at the frame
180  for (size_t i=0;i<numverts;i++)
181  {
182  result += CModelDef::SkinPoint(verts[i], GetAnimatedBoneMatrices());
183  }
184  // advance to next frame
185  m_AnimTime += anim->GetFrameTime();
186  }
187 
188  m_PositionValid = false;
189  m_Parent = oldparent;
190  SetTransform(oldtransform);
191  m_AnimTime = AnimTime;
192 }
193 
194 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
196 {
198  for (size_t i = 0; i < m_Props.size(); ++i)
199  bounds += m_Props[i].m_Model->GetWorldBoundsRec();
200  return bounds;
201 }
202 
204 {
205  CBoundingBoxAligned objBounds = GetObjectBounds(); // updates the (children-not-included) object-space bounds if necessary
206 
207  // now extend these bounds to include the props' selection bounds (if any)
208  for (size_t i = 0; i < m_Props.size(); ++i)
209  {
210  const Prop& prop = m_Props[i];
211  if (prop.m_Hidden)
212  continue; // prop is hidden from rendering, so it also shouldn't be used for selection
213 
214  CBoundingBoxAligned propSelectionBounds = prop.m_Model->GetObjectSelectionBoundsRec();
215  if (propSelectionBounds.IsEmpty())
216  continue; // submodel does not wish to participate in selection box, exclude it
217 
218  // We have the prop's bounds in its own object-space; now we need to transform them so they can be properly added
219  // to the bounds in our object-space. For that, we need the transform of the prop attachment point.
220  //
221  // We have the prop point information; however, it's not trivial to compute its exact location in our object-space
222  // since it may or may not be attached to a bone (see SPropPoint), which in turn may or may not be in the middle of
223  // an animation. The bone matrices might be of interest, but they're really only meant to be used for the animation
224  // system and are quite opaque to use from the outside (see @ref ValidatePosition).
225  //
226  // However, a nice side effect of ValidatePosition is that it also computes the absolute world-space transform of
227  // our props and sets it on their respective models. In particular, @ref ValidatePosition will compute the prop's
228  // world-space transform as either
229  //
230  // T' = T x B x O
231  // or
232  // T' = T x O
233  //
234  // where T' is the prop's world-space transform, T is our world-space transform, O is the prop's local
235  // offset/rotation matrix, and B is an optional transformation matrix of the bone the prop is attached to
236  // (taking into account animation and everything).
237  //
238  // From this, it is clear that either O or B x O is the object-space transformation matrix of the prop. So,
239  // all we need to do is apply our own inverse world-transform T^(-1) to T' to get our desired result. Luckily,
240  // this is precomputed upon setting the transform matrix (see @ref SetTransform), so it is free to fetch.
241 
242  CMatrix3D propObjectTransform = prop.m_Model->GetTransform(); // T'
243  propObjectTransform.Concatenate(GetInvTransform()); // T^(-1) x T'
244 
245  // Transform the prop's bounds into our object coordinate space
246  CBoundingBoxAligned transformedPropSelectionBounds;
247  propSelectionBounds.Transform(propObjectTransform, transformedPropSelectionBounds);
248 
249  objBounds += transformedPropSelectionBounds;
250  }
251 
252  return objBounds;
253 }
254 
255 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
256 // BuildAnimation: load raw animation frame animation from given file, and build a
257 // animation specific to this model
258 CSkeletonAnim* CModel::BuildAnimation(const VfsPath& pathname, const CStr& name, float speed, float actionpos, float actionpos2, float soundpos)
259 {
261  if (!def)
262  return NULL;
263 
264  CSkeletonAnim* anim = new CSkeletonAnim();
265  anim->m_Name = name;
266  anim->m_AnimDef = def;
267  anim->m_Speed = speed;
268 
269  if (actionpos == -1.f)
270  anim->m_ActionPos = -1.f;
271  else
272  anim->m_ActionPos = actionpos * anim->m_AnimDef->GetDuration();
273 
274  if (actionpos2 == -1.f)
275  anim->m_ActionPos2 = -1.f;
276  else
277  anim->m_ActionPos2 = actionpos2 * anim->m_AnimDef->GetDuration();
278 
279  if (soundpos == -1.f)
280  anim->m_SoundPos = -1.f;
281  else
282  anim->m_SoundPos = soundpos * anim->m_AnimDef->GetDuration();
283 
284  anim->m_ObjectBounds.SetEmpty();
286 
287  return anim;
288 }
289 
290 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
291 // Update: update this model to the given time, in msec
292 void CModel::UpdateTo(float time)
293 {
294  // update animation time, but don't calculate bone matrices - do that (lazily) when
295  // something requests them; that saves some calculation work for offscreen models,
296  // and also assures the world space, inverted bone matrices (required for normal
297  // skinning) are up to date with respect to m_Transform
298  m_AnimTime = time;
299 
300  // mark vertices as dirty
302 
303  // mark matrices as dirty
305 }
306 
307 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
308 // InvalidatePosition
310 {
311  m_PositionValid = false;
312 
313  for (size_t i = 0; i < m_Props.size(); ++i)
314  m_Props[i].m_Model->InvalidatePosition();
315 }
316 
317 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
318 // ValidatePosition: ensure that current transform and bone matrices are both uptodate
320 {
321  if (m_PositionValid)
322  {
324  return;
325  }
326 
328  {
329  // Make sure we don't base our calculations on
330  // a parent animation state that is out of date.
332 
333  // Parent will recursively call our validation.
335  return;
336  }
337 
338  if (m_Anim && m_BoneMatrices)
339  {
340 // PROFILE( "generating bone matrices" );
341 
342  ENSURE(m_pModelDef->GetNumBones() == m_Anim->m_AnimDef->GetNumKeys());
343 
345  }
346  else if (m_BoneMatrices)
347  {
348  // Bones but no animation - probably a buggy actor forgot to set up the animation,
349  // so just render it in its bind pose
350 
351  for (size_t i = 0; i < m_pModelDef->GetNumBones(); i++)
352  {
354  m_BoneMatrices[i].Rotate(m_pModelDef->GetBones()[i].m_Rotation);
355  m_BoneMatrices[i].Translate(m_pModelDef->GetBones()[i].m_Translation);
356  }
357  }
358 
359  // For CPU skinning, we precompute as much as possible so that the only
360  // per-vertex work is a single matrix*vec multiplication.
361  // For GPU skinning, we try to minimise CPU work by doing most computation
362  // in the vertex shader instead.
363  // Using g_Renderer.m_Options to detect CPU vs GPU is a bit hacky,
364  // and this doesn't allow the setting to change at runtime, but there isn't
365  // an obvious cleaner way to determine what data needs to be computed,
366  // and GPU skinning is a rarely-used experimental feature anyway.
367  bool worldSpaceBoneMatrices = !g_Renderer.m_Options.m_GPUSkinning;
368  bool computeBlendMatrices = !g_Renderer.m_Options.m_GPUSkinning;
369 
370  if (m_BoneMatrices && worldSpaceBoneMatrices)
371  {
372  // add world-space transformation to m_BoneMatrices
373  const CMatrix3D transform = GetTransform();
374  for (size_t i = 0; i < m_pModelDef->GetNumBones(); i++)
375  m_BoneMatrices[i].Concatenate(transform);
376  }
377 
378  // our own position is now valid; now we can safely update our props' positions without fearing
379  // that doing so will cause a revalidation of this model (see recursion above).
380  m_PositionValid = true;
381 
382  // re-position and validate all props
383  for (size_t j = 0; j < m_Props.size(); ++j)
384  {
385  const Prop& prop=m_Props[j];
386 
387  CMatrix3D proptransform = prop.m_Point->m_Transform;
388 
389  if (prop.m_Point->m_BoneIndex != 0xff)
390  {
391  CMatrix3D boneMatrix = m_BoneMatrices[prop.m_Point->m_BoneIndex];
392  if (!worldSpaceBoneMatrices)
393  boneMatrix.Concatenate(GetTransform());
394  proptransform.Concatenate(boneMatrix);
395  }
396  else
397  {
398  // not relative to any bone; just apply world-space transformation (i.e. relative to object-space origin)
399  proptransform.Concatenate(m_Transform);
400  }
401 
402  // Adjust prop height to terrain level when needed
403  if (prop.m_maxHeight != 0.f || prop.m_minHeight != 0.f)
404  {
405  CVector3D propTranslation = proptransform.GetTranslation();
406  CVector3D objTranslation = m_Transform.GetTranslation();
407 
409  if (cmpTerrain)
410  {
411  float objTerrain = cmpTerrain->GetExactGroundLevel(objTranslation.X, objTranslation.Z);
412  float propTerrain = cmpTerrain->GetExactGroundLevel(propTranslation.X, propTranslation.Z);
413  float translateHeight = std::min(prop.m_maxHeight,
414  std::max(prop.m_minHeight, propTerrain - objTerrain));
415  CMatrix3D translate = CMatrix3D();
416  translate.SetTranslation(0.f, translateHeight, 0.f);
417  proptransform.Concatenate(translate);
418  }
419  }
420 
421  prop.m_Model->SetTransform(proptransform);
422  prop.m_Model->ValidatePosition();
423  }
424 
425  if (m_BoneMatrices)
426  {
427  for (size_t i = 0; i < m_pModelDef->GetNumBones(); i++)
428  {
429  m_BoneMatrices[i] = m_BoneMatrices[i] * m_pModelDef->GetInverseBindBoneMatrices()[i];
430  }
431 
432  // Note: there is a special case of joint influence, in which the vertex
433  // is influenced by the bind-shape transform instead of a particular bone,
434  // which we indicate with the blending bone ID set to the total number
435  // of bones. But since we're skinning in world space, we use the model's
436  // world space transform and store that matrix in this special index.
437  // (see http://trac.wildfiregames.com/ticket/1012)
438  m_BoneMatrices[m_pModelDef->GetNumBones()] = m_Transform;
439 
440  if (computeBlendMatrices)
441  m_pModelDef->BlendBoneMatrices(m_BoneMatrices);
442  }
443 }
444 
445 
446 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
447 // SetAnimation: set the given animation as the current animation on this model;
448 // return false on error, else true
449 bool CModel::SetAnimation(CSkeletonAnim* anim, bool once)
450 {
451  m_Anim = NULL; // in case something fails
452 
453  if (anim)
454  {
456 
457  if (once)
459 
460  if (!m_BoneMatrices && anim->m_AnimDef)
461  {
462  // not boned, can't animate
463  return false;
464  }
465 
466  if (m_BoneMatrices && !anim->m_AnimDef)
467  {
468  // boned, but animation isn't valid
469  // (e.g. the default (static) idle animation on an animated unit)
470  return false;
471  }
472 
473  if (anim->m_AnimDef && anim->m_AnimDef->GetNumKeys() != m_pModelDef->GetNumBones())
474  {
475  // mismatch between model's skeleton and animation's skeleton
476  LOGERROR(L"Mismatch between model's skeleton and animation's skeleton (%lu model bones != %lu animation keys)",
477  (unsigned long)m_pModelDef->GetNumBones(), (unsigned long)anim->m_AnimDef->GetNumKeys());
478  return false;
479  }
480 
481  // reset the cached bounds when the animation is changed
484 
485  // start anim from beginning
486  m_AnimTime = 0;
487  }
488 
489  m_Anim = anim;
490 
491  return true;
492 }
493 
494 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
495 // CopyAnimation
497 {
498  m_Anim = source->m_Anim;
499  m_AnimTime = source->m_AnimTime;
500 
502  if (source->m_Flags & MODELFLAG_CASTSHADOWS)
504 
507 }
508 
509 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
510 // AddProp: add a prop to the model on the given point
511 void CModel::AddProp(const SPropPoint* point, CModelAbstract* model, CObjectEntry* objectentry, float minHeight, float maxHeight)
512 {
513  // position model according to prop point position
514 
515  // this next call will invalidate the bounds of "model", which will in turn also invalidate the selection box
516  model->SetTransform(point->m_Transform);
517  model->m_Parent = this;
518 
519  Prop prop;
520  prop.m_Point = point;
521  prop.m_Model = model;
522  prop.m_ObjectEntry = objectentry;
523  prop.m_minHeight = minHeight;
524  prop.m_maxHeight = maxHeight;
525  m_Props.push_back(prop);
526 }
527 
529 {
530  AddProp(point, model, objectentry);
531  m_AmmoPropPoint = point;
532  m_AmmoLoadedProp = m_Props.size() - 1;
533  m_Props[m_AmmoLoadedProp].m_Hidden = true;
534 
535  // we only need to invalidate the selection box here if it is based on props and their visibilities
537  m_SelectionBoxValid = false;
538 }
539 
541 {
542  if (m_AmmoPropPoint == NULL)
543  return;
544 
545  // Show the ammo prop, hide all others on the same prop point
546  for (size_t i = 0; i < m_Props.size(); ++i)
547  if (m_Props[i].m_Point == m_AmmoPropPoint)
548  m_Props[i].m_Hidden = (i != m_AmmoLoadedProp);
549 
550  // we only need to invalidate the selection box here if it is based on props and their visibilities
552  m_SelectionBoxValid = false;
553 }
554 
556 {
557  if (m_AmmoPropPoint == NULL)
558  return;
559 
560  // Hide the ammo prop, show all others on the same prop point
561  for (size_t i = 0; i < m_Props.size(); ++i)
562  if (m_Props[i].m_Point == m_AmmoPropPoint)
563  m_Props[i].m_Hidden = (i == m_AmmoLoadedProp);
564 
565  // we only need to invalidate here if the selection box is based on props and their visibilities
567  m_SelectionBoxValid = false;
568 }
569 
571 {
572  if (m_AmmoPropPoint)
573  return m_Props[m_AmmoLoadedProp].m_Model;
574 
575  for (size_t i = 0; i < m_Props.size(); ++i)
576  {
577  CModel* propModel = m_Props[i].m_Model->ToCModel();
578  if (propModel)
579  {
580  CModelAbstract* model = propModel->FindFirstAmmoProp();
581  if (model)
582  return model;
583  }
584  }
585 
586  return NULL;
587 }
588 
589 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
590 // Clone: return a clone of this model
592 {
595  clone->InitModel(m_pModelDef);
596  clone->SetMaterial(m_Material);
597  clone->SetAnimation(m_Anim);
598  clone->SetFlags(m_Flags);
599 
600  for (size_t i = 0; i < m_Props.size(); i++)
601  {
602  // eek! TODO, RC - need to investigate shallow clone here
603  if (m_AmmoPropPoint && i == m_AmmoLoadedProp)
604  clone->AddAmmoProp(m_Props[i].m_Point, m_Props[i].m_Model->Clone(), m_Props[i].m_ObjectEntry);
605  else
606  clone->AddProp(m_Props[i].m_Point, m_Props[i].m_Model->Clone(), m_Props[i].m_ObjectEntry, m_Props[i].m_minHeight, m_Props[i].m_maxHeight);
607  }
608 
609  return clone;
610 }
611 
612 
613 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
614 // SetTransform: set the transform on this object, and reorientate props accordingly
615 void CModel::SetTransform(const CMatrix3D& transform)
616 {
617  // call base class to set transform on this object
620 }
621 
622 //////////////////////////////////////////////////////////////////////////
623 
624 void CModel::AddFlagsRec(int flags)
625 {
626  m_Flags |= flags;
627 
628  if (flags & MODELFLAG_IGNORE_LOS)
629  {
630  m_Material.AddShaderDefine(str_IGNORE_LOS, str_1);
632  }
633 
634  for (size_t i = 0; i < m_Props.size(); ++i)
635  if (m_Props[i].m_Model->ToCModel())
636  m_Props[i].m_Model->ToCModel()->AddFlagsRec(flags);
637 }
638 
640 {
642 
643  m_Material.AddShaderDefine(str_DISABLE_RECEIVE_SHADOWS, str_1);
645 
646  for (size_t i = 0; i < m_Props.size(); ++i)
647  {
648  if (m_Props[i].m_Model->ToCModel())
649  m_Props[i].m_Model->ToCModel()->RemoveShadowsRec();
650  else if (m_Props[i].m_Model->ToCModelDecal())
651  m_Props[i].m_Model->ToCModelDecal()->RemoveShadows();
652  }
653 }
654 
655 void CModel::SetMaterial(const CMaterial &material)
656 {
657  m_Material = material;
658 }
659 
661 {
663 
664  for (std::vector<Prop>::iterator it = m_Props.begin(); it != m_Props.end(); ++it)
665  it->m_Model->SetPlayerID(id);
666 }
667 
668 void CModel::SetShadingColor(const CColor& colour)
669 {
671 
672  for (std::vector<Prop>::iterator it = m_Props.begin(); it != m_Props.end(); ++it)
673  it->m_Model->SetShadingColor(colour);
674 }
u8 m_BoneIndex
Index of parent bone to which this prop point is relative, if any.
Definition: ModelDef.h:79
void Translate(float x, float y, float z)
Definition: Matrix3D.cpp:172
void * rtl_AllocateAligned(size_t size, size_t align)
Definition: gcc.cpp:66
void Transform(const CMatrix3D &m, CBoundingBoxAligned &result) const
Transforms these bounds according to the specified transformation matrix m, and writes the axis-align...
CSkeletonAnimManager & m_SkeletonAnimManager
Definition: Model.h:303
void HideAmmoProp()
Hide the ammo prop (if any), and show any other props on that prop point.
Definition: Model.cpp:555
void AddShaderDefine(CStrIntern key, CStrIntern value)
Definition: Material.cpp:35
Describes the position of a prop point within its parent model.
Definition: ModelDef.h:48
size_t GetNumKeys() const
void SetTranslation(float x, float y, float z)
Definition: Matrix3D.cpp:158
virtual void SetPlayerID(player_id_t id)
float m_minHeight
Definition: Model.h:59
#define LOGERROR
Definition: CLogger.h:35
CMatrix3D * m_BoneMatrices
Current state of all bones on this model; null if associated modeldef isn&#39;t skeletal.
Definition: Model.h:288
const CMatrix3D & GetInvTransform() const
virtual const CBoundingBoxAligned GetWorldBoundsRec()
Returns world space bounds of this object and all child objects.
Definition: Model.cpp:195
float GetFrameTime() const
Definition: Overlay.h:34
virtual float GetExactGroundLevel(float x, float z)=0
#define RENDERDATA_UPDATE_VERTICES
virtual void SetTransform(const CMatrix3D &transform)
std::vector< Prop > m_Props
Definition: Model.h:290
void UpdateTo(float time)
Definition: Model.cpp:292
CSkeletonAnimDef * GetAnimation(const VfsPath &pathname)
CSkeletonAnimDef * m_AnimDef
Definition: SkeletonAnim.h:38
#define MODELFLAG_IGNORE_LOS
Definition: Model.h:44
void ReleaseData()
Definition: Model.cpp:63
void Rotate(const CQuaternion &quat)
Definition: Matrix3D.cpp:354
bool m_PositionValid
True if both transform and and bone matrices are valid.
float m_ActionPos2
Definition: SkeletonAnim.h:48
const entity_id_t SYSTEM_ENTITY
Entity ID for singleton &#39;system&#39; components.
Definition: Entity.h:44
Public API for simulation system.
Definition: Simulation2.h:46
int32_t player_id_t
valid player IDs are non-negative (see ICmpOwnership)
Definition: Player.h:24
#define g_Renderer
Definition: Renderer.h:61
const CMatrix3D * GetAnimatedBoneMatrices()
Definition: Model.h:195
CSkeletonAnim * BuildAnimation(const VfsPath &pathname, const CStr &name, float speed, float actionpos, float actionpos2, float soundpos)
Load raw animation frame animation from given file, and build an animation specific to this model...
Definition: Model.cpp:258
bool SetAnimation(CSkeletonAnim *anim, bool once=false)
Definition: Model.cpp:449
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
virtual void CalcBounds()
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.
Definition: Model.cpp:105
void RemoveShadowsRec()
Definition: Model.cpp:639
float m_maxHeight
Definition: Model.h:60
CBoundingBoxAligned m_WorldBounds
World-space bounds of this object.
int m_Flags
Definition: Model.h:266
float X
Definition: Vector3D.h:31
bool InitModel(const CModelDefPtr &modeldef)
Definition: Model.cpp:76
void BuildBoneMatrices(float time, CMatrix3D *matrices, bool loop) const
static CVector3D SkinPoint(const SModelVertex &vtx, const CMatrix3D newPoseMatrices[])
Transform the given vertex&#39;s position from the bind pose into the new pose.
Definition: ModelDef.cpp:33
Definition: path.h:75
CustomSelectionShape * m_CustomSelectionShape
Pointer to a descriptor for a custom-defined selection box shape.
void ShowAmmoProp()
Show the ammo prop (if any), and hide any other props on that prop point.
Definition: Model.cpp:540
virtual CModelAbstract * Clone() const
Definition: Model.cpp:591
virtual void ValidatePosition()
Ensure that both the transformation and the bone matrices are correct for this model and all its prop...
Definition: Model.cpp:319
CModelAbstract * m_Model
Pointer to the model associated with this prop.
Definition: Model.h:74
void SetDirty(u32 dirtyflags)
void SetIdentity()
Definition: Matrix3D.cpp:30
virtual void SetTransform(const CMatrix3D &transform)
Set transform of this object.
Definition: Model.cpp:615
void AddProp(const SPropPoint *point, CModelAbstract *model, CObjectEntry *objectentry, float minHeight=0.f, float maxHeight=0.f)
Add a prop to the model on the given point.
Definition: Model.cpp:511
size_t m_AmmoLoadedProp
If m_AmmoPropPoint is not NULL, then the index in m_Props of the ammo prop.
Definition: Model.h:300
virtual const CBoundingBoxAligned GetObjectSelectionBoundsRec()
Reimplemented here since proper models should participate in selection boxes.
Definition: Model.cpp:203
void AddAmmoProp(const SPropPoint *point, CModelAbstract *model, CObjectEntry *objectentry)
Add a prop to the model on the given point, and treat it as the ammo prop.
Definition: Model.cpp:528
#define MODELFLAG_CASTSHADOWS
Definition: Model.h:40
void CalcAnimatedObjectBounds(CSkeletonAnimDef *anim, CBoundingBoxAligned &result)
Auxiliary method; calculate object-space bounds encompassing all vertex positions for given animation...
Definition: Model.cpp:144
float m_SoundPos
Definition: SkeletonAnim.h:49
size_t GetNumFrames() const
A simplified syntax for accessing entity components.
Definition: CmpPtr.h:55
CBoundingBoxAligned m_ObjectBounds
Definition: SkeletonAnim.h:51
CMatrix3D m_Transform
Object to parent space transformation.
Definition: ModelDef.h:73
CModelAbstract * FindFirstAmmoProp()
Find the first prop used for ammo, by this model or its own props.
Definition: Model.cpp:570
float m_ActionPos
Definition: SkeletonAnim.h:47
const CBoundingBoxAligned & GetObjectBounds()
Returns the object-space bounds for this model, excluding its children.
Definition: Model.h:157
const SPropPoint * m_Point
Location of the prop point within its parent model, relative to either a bone in the parent model or ...
Definition: Model.h:67
void Concatenate(const CMatrix3D &m)
Definition: Matrix3D.h:188
virtual const CBoundingBoxAligned GetObjectSelectionBoundsRec()
Returns the (object-space) bounds that should be used to construct a selection box for this model and...
Abstract base class for graphical objects that are used by units, or as props attached to other CMode...
Definition: ModelAbstract.h:36
CModel(CSkeletonAnimManager &skeletonAnimManager, CSimulation2 &simulation)
Definition: Model.cpp:47
CVector3D m_Coords
Definition: ModelDef.h:104
static size_t model
Definition: x86_x64.cpp:211
CBoundingBoxAligned m_ObjectBounds
Definition: Model.h:274
float GetDuration() const
~CModel()
Definition: Model.cpp:56
void rtl_FreeAligned(void *alignedPointer)
Definition: gcc.cpp:93
#define MODELFLAG_NOLOOPANIMATION
Definition: Model.h:41
virtual void InvalidateBounds()
Marks the bounds as invalid.
float Z
Definition: Vector3D.h:31
const CMatrix3D & GetTransform() const
void CalcStaticObjectBounds()
Auxiliary method; calculates object space bounds of this model, based solely on vertex positions...
Definition: Model.cpp:130
Definition: Model.h:50
virtual void SetShadingColor(const CColor &colour)
CSkeletonAnim * m_Anim
Definition: Model.h:276
CVector3D GetTranslation() const
Definition: Matrix3D.cpp:195
bool m_SelectionBoxValid
Is the current selection box valid?
CMaterial m_Material
Definition: Model.h:268
const CBoundingBoxAligned & GetWorldBounds()
Returns the world-space axis-aligned bounds of this object.
void RecomputeCombinedShaderDefines()
Definition: Material.cpp:70
void SetPlayerID(player_id_t id)
Definition: Model.cpp:660
CSimulation2 & m_Simulation
Definition: Model.h:263
CObjectEntry * m_ObjectEntry
Definition: Model.h:75
void SetFlags(int flags)
Definition: Model.h:121
CModelAbstract * m_Parent
If non-null, points to the model that we are attached to.
const SPropPoint * m_AmmoPropPoint
The prop point to which the ammo prop is attached, or NULL if none.
Definition: Model.h:295
virtual void ValidatePosition()=0
Ensure that both the transformation and the bone matrices are correct for this model and all its prop...
void CopyAnimationFrom(CModel *source)
Definition: Model.cpp:496
virtual void SetShadingColor(const CColor &colour)
Definition: Model.cpp:668
virtual void InvalidatePosition()
Mark this model&#39;s position and bone matrices, and all props&#39; positions as invalid.
Definition: Model.cpp:309
bool m_Hidden
Should this prop be temporarily removed from rendering?
Definition: Model.h:77
float m_AnimTime
Definition: Model.h:278
void SetMaterial(const CMaterial &material)
Definition: Model.cpp:655
boost::shared_ptr< CModelDef > CModelDefPtr
Definition: MeshManager.h:27
CModelDefPtr m_pModelDef
Definition: Model.h:270
void AddFlagsRec(int flags)
Definition: Model.cpp:624