Pioneer
Model.h
Go to the documentation of this file.
1 // Copyright © 2008-2023 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: https://wiki.pioneerspacesim.net/wiki/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 SceneGraph {
73  class Animation;
74  class BaseLoader;
75  class BinaryConverter;
76  class MatrixTransform;
77  class ModelBinarizer;
78 
79  struct LoadingError : public std::runtime_error {
80  LoadingError(const std::string &str) :
81  std::runtime_error(str.c_str()) {}
82  };
83 
84  typedef std::vector<std::pair<std::string, RefCountedPtr<Graphics::Material>>> MaterialContainer;
85  typedef std::vector<Animation *> AnimationContainer;
86  typedef std::vector<MatrixTransform *> TagContainer;
87 
88  class Model : public DeleteEmitter {
89  public:
90  friend class BaseLoader;
91  friend class Loader;
92  friend class ModelBinarizer;
93  friend class BinaryConverter;
94  Model(Graphics::Renderer *r, const std::string &name);
95  ~Model();
96 
97  Model *MakeInstance() const;
98 
99  const std::string &GetName() const { return m_name; }
100 
101  float GetDrawClipRadius() const { return m_boundingRadius; }
102  void SetDrawClipRadius(float clipRadius) { m_boundingRadius = clipRadius; }
103 
104  void Render(const matrix4x4f &trans, const RenderData *rd = 0); //ModelNode can override RD
105  void Render(const std::vector<matrix4x4f> &trans, const RenderData *rd = 0); //ModelNode can override RD
106 
108  RefCountedPtr<CollMesh> GetCollisionMesh() const { return m_collMesh; }
109  void SetCollisionMesh(RefCountedPtr<CollMesh> collMesh) { m_collMesh.Reset(collMesh.Get()); }
110 
111  RefCountedPtr<Group> GetRoot() { return m_root; }
112 
113  //materials used in the nodes should be accessible from here for convenience
114  RefCountedPtr<Graphics::Material> GetMaterialByName(const std::string &name) const;
116  unsigned int GetNumMaterials() const { return static_cast<Uint32>(m_materials.size()); }
117 
118  unsigned int GetNumTags() const { return static_cast<Uint32>(m_tags.size()); }
119  MatrixTransform *GetTagByIndex(unsigned int index) const;
120  MatrixTransform *FindTagByName(const std::string &name) const;
121  typedef std::vector<MatrixTransform *> TVecMT;
122  void FindTagsByStartOfName(const std::string &name, TVecMT &outNameMTs) const;
123  void AddTag(const std::string &name, MatrixTransform *node);
124 
125  const PatternContainer &GetPatterns() const { return m_patterns; }
126  unsigned int GetNumPatterns() const { return static_cast<Uint32>(m_patterns.size()); }
127  void SetPattern(unsigned int index);
128  unsigned int GetPattern() const { return m_curPatternIndex; }
129  void SetColors(const std::vector<Color> &colors);
130  void SetDecalTexture(Graphics::Texture *t, unsigned int index = 0);
131  void ClearDecal(unsigned int index = 0);
132  void ClearDecals();
133  void SetLabel(const std::string &);
134 
135  //for modelviewer, at least
136  bool SupportsDecals();
137  bool SupportsPatterns();
138 
139  // update all animations once to ensure all transforms are correctly positioned
140  void InitAnimations();
141  // Get an animation matching the given name or return nullptr.
142  Animation *FindAnimation(const std::string &) const;
143  // Get the index of an animation in this container. If there is no such animation, returns UINT32_MAX.
144  uint32_t FindAnimationIndex(Animation *) const;
145  // Return a reference to all animations defined on this model.
146  const std::vector<Animation *> GetAnimations() const { return m_animations; }
147  // Mark an animation as actively updating. A maximum of 64 active animations are supported.
148  void SetAnimationActive(uint32_t index, bool active);
149  bool GetAnimationActive(uint32_t index) const;
150  // Update all active animations.
151  void UpdateAnimations();
152 
153  Graphics::Renderer *GetRenderer() const { return m_renderer; }
154 
155  //special for ship model use
156  void SetThrust(const vector3f &linear, const vector3f &angular);
157 
158  void SetThrusterColor(const vector3f &dir, const Color &color);
159  void SetThrusterColor(const std::string &name, const Color &color);
160  void SetThrusterColor(const Color &color);
161 
162  void SaveToJson(Json &jsonObj) const;
163  void LoadFromJson(const Json &jsonObj);
164 
165  //serialization aid
166  std::string GetNameForMaterial(Graphics::Material *) const;
167 
168  enum DebugFlags { // <enum scope='SceneGraph::Model' name=ModelDebugFlags prefix=DEBUG_ public>
169  DEBUG_NONE = 0x0,
170  DEBUG_BBOX = 0x1,
173  DEBUG_TAGS = 0x8,
175  DEBUG_GEOMBBOX = 0x20
176  };
177  void SetDebugFlags(Uint32 flags);
178 
179  private:
180  Model(const Model &);
181 
182  static const unsigned int MAX_DECAL_MATERIALS = 4;
183  ColorMap m_colorMap;
184  float m_boundingRadius;
185  MaterialContainer m_materials; //materials are shared throughout the model graph
186  PatternContainer m_patterns;
187  RefCountedPtr<CollMesh> m_collMesh;
188  RefCountedPtr<Graphics::Material> m_decalMaterials[MAX_DECAL_MATERIALS]; //spaceship insignia, advertising billboards
189  RefCountedPtr<Group> m_root;
190  Graphics::Renderer *m_renderer;
191  std::string m_name;
192  std::vector<Animation *> m_animations;
193  uint64_t m_activeAnimations; // bitmask of actively ticking animations
194  TagContainer m_tags; //named attachment points
195  RenderData m_renderData;
196 
197  //per-instance flavour data
198  unsigned int m_curPatternIndex;
199  Graphics::Texture *m_curPattern;
200  Graphics::Texture *m_curDecals[MAX_DECAL_MATERIALS];
201 
202  Uint32 m_debugFlags;
203 
204  std::unique_ptr<Graphics::MeshObject> m_debugMesh;
205  std::unique_ptr<Graphics::Material> m_debugLineMat;
206  };
207 
208 } // namespace SceneGraph
209 
210 #endif
nlohmann::json Json
Definition: Json.h:8
Definition: DeleteEmitter.h:16
Definition: Material.h:148
Definition: Renderer.h:44
Definition: Texture.h:106
Definition: Animation.h:19
Definition: BaseLoader.h:18
Definition: BinaryConverter.h:43
Definition: ColorMap.h:19
Definition: Loader.h:32
Definition: MatrixTransform.h:24
Definition: Model.h:88
void Render(const matrix4x4f &trans, const RenderData *rd=0)
Definition: Model.cpp:112
void SetThrusterColor(const vector3f &dir, const Color &color)
Definition: Model.cpp:399
MatrixTransform * GetTagByIndex(unsigned int index) const
Definition: Model.cpp:239
void AddTag(const std::string &name, MatrixTransform *node)
Definition: Model.cpp:269
Model(Graphics::Renderer *r, const std::string &name)
Definition: Model.cpp:38
void UpdateAnimations()
Definition: Model.cpp:356
RefCountedPtr< CollMesh > GetCollisionMesh() const
Definition: Model.h:108
bool SupportsDecals()
Definition: Model.cpp:321
void SetLabel(const std::string &)
Definition: Model.cpp:300
void SetAnimationActive(uint32_t index, bool active)
Definition: Model.cpp:373
std::vector< MatrixTransform * > TVecMT
Definition: Model.h:121
void ClearDecals()
Definition: Model.cpp:307
const PatternContainer & GetPatterns() const
Definition: Model.h:125
const std::string & GetName() const
Definition: Model.h:99
void SetThrust(const vector3f &linear, const vector3f &angular)
Definition: Model.cpp:388
void SetDecalTexture(Graphics::Texture *t, unsigned int index=0)
Definition: Model.cpp:293
void SetDrawClipRadius(float clipRadius)
Definition: Model.h:102
void LoadFromJson(const Json &jsonObj)
Definition: Model.cpp:465
friend class ModelBinarizer
Definition: Model.h:92
unsigned int GetPattern() const
Definition: Model.h:128
bool GetAnimationActive(uint32_t index) const
Definition: Model.cpp:382
MatrixTransform * FindTagByName(const std::string &name) const
Definition: Model.cpp:245
void SetPattern(unsigned int index)
Definition: Model.cpp:278
RefCountedPtr< CollMesh > CreateCollisionMesh()
Definition: Model.cpp:216
float GetDrawClipRadius() const
Definition: Model.h:101
DebugFlags
Definition: Model.h:168
@ DEBUG_GEOMBBOX
Definition: Model.h:175
@ DEBUG_COLLMESH
Definition: Model.h:171
@ DEBUG_NONE
Definition: Model.h:169
@ DEBUG_TAGS
Definition: Model.h:173
@ DEBUG_DOCKING
Definition: Model.h:174
@ DEBUG_WIREFRAME
Definition: Model.h:172
@ DEBUG_BBOX
Definition: Model.h:170
unsigned int GetNumMaterials() const
Definition: Model.h:116
RefCountedPtr< Graphics::Material > GetMaterialByIndex(const int) const
Definition: Model.cpp:234
void SaveToJson(Json &jsonObj) const
Definition: Model.cpp:447
void InitAnimations()
Definition: Model.cpp:350
Model * MakeInstance() const
Definition: Model.cpp:106
Graphics::Renderer * GetRenderer() const
Definition: Model.h:153
std::string GetNameForMaterial(Graphics::Material *) const
Definition: Model.cpp:492
bool SupportsPatterns()
Definition: Model.cpp:329
unsigned int GetNumPatterns() const
Definition: Model.h:126
RefCountedPtr< Group > GetRoot()
Definition: Model.h:111
void SetDebugFlags(Uint32 flags)
Definition: Model.cpp:638
void ClearDecal(unsigned int index=0)
Definition: Model.cpp:314
RefCountedPtr< Graphics::Material > GetMaterialByName(const std::string &name) const
Definition: Model.cpp:225
unsigned int GetNumTags() const
Definition: Model.h:118
uint32_t FindAnimationIndex(Animation *) const
Definition: Model.cpp:364
Animation * FindAnimation(const std::string &) const
Definition: Model.cpp:342
~Model()
Definition: Model.cpp:100
void SetCollisionMesh(RefCountedPtr< CollMesh > collMesh)
Definition: Model.h:109
void FindTagsByStartOfName(const std::string &name, TVecMT &outNameMTs) const
Definition: Model.cpp:256
const std::vector< Animation * > GetAnimations() const
Definition: Model.h:146
void SetColors(const std::vector< Color > &colors)
Definition: Model.cpp:287
T * Get() const
Definition: SmartPtr.h:37
void Reset(T *p=0)
Definition: SmartPtr.h:25
Definition: CityOnPlanet.h:31
std::vector< MatrixTransform * > TagContainer
Definition: Model.h:86
std::vector< std::pair< std::string, RefCountedPtr< Graphics::Material > > > MaterialContainer
Definition: Model.h:84
std::vector< Pattern > PatternContainer
Definition: Pattern.h:34
std::vector< Animation * > AnimationContainer
Definition: Model.h:85
Definition: Color.h:66
Definition: Model.h:79
LoadingError(const std::string &str)
Definition: Model.h:80
Definition: Node.h:44