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