Pioneer
Loading...
Searching...
No Matches
Model.h
Go to the documentation of this file.
1// Copyright © 2008-2024 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. Nodes should only be attached
28 * to a single parent for consistency.
29 *
30 * Models are defined in a simple .model text file, which describes materials,
31 * detail levels, meshes to import to each detail level and animations.
32 *
33 * While assimp supports a large number of formats most models are expected
34 * to use Collada (.dae). The format needs to support node names since many
35 * special features are based on that.
36 *
37 * Loading all the meshes can be quite slow, so there will be a system to
38 * compile them into a more game-friendly binary format.
39 *
40 * Animation: position/rotation/scale keyframe animation affecting MatrixTransforms,
41 * and subsequently nodes attached to them. There is no animation blending, although
42 * an animated matrixtransform can be attached to another further down the chain just fine.
43 * Due to format & exporter limitations, animations need to be combined into one timeline
44 * and then split into new animations using frame ranges.
45 *
46 * Attaching models to other models (guns etc. to ships): models may specify
47 * named hardpoints, known as "tags" (term from Q3).
48 * Users can query tags by name or index and create a ModelNode to wrap the sub model
49 *
50 * Minor features:
51 * - pattern + customizable colour system (one pattern per model). Patterns can be
52 * dropped into the model directory.
53 * - dynamic textures (logos on spaceships, advertisements on stations)
54 * - 3D labels (well, 2D) on models
55 * - spaceship thrusters
56 *
57 * Things to optimize:
58 * - model cache
59 * - removing unnecessary nodes from the scene graph: pre-translate unanimated meshes etc.
60 */
61#include "CollMesh.h"
62#include "ColorMap.h"
63#include "DeleteEmitter.h"
64#include "Group.h"
65#include "JsonFwd.h"
66#include "Pattern.h"
67#include "graphics/Drawables.h"
68#include "graphics/Material.h"
69#include <stdexcept>
70
71namespace SceneGraph {
72 class Animation;
73 class BaseLoader;
74 class BinaryConverter;
75 class MatrixTransform;
76 class ModelBinarizer;
77 class Tag;
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
87 class Model : public DeleteEmitter {
88 public:
89 friend class BaseLoader;
90 friend class Loader;
91 friend class ModelBinarizer;
92 friend class BinaryConverter;
93 Model(Graphics::Renderer *r, const std::string &name);
94 ~Model();
95
96 Model *MakeInstance() const;
97
98 const std::string &GetName() const { return m_name; }
99
100 float GetDrawClipRadius() const { return m_boundingRadius; }
101 void SetDrawClipRadius(float clipRadius) { m_boundingRadius = clipRadius; }
102
103 void Render(const matrix4x4f &trans, const RenderData *rd = 0); //ModelNode can override RD
104 void Render(const std::vector<matrix4x4f> &trans, const RenderData *rd = 0); //ModelNode can override RD
105
107 RefCountedPtr<CollMesh> GetCollisionMesh() const { return m_collMesh; }
108 void SetCollisionMesh(RefCountedPtr<CollMesh> collMesh) { m_collMesh.Reset(collMesh.Get()); }
109
110 RefCountedPtr<Group> GetRoot() { return m_root; }
111
112 //materials used in the nodes should be accessible from here for convenience
113 RefCountedPtr<Graphics::Material> GetMaterialByName(const std::string &name) const;
115 unsigned int GetNumMaterials() const { return static_cast<Uint32>(m_materials.size()); }
116
117 // Utilities for iterating the array of model tags
118 // Tag indicies should not be considered stable
119 size_t GetNumTags() const { return m_tags.size(); }
120 Tag *GetTagByIndex(size_t index) const;
121
122 // Find the given tag in the model
123 Tag *FindTagByName(std::string_view name) const;
124 void FindTagsByStartOfName(std::string_view name, std::vector<Tag *> &outTags) const;
125
126 // Add a tag to this model in the given parent
127 void AddTag(std::string_view name, Group *parent, Tag *node);
128 // Recalculate tag global transforms after e.g. animation changes
129 void UpdateTagTransforms();
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>
181 DEBUG_GEOMBBOX = 0x20
182 };
183 void SetDebugFlags(Uint32 flags);
184
185 private:
186 Model(const Model &);
187
188 static const unsigned int MAX_DECAL_MATERIALS = 4;
189 ColorMap m_colorMap;
190 float m_boundingRadius;
191 MaterialContainer m_materials; //materials are shared throughout the model graph
192 PatternContainer m_patterns;
193 RefCountedPtr<CollMesh> m_collMesh;
194 RefCountedPtr<Graphics::Material> m_decalMaterials[MAX_DECAL_MATERIALS]; //spaceship insignia, advertising billboards
196 Graphics::Renderer *m_renderer;
197 std::string m_name;
198
199 std::vector<Animation *> m_animations;
200 uint64_t m_activeAnimations; // bitmask of actively ticking animations
201
202 std::vector<Tag *> m_tags; //named attachment points
203
204 RenderData m_renderData;
205
206 //per-instance flavour data
207 unsigned int m_curPatternIndex;
208 Graphics::Texture *m_curPattern;
209 Graphics::Texture *m_curDecals[MAX_DECAL_MATERIALS];
210
211 Uint32 m_debugFlags;
212 bool m_tagsDirty;
213
214 std::unique_ptr<Graphics::MeshObject> m_debugMesh;
215 std::unique_ptr<Graphics::Material> m_debugLineMat;
216 };
217
218} // namespace SceneGraph
219
220#endif
nlohmann::json Json
Definition: Json.h:8
Definition: DeleteEmitter.h:16
Definition: Material.h:148
Definition: Renderer.h:45
Definition: Texture.h:103
Definition: RefCounted.h:36
Definition: Animation.h:19
Definition: BaseLoader.h:17
Definition: BinaryConverter.h:44
Definition: ColorMap.h:18
Definition: Group.h:13
Definition: Loader.h:32
Definition: Model.h:87
void AddTag(std::string_view name, Group *parent, Tag *node)
Definition: Model.cpp:272
void Render(const matrix4x4f &trans, const RenderData *rd=0)
Definition: Model.cpp:116
void SetThrusterColor(const vector3f &dir, const Color &color)
Definition: Model.cpp:419
const std::string & GetName() const
Definition: Model.h:98
void FindTagsByStartOfName(std::string_view name, std::vector< Tag * > &outTags) const
Definition: Model.cpp:261
RefCountedPtr< CollMesh > GetCollisionMesh() const
Definition: Model.h:107
void UpdateAnimations()
Definition: Model.cpp:369
bool SupportsDecals()
Definition: Model.cpp:334
void SetLabel(const std::string &)
Definition: Model.cpp:313
void SetAnimationActive(uint32_t index, bool active)
Definition: Model.cpp:393
Graphics::Renderer * GetRenderer() const
Definition: Model.h:159
void ClearDecals()
Definition: Model.cpp:320
size_t GetNumTags() const
Definition: Model.h:119
Tag * GetTagByIndex(size_t index) const
Definition: Model.cpp:243
void SetThrust(const vector3f &linear, const vector3f &angular)
Definition: Model.cpp:408
void SetDecalTexture(Graphics::Texture *t, unsigned int index=0)
Definition: Model.cpp:306
void UpdateTagTransforms()
Definition: Model.cpp:282
void SetDrawClipRadius(float clipRadius)
Definition: Model.h:101
void LoadFromJson(const Json &jsonObj)
Definition: Model.cpp:485
friend class ModelBinarizer
Definition: Model.h:91
unsigned int GetPattern() const
Definition: Model.h:134
bool GetAnimationActive(uint32_t index) const
Definition: Model.cpp:402
Tag * FindTagByName(std::string_view name) const
Definition: Model.cpp:251
void SetPattern(unsigned int index)
Definition: Model.cpp:291
RefCountedPtr< CollMesh > CreateCollisionMesh()
Definition: Model.cpp:220
float GetDrawClipRadius() const
Definition: Model.h:100
DebugFlags
Definition: Model.h:174
@ DEBUG_GEOMBBOX
Definition: Model.h:181
@ 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:115
RefCountedPtr< Graphics::Material > GetMaterialByIndex(const int) const
Definition: Model.cpp:238
void SaveToJson(Json &jsonObj) const
Definition: Model.cpp:467
void InitAnimations()
Definition: Model.cpp:363
Model * MakeInstance() const
Definition: Model.cpp:110
const PatternContainer & GetPatterns() const
Definition: Model.h:131
std::string GetNameForMaterial(Graphics::Material *) const
Definition: Model.cpp:512
bool SupportsPatterns()
Definition: Model.cpp:342
unsigned int GetNumPatterns() const
Definition: Model.h:132
RefCountedPtr< Group > GetRoot()
Definition: Model.h:110
void SetDebugFlags(Uint32 flags)
Definition: Model.cpp:630
void ClearDecal(unsigned int index=0)
Definition: Model.cpp:327
RefCountedPtr< Graphics::Material > GetMaterialByName(const std::string &name) const
Definition: Model.cpp:229
uint32_t FindAnimationIndex(Animation *) const
Definition: Model.cpp:384
const std::vector< Animation * > GetAnimations() const
Definition: Model.h:152
Animation * FindAnimation(const std::string &) const
Definition: Model.cpp:355
~Model()
Definition: Model.cpp:104
void SetCollisionMesh(RefCountedPtr< CollMesh > collMesh)
Definition: Model.h:108
void SetColors(const std::vector< Color > &colors)
Definition: Model.cpp:300
Definition: Tag.h:18
T * Get() const
Definition: SmartPtr.h:37
void Reset(T *p=0)
Definition: SmartPtr.h:25
Definition: CityOnPlanet.h:32
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:47