rev |
line source |
nuclear@0
|
1 /*
|
nuclear@0
|
2 ---------------------------------------------------------------------------
|
nuclear@0
|
3 Open Asset Import Library (assimp)
|
nuclear@0
|
4 ---------------------------------------------------------------------------
|
nuclear@0
|
5
|
nuclear@0
|
6 Copyright (c) 2006-2018, assimp team
|
nuclear@0
|
7
|
nuclear@0
|
8
|
nuclear@0
|
9
|
nuclear@0
|
10 All rights reserved.
|
nuclear@0
|
11
|
nuclear@0
|
12 Redistribution and use of this software in source and binary forms,
|
nuclear@0
|
13 with or without modification, are permitted provided that the following
|
nuclear@0
|
14 conditions are met:
|
nuclear@0
|
15
|
nuclear@0
|
16 * Redistributions of source code must retain the above
|
nuclear@0
|
17 copyright notice, this list of conditions and the
|
nuclear@0
|
18 following disclaimer.
|
nuclear@0
|
19
|
nuclear@0
|
20 * Redistributions in binary form must reproduce the above
|
nuclear@0
|
21 copyright notice, this list of conditions and the
|
nuclear@0
|
22 following disclaimer in the documentation and/or other
|
nuclear@0
|
23 materials provided with the distribution.
|
nuclear@0
|
24
|
nuclear@0
|
25 * Neither the name of the assimp team, nor the names of its
|
nuclear@0
|
26 contributors may be used to endorse or promote products
|
nuclear@0
|
27 derived from this software without specific prior
|
nuclear@0
|
28 written permission of the assimp team.
|
nuclear@0
|
29
|
nuclear@0
|
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
nuclear@0
|
31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
nuclear@0
|
32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
nuclear@0
|
33 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
nuclear@0
|
34 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
nuclear@0
|
35 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
nuclear@0
|
36 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
nuclear@0
|
37 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
nuclear@0
|
38 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
nuclear@0
|
39 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
nuclear@0
|
40 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
nuclear@0
|
41 ---------------------------------------------------------------------------
|
nuclear@0
|
42 */
|
nuclear@0
|
43 /** @file Assimp.cpp
|
nuclear@0
|
44 * @brief Implementation of the Plain-C API
|
nuclear@0
|
45 */
|
nuclear@0
|
46
|
nuclear@0
|
47 #include <miniassimp/cimport.h>
|
nuclear@0
|
48 #include <miniassimp/LogStream.hpp>
|
nuclear@0
|
49 #include <miniassimp/DefaultLogger.hpp>
|
nuclear@0
|
50 #include <miniassimp/Importer.hpp>
|
nuclear@0
|
51 #include <miniassimp/importerdesc.h>
|
nuclear@0
|
52 #include <miniassimp/scene.h>
|
nuclear@0
|
53 #include <miniassimp/GenericProperty.h>
|
nuclear@0
|
54 #include <miniassimp/Exceptional.h>
|
nuclear@0
|
55 #include <miniassimp/BaseImporter.h>
|
nuclear@0
|
56
|
nuclear@0
|
57 #include "CInterfaceIOWrapper.h"
|
nuclear@0
|
58 #include "Importer.h"
|
nuclear@0
|
59 #include "ScenePrivate.h"
|
nuclear@0
|
60
|
nuclear@0
|
61 #include <list>
|
nuclear@0
|
62
|
nuclear@0
|
63 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
64 #ifndef ASSIMP_BUILD_SINGLETHREADED
|
nuclear@0
|
65 # include <thread>
|
nuclear@0
|
66 # include <mutex>
|
nuclear@0
|
67 #endif
|
nuclear@0
|
68 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
69 using namespace Assimp;
|
nuclear@0
|
70
|
nuclear@0
|
71 namespace Assimp {
|
nuclear@0
|
72 // underlying structure for aiPropertyStore
|
nuclear@0
|
73 typedef BatchLoader::PropertyMap PropertyMap;
|
nuclear@0
|
74
|
nuclear@0
|
75 /** Stores the LogStream objects for all active C log streams */
|
nuclear@0
|
76 struct mpred {
|
nuclear@0
|
77 bool operator () (const aiLogStream& s0, const aiLogStream& s1) const {
|
nuclear@0
|
78 return s0.callback<s1.callback&&s0.user<s1.user;
|
nuclear@0
|
79 }
|
nuclear@0
|
80 };
|
nuclear@0
|
81 typedef std::map<aiLogStream, Assimp::LogStream*, mpred> LogStreamMap;
|
nuclear@0
|
82
|
nuclear@0
|
83 /** Stores the LogStream objects allocated by #aiGetPredefinedLogStream */
|
nuclear@0
|
84 typedef std::list<Assimp::LogStream*> PredefLogStreamMap;
|
nuclear@0
|
85
|
nuclear@0
|
86 /** Local storage of all active log streams */
|
nuclear@0
|
87 static LogStreamMap gActiveLogStreams;
|
nuclear@0
|
88
|
nuclear@0
|
89 /** Local storage of LogStreams allocated by #aiGetPredefinedLogStream */
|
nuclear@0
|
90 static PredefLogStreamMap gPredefinedStreams;
|
nuclear@0
|
91
|
nuclear@0
|
92 /** Error message of the last failed import process */
|
nuclear@0
|
93 static std::string gLastErrorString;
|
nuclear@0
|
94
|
nuclear@0
|
95 /** Verbose logging active or not? */
|
nuclear@0
|
96 static aiBool gVerboseLogging = false;
|
nuclear@0
|
97
|
nuclear@0
|
98 /** will return all registered importers. */
|
nuclear@0
|
99 void GetImporterInstanceList(std::vector< BaseImporter* >& out);
|
nuclear@0
|
100
|
nuclear@0
|
101 /** will delete all registered importers. */
|
nuclear@0
|
102 void DeleteImporterInstanceList(std::vector< BaseImporter* >& out);
|
nuclear@0
|
103 } // namespace assimp
|
nuclear@0
|
104
|
nuclear@0
|
105
|
nuclear@0
|
106 #ifndef ASSIMP_BUILD_SINGLETHREADED
|
nuclear@0
|
107 /** Global mutex to manage the access to the log-stream map */
|
nuclear@0
|
108 static std::mutex gLogStreamMutex;
|
nuclear@0
|
109 #endif
|
nuclear@0
|
110
|
nuclear@0
|
111 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
112 // Custom LogStream implementation for the C-API
|
nuclear@0
|
113 class LogToCallbackRedirector : public LogStream {
|
nuclear@0
|
114 public:
|
nuclear@0
|
115 explicit LogToCallbackRedirector(const aiLogStream& s)
|
nuclear@0
|
116 : stream (s) {
|
nuclear@0
|
117 ai_assert(NULL != s.callback);
|
nuclear@0
|
118 }
|
nuclear@0
|
119
|
nuclear@0
|
120 ~LogToCallbackRedirector() {
|
nuclear@0
|
121 #ifndef ASSIMP_BUILD_SINGLETHREADED
|
nuclear@0
|
122 std::lock_guard<std::mutex> lock(gLogStreamMutex);
|
nuclear@0
|
123 #endif
|
nuclear@0
|
124 // (HACK) Check whether the 'stream.user' pointer points to a
|
nuclear@0
|
125 // custom LogStream allocated by #aiGetPredefinedLogStream.
|
nuclear@0
|
126 // In this case, we need to delete it, too. Of course, this
|
nuclear@0
|
127 // might cause strange problems, but the chance is quite low.
|
nuclear@0
|
128
|
nuclear@0
|
129 PredefLogStreamMap::iterator it = std::find(gPredefinedStreams.begin(),
|
nuclear@0
|
130 gPredefinedStreams.end(), (Assimp::LogStream*)stream.user);
|
nuclear@0
|
131
|
nuclear@0
|
132 if (it != gPredefinedStreams.end()) {
|
nuclear@0
|
133 delete *it;
|
nuclear@0
|
134 gPredefinedStreams.erase(it);
|
nuclear@0
|
135 }
|
nuclear@0
|
136 }
|
nuclear@0
|
137
|
nuclear@0
|
138 /** @copydoc LogStream::write */
|
nuclear@0
|
139 void write(const char* message) {
|
nuclear@0
|
140 stream.callback(message,stream.user);
|
nuclear@0
|
141 }
|
nuclear@0
|
142
|
nuclear@0
|
143 private:
|
nuclear@0
|
144 aiLogStream stream;
|
nuclear@0
|
145 };
|
nuclear@0
|
146
|
nuclear@0
|
147 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
148 void ReportSceneNotFoundError() {
|
nuclear@0
|
149 ASSIMP_LOG_ERROR("Unable to find the Assimp::Importer for this aiScene. "
|
nuclear@0
|
150 "The C-API does not accept scenes produced by the C++ API and vice versa");
|
nuclear@0
|
151
|
nuclear@0
|
152 ai_assert(false);
|
nuclear@0
|
153 }
|
nuclear@0
|
154
|
nuclear@0
|
155 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
156 // Reads the given file and returns its content.
|
nuclear@0
|
157 const aiScene* aiImportFile( const char* pFile, unsigned int pFlags) {
|
nuclear@0
|
158 return aiImportFileEx(pFile,pFlags,NULL);
|
nuclear@0
|
159 }
|
nuclear@0
|
160
|
nuclear@0
|
161 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
162 const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags, aiFileIO* pFS) {
|
nuclear@0
|
163 return aiImportFileExWithProperties(pFile, pFlags, pFS, NULL);
|
nuclear@0
|
164 }
|
nuclear@0
|
165
|
nuclear@0
|
166 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
167 const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags,
|
nuclear@0
|
168 aiFileIO* pFS, const aiPropertyStore* props) {
|
nuclear@0
|
169 ai_assert(NULL != pFile);
|
nuclear@0
|
170
|
nuclear@0
|
171 const aiScene* scene = NULL;
|
nuclear@0
|
172 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
173
|
nuclear@0
|
174 // create an Importer for this file
|
nuclear@0
|
175 Assimp::Importer* imp = new Assimp::Importer();
|
nuclear@0
|
176
|
nuclear@0
|
177 // copy properties
|
nuclear@0
|
178 if(props) {
|
nuclear@0
|
179 const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
|
nuclear@0
|
180 ImporterPimpl* pimpl = imp->Pimpl();
|
nuclear@0
|
181 pimpl->mIntProperties = pp->ints;
|
nuclear@0
|
182 pimpl->mFloatProperties = pp->floats;
|
nuclear@0
|
183 pimpl->mStringProperties = pp->strings;
|
nuclear@0
|
184 pimpl->mMatrixProperties = pp->matrices;
|
nuclear@0
|
185 }
|
nuclear@0
|
186 // setup a custom IO system if necessary
|
nuclear@0
|
187 if (pFS) {
|
nuclear@0
|
188 imp->SetIOHandler( new CIOSystemWrapper (pFS) );
|
nuclear@0
|
189 }
|
nuclear@0
|
190
|
nuclear@0
|
191 // and have it read the file
|
nuclear@0
|
192 scene = imp->ReadFile( pFile, pFlags);
|
nuclear@0
|
193
|
nuclear@0
|
194 // if succeeded, store the importer in the scene and keep it alive
|
nuclear@0
|
195 if( scene) {
|
nuclear@0
|
196 ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
|
nuclear@0
|
197 priv->mOrigImporter = imp;
|
nuclear@0
|
198 } else {
|
nuclear@0
|
199 // if failed, extract error code and destroy the import
|
nuclear@0
|
200 gLastErrorString = imp->GetErrorString();
|
nuclear@0
|
201 delete imp;
|
nuclear@0
|
202 }
|
nuclear@0
|
203
|
nuclear@0
|
204 // return imported data. If the import failed the pointer is NULL anyways
|
nuclear@0
|
205 ASSIMP_END_EXCEPTION_REGION(const aiScene*);
|
nuclear@0
|
206
|
nuclear@0
|
207 return scene;
|
nuclear@0
|
208 }
|
nuclear@0
|
209
|
nuclear@0
|
210 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
211 const aiScene* aiImportFileFromMemory(
|
nuclear@0
|
212 const char* pBuffer,
|
nuclear@0
|
213 unsigned int pLength,
|
nuclear@0
|
214 unsigned int pFlags,
|
nuclear@0
|
215 const char* pHint)
|
nuclear@0
|
216 {
|
nuclear@0
|
217 return aiImportFileFromMemoryWithProperties(pBuffer, pLength, pFlags, pHint, NULL);
|
nuclear@0
|
218 }
|
nuclear@0
|
219
|
nuclear@0
|
220 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
221 const aiScene* aiImportFileFromMemoryWithProperties(
|
nuclear@0
|
222 const char* pBuffer,
|
nuclear@0
|
223 unsigned int pLength,
|
nuclear@0
|
224 unsigned int pFlags,
|
nuclear@0
|
225 const char* pHint,
|
nuclear@0
|
226 const aiPropertyStore* props)
|
nuclear@0
|
227 {
|
nuclear@0
|
228 ai_assert( NULL != pBuffer );
|
nuclear@0
|
229 ai_assert( 0 != pLength );
|
nuclear@0
|
230
|
nuclear@0
|
231 const aiScene* scene = NULL;
|
nuclear@0
|
232 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
233
|
nuclear@0
|
234 // create an Importer for this file
|
nuclear@0
|
235 Assimp::Importer* imp = new Assimp::Importer();
|
nuclear@0
|
236
|
nuclear@0
|
237 // copy properties
|
nuclear@0
|
238 if(props) {
|
nuclear@0
|
239 const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
|
nuclear@0
|
240 ImporterPimpl* pimpl = imp->Pimpl();
|
nuclear@0
|
241 pimpl->mIntProperties = pp->ints;
|
nuclear@0
|
242 pimpl->mFloatProperties = pp->floats;
|
nuclear@0
|
243 pimpl->mStringProperties = pp->strings;
|
nuclear@0
|
244 pimpl->mMatrixProperties = pp->matrices;
|
nuclear@0
|
245 }
|
nuclear@0
|
246
|
nuclear@0
|
247 // and have it read the file from the memory buffer
|
nuclear@0
|
248 scene = imp->ReadFileFromMemory( pBuffer, pLength, pFlags,pHint);
|
nuclear@0
|
249
|
nuclear@0
|
250 // if succeeded, store the importer in the scene and keep it alive
|
nuclear@0
|
251 if( scene) {
|
nuclear@0
|
252 ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
|
nuclear@0
|
253 priv->mOrigImporter = imp;
|
nuclear@0
|
254 }
|
nuclear@0
|
255 else {
|
nuclear@0
|
256 // if failed, extract error code and destroy the import
|
nuclear@0
|
257 gLastErrorString = imp->GetErrorString();
|
nuclear@0
|
258 delete imp;
|
nuclear@0
|
259 }
|
nuclear@0
|
260 // return imported data. If the import failed the pointer is NULL anyways
|
nuclear@0
|
261 ASSIMP_END_EXCEPTION_REGION(const aiScene*);
|
nuclear@0
|
262 return scene;
|
nuclear@0
|
263 }
|
nuclear@0
|
264
|
nuclear@0
|
265 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
266 // Releases all resources associated with the given import process.
|
nuclear@0
|
267 void aiReleaseImport( const aiScene* pScene)
|
nuclear@0
|
268 {
|
nuclear@0
|
269 if (!pScene) {
|
nuclear@0
|
270 return;
|
nuclear@0
|
271 }
|
nuclear@0
|
272
|
nuclear@0
|
273 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
274
|
nuclear@0
|
275 // find the importer associated with this data
|
nuclear@0
|
276 const ScenePrivateData* priv = ScenePriv(pScene);
|
nuclear@0
|
277 if( !priv || !priv->mOrigImporter) {
|
nuclear@0
|
278 delete pScene;
|
nuclear@0
|
279 }
|
nuclear@0
|
280 else {
|
nuclear@0
|
281 // deleting the Importer also deletes the scene
|
nuclear@0
|
282 // Note: the reason that this is not written as 'delete priv->mOrigImporter'
|
nuclear@0
|
283 // is a suspected bug in gcc 4.4+ (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52339)
|
nuclear@0
|
284 Importer* importer = priv->mOrigImporter;
|
nuclear@0
|
285 delete importer;
|
nuclear@0
|
286 }
|
nuclear@0
|
287
|
nuclear@0
|
288 ASSIMP_END_EXCEPTION_REGION(void);
|
nuclear@0
|
289 }
|
nuclear@0
|
290
|
nuclear@0
|
291 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
292 ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene* pScene,
|
nuclear@0
|
293 unsigned int pFlags)
|
nuclear@0
|
294 {
|
nuclear@0
|
295 const aiScene* sc = NULL;
|
nuclear@0
|
296
|
nuclear@0
|
297
|
nuclear@0
|
298 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
299
|
nuclear@0
|
300 // find the importer associated with this data
|
nuclear@0
|
301 const ScenePrivateData* priv = ScenePriv(pScene);
|
nuclear@0
|
302 if( !priv || !priv->mOrigImporter) {
|
nuclear@0
|
303 ReportSceneNotFoundError();
|
nuclear@0
|
304 return NULL;
|
nuclear@0
|
305 }
|
nuclear@0
|
306
|
nuclear@0
|
307 sc = priv->mOrigImporter->ApplyPostProcessing(pFlags);
|
nuclear@0
|
308
|
nuclear@0
|
309 if (!sc) {
|
nuclear@0
|
310 aiReleaseImport(pScene);
|
nuclear@0
|
311 return NULL;
|
nuclear@0
|
312 }
|
nuclear@0
|
313
|
nuclear@0
|
314 ASSIMP_END_EXCEPTION_REGION(const aiScene*);
|
nuclear@0
|
315 return sc;
|
nuclear@0
|
316 }
|
nuclear@0
|
317
|
nuclear@0
|
318 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
319 ASSIMP_API const aiScene *aiApplyCustomizedPostProcessing( const aiScene *scene,
|
nuclear@0
|
320 BaseProcess* process,
|
nuclear@0
|
321 bool requestValidation ) {
|
nuclear@0
|
322 const aiScene* sc( NULL );
|
nuclear@0
|
323
|
nuclear@0
|
324 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
325
|
nuclear@0
|
326 // find the importer associated with this data
|
nuclear@0
|
327 const ScenePrivateData* priv = ScenePriv( scene );
|
nuclear@0
|
328 if ( NULL == priv || NULL == priv->mOrigImporter ) {
|
nuclear@0
|
329 ReportSceneNotFoundError();
|
nuclear@0
|
330 return NULL;
|
nuclear@0
|
331 }
|
nuclear@0
|
332
|
nuclear@0
|
333 sc = priv->mOrigImporter->ApplyCustomizedPostProcessing( process, requestValidation );
|
nuclear@0
|
334
|
nuclear@0
|
335 if ( !sc ) {
|
nuclear@0
|
336 aiReleaseImport( scene );
|
nuclear@0
|
337 return NULL;
|
nuclear@0
|
338 }
|
nuclear@0
|
339
|
nuclear@0
|
340 ASSIMP_END_EXCEPTION_REGION( const aiScene* );
|
nuclear@0
|
341
|
nuclear@0
|
342 return sc;
|
nuclear@0
|
343 }
|
nuclear@0
|
344
|
nuclear@0
|
345 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
346 void CallbackToLogRedirector (const char* msg, char* dt)
|
nuclear@0
|
347 {
|
nuclear@0
|
348 ai_assert( NULL != msg );
|
nuclear@0
|
349 ai_assert( NULL != dt );
|
nuclear@0
|
350 LogStream* s = (LogStream*)dt;
|
nuclear@0
|
351
|
nuclear@0
|
352 s->write(msg);
|
nuclear@0
|
353 }
|
nuclear@0
|
354
|
nuclear@0
|
355 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
356 ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream,const char* file)
|
nuclear@0
|
357 {
|
nuclear@0
|
358 aiLogStream sout;
|
nuclear@0
|
359
|
nuclear@0
|
360 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
361 LogStream* stream = LogStream::createDefaultStream(pStream,file);
|
nuclear@0
|
362 if (!stream) {
|
nuclear@0
|
363 sout.callback = NULL;
|
nuclear@0
|
364 sout.user = NULL;
|
nuclear@0
|
365 }
|
nuclear@0
|
366 else {
|
nuclear@0
|
367 sout.callback = &CallbackToLogRedirector;
|
nuclear@0
|
368 sout.user = (char*)stream;
|
nuclear@0
|
369 }
|
nuclear@0
|
370 gPredefinedStreams.push_back(stream);
|
nuclear@0
|
371 ASSIMP_END_EXCEPTION_REGION(aiLogStream);
|
nuclear@0
|
372 return sout;
|
nuclear@0
|
373 }
|
nuclear@0
|
374
|
nuclear@0
|
375 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
376 ASSIMP_API void aiAttachLogStream( const aiLogStream* stream )
|
nuclear@0
|
377 {
|
nuclear@0
|
378 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
379
|
nuclear@0
|
380 #ifndef ASSIMP_BUILD_SINGLETHREADED
|
nuclear@0
|
381 std::lock_guard<std::mutex> lock(gLogStreamMutex);
|
nuclear@0
|
382 #endif
|
nuclear@0
|
383
|
nuclear@0
|
384 LogStream* lg = new LogToCallbackRedirector(*stream);
|
nuclear@0
|
385 gActiveLogStreams[*stream] = lg;
|
nuclear@0
|
386
|
nuclear@0
|
387 if (DefaultLogger::isNullLogger()) {
|
nuclear@0
|
388 DefaultLogger::create(NULL,(gVerboseLogging == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
|
nuclear@0
|
389 }
|
nuclear@0
|
390 DefaultLogger::get()->attachStream(lg);
|
nuclear@0
|
391 ASSIMP_END_EXCEPTION_REGION(void);
|
nuclear@0
|
392 }
|
nuclear@0
|
393
|
nuclear@0
|
394 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
395 ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream)
|
nuclear@0
|
396 {
|
nuclear@0
|
397 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
398
|
nuclear@0
|
399 #ifndef ASSIMP_BUILD_SINGLETHREADED
|
nuclear@0
|
400 std::lock_guard<std::mutex> lock(gLogStreamMutex);
|
nuclear@0
|
401 #endif
|
nuclear@0
|
402 // find the log-stream associated with this data
|
nuclear@0
|
403 LogStreamMap::iterator it = gActiveLogStreams.find( *stream);
|
nuclear@0
|
404 // it should be there... else the user is playing fools with us
|
nuclear@0
|
405 if( it == gActiveLogStreams.end()) {
|
nuclear@0
|
406 return AI_FAILURE;
|
nuclear@0
|
407 }
|
nuclear@0
|
408 DefaultLogger::get()->detatchStream( it->second );
|
nuclear@0
|
409 delete it->second;
|
nuclear@0
|
410
|
nuclear@0
|
411 gActiveLogStreams.erase( it);
|
nuclear@0
|
412
|
nuclear@0
|
413 if (gActiveLogStreams.empty()) {
|
nuclear@0
|
414 DefaultLogger::kill();
|
nuclear@0
|
415 }
|
nuclear@0
|
416 ASSIMP_END_EXCEPTION_REGION(aiReturn);
|
nuclear@0
|
417 return AI_SUCCESS;
|
nuclear@0
|
418 }
|
nuclear@0
|
419
|
nuclear@0
|
420 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
421 ASSIMP_API void aiDetachAllLogStreams(void)
|
nuclear@0
|
422 {
|
nuclear@0
|
423 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
424 #ifndef ASSIMP_BUILD_SINGLETHREADED
|
nuclear@0
|
425 std::lock_guard<std::mutex> lock(gLogStreamMutex);
|
nuclear@0
|
426 #endif
|
nuclear@0
|
427 Logger *logger( DefaultLogger::get() );
|
nuclear@0
|
428 if ( NULL == logger ) {
|
nuclear@0
|
429 return;
|
nuclear@0
|
430 }
|
nuclear@0
|
431
|
nuclear@0
|
432 for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
|
nuclear@0
|
433 logger->detatchStream( it->second );
|
nuclear@0
|
434 delete it->second;
|
nuclear@0
|
435 }
|
nuclear@0
|
436 gActiveLogStreams.clear();
|
nuclear@0
|
437 DefaultLogger::kill();
|
nuclear@0
|
438
|
nuclear@0
|
439 ASSIMP_END_EXCEPTION_REGION(void);
|
nuclear@0
|
440 }
|
nuclear@0
|
441
|
nuclear@0
|
442 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
443 ASSIMP_API void aiEnableVerboseLogging(aiBool d)
|
nuclear@0
|
444 {
|
nuclear@0
|
445 if (!DefaultLogger::isNullLogger()) {
|
nuclear@0
|
446 DefaultLogger::get()->setLogSeverity((d == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
|
nuclear@0
|
447 }
|
nuclear@0
|
448 gVerboseLogging = d;
|
nuclear@0
|
449 }
|
nuclear@0
|
450
|
nuclear@0
|
451 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
452 // Returns the error text of the last failed import process.
|
nuclear@0
|
453 const char* aiGetErrorString()
|
nuclear@0
|
454 {
|
nuclear@0
|
455 return gLastErrorString.c_str();
|
nuclear@0
|
456 }
|
nuclear@0
|
457
|
nuclear@0
|
458 // -----------------------------------------------------------------------------------------------
|
nuclear@0
|
459 // Return the description of a importer given its index
|
nuclear@0
|
460 const aiImporterDesc* aiGetImportFormatDescription( size_t pIndex)
|
nuclear@0
|
461 {
|
nuclear@0
|
462 return Importer().GetImporterInfo(pIndex);
|
nuclear@0
|
463 }
|
nuclear@0
|
464
|
nuclear@0
|
465 // -----------------------------------------------------------------------------------------------
|
nuclear@0
|
466 // Return the number of importers
|
nuclear@0
|
467 size_t aiGetImportFormatCount(void)
|
nuclear@0
|
468 {
|
nuclear@0
|
469 return Importer().GetImporterCount();
|
nuclear@0
|
470 }
|
nuclear@0
|
471
|
nuclear@0
|
472 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
473 // Returns the error text of the last failed import process.
|
nuclear@0
|
474 aiBool aiIsExtensionSupported(const char* szExtension)
|
nuclear@0
|
475 {
|
nuclear@0
|
476 ai_assert(NULL != szExtension);
|
nuclear@0
|
477 aiBool candoit=AI_FALSE;
|
nuclear@0
|
478 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
479
|
nuclear@0
|
480 // FIXME: no need to create a temporary Importer instance just for that ..
|
nuclear@0
|
481 Assimp::Importer tmp;
|
nuclear@0
|
482 candoit = tmp.IsExtensionSupported(std::string(szExtension)) ? AI_TRUE : AI_FALSE;
|
nuclear@0
|
483
|
nuclear@0
|
484 ASSIMP_END_EXCEPTION_REGION(aiBool);
|
nuclear@0
|
485 return candoit;
|
nuclear@0
|
486 }
|
nuclear@0
|
487
|
nuclear@0
|
488 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
489 // Get a list of all file extensions supported by ASSIMP
|
nuclear@0
|
490 void aiGetExtensionList(aiString* szOut)
|
nuclear@0
|
491 {
|
nuclear@0
|
492 ai_assert(NULL != szOut);
|
nuclear@0
|
493 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
494
|
nuclear@0
|
495 // FIXME: no need to create a temporary Importer instance just for that ..
|
nuclear@0
|
496 Assimp::Importer tmp;
|
nuclear@0
|
497 tmp.GetExtensionList(*szOut);
|
nuclear@0
|
498
|
nuclear@0
|
499 ASSIMP_END_EXCEPTION_REGION(void);
|
nuclear@0
|
500 }
|
nuclear@0
|
501
|
nuclear@0
|
502 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
503 // Get the memory requirements for a particular import.
|
nuclear@0
|
504 void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn,
|
nuclear@0
|
505 C_STRUCT aiMemoryInfo* in)
|
nuclear@0
|
506 {
|
nuclear@0
|
507 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
508
|
nuclear@0
|
509 // find the importer associated with this data
|
nuclear@0
|
510 const ScenePrivateData* priv = ScenePriv(pIn);
|
nuclear@0
|
511 if( !priv || !priv->mOrigImporter) {
|
nuclear@0
|
512 ReportSceneNotFoundError();
|
nuclear@0
|
513 return;
|
nuclear@0
|
514 }
|
nuclear@0
|
515
|
nuclear@0
|
516 return priv->mOrigImporter->GetMemoryRequirements(*in);
|
nuclear@0
|
517 ASSIMP_END_EXCEPTION_REGION(void);
|
nuclear@0
|
518 }
|
nuclear@0
|
519
|
nuclear@0
|
520 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
521 ASSIMP_API aiPropertyStore* aiCreatePropertyStore(void)
|
nuclear@0
|
522 {
|
nuclear@0
|
523 return reinterpret_cast<aiPropertyStore*>( new PropertyMap() );
|
nuclear@0
|
524 }
|
nuclear@0
|
525
|
nuclear@0
|
526 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
527 ASSIMP_API void aiReleasePropertyStore(aiPropertyStore* p)
|
nuclear@0
|
528 {
|
nuclear@0
|
529 delete reinterpret_cast<PropertyMap*>(p);
|
nuclear@0
|
530 }
|
nuclear@0
|
531
|
nuclear@0
|
532 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
533 // Importer::SetPropertyInteger
|
nuclear@0
|
534 ASSIMP_API void aiSetImportPropertyInteger(aiPropertyStore* p, const char* szName, int value)
|
nuclear@0
|
535 {
|
nuclear@0
|
536 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
537 PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
nuclear@0
|
538 SetGenericProperty<int>(pp->ints,szName,value);
|
nuclear@0
|
539 ASSIMP_END_EXCEPTION_REGION(void);
|
nuclear@0
|
540 }
|
nuclear@0
|
541
|
nuclear@0
|
542 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
543 // Importer::SetPropertyFloat
|
nuclear@0
|
544 ASSIMP_API void aiSetImportPropertyFloat(aiPropertyStore* p, const char* szName, ai_real value)
|
nuclear@0
|
545 {
|
nuclear@0
|
546 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
547 PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
nuclear@0
|
548 SetGenericProperty<ai_real>(pp->floats,szName,value);
|
nuclear@0
|
549 ASSIMP_END_EXCEPTION_REGION(void);
|
nuclear@0
|
550 }
|
nuclear@0
|
551
|
nuclear@0
|
552 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
553 // Importer::SetPropertyString
|
nuclear@0
|
554 ASSIMP_API void aiSetImportPropertyString(aiPropertyStore* p, const char* szName,
|
nuclear@0
|
555 const C_STRUCT aiString* st)
|
nuclear@0
|
556 {
|
nuclear@0
|
557 if (!st) {
|
nuclear@0
|
558 return;
|
nuclear@0
|
559 }
|
nuclear@0
|
560 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
561 PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
nuclear@0
|
562 SetGenericProperty<std::string>(pp->strings,szName,std::string(st->C_Str()));
|
nuclear@0
|
563 ASSIMP_END_EXCEPTION_REGION(void);
|
nuclear@0
|
564 }
|
nuclear@0
|
565
|
nuclear@0
|
566 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
567 // Importer::SetPropertyMatrix
|
nuclear@0
|
568 ASSIMP_API void aiSetImportPropertyMatrix(aiPropertyStore* p, const char* szName,
|
nuclear@0
|
569 const C_STRUCT aiMatrix4x4* mat)
|
nuclear@0
|
570 {
|
nuclear@0
|
571 if (!mat) {
|
nuclear@0
|
572 return;
|
nuclear@0
|
573 }
|
nuclear@0
|
574 ASSIMP_BEGIN_EXCEPTION_REGION();
|
nuclear@0
|
575 PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
nuclear@0
|
576 SetGenericProperty<aiMatrix4x4>(pp->matrices,szName,*mat);
|
nuclear@0
|
577 ASSIMP_END_EXCEPTION_REGION(void);
|
nuclear@0
|
578 }
|
nuclear@0
|
579
|
nuclear@0
|
580 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
581 // Rotation matrix to quaternion
|
nuclear@0
|
582 ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat)
|
nuclear@0
|
583 {
|
nuclear@0
|
584 ai_assert( NULL != quat );
|
nuclear@0
|
585 ai_assert( NULL != mat );
|
nuclear@0
|
586 *quat = aiQuaternion(*mat);
|
nuclear@0
|
587 }
|
nuclear@0
|
588
|
nuclear@0
|
589 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
590 // Matrix decomposition
|
nuclear@0
|
591 ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat,aiVector3D* scaling,
|
nuclear@0
|
592 aiQuaternion* rotation,
|
nuclear@0
|
593 aiVector3D* position)
|
nuclear@0
|
594 {
|
nuclear@0
|
595 ai_assert( NULL != rotation );
|
nuclear@0
|
596 ai_assert( NULL != position );
|
nuclear@0
|
597 ai_assert( NULL != scaling );
|
nuclear@0
|
598 ai_assert( NULL != mat );
|
nuclear@0
|
599 mat->Decompose(*scaling,*rotation,*position);
|
nuclear@0
|
600 }
|
nuclear@0
|
601
|
nuclear@0
|
602 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
603 // Matrix transpose
|
nuclear@0
|
604 ASSIMP_API void aiTransposeMatrix3(aiMatrix3x3* mat)
|
nuclear@0
|
605 {
|
nuclear@0
|
606 ai_assert(NULL != mat);
|
nuclear@0
|
607 mat->Transpose();
|
nuclear@0
|
608 }
|
nuclear@0
|
609
|
nuclear@0
|
610 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
611 ASSIMP_API void aiTransposeMatrix4(aiMatrix4x4* mat)
|
nuclear@0
|
612 {
|
nuclear@0
|
613 ai_assert(NULL != mat);
|
nuclear@0
|
614 mat->Transpose();
|
nuclear@0
|
615 }
|
nuclear@0
|
616
|
nuclear@0
|
617 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
618 // Vector transformation
|
nuclear@0
|
619 ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec,
|
nuclear@0
|
620 const aiMatrix3x3* mat)
|
nuclear@0
|
621 {
|
nuclear@0
|
622 ai_assert( NULL != mat );
|
nuclear@0
|
623 ai_assert( NULL != vec);
|
nuclear@0
|
624 *vec *= (*mat);
|
nuclear@0
|
625 }
|
nuclear@0
|
626
|
nuclear@0
|
627 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
628 ASSIMP_API void aiTransformVecByMatrix4(aiVector3D* vec,
|
nuclear@0
|
629 const aiMatrix4x4* mat)
|
nuclear@0
|
630 {
|
nuclear@0
|
631 ai_assert( NULL != mat );
|
nuclear@0
|
632 ai_assert( NULL != vec );
|
nuclear@0
|
633
|
nuclear@0
|
634 *vec *= (*mat);
|
nuclear@0
|
635 }
|
nuclear@0
|
636
|
nuclear@0
|
637 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
638 // Matrix multiplication
|
nuclear@0
|
639 ASSIMP_API void aiMultiplyMatrix4(
|
nuclear@0
|
640 aiMatrix4x4* dst,
|
nuclear@0
|
641 const aiMatrix4x4* src)
|
nuclear@0
|
642 {
|
nuclear@0
|
643 ai_assert( NULL != dst );
|
nuclear@0
|
644 ai_assert( NULL != src );
|
nuclear@0
|
645 *dst = (*dst) * (*src);
|
nuclear@0
|
646 }
|
nuclear@0
|
647
|
nuclear@0
|
648 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
649 ASSIMP_API void aiMultiplyMatrix3(
|
nuclear@0
|
650 aiMatrix3x3* dst,
|
nuclear@0
|
651 const aiMatrix3x3* src)
|
nuclear@0
|
652 {
|
nuclear@0
|
653 ai_assert( NULL != dst );
|
nuclear@0
|
654 ai_assert( NULL != src );
|
nuclear@0
|
655 *dst = (*dst) * (*src);
|
nuclear@0
|
656 }
|
nuclear@0
|
657
|
nuclear@0
|
658 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
659 // Matrix identity
|
nuclear@0
|
660 ASSIMP_API void aiIdentityMatrix3(
|
nuclear@0
|
661 aiMatrix3x3* mat)
|
nuclear@0
|
662 {
|
nuclear@0
|
663 ai_assert(NULL != mat);
|
nuclear@0
|
664 *mat = aiMatrix3x3();
|
nuclear@0
|
665 }
|
nuclear@0
|
666
|
nuclear@0
|
667 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
668 ASSIMP_API void aiIdentityMatrix4(
|
nuclear@0
|
669 aiMatrix4x4* mat)
|
nuclear@0
|
670 {
|
nuclear@0
|
671 ai_assert(NULL != mat);
|
nuclear@0
|
672 *mat = aiMatrix4x4();
|
nuclear@0
|
673 }
|
nuclear@0
|
674
|
nuclear@0
|
675 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
676 ASSIMP_API C_STRUCT const aiImporterDesc* aiGetImporterDesc( const char *extension ) {
|
nuclear@0
|
677 if( NULL == extension ) {
|
nuclear@0
|
678 return NULL;
|
nuclear@0
|
679 }
|
nuclear@0
|
680 const aiImporterDesc *desc( NULL );
|
nuclear@0
|
681 std::vector< BaseImporter* > out;
|
nuclear@0
|
682 GetImporterInstanceList( out );
|
nuclear@0
|
683 for( size_t i = 0; i < out.size(); ++i ) {
|
nuclear@0
|
684 if( 0 == strncmp( out[ i ]->GetInfo()->mFileExtensions, extension, strlen( extension ) ) ) {
|
nuclear@0
|
685 desc = out[ i ]->GetInfo();
|
nuclear@0
|
686 break;
|
nuclear@0
|
687 }
|
nuclear@0
|
688 }
|
nuclear@0
|
689
|
nuclear@0
|
690 DeleteImporterInstanceList(out);
|
nuclear@0
|
691
|
nuclear@0
|
692 return desc;
|
nuclear@0
|
693 }
|
nuclear@0
|
694
|
nuclear@0
|
695 // ------------------------------------------------------------------------------------------------
|