1 | /* |
2 | Open Asset Import Library (assimp) |
3 | ---------------------------------------------------------------------- |
4 | |
5 | Copyright (c) 2006-2017, 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 | r |
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 FBXImporter.cpp |
43 | * @brief Implementation of the FBX importer. |
44 | */ |
45 | |
46 | #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER |
47 | |
48 | #include "FBXImporter.h" |
49 | |
50 | #include "FBXTokenizer.h" |
51 | #include "FBXParser.h" |
52 | #include "FBXUtil.h" |
53 | #include "FBXDocument.h" |
54 | #include "FBXConverter.h" |
55 | |
56 | #include "StreamReader.h" |
57 | #include "MemoryIOWrapper.h" |
58 | #include <assimp/Importer.hpp> |
59 | #include <assimp/importerdesc.h> |
60 | |
61 | namespace Assimp { |
62 | template<> const char* LogFunctions<FBXImporter>::Prefix() |
63 | { |
64 | static auto prefix = "FBX: " ; |
65 | return prefix; |
66 | } |
67 | } |
68 | |
69 | using namespace Assimp; |
70 | using namespace Assimp::Formatter; |
71 | using namespace Assimp::FBX; |
72 | |
73 | namespace { |
74 | static const aiImporterDesc desc = { |
75 | "Autodesk FBX Importer" , |
76 | "" , |
77 | "" , |
78 | "" , |
79 | aiImporterFlags_SupportTextFlavour, |
80 | 0, |
81 | 0, |
82 | 0, |
83 | 0, |
84 | "fbx" |
85 | }; |
86 | } |
87 | |
88 | // ------------------------------------------------------------------------------------------------ |
89 | // Constructor to be privately used by #Importer |
90 | FBXImporter::FBXImporter() |
91 | { |
92 | } |
93 | |
94 | // ------------------------------------------------------------------------------------------------ |
95 | // Destructor, private as well |
96 | FBXImporter::~FBXImporter() |
97 | { |
98 | } |
99 | |
100 | // ------------------------------------------------------------------------------------------------ |
101 | // Returns whether the class can handle the format of the given file. |
102 | bool FBXImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const |
103 | { |
104 | const std::string& extension = GetExtension(pFile); |
105 | if (extension == std::string( desc.mFileExtensions ) ) { |
106 | return true; |
107 | } |
108 | |
109 | else if ((!extension.length() || checkSig) && pIOHandler) { |
110 | // at least ASCII-FBX files usually have a 'FBX' somewhere in their head |
111 | const char* tokens[] = {"fbx" }; |
112 | return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1); |
113 | } |
114 | return false; |
115 | } |
116 | |
117 | // ------------------------------------------------------------------------------------------------ |
118 | // List all extensions handled by this loader |
119 | const aiImporterDesc* FBXImporter::GetInfo () const |
120 | { |
121 | return &desc; |
122 | } |
123 | |
124 | // ------------------------------------------------------------------------------------------------ |
125 | // Setup configuration properties for the loader |
126 | void FBXImporter::SetupProperties(const Importer* pImp) |
127 | { |
128 | settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true); |
129 | settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false); |
130 | settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true); |
131 | settings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true); |
132 | settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true); |
133 | settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true); |
134 | settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true); |
135 | settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false); |
136 | settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true); |
137 | settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true); |
138 | settings.searchEmbeddedTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES, false); |
139 | } |
140 | |
141 | // ------------------------------------------------------------------------------------------------ |
142 | // Imports the given file into the given scene structure. |
143 | void FBXImporter::InternReadFile( const std::string& pFile, |
144 | aiScene* pScene, IOSystem* pIOHandler) |
145 | { |
146 | std::unique_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb" )); |
147 | if (!stream) { |
148 | ThrowException("Could not open file for reading" ); |
149 | } |
150 | |
151 | // read entire file into memory - no streaming for this, fbx |
152 | // files can grow large, but the assimp output data structure |
153 | // then becomes very large, too. Assimp doesn't support |
154 | // streaming for its output data structures so the net win with |
155 | // streaming input data would be very low. |
156 | std::vector<char> contents; |
157 | contents.resize(stream->FileSize()+1); |
158 | stream->Read( &*contents.begin(), 1, contents.size()-1 ); |
159 | contents[ contents.size() - 1 ] = 0; |
160 | const char* const begin = &*contents.begin(); |
161 | |
162 | // broadphase tokenizing pass in which we identify the core |
163 | // syntax elements of FBX (brackets, commas, key:value mappings) |
164 | TokenList tokens; |
165 | try { |
166 | |
167 | bool is_binary = false; |
168 | if (!strncmp(begin,"Kaydara FBX Binary" ,18)) { |
169 | is_binary = true; |
170 | TokenizeBinary(tokens,begin,static_cast<unsigned int>(contents.size())); |
171 | } |
172 | else { |
173 | Tokenize(tokens,begin); |
174 | } |
175 | |
176 | // use this information to construct a very rudimentary |
177 | // parse-tree representing the FBX scope structure |
178 | Parser parser(tokens, is_binary); |
179 | |
180 | // take the raw parse-tree and convert it to a FBX DOM |
181 | Document doc(parser,settings); |
182 | |
183 | // convert the FBX DOM to aiScene |
184 | ConvertToAssimpScene(pScene,doc); |
185 | |
186 | std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>()); |
187 | } |
188 | catch(std::exception&) { |
189 | std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>()); |
190 | throw; |
191 | } |
192 | } |
193 | |
194 | #endif // !ASSIMP_BUILD_NO_FBX_IMPORTER |
195 | |