1/*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
4
5 Copyright (c) 2006-2025, 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 ColladaParser.h
43 * @brief Defines the parser helper class for the collada loader
44 */
45
46#pragma once
47#ifndef AI_COLLADAPARSER_H_INC
48#define AI_COLLADAPARSER_H_INC
49
50#include "ColladaHelper.h"
51#include <assimp/ai_assert.h>
52#include <assimp/XmlParser.h>
53
54#include <map>
55
56namespace Assimp {
57
58class ZipArchiveIOSystem;
59
60// ------------------------------------------------------------------------------------------
61/** Parser helper class for the Collada loader.
62 *
63 * Does all the XML reading and builds internal data structures from it,
64 * but leaves the resolving of all the references to the loader.
65 */
66class ColladaParser {
67 friend class ColladaLoader;
68
69public:
70 /// Map for generic metadata as aiString.
71 using StringMetaData = std::map<std::string, aiString>;
72
73 /// Constructor from XML file.
74 ColladaParser(IOSystem *pIOHandler, const std::string &pFile);
75
76 /// Destructor
77 ~ColladaParser();
78
79 /// Attempts to read the ZAE manifest and returns the DAE to open
80 static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive);
81
82 /// Reads the contents of the file
83 void ReadContents(XmlNode &node);
84
85 /// Reads the structure of the file
86 void ReadStructure(XmlNode &node);
87
88 /// Reads asset information such as coordinate system information and legal blah
89 void ReadAssetInfo(XmlNode &node);
90
91 /// Reads contributor information such as author and legal blah
92 void ReadContributorInfo(XmlNode &node);
93
94 /// Reads the animation library
95 void ReadAnimationLibrary(XmlNode &node);
96
97 /// Reads the animation clip library
98 void ReadAnimationClipLibrary(XmlNode &node);
99
100 /// Unwrap controllers dependency hierarchy
101 void PostProcessControllers();
102
103 /// Re-build animations from animation clip library, if present, otherwise combine single-channel animations
104 void PostProcessRootAnimations();
105
106 /// Reads an animation into the given parent structure
107 void ReadAnimation(XmlNode &node, Collada::Animation *pParent);
108
109 /// Reads the skeleton controller library
110 void ReadControllerLibrary(XmlNode &node);
111
112 /// Reads a controller into the given mesh structure
113 void ReadController(XmlNode &node, Collada::Controller &pController);
114
115 /// Reads the image library contents
116 void ReadImageLibrary(const XmlNode &node);
117
118 /// Reads an image entry into the given image
119 void ReadImage(const XmlNode &node, Collada::Image &pImage) const;
120
121 /// Reads the material library
122 void ReadMaterialLibrary(XmlNode &node);
123
124 /// Reads the camera library
125 void ReadCameraLibrary(XmlNode &node);
126
127 /// Reads the light library
128 void ReadLightLibrary(XmlNode &node);
129
130 /// Reads the effect library
131 void ReadEffectLibrary(XmlNode &node);
132
133 /// Reads an effect entry into the given effect
134 void ReadEffect(XmlNode &node, Collada::Effect &pEffect);
135
136 /// Reads an COMMON effect profile
137 void ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect);
138
139 /// Read sampler properties
140 void ReadSamplerProperties(XmlNode &node, Collada::Sampler &pSampler);
141
142 /// Reads an effect entry containing a color or a texture defining that color
143 void ReadEffectColor(XmlNode &node, aiColor4D &pColor, Collada::Sampler &pSampler);
144
145 /// Reads an effect entry containing a float
146 void ReadEffectFloat(XmlNode &node, ai_real &pFloat);
147
148 /// Reads an effect parameter specification of any kind
149 void ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam);
150
151 /// Reads the geometry library contents
152 void ReadGeometryLibrary(XmlNode &node);
153
154 /// Reads a geometry from the geometry library.
155 void ReadGeometry(XmlNode &node, Collada::Mesh &pMesh);
156
157 /// Reads a mesh from the geometry library
158 void ReadMesh(XmlNode &node, Collada::Mesh &pMesh);
159
160 /// Reads a source element - a combination of raw data and an accessor defining
161 ///things that should not be definable. Yes, that's another rant.
162 void ReadSource(XmlNode &node);
163
164 /// Reads a data array holding a number of elements, and stores it in the global library.
165 /// Currently supported are array of floats and arrays of strings.
166 void ReadDataArray(XmlNode &node);
167
168 /// Reads an accessor and stores it in the global library under the given ID -
169 /// accessors use the ID of the parent <source> element
170 void ReadAccessor(XmlNode &node, const std::string &pID);
171
172 /// Reads input declarations of per-vertex mesh data into the given mesh
173 void ReadVertexData(XmlNode &node, Collada::Mesh &pMesh);
174
175 /// Reads input declarations of per-index mesh data into the given mesh
176 void ReadIndexData(XmlNode &node, Collada::Mesh &pMesh);
177
178 /// Reads a single input channel element and stores it in the given array, if valid
179 void ReadInputChannel(XmlNode &node, std::vector<Collada::InputChannel> &poChannels);
180
181 /// Reads a <p> primitive index list and assembles the mesh data into the given mesh
182 size_t ReadPrimitives(XmlNode &node, Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels,
183 size_t pNumPrimitives, const std::vector<size_t> &pVCount, Collada::PrimitiveType pPrimType);
184
185 /// Copies the data for a single primitive into the mesh, based on the InputChannels
186 void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
187 Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels,
188 size_t currentPrimitive, const std::vector<size_t> &indices);
189
190 /// Reads one triangle of a tristrip into the mesh
191 void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh &pMesh,
192 std::vector<Collada::InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices);
193
194 /// Extracts a single object from an input channel and stores it in the appropriate mesh data array
195 void ExtractDataObjectFromChannel(const Collada::InputChannel &pInput, size_t pLocalIndex, Collada::Mesh &pMesh);
196
197 /// Reads the library of node hierarchies and scene parts
198 void ReadSceneLibrary(XmlNode &node);
199
200 /// Reads a scene node's contents including children and stores it in the given node
201 void ReadSceneNode(XmlNode &node, Collada::Node *pNode);
202
203 /// Reads a mesh reference in a node and adds it to the node's mesh list
204 void ReadNodeGeometry(XmlNode &node, Collada::Node *pNode);
205
206 /// Reads the collada scene
207 void ReadScene(XmlNode &node);
208
209 /// Processes bind_vertex_input and bind elements
210 void ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl);
211
212 /// Reads embedded textures from a ZAE archive
213 void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
214
215protected:
216 /// Converts a path read from a collada file to the usual representation
217 static void UriDecodePath(aiString &ss);
218
219 /// Calculates the resulting transformation from all the given transform steps
220 aiMatrix4x4 CalculateResultTransform(const std::vector<Collada::Transform> &pTransforms) const;
221
222 /// Determines the input data type for the given semantic string
223 Collada::InputType GetTypeForSemantic(const std::string &pSemantic);
224
225 /// Finds the item in the given library by its reference, throws if not found
226 template <typename Type>
227 const Type &ResolveLibraryReference(const std::map<std::string, Type> &pLibrary, const std::string &pURL) const;
228
229private:
230 /// Filename, for a verbose error message
231 std::string mFileName;
232
233 /// XML reader, member for everyday use
234 XmlParser mXmlParser;
235
236 /// All data arrays found in the file by ID. Might be referred to by actually
237 /// everyone. Collada, you are a steaming pile of indirection.
238 using DataLibrary = std::map<std::string, Collada::Data> ;
239 DataLibrary mDataLibrary;
240
241 /// Same for accessors which define how the data in a data array is accessed.
242 using AccessorLibrary = std::map<std::string, Collada::Accessor> ;
243 AccessorLibrary mAccessorLibrary;
244
245 /// Mesh library: mesh by ID
246 using MeshLibrary = std::map<std::string, Collada::Mesh *>;
247 MeshLibrary mMeshLibrary;
248
249 /// node library: root node of the hierarchy part by ID
250 using NodeLibrary = std::map<std::string, Collada::Node *>;
251 NodeLibrary mNodeLibrary;
252
253 /// Image library: stores texture properties by ID
254 using ImageLibrary = std::map<std::string, Collada::Image> ;
255 ImageLibrary mImageLibrary;
256
257 /// Effect library: surface attributes by ID
258 using EffectLibrary = std::map<std::string, Collada::Effect> ;
259 EffectLibrary mEffectLibrary;
260
261 /// Material library: surface material by ID
262 using MaterialLibrary = std::map<std::string, Collada::Material> ;
263 MaterialLibrary mMaterialLibrary;
264
265 /// Light library: surface light by ID
266 using LightLibrary = std::map<std::string, Collada::Light> ;
267 LightLibrary mLightLibrary;
268
269 /// Camera library: surface material by ID
270 using CameraLibrary = std::map<std::string, Collada::Camera> ;
271 CameraLibrary mCameraLibrary;
272
273 /// Controller library: joint controllers by ID
274 using ControllerLibrary = std::map<std::string, Collada::Controller> ;
275 ControllerLibrary mControllerLibrary;
276
277 /// Animation library: animation references by ID
278 using AnimationLibrary = std::map<std::string, Collada::Animation *> ;
279 AnimationLibrary mAnimationLibrary;
280
281 /// Animation clip library: clip animation references by ID
282 using AnimationClipLibrary = std::vector<std::pair<std::string, std::vector<std::string>>> ;
283 AnimationClipLibrary mAnimationClipLibrary;
284
285 /// Pointer to the root node. Don't delete, it just points to one of the nodes in the node library.
286 Collada::Node *mRootNode;
287
288 /// Root animation container
289 Collada::Animation mAnims;
290
291 /// Size unit: how large compared to a meter
292 ai_real mUnitSize;
293
294 /// Which is the up vector
295 enum { UP_X,
296 UP_Y,
297 UP_Z } mUpDirection;
298
299 /// Asset metadata (global for scene)
300 StringMetaData mAssetMetaData;
301
302 /// Collada file format version
303 Collada::FormatVersion mFormat;
304};
305
306// ------------------------------------------------------------------------------------------------
307// Finds the item in the given library by its reference, throws if not found
308template <typename Type>
309const Type &ColladaParser::ResolveLibraryReference(const std::map<std::string, Type> &pLibrary, const std::string &pURL) const {
310 typename std::map<std::string, Type>::const_iterator it = pLibrary.find(pURL);
311 if (it == pLibrary.end()) {
312 throw DeadlyImportError("Unable to resolve library reference \"", pURL, "\".");
313 }
314 return it->second;
315}
316
317} // end of namespace Assimp
318
319#endif // AI_COLLADAPARSER_H_INC
320

source code of qtquick3d/src/3rdparty/assimp/src/code/AssetLib/Collada/ColladaParser.h