/
imodel.h
231 lines (191 loc) · 6.44 KB
/
imodel.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#pragma once
#include "Bounded.h"
#include "irender.h"
#include "inode.h"
#include "imodule.h"
/* Forward decls */
class AABB;
class ModelSkin;
namespace model
{
class IModelSurface; // see imodelsurface.h
typedef std::vector<std::string> StringList;
/**
* \brief
* Interface for static models.
*
* This interface provides functions for obtaining information about a LWO or
* ASE model, such as its bounding box or poly count. The interface also
* inherits from OpenGLRenderable to allow model instances to be used for
* rendering.
*/
class IModel
: public OpenGLRenderable,
public Bounded
{
public:
/**
* greebo: The filename (without path) of this model.
*/
virtual std::string getFilename() const = 0;
/**
* greebo: Returns the VFS path which can be used to load
* this model from the modelcache.
*/
virtual std::string getModelPath() const = 0;
/** Apply the given skin to this model.
*
* @param skin
* The ModelSkin instance to apply to this model.
*/
virtual void applySkin(const ModelSkin& skin) = 0;
/** Return the number of material surfaces on this model. Each material
* surface consists of a set of polygons sharing the same material.
*/
virtual int getSurfaceCount() const = 0;
/** Return the number of vertices in this model, equal to the sum of the
* vertex count from each surface.
*/
virtual int getVertexCount() const = 0;
/** Return the number of triangles in this model, equal to the sum of the
* triangle count from each surface.
*/
virtual int getPolyCount() const = 0;
/**
* \brief
* Return a vector of strings listing the active materials used in this
* model, after any skin remaps.
*
* The list is owned by the model instance.
*/
virtual const StringList& getActiveMaterials() const = 0;
/**
* \brief
* Return the surface with the given index
*
* Retrieves the interface of a specific surface, to get access to the
* surface's polygons and vertices.
*
* \param surfaceNum
* The surface index, must be in [0..getSurfaceCount())
*/
virtual const IModelSurface& getSurface(unsigned surfaceNum) const = 0;
};
// Smart pointer typedefs
typedef std::shared_ptr<IModel> IModelPtr;
typedef std::weak_ptr<IModel> IModelWeakPtr;
/**
* greebo: Each node in the scene that represents "just" a model,
* derives from this class. Use a cast on this class to
* identify model nodes in the scene.
*/
class ModelNode
{
public:
virtual ~ModelNode()
{}
// Returns the contained IModel
virtual const IModel& getIModel() const = 0;
// Returns the contained IModel
virtual IModel& getIModel() = 0;
// Returns true if this model's scale has been modified
// and needs to be written to file
virtual bool hasModifiedScale() = 0;
};
typedef std::shared_ptr<ModelNode> ModelNodePtr;
class IModelExporter;
typedef std::shared_ptr<IModelExporter> IModelExporterPtr;
/**
* Exporter Interface for models (meshes).
*/
class IModelExporter
{
public:
virtual ~IModelExporter()
{}
// Virtual constructor idiom. Use this method to generate a new
// instance of the implementing subclass. This way the model format manager
// can create a fresh instance of this exporter on demand.
virtual IModelExporterPtr clone() = 0;
enum class Format
{
Text, // Exporter writes text-based format
Binary, // Exporter exports to a binary stream
};
virtual Format getFileFormat() const = 0;
// Returns the uppercase file extension this exporter is suitable for
virtual const std::string& getExtension() const = 0;
// Adds the given Surface to the exporter's queue
virtual void addSurface(const IModelSurface& surface) = 0;
// Export the model file to the given stream
virtual void exportToStream(std::ostream& stream) = 0;
};
/**
* Importer interface for models. An importer must be able
* to load a model (node) from the VFS.
* The importer instance shouldn't maintain an internal state,
* such that the same instance can be used to load several models,
* from different client code.
*/
class IModelImporter
{
public:
// Returns the uppercase file extension this exporter is suitable for
virtual const std::string& getExtension() const = 0;
/**
* greebo: Returns a newly created model node for the given model name.
*
* @modelName: This is usually the value of the "model" spawnarg of entities.
*
* @returns: the newly created modelnode (can be NULL if the model was not found).
*/
virtual scene::INodePtr loadModel(const std::string& modelName) = 0;
/**
* Load a model from the VFS, and return the IModel subclass for it.
*
* @returns: the IModelPtr containing the renderable model or
* NULL if the model loader could not load the file.
*/
virtual model::IModelPtr loadModelFromPath(const std::string& path) = 0;
};
typedef std::shared_ptr<IModelImporter> IModelImporterPtr;
class IModelFormatManager :
public RegisterableModule
{
public:
virtual ~IModelFormatManager()
{}
// Register/unregister an importer class
virtual void registerImporter(const IModelImporterPtr& importer) = 0;
virtual void unregisterImporter(const IModelImporterPtr& importer) = 0;
// Find an importer for the given extension, returns the NullModelLoader if nothing found
// Passing in an empty extension will return the NullModelLoader as well
virtual IModelImporterPtr getImporter(const std::string& extension) = 0;
// Register/unregister an exporter class
virtual void registerExporter(const IModelExporterPtr& exporter) = 0;
virtual void unregisterExporter(const IModelExporterPtr& exporter) = 0;
// Find an exporter for the given extension, returns empty if nothing found
virtual IModelExporterPtr getExporter(const std::string& extension) = 0;
};
} // namespace model
// Utility methods
inline bool Node_isModel(const scene::INodePtr& node)
{
return std::dynamic_pointer_cast<model::ModelNode>(node) != nullptr;
}
inline model::ModelNodePtr Node_getModel(const scene::INodePtr& node)
{
return std::dynamic_pointer_cast<model::ModelNode>(node);
}
// Contains the default format used for exporting scaled models
const char* const RKEY_DEFAULT_MODEL_EXPORT_FORMAT = "user/ui/map/defaultScaledModelExportFormat";
const char* const MODULE_MODELFORMATMANAGER("ModelFormatManager");
inline model::IModelFormatManager& GlobalModelFormatManager()
{
std::shared_ptr<model::IModelFormatManager> _modelFormatManager(
std::static_pointer_cast<model::IModelFormatManager>(
module::GlobalModuleRegistry().getModule(MODULE_MODELFORMATMANAGER)
)
);
return *_modelFormatManager;
}