Pioneer
Model.h
Go to the documentation of this file.
1 // Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #ifndef _SCENEGRAPH_MODEL_H
5 #define _SCENEGRAPH_MODEL_H
6 /*
7  * A new model system with a scene graph based approach.
8  * Also see: http://pioneerwiki.com/wiki/New_Model_System
9  * Open Asset Import Library (assimp) is used as the mesh loader.
10  *
11  * Similar systems:
12  * - OpenSceneGraph http://www.openscenegraph.org/projects/osg has been
13  * an inspiration for naming some things and it also uses node visitors.
14  * It is a lot more complicated however
15  * - Assimp also has its own scenegraph structure (much simpler)
16  *
17  * A model has an internal stucture of one or (almost always several) nodes
18  * For example:
19  * RootNode
20  * MatrixTransformNode (applies a scale or something to child nodes)
21  * LodSwitchNode (picks 1-3)
22  * StaticGeometry_low
23  * StaticGeometry_med
24  * StaticGeometry_hi
25  *
26  * It's not supposed to be too complex. For example there are no "Material" nodes.
27  * Geometry nodes can contain multiple separate meshes. One node can be attached to
28  * multiple parents to achieve a simple form of instancing, although the support for
29  * this is dependanant on tools.
30  *
31  * Models are defined in a simple .model text file, which describes materials,
32  * detail levels, meshes to import to each detail level and animations.
33  *
34  * While assimp supports a large number of formats most models are expected
35  * to use Collada (.dae). The format needs to support node names since many
36  * special features are based on that.
37  *
38  * Loading all the meshes can be quite slow, so there will be a system to
39  * compile them into a more game-friendly binary format.
40  *
41  * Animation: position/rotation/scale keyframe animation affecting MatrixTransforms,
42  * and subsequently nodes attached to them. There is no animation blending, although
43  * an animated matrixtransform can be attached to another further down the chain just fine.
44  * Due to format & exporter limitations, animations need to be combined into one timeline
45  * and then split into new animations using frame ranges.
46  *
47  * Attaching models to other models (guns etc. to ships): models may specify
48  * named hardpoints, known as "tags" (term from Q3).
49  * Users can query tags by name or index and create a ModelNode to wrap the sub model
50  *
51  * Minor features:
52  * - pattern + customizable colour system (one pattern per model). Patterns can be
53  * dropped into the model directory.
54  * - dynamic textures (logos on spaceships, advertisements on stations)
55  * - 3D labels (well, 2D) on models
56  * - spaceship thrusters
57  *
58  * Things to optimize:
59  * - model cache
60  * - removing unnecessary nodes from the scene graph: pre-translate unanimated meshes etc.
61  */
62 #include "CollMesh.h"
63 #include "ColorMap.h"
64 #include "DeleteEmitter.h"
65 #include "Group.h"
66 #include "JsonFwd.h"
67 #include "Pattern.h"
68 #include "graphics/Drawables.h"
69 #include "graphics/Material.h"
70 #include <stdexcept>
71 
72 namespace Graphics {
73  class Renderer;
74  class RenderState;
75  class VertexBuffer;
76 } // namespace Graphics
77 
78 namespace SceneGraph {
79  class Animation;
80  class BaseLoader;
81  class BinaryConverter;
82  class MatrixTransform;
83  class ModelBinarizer;
84 
85  struct LoadingError : public std::runtime_error {
86  LoadingError(const std::string &str) :
87  std::runtime_error(str.c_str()) {}
88  };
89 
90  typedef std::vector<std::pair<std::string, RefCountedPtr<Graphics::Material>>> MaterialContainer;
91  typedef std::vector<Animation *> AnimationContainer;
92  typedef std::vector<MatrixTransform *> TagContainer;
93 
94  class Model : public DeleteEmitter {
95  public:
96  friend class BaseLoader;
97  friend class Loader;
98  friend class ModelBinarizer;
99  friend class BinaryConverter;
100  Model(Graphics::Renderer *r, const std::string &name);
101  ~Model();
102 
103  Model *MakeInstance() const;
104 
105  const std::string &GetName() const { return m_name; }
106 
107  float GetDrawClipRadius() const { return m_boundingRadius; }
108  void SetDrawClipRadius(float clipRadius) { m_boundingRadius = clipRadius; }
109 
110  void Render(const matrix4x4f &trans, const RenderData *rd = 0); //ModelNode can override RD
111  void Render(const std::vector<matrix4x4f> &trans, const RenderData *rd = 0); //ModelNode can override RD
112 
114  RefCountedPtr<CollMesh> GetCollisionMesh() const { return m_collMesh; }
115  void SetCollisionMesh(RefCountedPtr<CollMesh> collMesh) { m_collMesh.Reset(collMesh.Get()); }
116 
117  RefCountedPtr<Group> GetRoot() { return m_root; }
118 
119  //materials used in the nodes should be accessible from here for convenience
120  RefCountedPtr<Graphics::Material> GetMaterialByName(const std::string &name) const;
122  unsigned int GetNumMaterials() const { return static_cast<Uint32>(m_materials.size()); }
123 
124  unsigned int GetNumTags() const { return static_cast<Uint32>(m_tags.size()); }
125  MatrixTransform *GetTagByIndex(unsigned int index) const;
126  MatrixTransform *FindTagByName(const std::string &name) const;
127  typedef std::vector<MatrixTransform *> TVecMT;
128  void FindTagsByStartOfName(const std::string &name, TVecMT &outNameMTs) const;
129  void AddTag(const std::string &name, MatrixTransform *node);
130 
131  const PatternContainer &GetPatterns() const { return m_patterns; }
132  unsigned int GetNumPatterns() const { return static_cast<Uint32>(m_patterns.size()); }
133  void SetPattern(unsigned int index);
134  unsigned int GetPattern() const { return m_curPatternIndex; }
135  void SetColors(const std::vector<Color> &colors);
136  void SetDecalTexture(Graphics::Texture *t, unsigned int index = 0);
137  void ClearDecal(unsigned int index = 0);
138  void ClearDecals();
139  void SetLabel(const std::string &);
140 
141  //for modelviewer, at least
142  bool SupportsDecals();
143  bool SupportsPatterns();
144 
145  // update all animations once to ensure all transforms are correctly positioned
146  void InitAnimations();
147  // Get an animation matching the given name or return nullptr.
148  Animation *FindAnimation(const std::string &) const;
149  // Get the index of an animation in this container. If there is no such animation, returns UINT32_MAX.
150  uint32_t FindAnimationIndex(Animation *) const;
151  // Return a reference to all animations defined on this model.
152  const std::vector<Animation *> GetAnimations() const { return m_animations; }
153  // Mark an animation as actively updating. A maximum of 64 active animations are supported.
154  void SetAnimationActive(uint32_t index, bool active);
155  bool GetAnimationActive(uint32_t index) const;
156  // Update all active animations.
157  void UpdateAnimations();
158 
159  Graphics::Renderer *GetRenderer() const { return m_renderer; }
160 
161  //special for ship model use
162  void SetThrust(const vector3f &linear, const vector3f &angular);
163 
164  void SetThrusterColor(const vector3f &dir, const Color &color);
165  void SetThrusterColor(const std::string &name, const Color &color);
166  void SetThrusterColor(const Color &color);
167 
168  void SaveToJson(Json &jsonObj) const;
169  void LoadFromJson(const Json &jsonObj);
170 
171  //serialization aid
172  std::string GetNameForMaterial(Graphics::Material *) const;
173 
174  enum DebugFlags { // <enum scope='SceneGraph::Model' name=ModelDebugFlags prefix=DEBUG_ public>
175  DEBUG_NONE = 0x0,
176  DEBUG_BBOX = 0x1,
179  DEBUG_TAGS = 0x8,
180  DEBUG_DOCKING = 0x10
181  };
182  void SetDebugFlags(Uint32 flags);
183 
184  private:
185  Model(const Model &);
186 
187  static const unsigned int MAX_DECAL_MATERIALS = 4;
188  ColorMap m_colorMap;
189  float m_boundingRadius;
190  MaterialContainer m_materials; //materials are shared throughout the model graph
191  PatternContainer m_patterns;
192  RefCountedPtr<CollMesh> m_collMesh;
193  RefCountedPtr<Graphics::Material> m_decalMaterials[MAX_DECAL_MATERIALS]; //spaceship insignia, advertising billboards
194  RefCountedPtr<Group> m_root;
195  Graphics::Renderer *m_renderer;
196  std::string m_name;
197  std::vector<Animation *> m_animations;
198  uint64_t m_activeAnimations; // bitmask of actively ticking animations
199  TagContainer m_tags; //named attachment points
200  RenderData m_renderData;
201 
202  //per-instance flavour data
203  unsigned int m_curPatternIndex;
204  Graphics::Texture *m_curPattern;
205  Graphics::Texture *m_curDecals[MAX_DECAL_MATERIALS];
206 
207  // debug support
208  void CreateAabbVB();
209  void DrawAabb();
210  void DrawCollisionMesh();
211  void DrawAxisIndicators(std::vector<Graphics::Drawables::Line3D> &lines);
212  void AddAxisIndicators(const std::vector<MatrixTransform *> &mts, std::vector<Graphics::Drawables::Line3D> &lines);
213 
214  Uint32 m_debugFlags;
215  std::vector<Graphics::Drawables::Line3D> m_tagPoints;
216  std::vector<Graphics::Drawables::Line3D> m_dockingPoints;
217  RefCountedPtr<Graphics::VertexBuffer> m_collisionMeshVB;
220  Graphics::RenderState *m_state;
221  };
222 
223 } // namespace SceneGraph
224 
225 #endif
nlohmann::json Json
Definition: Json.h:8
Definition: DeleteEmitter.h:16
Definition: Material.h:81
Definition: RenderState.h:25
Definition: Renderer.h:39
Definition: Texture.h:106
Definition: Animation.h:19
Definition: BaseLoader.h:18
Definition: BinaryConverter.h:32
Definition: ColorMap.h:19
Definition: Loader.h:32
Definition: MatrixTransform.h:24
Definition: Model.h:94
void Render(const matrix4x4f &trans, const RenderData *rd=0)
Definition: Model.cpp:107
void SetThrusterColor(const vector3f &dir, const Color &color)
Definition: Model.cpp:512
MatrixTransform * GetTagByIndex(unsigned int index) const
Definition: Model.cpp:352
void AddTag(const std::string &name, MatrixTransform *node)
Definition: Model.cpp:382
Model(Graphics::Renderer *r, const std::string &name)
Definition: Model.cpp:34
void UpdateAnimations()
Definition: Model.cpp:469
RefCountedPtr< CollMesh > GetCollisionMesh() const
Definition: Model.h:114
bool SupportsDecals()
Definition: Model.cpp:434
void SetLabel(const std::string &)
Definition: Model.cpp:413
void SetAnimationActive(uint32_t index, bool active)
Definition: Model.cpp:486
std::vector< MatrixTransform * > TVecMT
Definition: Model.h:127
void ClearDecals()
Definition: Model.cpp:420
const PatternContainer & GetPatterns() const
Definition: Model.h:131
const std::string & GetName() const
Definition: Model.h:105
void SetThrust(const vector3f &linear, const vector3f &angular)
Definition: Model.cpp:501
void SetDecalTexture(Graphics::Texture *t, unsigned int index=0)
Definition: Model.cpp:406
void SetDrawClipRadius(float clipRadius)
Definition: Model.h:108
void LoadFromJson(const Json &jsonObj)
Definition: Model.cpp:578
friend class ModelBinarizer
Definition: Model.h:98
unsigned int GetPattern() const
Definition: Model.h:134
bool GetAnimationActive(uint32_t index) const
Definition: Model.cpp:495
MatrixTransform * FindTagByName(const std::string &name) const
Definition: Model.cpp:358
void SetPattern(unsigned int index)
Definition: Model.cpp:391
RefCountedPtr< CollMesh > CreateCollisionMesh()
Definition: Model.cpp:329
float GetDrawClipRadius() const
Definition: Model.h:107
DebugFlags
Definition: Model.h:174
@ DEBUG_COLLMESH
Definition: Model.h:177
@ DEBUG_NONE
Definition: Model.h:175
@ DEBUG_TAGS
Definition: Model.h:179
@ DEBUG_DOCKING
Definition: Model.h:180
@ DEBUG_WIREFRAME
Definition: Model.h:178
@ DEBUG_BBOX
Definition: Model.h:176
unsigned int GetNumMaterials() const
Definition: Model.h:122
RefCountedPtr< Graphics::Material > GetMaterialByIndex(const int) const
Definition: Model.cpp:347
void SaveToJson(Json &jsonObj) const
Definition: Model.cpp:560
void InitAnimations()
Definition: Model.cpp:463
Model * MakeInstance() const
Definition: Model.cpp:101
Graphics::Renderer * GetRenderer() const
Definition: Model.h:159
std::string GetNameForMaterial(Graphics::Material *) const
Definition: Model.cpp:605
bool SupportsPatterns()
Definition: Model.cpp:442
unsigned int GetNumPatterns() const
Definition: Model.h:132
RefCountedPtr< Group > GetRoot()
Definition: Model.h:117
void SetDebugFlags(Uint32 flags)
Definition: Model.cpp:652
void ClearDecal(unsigned int index=0)
Definition: Model.cpp:427
RefCountedPtr< Graphics::Material > GetMaterialByName(const std::string &name) const
Definition: Model.cpp:338
unsigned int GetNumTags() const
Definition: Model.h:124
uint32_t FindAnimationIndex(Animation *) const
Definition: Model.cpp:477
Animation * FindAnimation(const std::string &) const
Definition: Model.cpp:455
~Model()
Definition: Model.cpp:95
void SetCollisionMesh(RefCountedPtr< CollMesh > collMesh)
Definition: Model.h:115
void FindTagsByStartOfName(const std::string &name, TVecMT &outNameMTs) const
Definition: Model.cpp:369
const std::vector< Animation * > GetAnimations() const
Definition: Model.h:152
void SetColors(const std::vector< Color > &colors)
Definition: Model.cpp:400
T * Get() const
Definition: SmartPtr.h:37
void Reset(T *p=0)
Definition: SmartPtr.h:25
Definition: Background.h:13
Definition: CityOnPlanet.h:23
std::vector< MatrixTransform * > TagContainer
Definition: Model.h:92
std::vector< std::pair< std::string, RefCountedPtr< Graphics::Material > > > MaterialContainer
Definition: Model.h:90
std::vector< Pattern > PatternContainer
Definition: Pattern.h:34
std::vector< Animation * > AnimationContainer
Definition: Model.h:91
Definition: Color.h:66
Definition: Model.h:85
LoadingError(const std::string &str)
Definition: Model.h:86
Definition: Node.h:44