/src/assimp/code/AssetLib/Collada/ColladaExporter.h
Line | Count | Source |
1 | | /* |
2 | | Open Asset Import Library (assimp) |
3 | | ---------------------------------------------------------------------- |
4 | | |
5 | | Copyright (c) 2006-2026, assimp team |
6 | | |
7 | | All rights reserved. |
8 | | |
9 | | Redistribution and use of this software in source and binary forms, |
10 | | with or without modification, are permitted provided that the |
11 | | following conditions are met: |
12 | | |
13 | | * Redistributions of source code must retain the above |
14 | | copyright notice, this list of conditions and the |
15 | | following disclaimer. |
16 | | |
17 | | * Redistributions in binary form must reproduce the above |
18 | | copyright notice, this list of conditions and the |
19 | | following disclaimer in the documentation and/or other |
20 | | materials provided with the distribution. |
21 | | |
22 | | * Neither the name of the assimp team, nor the names of its |
23 | | contributors may be used to endorse or promote products |
24 | | derived from this software without specific prior |
25 | | written permission of the assimp team. |
26 | | |
27 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
28 | | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
29 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
30 | | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
31 | | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
32 | | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
33 | | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
34 | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
35 | | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
36 | | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
37 | | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
38 | | |
39 | | ---------------------------------------------------------------------- |
40 | | */ |
41 | | |
42 | | /** @file ColladaExporter.h |
43 | | * Declares the exporter class to write a scene to a Collada file |
44 | | */ |
45 | | #ifndef AI_COLLADAEXPORTER_H_INC |
46 | | #define AI_COLLADAEXPORTER_H_INC |
47 | | |
48 | | #include <assimp/ai_assert.h> |
49 | | #include <assimp/material.h> |
50 | | |
51 | | #include <array> |
52 | | #include <map> |
53 | | #include <sstream> |
54 | | #include <unordered_set> |
55 | | #include <vector> |
56 | | |
57 | | struct aiScene; |
58 | | struct aiNode; |
59 | | struct aiLight; |
60 | | struct aiBone; |
61 | | |
62 | | namespace Assimp { |
63 | | |
64 | | class IOSystem; |
65 | | |
66 | | /// Helper class to export a given scene to a Collada file. Just for my personal |
67 | | /// comfort when implementing it. |
68 | | class ColladaExporter final { |
69 | | public: |
70 | | /// Constructor for a specific scene to export |
71 | | ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, const std::string &path, const std::string &file); |
72 | | |
73 | | /// Destructor |
74 | 0 | virtual ~ColladaExporter() = default; |
75 | | |
76 | | protected: |
77 | | /// Starts writing the contents |
78 | | void WriteFile(); |
79 | | |
80 | | /// Writes the asset header |
81 | | void WriteHeader(); |
82 | | |
83 | | /// Writes the embedded textures |
84 | | void WriteTextures(); |
85 | | |
86 | | /// Writes the material setup |
87 | | void WriteMaterials(); |
88 | | |
89 | | /// Writes the cameras library |
90 | | void WriteCamerasLibrary(); |
91 | | |
92 | | // Write a camera entry |
93 | | void WriteCamera(size_t pIndex); |
94 | | |
95 | | /// Writes the cameras library |
96 | | void WriteLightsLibrary(); |
97 | | |
98 | | // Write a camera entry |
99 | | void WriteLight(size_t pIndex); |
100 | | void WritePointLight(const aiLight *const light); |
101 | | void WriteDirectionalLight(const aiLight *const light); |
102 | | void WriteSpotLight(const aiLight *const light); |
103 | | void WriteAmbientLight(const aiLight *const light); |
104 | | |
105 | | /// Writes the controller library |
106 | | void WriteControllerLibrary(); |
107 | | |
108 | | /// Writes a skin controller of the given mesh |
109 | | void WriteController(size_t pIndex); |
110 | | |
111 | | /// Writes the geometry library |
112 | | void WriteGeometryLibrary(); |
113 | | |
114 | | /// Writes the given mesh |
115 | | void WriteGeometry(size_t pIndex); |
116 | | |
117 | | //enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight }; |
118 | | // customized to add animation related type |
119 | | enum FloatDataType { FloatType_Vector, |
120 | | FloatType_TexCoord2, |
121 | | FloatType_TexCoord3, |
122 | | FloatType_Color, |
123 | | FloatType_Mat4x4, |
124 | | FloatType_Weight, |
125 | | FloatType_Time }; |
126 | | |
127 | | /// Writes a float array of the given type |
128 | | void WriteFloatArray(const std::string &pIdString, FloatDataType pType, const ai_real *pData, size_t pElementCount); |
129 | | |
130 | | /// Writes the scene library |
131 | | void WriteSceneLibrary(); |
132 | | |
133 | | // customized, Writes the animation library |
134 | | void WriteAnimationsLibrary(); |
135 | | void WriteAnimationLibrary(size_t pIndex); |
136 | | std::string mFoundSkeletonRootNodeID = "skeleton_root"; // will be replaced by found node id in the WriteNode call. |
137 | | |
138 | | /// Recursively writes the given node |
139 | | void WriteNode(const aiNode *pNode); |
140 | | |
141 | | /// Enters a new xml element, which increases the indentation |
142 | 0 | void PushTag() { startstr.append(" "); } |
143 | | /// Leaves an element, decreasing the indentation |
144 | 0 | void PopTag() { |
145 | 0 | ai_assert(startstr.length() > 1); |
146 | 0 | startstr.erase(startstr.length() - 2); |
147 | 0 | } |
148 | | |
149 | | void CreateNodeIds(const aiNode *node); |
150 | | |
151 | | /// Get or Create a unique Node ID string for the given Node |
152 | | std::string GetNodeUniqueId(const aiNode *node); |
153 | | std::string GetNodeName(const aiNode *node); |
154 | | |
155 | | std::string GetBoneUniqueId(const aiBone *bone); |
156 | | |
157 | | enum class AiObjectType { |
158 | | Mesh, |
159 | | Material, |
160 | | Animation, |
161 | | Light, |
162 | | Camera, |
163 | | Count, |
164 | | }; |
165 | | /// Get or Create a unique ID string for the given scene object index |
166 | | std::string GetObjectUniqueId(AiObjectType type, size_t pIndex); |
167 | | /// Get or Create a name string for the given scene object index |
168 | | std::string GetObjectName(AiObjectType type, size_t pIndex); |
169 | | |
170 | | typedef std::map<size_t, std::string> IndexIdMap; |
171 | | typedef std::pair<std::string, std::string> NameIdPair; |
172 | | NameIdPair AddObjectIndexToMaps(AiObjectType type, size_t pIndex); |
173 | | |
174 | | // Helpers |
175 | 0 | inline IndexIdMap &GetObjectIdMap(AiObjectType type) { return mObjectIdMap[static_cast<size_t>(type)]; } |
176 | 0 | inline IndexIdMap &GetObjectNameMap(AiObjectType type) { return mObjectNameMap[static_cast<size_t>(type)]; } |
177 | | |
178 | | private: |
179 | | std::unordered_set<std::string> mUniqueIds; // Cache of used unique ids |
180 | | std::map<const void *, std::string> mNodeIdMap; // Cache of encoded node and bone ids |
181 | | std::array<IndexIdMap, static_cast<size_t>(AiObjectType::Count)> mObjectIdMap; // Cache of encoded unique IDs |
182 | | std::array<IndexIdMap, static_cast<size_t>(AiObjectType::Count)> mObjectNameMap; // Cache of encoded names |
183 | | |
184 | | public: |
185 | | /// Stringstream to write all output into |
186 | | std::stringstream mOutput; |
187 | | |
188 | | /// The IOSystem for output |
189 | | IOSystem *mIOSystem; |
190 | | |
191 | | /// Path of the directory where the scene will be exported |
192 | | const std::string mPath; |
193 | | |
194 | | /// Name of the file (without extension) where the scene will be exported |
195 | | const std::string mFile; |
196 | | |
197 | | /// The scene to be written |
198 | | const aiScene *const mScene; |
199 | | std::string mSceneId; |
200 | | bool mAdd_root_node = false; |
201 | | |
202 | | /// current line start string, contains the current indentation for simple stream insertion |
203 | | std::string startstr; |
204 | | /// current line end string for simple stream insertion |
205 | | const std::string endstr; |
206 | | |
207 | | // pair of color and texture - texture precedences color |
208 | | struct Surface { |
209 | | bool exist; |
210 | | aiColor4D color; |
211 | | std::string texture; |
212 | | size_t channel; |
213 | 0 | Surface() { |
214 | 0 | exist = false; |
215 | 0 | channel = 0; |
216 | 0 | } |
217 | | }; |
218 | | |
219 | | struct Property { |
220 | | bool exist; |
221 | | ai_real value; |
222 | | Property() : |
223 | 0 | exist(false), |
224 | 0 | value(0.0) {} |
225 | | }; |
226 | | |
227 | | // summarize a material in an convenient way. |
228 | | struct Material { |
229 | | std::string id; |
230 | | std::string name; |
231 | | std::string shading_model; |
232 | | Surface ambient, diffuse, specular, emissive, reflective, transparent, normal; |
233 | | Property shininess, transparency, index_refraction; |
234 | | |
235 | 0 | Material() = default; |
236 | | }; |
237 | | |
238 | | std::map<unsigned int, std::string> textures; |
239 | | |
240 | | public: |
241 | | /// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions |
242 | | /// Reads a single surface entry from the given material keys |
243 | | bool ReadMaterialSurface(Surface &poSurface, const aiMaterial &pSrcMat, aiTextureType pTexture, const char *pKey, size_t pType, size_t pIndex); |
244 | | /// Writes an image entry for the given surface |
245 | | void WriteImageEntry(const Surface &pSurface, const std::string &imageId); |
246 | | /// Writes the two parameters necessary for referencing a texture in an effect entry |
247 | | void WriteTextureParamEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &materialId); |
248 | | /// Writes a color-or-texture entry into an effect definition |
249 | | void WriteTextureColorEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &imageId); |
250 | | /// Writes a scalar property |
251 | | void WriteFloatEntry(const Property &pProperty, const std::string &pTypeName); |
252 | | }; |
253 | | |
254 | | } // namespace Assimp |
255 | | |
256 | | #endif // !! AI_COLLADAEXPORTER_H_INC |