/src/assimp/code/Common/Assimp.cpp
Line | Count | Source |
1 | | /* |
2 | | --------------------------------------------------------------------------- |
3 | | Open Asset Import Library (assimp) |
4 | | --------------------------------------------------------------------------- |
5 | | |
6 | | Copyright (c) 2006-2026, assimp team |
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 following |
12 | | 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 | | /** @file Assimp.cpp |
42 | | * @brief Implementation of the Plain-C API |
43 | | */ |
44 | | |
45 | | #include <assimp/BaseImporter.h> |
46 | | #include <assimp/Exceptional.h> |
47 | | #include <assimp/GenericProperty.h> |
48 | | #include <assimp/cimport.h> |
49 | | #include <assimp/importerdesc.h> |
50 | | #include <assimp/scene.h> |
51 | | #include <assimp/DefaultLogger.hpp> |
52 | | #include <assimp/Importer.hpp> |
53 | | #include <assimp/LogStream.hpp> |
54 | | |
55 | | #include "CApi/CInterfaceIOWrapper.h" |
56 | | #include "Importer.h" |
57 | | #include "ScenePrivate.h" |
58 | | |
59 | | #include <list> |
60 | | |
61 | | // ------------------------------------------------------------------------------------------------ |
62 | | #ifndef ASSIMP_BUILD_SINGLETHREADED |
63 | | #include <mutex> |
64 | | #include <thread> |
65 | | #endif |
66 | | // ------------------------------------------------------------------------------------------------ |
67 | | using namespace Assimp; |
68 | | |
69 | | namespace Assimp { |
70 | | |
71 | | // underlying structure for aiPropertyStore |
72 | | using PropertyMap = BatchLoader::PropertyMap ; |
73 | | |
74 | | #if defined(__has_warning) |
75 | | # if __has_warning("-Wordered-compare-function-pointers") |
76 | | # pragma GCC diagnostic push |
77 | | # pragma GCC diagnostic ignored "-Wordered-compare-function-pointers" |
78 | | #endif |
79 | | #endif |
80 | | |
81 | | /** Stores the LogStream objects for all active C log streams */ |
82 | | struct mpred { |
83 | 0 | bool operator()(const aiLogStream &s0, const aiLogStream &s1) const { |
84 | 0 | return s0.callback < s1.callback && s0.user < s1.user; |
85 | 0 | } |
86 | | }; |
87 | | |
88 | | #if defined(__has_warning) |
89 | | #if __has_warning("-Wordered-compare-function-pointers") |
90 | | #pragma GCC diagnostic pop |
91 | | #endif |
92 | | #endif |
93 | | typedef std::map<aiLogStream, Assimp::LogStream *, mpred> LogStreamMap; |
94 | | |
95 | | /** Stores the LogStream objects allocated by #aiGetPredefinedLogStream */ |
96 | | typedef std::list<Assimp::LogStream *> PredefLogStreamMap; |
97 | | |
98 | | /** Local storage of all active log streams */ |
99 | | static LogStreamMap gActiveLogStreams; |
100 | | |
101 | | /** Local storage of LogStreams allocated by #aiGetPredefinedLogStream */ |
102 | | static PredefLogStreamMap gPredefinedStreams; |
103 | | |
104 | | /** Error message of the last failed import process */ |
105 | | static std::string gLastErrorString; |
106 | | |
107 | | /** Verbose logging active or not? */ |
108 | | static aiBool gVerboseLogging = false; |
109 | | |
110 | | /** will return all registered importers. */ |
111 | | void GetImporterInstanceList(std::vector<BaseImporter *> &out); |
112 | | |
113 | | /** will delete all registered importers. */ |
114 | | void DeleteImporterInstanceList(std::vector<BaseImporter *> &out); |
115 | | |
116 | | } // namespace Assimp |
117 | | |
118 | | #ifndef ASSIMP_BUILD_SINGLETHREADED |
119 | | /** Global mutex to manage the access to the log-stream map */ |
120 | | static std::mutex gLogStreamMutex; |
121 | | #endif |
122 | | |
123 | | // ------------------------------------------------------------------------------------------------ |
124 | | // Custom LogStream implementation for the C-API |
125 | | class LogToCallbackRedirector final : public LogStream { |
126 | | public: |
127 | | explicit LogToCallbackRedirector(const aiLogStream &s) : |
128 | 0 | mStream(s) { |
129 | 0 | ai_assert(nullptr != s.callback); |
130 | 0 | } |
131 | | |
132 | 0 | ~LogToCallbackRedirector() override { |
133 | | #ifndef ASSIMP_BUILD_SINGLETHREADED |
134 | | std::lock_guard<std::mutex> lock(gLogStreamMutex); |
135 | | #endif |
136 | | // (HACK) Check whether the 'stream.user' pointer points to a |
137 | | // custom LogStream allocated by #aiGetPredefinedLogStream. |
138 | | // In this case, we need to delete it, too. Of course, this |
139 | | // might cause strange problems, but the chance is quite low. |
140 | |
|
141 | 0 | PredefLogStreamMap::iterator it = std::find(gPredefinedStreams.begin(), |
142 | 0 | gPredefinedStreams.end(), (Assimp::LogStream *)mStream.user); |
143 | |
|
144 | 0 | if (it != gPredefinedStreams.end()) { |
145 | 0 | delete *it; |
146 | 0 | gPredefinedStreams.erase(it); |
147 | 0 | } |
148 | 0 | } |
149 | | |
150 | | /** @copydoc LogStream::write */ |
151 | 0 | void write(const char *message) override { |
152 | 0 | mStream.callback(message, mStream.user); |
153 | 0 | } |
154 | | |
155 | | private: |
156 | | const aiLogStream &mStream; |
157 | | }; |
158 | | |
159 | | // ------------------------------------------------------------------------------------------------ |
160 | 0 | void ReportSceneNotFoundError() { |
161 | 0 | ASSIMP_LOG_ERROR("Unable to find the Assimp::Importer for this aiScene. " |
162 | 0 | "The C-API does not accept scenes produced by the C++ API and vice versa"); |
163 | |
|
164 | 0 | ai_assert(false); |
165 | 0 | } |
166 | | |
167 | | // ------------------------------------------------------------------------------------------------ |
168 | | // Reads the given file and returns its content. |
169 | 0 | const aiScene *aiImportFile(const char *pFile, unsigned int pFlags) { |
170 | 0 | return aiImportFileEx(pFile, pFlags, nullptr); |
171 | 0 | } |
172 | | |
173 | | // ------------------------------------------------------------------------------------------------ |
174 | 0 | const aiScene *aiImportFileEx(const char *pFile, unsigned int pFlags, aiFileIO *pFS) { |
175 | 0 | return aiImportFileExWithProperties(pFile, pFlags, pFS, nullptr); |
176 | 0 | } |
177 | | |
178 | | // ------------------------------------------------------------------------------------------------ |
179 | | const aiScene *aiImportFileExWithProperties(const char *pFile, unsigned int pFlags, |
180 | 0 | aiFileIO *pFS, const aiPropertyStore *props) { |
181 | 0 | ai_assert(nullptr != pFile); |
182 | |
|
183 | 0 | const aiScene *scene = nullptr; |
184 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
185 | | |
186 | | // create an Importer for this file |
187 | 0 | Assimp::Importer *imp = new Assimp::Importer(); |
188 | | |
189 | | // copy properties |
190 | 0 | if (props) { |
191 | 0 | const PropertyMap *pp = reinterpret_cast<const PropertyMap *>(props); |
192 | 0 | ImporterPimpl *pimpl = imp->Pimpl(); |
193 | 0 | pimpl->mIntProperties = pp->ints; |
194 | 0 | pimpl->mFloatProperties = pp->floats; |
195 | 0 | pimpl->mStringProperties = pp->strings; |
196 | 0 | pimpl->mMatrixProperties = pp->matrices; |
197 | 0 | } |
198 | | // setup a custom IO system if necessary |
199 | 0 | if (pFS) { |
200 | 0 | imp->SetIOHandler(new CIOSystemWrapper(pFS)); |
201 | 0 | } |
202 | | |
203 | | // and have it read the file |
204 | 0 | scene = imp->ReadFile(pFile, pFlags); |
205 | | |
206 | | // if succeeded, store the importer in the scene and keep it alive |
207 | 0 | if (scene) { |
208 | 0 | ScenePrivateData *priv = const_cast<ScenePrivateData *>(ScenePriv(scene)); |
209 | 0 | priv->mOrigImporter = imp; |
210 | 0 | } else { |
211 | | // if failed, extract error code and destroy the import |
212 | 0 | gLastErrorString = imp->GetErrorString(); |
213 | 0 | delete imp; |
214 | 0 | } |
215 | | |
216 | | // return imported data. If the import failed the pointer is nullptr anyways |
217 | 0 | ASSIMP_END_EXCEPTION_REGION(const aiScene *); |
218 | |
|
219 | 0 | return scene; |
220 | 0 | } |
221 | | |
222 | | // ------------------------------------------------------------------------------------------------ |
223 | | const aiScene *aiImportFileFromMemory( |
224 | | const char *pBuffer, |
225 | | unsigned int pLength, |
226 | | unsigned int pFlags, |
227 | 0 | const char *pHint) { |
228 | 0 | return aiImportFileFromMemoryWithProperties(pBuffer, pLength, pFlags, pHint, nullptr); |
229 | 0 | } |
230 | | |
231 | | // ------------------------------------------------------------------------------------------------ |
232 | | const aiScene *aiImportFileFromMemoryWithProperties( |
233 | | const char *pBuffer, |
234 | | unsigned int pLength, |
235 | | unsigned int pFlags, |
236 | | const char *pHint, |
237 | 0 | const aiPropertyStore *props) { |
238 | 0 | if (pBuffer == nullptr) { |
239 | 0 | return nullptr; |
240 | 0 | } |
241 | | |
242 | 0 | if (pLength == 0u) { |
243 | 0 | return nullptr; |
244 | 0 | } |
245 | | |
246 | 0 | const aiScene *scene = nullptr; |
247 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
248 | | |
249 | | // create an Importer for this file |
250 | 0 | Assimp::Importer *imp = new Assimp::Importer(); |
251 | | |
252 | | // copy properties |
253 | 0 | if (props) { |
254 | 0 | const PropertyMap *pp = reinterpret_cast<const PropertyMap *>(props); |
255 | 0 | ImporterPimpl *pimpl = imp->Pimpl(); |
256 | 0 | pimpl->mIntProperties = pp->ints; |
257 | 0 | pimpl->mFloatProperties = pp->floats; |
258 | 0 | pimpl->mStringProperties = pp->strings; |
259 | 0 | pimpl->mMatrixProperties = pp->matrices; |
260 | 0 | } |
261 | | |
262 | | // and have it read the file from the memory buffer |
263 | 0 | scene = imp->ReadFileFromMemory(pBuffer, pLength, pFlags, pHint); |
264 | | |
265 | | // if succeeded, store the importer in the scene and keep it alive |
266 | 0 | if (scene) { |
267 | 0 | ScenePrivateData *priv = const_cast<ScenePrivateData *>(ScenePriv(scene)); |
268 | 0 | priv->mOrigImporter = imp; |
269 | 0 | } else { |
270 | | // if failed, extract error code and destroy the import |
271 | 0 | gLastErrorString = imp->GetErrorString(); |
272 | 0 | delete imp; |
273 | 0 | } |
274 | | // return imported data. If the import failed the pointer is nullptr anyways |
275 | 0 | ASSIMP_END_EXCEPTION_REGION(const aiScene *); |
276 | 0 | return scene; |
277 | 0 | } |
278 | | |
279 | | // ------------------------------------------------------------------------------------------------ |
280 | | // Releases all resources associated with the given import process. |
281 | 0 | void aiReleaseImport(const aiScene *pScene) { |
282 | 0 | if (!pScene) { |
283 | 0 | return; |
284 | 0 | } |
285 | | |
286 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
287 | | |
288 | | // find the importer associated with this data |
289 | 0 | const ScenePrivateData *priv = ScenePriv(pScene); |
290 | 0 | if (!priv || !priv->mOrigImporter) { |
291 | 0 | delete pScene; |
292 | 0 | } else { |
293 | | // deleting the Importer also deletes the scene |
294 | | // Note: the reason that this is not written as 'delete priv->mOrigImporter' |
295 | | // is a suspected bug in gcc 4.4+ (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52339) |
296 | 0 | Importer *importer = priv->mOrigImporter; |
297 | 0 | delete importer; |
298 | 0 | } |
299 | |
|
300 | 0 | ASSIMP_END_EXCEPTION_REGION(void); |
301 | 0 | } |
302 | | |
303 | | // ------------------------------------------------------------------------------------------------ |
304 | | ASSIMP_API const aiScene *aiApplyPostProcessing(const aiScene *pScene, |
305 | 0 | unsigned int pFlags) { |
306 | 0 | const aiScene *sc = nullptr; |
307 | |
|
308 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
309 | | |
310 | | // find the importer associated with this data |
311 | 0 | const ScenePrivateData *priv = ScenePriv(pScene); |
312 | 0 | if (!priv || !priv->mOrigImporter) { |
313 | 0 | ReportSceneNotFoundError(); |
314 | 0 | return nullptr; |
315 | 0 | } |
316 | | |
317 | 0 | sc = priv->mOrigImporter->ApplyPostProcessing(pFlags); |
318 | |
|
319 | 0 | if (!sc) { |
320 | 0 | aiReleaseImport(pScene); |
321 | 0 | return nullptr; |
322 | 0 | } |
323 | |
|
324 | 0 | ASSIMP_END_EXCEPTION_REGION(const aiScene *); |
325 | 0 | return sc; |
326 | 0 | } |
327 | | |
328 | | // ------------------------------------------------------------------------------------------------ |
329 | | ASSIMP_API const aiScene *aiApplyCustomizedPostProcessing(const aiScene *scene, |
330 | | BaseProcess *process, |
331 | 0 | bool requestValidation) { |
332 | 0 | const aiScene *sc(nullptr); |
333 | |
|
334 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
335 | | |
336 | | // find the importer associated with this data |
337 | 0 | const ScenePrivateData *priv = ScenePriv(scene); |
338 | 0 | if (nullptr == priv || nullptr == priv->mOrigImporter) { |
339 | 0 | ReportSceneNotFoundError(); |
340 | 0 | return nullptr; |
341 | 0 | } |
342 | | |
343 | 0 | sc = priv->mOrigImporter->ApplyCustomizedPostProcessing(process, requestValidation); |
344 | |
|
345 | 0 | if (!sc) { |
346 | 0 | aiReleaseImport(scene); |
347 | 0 | return nullptr; |
348 | 0 | } |
349 | |
|
350 | 0 | ASSIMP_END_EXCEPTION_REGION(const aiScene *); |
351 | |
|
352 | 0 | return sc; |
353 | 0 | } |
354 | | |
355 | | // ------------------------------------------------------------------------------------------------ |
356 | 0 | void CallbackToLogRedirector(const char *msg, char *dt) { |
357 | 0 | ai_assert(nullptr != msg); |
358 | 0 | ai_assert(nullptr != dt); |
359 | 0 | LogStream *stream = (LogStream *)dt; |
360 | 0 | if (stream != nullptr) { |
361 | 0 | stream->write(msg); |
362 | 0 | } |
363 | 0 | } |
364 | | |
365 | | static LogStream *DefaultStream = nullptr; |
366 | | |
367 | | // ------------------------------------------------------------------------------------------------ |
368 | 0 | ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream, const char *file) { |
369 | 0 | aiLogStream sout; |
370 | |
|
371 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
372 | 0 | if (DefaultStream == nullptr) { |
373 | 0 | DefaultStream = LogStream::createDefaultStream(pStream, file); |
374 | 0 | } |
375 | |
|
376 | 0 | if (!DefaultStream) { |
377 | 0 | sout.callback = nullptr; |
378 | 0 | sout.user = nullptr; |
379 | 0 | } else { |
380 | 0 | sout.callback = &CallbackToLogRedirector; |
381 | 0 | sout.user = (char *)DefaultStream; |
382 | 0 | } |
383 | 0 | gPredefinedStreams.push_back(DefaultStream); |
384 | 0 | ASSIMP_END_EXCEPTION_REGION(aiLogStream); |
385 | 0 | return sout; |
386 | 0 | } |
387 | | |
388 | | // ------------------------------------------------------------------------------------------------ |
389 | 0 | ASSIMP_API void aiAttachLogStream(const aiLogStream *stream) { |
390 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
391 | |
|
392 | | #ifndef ASSIMP_BUILD_SINGLETHREADED |
393 | | std::lock_guard<std::mutex> lock(gLogStreamMutex); |
394 | | #endif |
395 | |
|
396 | 0 | LogStream *lg = new LogToCallbackRedirector(*stream); |
397 | 0 | gActiveLogStreams[*stream] = lg; |
398 | |
|
399 | 0 | if (DefaultLogger::isNullLogger()) { |
400 | 0 | DefaultLogger::create(nullptr, (gVerboseLogging == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL)); |
401 | 0 | } |
402 | 0 | DefaultLogger::get()->attachStream(lg); |
403 | 0 | ASSIMP_END_EXCEPTION_REGION(void); |
404 | 0 | } |
405 | | |
406 | | // ------------------------------------------------------------------------------------------------ |
407 | 0 | ASSIMP_API aiReturn aiDetachLogStream(const aiLogStream *stream) { |
408 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
409 | |
|
410 | | #ifndef ASSIMP_BUILD_SINGLETHREADED |
411 | | std::lock_guard<std::mutex> lock(gLogStreamMutex); |
412 | | #endif |
413 | | // find the log-stream associated with this data |
414 | 0 | LogStreamMap::iterator it = gActiveLogStreams.find(*stream); |
415 | | // it should be there... else the user is playing fools with us |
416 | 0 | if (it == gActiveLogStreams.end()) { |
417 | 0 | return AI_FAILURE; |
418 | 0 | } |
419 | 0 | DefaultLogger::get()->detachStream(it->second); |
420 | 0 | delete it->second; |
421 | |
|
422 | 0 | if ((Assimp::LogStream *)stream->user == DefaultStream) { |
423 | 0 | DefaultStream = nullptr; |
424 | 0 | } |
425 | |
|
426 | 0 | gActiveLogStreams.erase(it); |
427 | |
|
428 | 0 | if (gActiveLogStreams.empty()) { |
429 | 0 | DefaultLogger::kill(); |
430 | 0 | } |
431 | 0 | ASSIMP_END_EXCEPTION_REGION(aiReturn); |
432 | 0 | return AI_SUCCESS; |
433 | 0 | } |
434 | | |
435 | | // ------------------------------------------------------------------------------------------------ |
436 | 0 | ASSIMP_API void aiDetachAllLogStreams(void) { |
437 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
438 | | #ifndef ASSIMP_BUILD_SINGLETHREADED |
439 | | std::lock_guard<std::mutex> lock(gLogStreamMutex); |
440 | | #endif |
441 | 0 | Logger *logger(DefaultLogger::get()); |
442 | 0 | if (nullptr == logger) { |
443 | 0 | return; |
444 | 0 | } |
445 | | |
446 | 0 | for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) { |
447 | 0 | logger->detachStream(it->second); |
448 | 0 | delete it->second; |
449 | 0 | } |
450 | 0 | gActiveLogStreams.clear(); |
451 | 0 | DefaultLogger::kill(); |
452 | |
|
453 | 0 | ASSIMP_END_EXCEPTION_REGION(void); |
454 | 0 | } |
455 | | |
456 | | // ------------------------------------------------------------------------------------------------ |
457 | 0 | ASSIMP_API void aiEnableVerboseLogging(aiBool d) { |
458 | 0 | if (!DefaultLogger::isNullLogger()) { |
459 | 0 | DefaultLogger::get()->setLogSeverity((d == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL)); |
460 | 0 | } |
461 | 0 | gVerboseLogging = d; |
462 | 0 | } |
463 | | |
464 | | // ------------------------------------------------------------------------------------------------ |
465 | | // Returns the error text of the last failed import process. |
466 | 0 | const char *aiGetErrorString() { |
467 | 0 | return gLastErrorString.c_str(); |
468 | 0 | } |
469 | | |
470 | | // ----------------------------------------------------------------------------------------------- |
471 | | // Return the description of a importer given its index |
472 | 0 | const aiImporterDesc *aiGetImportFormatDescription(size_t pIndex) { |
473 | 0 | return Importer().GetImporterInfo(pIndex); |
474 | 0 | } |
475 | | |
476 | | // ----------------------------------------------------------------------------------------------- |
477 | | // Return the number of importers |
478 | 0 | size_t aiGetImportFormatCount(void) { |
479 | 0 | return Importer().GetImporterCount(); |
480 | 0 | } |
481 | | |
482 | | // ------------------------------------------------------------------------------------------------ |
483 | | // Returns the error text of the last failed import process. |
484 | 0 | aiBool aiIsExtensionSupported(const char *szExtension) { |
485 | 0 | ai_assert(nullptr != szExtension); |
486 | 0 | aiBool candoit = AI_FALSE; |
487 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
488 | | |
489 | | // FIXME: no need to create a temporary Importer instance just for that .. |
490 | 0 | Assimp::Importer tmp; |
491 | 0 | candoit = tmp.IsExtensionSupported(std::string(szExtension)) ? AI_TRUE : AI_FALSE; |
492 | |
|
493 | 0 | ASSIMP_END_EXCEPTION_REGION(aiBool); |
494 | 0 | return candoit; |
495 | 0 | } |
496 | | |
497 | | // ------------------------------------------------------------------------------------------------ |
498 | | // Get a list of all file extensions supported by ASSIMP |
499 | 0 | void aiGetExtensionList(aiString *szOut) { |
500 | 0 | ai_assert(nullptr != szOut); |
501 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
502 | | |
503 | | // FIXME: no need to create a temporary Importer instance just for that .. |
504 | 0 | Assimp::Importer tmp; |
505 | 0 | tmp.GetExtensionList(*szOut); |
506 | |
|
507 | 0 | ASSIMP_END_EXCEPTION_REGION(void); |
508 | 0 | } |
509 | | |
510 | | // ------------------------------------------------------------------------------------------------ |
511 | | // Get the memory requirements for a particular import. |
512 | | void aiGetMemoryRequirements(const C_STRUCT aiScene *pIn, |
513 | 0 | C_STRUCT aiMemoryInfo *in) { |
514 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
515 | | |
516 | | // find the importer associated with this data |
517 | 0 | const ScenePrivateData *priv = ScenePriv(pIn); |
518 | 0 | if (!priv || !priv->mOrigImporter) { |
519 | 0 | ReportSceneNotFoundError(); |
520 | 0 | return; |
521 | 0 | } |
522 | | |
523 | 0 | return priv->mOrigImporter->GetMemoryRequirements(*in); |
524 | 0 | ASSIMP_END_EXCEPTION_REGION(void); |
525 | 0 | } |
526 | | |
527 | | // ------------------------------------------------------------------------------------------------ |
528 | 0 | ASSIMP_API const C_STRUCT aiTexture *aiGetEmbeddedTexture(const C_STRUCT aiScene *pIn, const char *filename) { |
529 | 0 | return pIn->GetEmbeddedTexture(filename); |
530 | 0 | } |
531 | | |
532 | | // ------------------------------------------------------------------------------------------------ |
533 | 0 | ASSIMP_API aiPropertyStore *aiCreatePropertyStore(void) { |
534 | 0 | return reinterpret_cast<aiPropertyStore *>(new PropertyMap()); |
535 | 0 | } |
536 | | |
537 | | // ------------------------------------------------------------------------------------------------ |
538 | 0 | ASSIMP_API void aiReleasePropertyStore(aiPropertyStore *p) { |
539 | 0 | delete reinterpret_cast<PropertyMap *>(p); |
540 | 0 | } |
541 | | |
542 | | // ------------------------------------------------------------------------------------------------ |
543 | | // Importer::SetPropertyInteger |
544 | 0 | ASSIMP_API void aiSetImportPropertyInteger(aiPropertyStore *p, const char *szName, int value) { |
545 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
546 | 0 | PropertyMap *pp = reinterpret_cast<PropertyMap *>(p); |
547 | 0 | SetGenericProperty<int>(pp->ints, szName, value); |
548 | 0 | ASSIMP_END_EXCEPTION_REGION(void); |
549 | 0 | } |
550 | | |
551 | | // ------------------------------------------------------------------------------------------------ |
552 | | // Importer::SetPropertyFloat |
553 | 0 | ASSIMP_API void aiSetImportPropertyFloat(aiPropertyStore *p, const char *szName, ai_real value) { |
554 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
555 | 0 | PropertyMap *pp = reinterpret_cast<PropertyMap *>(p); |
556 | 0 | SetGenericProperty<ai_real>(pp->floats, szName, value); |
557 | 0 | ASSIMP_END_EXCEPTION_REGION(void); |
558 | 0 | } |
559 | | |
560 | | // ------------------------------------------------------------------------------------------------ |
561 | | // Importer::SetPropertyString |
562 | | ASSIMP_API void aiSetImportPropertyString(aiPropertyStore *p, const char *szName, |
563 | 0 | const C_STRUCT aiString *st) { |
564 | 0 | if (!st) { |
565 | 0 | return; |
566 | 0 | } |
567 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
568 | 0 | PropertyMap *pp = reinterpret_cast<PropertyMap *>(p); |
569 | 0 | SetGenericProperty<std::string>(pp->strings, szName, std::string(st->C_Str())); |
570 | 0 | ASSIMP_END_EXCEPTION_REGION(void); |
571 | 0 | } |
572 | | |
573 | | // ------------------------------------------------------------------------------------------------ |
574 | | // Importer::SetPropertyMatrix |
575 | | ASSIMP_API void aiSetImportPropertyMatrix(aiPropertyStore *p, const char *szName, |
576 | 0 | const C_STRUCT aiMatrix4x4 *mat) { |
577 | 0 | if (!mat) { |
578 | 0 | return; |
579 | 0 | } |
580 | 0 | ASSIMP_BEGIN_EXCEPTION_REGION(); |
581 | 0 | PropertyMap *pp = reinterpret_cast<PropertyMap *>(p); |
582 | 0 | SetGenericProperty<aiMatrix4x4>(pp->matrices, szName, *mat); |
583 | 0 | ASSIMP_END_EXCEPTION_REGION(void); |
584 | 0 | } |
585 | | |
586 | | // ------------------------------------------------------------------------------------------------ |
587 | | // Rotation matrix to quaternion |
588 | 0 | ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion *quat, const aiMatrix3x3 *mat) { |
589 | 0 | ai_assert(nullptr != quat); |
590 | 0 | ai_assert(nullptr != mat); |
591 | 0 | *quat = aiQuaternion(*mat); |
592 | 0 | } |
593 | | |
594 | | // ------------------------------------------------------------------------------------------------ |
595 | | // Matrix decomposition |
596 | | ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4 *mat, aiVector3D *scaling, |
597 | | aiQuaternion *rotation, |
598 | 0 | aiVector3D *position) { |
599 | 0 | ai_assert(nullptr != rotation); |
600 | 0 | ai_assert(nullptr != position); |
601 | 0 | ai_assert(nullptr != scaling); |
602 | 0 | ai_assert(nullptr != mat); |
603 | 0 | mat->Decompose(*scaling, *rotation, *position); |
604 | 0 | } |
605 | | |
606 | | // ------------------------------------------------------------------------------------------------ |
607 | | // Matrix transpose |
608 | 0 | ASSIMP_API void aiTransposeMatrix3(aiMatrix3x3 *mat) { |
609 | 0 | ai_assert(nullptr != mat); |
610 | 0 | mat->Transpose(); |
611 | 0 | } |
612 | | |
613 | | // ------------------------------------------------------------------------------------------------ |
614 | 0 | ASSIMP_API void aiTransposeMatrix4(aiMatrix4x4 *mat) { |
615 | 0 | ai_assert(nullptr != mat); |
616 | 0 | mat->Transpose(); |
617 | 0 | } |
618 | | |
619 | | // ------------------------------------------------------------------------------------------------ |
620 | | // Vector transformation |
621 | | ASSIMP_API void aiTransformVecByMatrix3(aiVector3D *vec, |
622 | 0 | const aiMatrix3x3 *mat) { |
623 | 0 | ai_assert(nullptr != mat); |
624 | 0 | ai_assert(nullptr != vec); |
625 | 0 | *vec *= (*mat); |
626 | 0 | } |
627 | | |
628 | | // ------------------------------------------------------------------------------------------------ |
629 | | ASSIMP_API void aiTransformVecByMatrix4(aiVector3D *vec, |
630 | 0 | const aiMatrix4x4 *mat) { |
631 | 0 | ai_assert(nullptr != mat); |
632 | 0 | ai_assert(nullptr != vec); |
633 | |
|
634 | 0 | *vec *= (*mat); |
635 | 0 | } |
636 | | |
637 | | // ------------------------------------------------------------------------------------------------ |
638 | | // Matrix multiplication |
639 | | ASSIMP_API void aiMultiplyMatrix4( |
640 | | aiMatrix4x4 *dst, |
641 | 0 | const aiMatrix4x4 *src) { |
642 | 0 | ai_assert(nullptr != dst); |
643 | 0 | ai_assert(nullptr != src); |
644 | 0 | *dst = (*dst) * (*src); |
645 | 0 | } |
646 | | |
647 | | // ------------------------------------------------------------------------------------------------ |
648 | | ASSIMP_API void aiMultiplyMatrix3( |
649 | | aiMatrix3x3 *dst, |
650 | 0 | const aiMatrix3x3 *src) { |
651 | 0 | ai_assert(nullptr != dst); |
652 | 0 | ai_assert(nullptr != src); |
653 | 0 | *dst = (*dst) * (*src); |
654 | 0 | } |
655 | | |
656 | | // ------------------------------------------------------------------------------------------------ |
657 | | // Matrix identity |
658 | | ASSIMP_API void aiIdentityMatrix3( |
659 | 0 | aiMatrix3x3 *mat) { |
660 | 0 | ai_assert(nullptr != mat); |
661 | 0 | *mat = aiMatrix3x3(); |
662 | 0 | } |
663 | | |
664 | | // ------------------------------------------------------------------------------------------------ |
665 | | ASSIMP_API void aiIdentityMatrix4( |
666 | 0 | aiMatrix4x4 *mat) { |
667 | 0 | ai_assert(nullptr != mat); |
668 | 0 | *mat = aiMatrix4x4(); |
669 | 0 | } |
670 | | |
671 | | // ------------------------------------------------------------------------------------------------ |
672 | 0 | ASSIMP_API C_STRUCT const aiImporterDesc *aiGetImporterDesc(const char *extension) { |
673 | 0 | if (nullptr == extension) { |
674 | 0 | return nullptr; |
675 | 0 | } |
676 | 0 | const aiImporterDesc *desc(nullptr); |
677 | 0 | std::vector<BaseImporter *> out; |
678 | 0 | GetImporterInstanceList(out); |
679 | 0 | for (size_t i = 0; i < out.size(); ++i) { |
680 | 0 | if (0 == strncmp(out[i]->GetInfo()->mFileExtensions, extension, strlen(extension))) { |
681 | 0 | desc = out[i]->GetInfo(); |
682 | 0 | break; |
683 | 0 | } |
684 | 0 | } |
685 | |
|
686 | 0 | DeleteImporterInstanceList(out); |
687 | |
|
688 | 0 | return desc; |
689 | 0 | } |
690 | | |
691 | | // ------------------------------------------------------------------------------------------------ |
692 | | ASSIMP_API int aiVector2AreEqual( |
693 | | const C_STRUCT aiVector2D *a, |
694 | 0 | const C_STRUCT aiVector2D *b) { |
695 | 0 | ai_assert(nullptr != a); |
696 | 0 | ai_assert(nullptr != b); |
697 | 0 | return *a == *b; |
698 | 0 | } |
699 | | |
700 | | // ------------------------------------------------------------------------------------------------ |
701 | | ASSIMP_API int aiVector2AreEqualEpsilon( |
702 | | const C_STRUCT aiVector2D *a, |
703 | | const C_STRUCT aiVector2D *b, |
704 | 0 | const float epsilon) { |
705 | 0 | ai_assert(nullptr != a); |
706 | 0 | ai_assert(nullptr != b); |
707 | 0 | return a->Equal(*b, epsilon); |
708 | 0 | } |
709 | | |
710 | | // ------------------------------------------------------------------------------------------------ |
711 | | ASSIMP_API void aiVector2Add( |
712 | | C_STRUCT aiVector2D *dst, |
713 | 0 | const C_STRUCT aiVector2D *src) { |
714 | 0 | ai_assert(nullptr != dst); |
715 | 0 | ai_assert(nullptr != src); |
716 | 0 | *dst = *dst + *src; |
717 | 0 | } |
718 | | |
719 | | // ------------------------------------------------------------------------------------------------ |
720 | | ASSIMP_API void aiVector2Subtract( |
721 | | C_STRUCT aiVector2D *dst, |
722 | 0 | const C_STRUCT aiVector2D *src) { |
723 | 0 | ai_assert(nullptr != dst); |
724 | 0 | ai_assert(nullptr != src); |
725 | 0 | *dst = *dst - *src; |
726 | 0 | } |
727 | | |
728 | | // ------------------------------------------------------------------------------------------------ |
729 | | ASSIMP_API void aiVector2Scale( |
730 | | C_STRUCT aiVector2D *dst, |
731 | 0 | const float s) { |
732 | 0 | ai_assert(nullptr != dst); |
733 | 0 | *dst *= s; |
734 | 0 | } |
735 | | |
736 | | // ------------------------------------------------------------------------------------------------ |
737 | | ASSIMP_API void aiVector2SymMul( |
738 | | C_STRUCT aiVector2D *dst, |
739 | 0 | const C_STRUCT aiVector2D *other) { |
740 | 0 | ai_assert(nullptr != dst); |
741 | 0 | ai_assert(nullptr != other); |
742 | 0 | *dst = dst->SymMul(*other); |
743 | 0 | } |
744 | | |
745 | | // ------------------------------------------------------------------------------------------------ |
746 | | ASSIMP_API void aiVector2DivideByScalar( |
747 | | C_STRUCT aiVector2D *dst, |
748 | 0 | const float s) { |
749 | 0 | ai_assert(nullptr != dst); |
750 | 0 | *dst /= s; |
751 | 0 | } |
752 | | |
753 | | // ------------------------------------------------------------------------------------------------ |
754 | | ASSIMP_API void aiVector2DivideByVector( |
755 | | C_STRUCT aiVector2D *dst, |
756 | 0 | C_STRUCT aiVector2D *v) { |
757 | 0 | ai_assert(nullptr != dst); |
758 | 0 | ai_assert(nullptr != v); |
759 | 0 | *dst = *dst / *v; |
760 | 0 | } |
761 | | |
762 | | // ------------------------------------------------------------------------------------------------ |
763 | | ASSIMP_API ai_real aiVector2Length( |
764 | 0 | const C_STRUCT aiVector2D *v) { |
765 | 0 | ai_assert(nullptr != v); |
766 | 0 | return v->Length(); |
767 | 0 | } |
768 | | |
769 | | // ------------------------------------------------------------------------------------------------ |
770 | | ASSIMP_API ai_real aiVector2SquareLength( |
771 | 0 | const C_STRUCT aiVector2D *v) { |
772 | 0 | ai_assert(nullptr != v); |
773 | 0 | return v->SquareLength(); |
774 | 0 | } |
775 | | |
776 | | // ------------------------------------------------------------------------------------------------ |
777 | | ASSIMP_API void aiVector2Negate( |
778 | 0 | C_STRUCT aiVector2D *dst) { |
779 | 0 | ai_assert(nullptr != dst); |
780 | 0 | *dst = -(*dst); |
781 | 0 | } |
782 | | |
783 | | // ------------------------------------------------------------------------------------------------ |
784 | | ASSIMP_API ai_real aiVector2DotProduct( |
785 | | const C_STRUCT aiVector2D *a, |
786 | 0 | const C_STRUCT aiVector2D *b) { |
787 | 0 | ai_assert(nullptr != a); |
788 | 0 | ai_assert(nullptr != b); |
789 | 0 | return (*a) * (*b); |
790 | 0 | } |
791 | | |
792 | | // ------------------------------------------------------------------------------------------------ |
793 | | ASSIMP_API void aiVector2Normalize( |
794 | 0 | C_STRUCT aiVector2D *v) { |
795 | 0 | ai_assert(nullptr != v); |
796 | 0 | v->Normalize(); |
797 | 0 | } |
798 | | |
799 | | // ------------------------------------------------------------------------------------------------ |
800 | | ASSIMP_API int aiVector3AreEqual( |
801 | | const C_STRUCT aiVector3D *a, |
802 | 0 | const C_STRUCT aiVector3D *b) { |
803 | 0 | ai_assert(nullptr != a); |
804 | 0 | ai_assert(nullptr != b); |
805 | 0 | return *a == *b; |
806 | 0 | } |
807 | | |
808 | | // ------------------------------------------------------------------------------------------------ |
809 | | ASSIMP_API int aiVector3AreEqualEpsilon( |
810 | | const C_STRUCT aiVector3D *a, |
811 | | const C_STRUCT aiVector3D *b, |
812 | 0 | const float epsilon) { |
813 | 0 | ai_assert(nullptr != a); |
814 | 0 | ai_assert(nullptr != b); |
815 | 0 | return a->Equal(*b, epsilon); |
816 | 0 | } |
817 | | |
818 | | // ------------------------------------------------------------------------------------------------ |
819 | | ASSIMP_API int aiVector3LessThan( |
820 | | const C_STRUCT aiVector3D *a, |
821 | 0 | const C_STRUCT aiVector3D *b) { |
822 | 0 | ai_assert(nullptr != a); |
823 | 0 | ai_assert(nullptr != b); |
824 | 0 | return *a < *b; |
825 | 0 | } |
826 | | |
827 | | // ------------------------------------------------------------------------------------------------ |
828 | | ASSIMP_API void aiVector3Add( |
829 | | C_STRUCT aiVector3D *dst, |
830 | 0 | const C_STRUCT aiVector3D *src) { |
831 | 0 | ai_assert(nullptr != dst); |
832 | 0 | ai_assert(nullptr != src); |
833 | 0 | *dst = *dst + *src; |
834 | 0 | } |
835 | | |
836 | | // ------------------------------------------------------------------------------------------------ |
837 | | ASSIMP_API void aiVector3Subtract( |
838 | | C_STRUCT aiVector3D *dst, |
839 | 0 | const C_STRUCT aiVector3D *src) { |
840 | 0 | ai_assert(nullptr != dst); |
841 | 0 | ai_assert(nullptr != src); |
842 | 0 | *dst = *dst - *src; |
843 | 0 | } |
844 | | |
845 | | // ------------------------------------------------------------------------------------------------ |
846 | | ASSIMP_API void aiVector3Scale( |
847 | | C_STRUCT aiVector3D *dst, |
848 | 0 | const float s) { |
849 | 0 | ai_assert(nullptr != dst); |
850 | 0 | *dst *= s; |
851 | 0 | } |
852 | | |
853 | | // ------------------------------------------------------------------------------------------------ |
854 | | ASSIMP_API void aiVector3SymMul( |
855 | | C_STRUCT aiVector3D *dst, |
856 | 0 | const C_STRUCT aiVector3D *other) { |
857 | 0 | ai_assert(nullptr != dst); |
858 | 0 | ai_assert(nullptr != other); |
859 | 0 | *dst = dst->SymMul(*other); |
860 | 0 | } |
861 | | |
862 | | // ------------------------------------------------------------------------------------------------ |
863 | | ASSIMP_API void aiVector3DivideByScalar( |
864 | 0 | C_STRUCT aiVector3D *dst, const float s) { |
865 | 0 | ai_assert(nullptr != dst); |
866 | 0 | *dst /= s; |
867 | 0 | } |
868 | | |
869 | | // ------------------------------------------------------------------------------------------------ |
870 | | ASSIMP_API void aiVector3DivideByVector( |
871 | | C_STRUCT aiVector3D *dst, |
872 | 0 | C_STRUCT aiVector3D *v) { |
873 | 0 | ai_assert(nullptr != dst); |
874 | 0 | ai_assert(nullptr != v); |
875 | 0 | *dst = *dst / *v; |
876 | 0 | } |
877 | | |
878 | | // ------------------------------------------------------------------------------------------------ |
879 | | ASSIMP_API ai_real aiVector3Length( |
880 | 0 | const C_STRUCT aiVector3D *v) { |
881 | 0 | ai_assert(nullptr != v); |
882 | 0 | return v->Length(); |
883 | 0 | } |
884 | | |
885 | | // ------------------------------------------------------------------------------------------------ |
886 | | ASSIMP_API ai_real aiVector3SquareLength( |
887 | 0 | const C_STRUCT aiVector3D *v) { |
888 | 0 | ai_assert(nullptr != v); |
889 | 0 | return v->SquareLength(); |
890 | 0 | } |
891 | | |
892 | | // ------------------------------------------------------------------------------------------------ |
893 | | ASSIMP_API void aiVector3Negate( |
894 | 0 | C_STRUCT aiVector3D *dst) { |
895 | 0 | ai_assert(nullptr != dst); |
896 | 0 | *dst = -(*dst); |
897 | 0 | } |
898 | | |
899 | | // ------------------------------------------------------------------------------------------------ |
900 | | ASSIMP_API ai_real aiVector3DotProduct( |
901 | | const C_STRUCT aiVector3D *a, |
902 | 0 | const C_STRUCT aiVector3D *b) { |
903 | 0 | ai_assert(nullptr != a); |
904 | 0 | ai_assert(nullptr != b); |
905 | 0 | return (*a) * (*b); |
906 | 0 | } |
907 | | |
908 | | // ------------------------------------------------------------------------------------------------ |
909 | | ASSIMP_API void aiVector3CrossProduct( |
910 | | C_STRUCT aiVector3D *dst, |
911 | | const C_STRUCT aiVector3D *a, |
912 | 0 | const C_STRUCT aiVector3D *b) { |
913 | 0 | ai_assert(nullptr != dst); |
914 | 0 | ai_assert(nullptr != a); |
915 | 0 | ai_assert(nullptr != b); |
916 | 0 | *dst = *a ^ *b; |
917 | 0 | } |
918 | | |
919 | | // ------------------------------------------------------------------------------------------------ |
920 | | ASSIMP_API void aiVector3Normalize( |
921 | 0 | C_STRUCT aiVector3D *v) { |
922 | 0 | ai_assert(nullptr != v); |
923 | 0 | v->Normalize(); |
924 | 0 | } |
925 | | |
926 | | // ------------------------------------------------------------------------------------------------ |
927 | | ASSIMP_API void aiVector3NormalizeSafe( |
928 | 0 | C_STRUCT aiVector3D *v) { |
929 | 0 | ai_assert(nullptr != v); |
930 | 0 | v->NormalizeSafe(); |
931 | 0 | } |
932 | | |
933 | | // ------------------------------------------------------------------------------------------------ |
934 | | ASSIMP_API void aiVector3RotateByQuaternion( |
935 | | C_STRUCT aiVector3D *v, |
936 | 0 | const C_STRUCT aiQuaternion *q) { |
937 | 0 | ai_assert(nullptr != v); |
938 | 0 | ai_assert(nullptr != q); |
939 | 0 | *v = q->Rotate(*v); |
940 | 0 | } |
941 | | |
942 | | // ------------------------------------------------------------------------------------------------ |
943 | | ASSIMP_API void aiMatrix3FromMatrix4( |
944 | | C_STRUCT aiMatrix3x3 *dst, |
945 | 0 | const C_STRUCT aiMatrix4x4 *mat) { |
946 | 0 | ai_assert(nullptr != dst); |
947 | 0 | ai_assert(nullptr != mat); |
948 | 0 | *dst = aiMatrix3x3(*mat); |
949 | 0 | } |
950 | | |
951 | | // ------------------------------------------------------------------------------------------------ |
952 | | ASSIMP_API void aiMatrix3FromQuaternion( |
953 | | C_STRUCT aiMatrix3x3 *mat, |
954 | 0 | const C_STRUCT aiQuaternion *q) { |
955 | 0 | ai_assert(nullptr != mat); |
956 | 0 | ai_assert(nullptr != q); |
957 | 0 | *mat = q->GetMatrix(); |
958 | 0 | } |
959 | | |
960 | | // ------------------------------------------------------------------------------------------------ |
961 | | ASSIMP_API int aiMatrix3AreEqual( |
962 | | const C_STRUCT aiMatrix3x3 *a, |
963 | 0 | const C_STRUCT aiMatrix3x3 *b) { |
964 | 0 | ai_assert(nullptr != a); |
965 | 0 | ai_assert(nullptr != b); |
966 | 0 | return *a == *b; |
967 | 0 | } |
968 | | |
969 | | // ------------------------------------------------------------------------------------------------ |
970 | | ASSIMP_API int aiMatrix3AreEqualEpsilon( |
971 | | const C_STRUCT aiMatrix3x3 *a, |
972 | | const C_STRUCT aiMatrix3x3 *b, |
973 | 0 | const float epsilon) { |
974 | 0 | ai_assert(nullptr != a); |
975 | 0 | ai_assert(nullptr != b); |
976 | 0 | return a->Equal(*b, epsilon); |
977 | 0 | } |
978 | | |
979 | | // ------------------------------------------------------------------------------------------------ |
980 | 0 | ASSIMP_API void aiMatrix3Inverse(C_STRUCT aiMatrix3x3 *mat) { |
981 | 0 | ai_assert(nullptr != mat); |
982 | 0 | mat->Inverse(); |
983 | 0 | } |
984 | | |
985 | | // ------------------------------------------------------------------------------------------------ |
986 | 0 | ASSIMP_API ai_real aiMatrix3Determinant(const C_STRUCT aiMatrix3x3 *mat) { |
987 | 0 | ai_assert(nullptr != mat); |
988 | 0 | return mat->Determinant(); |
989 | 0 | } |
990 | | |
991 | | // ------------------------------------------------------------------------------------------------ |
992 | | ASSIMP_API void aiMatrix3RotationZ( |
993 | | C_STRUCT aiMatrix3x3 *mat, |
994 | 0 | const float angle) { |
995 | 0 | ai_assert(nullptr != mat); |
996 | 0 | aiMatrix3x3::RotationZ(angle, *mat); |
997 | 0 | } |
998 | | |
999 | | // ------------------------------------------------------------------------------------------------ |
1000 | | ASSIMP_API void aiMatrix3FromRotationAroundAxis( |
1001 | | C_STRUCT aiMatrix3x3 *mat, |
1002 | | const C_STRUCT aiVector3D *axis, |
1003 | 0 | const float angle) { |
1004 | 0 | ai_assert(nullptr != mat); |
1005 | 0 | ai_assert(nullptr != axis); |
1006 | 0 | aiMatrix3x3::Rotation(angle, *axis, *mat); |
1007 | 0 | } |
1008 | | |
1009 | | // ------------------------------------------------------------------------------------------------ |
1010 | | ASSIMP_API void aiMatrix3Translation( |
1011 | | C_STRUCT aiMatrix3x3 *mat, |
1012 | 0 | const C_STRUCT aiVector2D *translation) { |
1013 | 0 | ai_assert(nullptr != mat); |
1014 | 0 | ai_assert(nullptr != translation); |
1015 | 0 | aiMatrix3x3::Translation(*translation, *mat); |
1016 | 0 | } |
1017 | | |
1018 | | // ------------------------------------------------------------------------------------------------ |
1019 | | ASSIMP_API void aiMatrix3FromTo( |
1020 | | C_STRUCT aiMatrix3x3 *mat, |
1021 | | const C_STRUCT aiVector3D *from, |
1022 | 0 | const C_STRUCT aiVector3D *to) { |
1023 | 0 | ai_assert(nullptr != mat); |
1024 | 0 | ai_assert(nullptr != from); |
1025 | 0 | ai_assert(nullptr != to); |
1026 | 0 | aiMatrix3x3::FromToMatrix(*from, *to, *mat); |
1027 | 0 | } |
1028 | | |
1029 | | // ------------------------------------------------------------------------------------------------ |
1030 | | ASSIMP_API void aiMatrix4FromMatrix3( |
1031 | | C_STRUCT aiMatrix4x4 *dst, |
1032 | 0 | const C_STRUCT aiMatrix3x3 *mat) { |
1033 | 0 | ai_assert(nullptr != dst); |
1034 | 0 | ai_assert(nullptr != mat); |
1035 | 0 | *dst = aiMatrix4x4(*mat); |
1036 | 0 | } |
1037 | | |
1038 | | // ------------------------------------------------------------------------------------------------ |
1039 | | ASSIMP_API void aiMatrix4FromScalingQuaternionPosition( |
1040 | | C_STRUCT aiMatrix4x4 *mat, |
1041 | | const C_STRUCT aiVector3D *scaling, |
1042 | | const C_STRUCT aiQuaternion *rotation, |
1043 | 0 | const C_STRUCT aiVector3D *position) { |
1044 | 0 | ai_assert(nullptr != mat); |
1045 | 0 | ai_assert(nullptr != scaling); |
1046 | 0 | ai_assert(nullptr != rotation); |
1047 | 0 | ai_assert(nullptr != position); |
1048 | 0 | *mat = aiMatrix4x4(*scaling, *rotation, *position); |
1049 | 0 | } |
1050 | | |
1051 | | // ------------------------------------------------------------------------------------------------ |
1052 | | ASSIMP_API void aiMatrix4Add( |
1053 | | C_STRUCT aiMatrix4x4 *dst, |
1054 | 0 | const C_STRUCT aiMatrix4x4 *src) { |
1055 | 0 | ai_assert(nullptr != dst); |
1056 | 0 | ai_assert(nullptr != src); |
1057 | 0 | *dst = *dst + *src; |
1058 | 0 | } |
1059 | | |
1060 | | // ------------------------------------------------------------------------------------------------ |
1061 | | ASSIMP_API int aiMatrix4AreEqual( |
1062 | | const C_STRUCT aiMatrix4x4 *a, |
1063 | 0 | const C_STRUCT aiMatrix4x4 *b) { |
1064 | 0 | ai_assert(nullptr != a); |
1065 | 0 | ai_assert(nullptr != b); |
1066 | 0 | return *a == *b; |
1067 | 0 | } |
1068 | | |
1069 | | // ------------------------------------------------------------------------------------------------ |
1070 | | ASSIMP_API int aiMatrix4AreEqualEpsilon( |
1071 | | const C_STRUCT aiMatrix4x4 *a, |
1072 | | const C_STRUCT aiMatrix4x4 *b, |
1073 | 0 | const float epsilon) { |
1074 | 0 | ai_assert(nullptr != a); |
1075 | 0 | ai_assert(nullptr != b); |
1076 | 0 | return a->Equal(*b, epsilon); |
1077 | 0 | } |
1078 | | |
1079 | | // ------------------------------------------------------------------------------------------------ |
1080 | 0 | ASSIMP_API void aiMatrix4Inverse(C_STRUCT aiMatrix4x4 *mat) { |
1081 | 0 | ai_assert(nullptr != mat); |
1082 | 0 | mat->Inverse(); |
1083 | 0 | } |
1084 | | |
1085 | | // ------------------------------------------------------------------------------------------------ |
1086 | 0 | ASSIMP_API ai_real aiMatrix4Determinant(const C_STRUCT aiMatrix4x4 *mat) { |
1087 | 0 | ai_assert(nullptr != mat); |
1088 | 0 | return mat->Determinant(); |
1089 | 0 | } |
1090 | | |
1091 | | // ------------------------------------------------------------------------------------------------ |
1092 | 0 | ASSIMP_API int aiMatrix4IsIdentity(const C_STRUCT aiMatrix4x4 *mat) { |
1093 | 0 | ai_assert(nullptr != mat); |
1094 | 0 | return mat->IsIdentity(); |
1095 | 0 | } |
1096 | | |
1097 | | // ------------------------------------------------------------------------------------------------ |
1098 | | ASSIMP_API void aiMatrix4DecomposeIntoScalingEulerAnglesPosition( |
1099 | | const C_STRUCT aiMatrix4x4 *mat, |
1100 | | C_STRUCT aiVector3D *scaling, |
1101 | | C_STRUCT aiVector3D *rotation, |
1102 | 0 | C_STRUCT aiVector3D *position) { |
1103 | 0 | ai_assert(nullptr != mat); |
1104 | 0 | ai_assert(nullptr != scaling); |
1105 | 0 | ai_assert(nullptr != rotation); |
1106 | 0 | ai_assert(nullptr != position); |
1107 | 0 | mat->Decompose(*scaling, *rotation, *position); |
1108 | 0 | } |
1109 | | |
1110 | | // ------------------------------------------------------------------------------------------------ |
1111 | | ASSIMP_API void aiMatrix4DecomposeIntoScalingAxisAnglePosition( |
1112 | | const C_STRUCT aiMatrix4x4 *mat, |
1113 | | C_STRUCT aiVector3D *scaling, |
1114 | | C_STRUCT aiVector3D *axis, |
1115 | | ai_real *angle, |
1116 | 0 | C_STRUCT aiVector3D *position) { |
1117 | 0 | ai_assert(nullptr != mat); |
1118 | 0 | ai_assert(nullptr != scaling); |
1119 | 0 | ai_assert(nullptr != axis); |
1120 | 0 | ai_assert(nullptr != angle); |
1121 | 0 | ai_assert(nullptr != position); |
1122 | 0 | mat->Decompose(*scaling, *axis, *angle, *position); |
1123 | 0 | } |
1124 | | |
1125 | | // ------------------------------------------------------------------------------------------------ |
1126 | | ASSIMP_API void aiMatrix4DecomposeNoScaling( |
1127 | | const C_STRUCT aiMatrix4x4 *mat, |
1128 | | C_STRUCT aiQuaternion *rotation, |
1129 | 0 | C_STRUCT aiVector3D *position) { |
1130 | 0 | ai_assert(nullptr != mat); |
1131 | 0 | ai_assert(nullptr != rotation); |
1132 | 0 | ai_assert(nullptr != position); |
1133 | 0 | mat->DecomposeNoScaling(*rotation, *position); |
1134 | 0 | } |
1135 | | |
1136 | | // ------------------------------------------------------------------------------------------------ |
1137 | | ASSIMP_API void aiMatrix4FromEulerAngles( |
1138 | | C_STRUCT aiMatrix4x4 *mat, |
1139 | 0 | float x, float y, float z) { |
1140 | 0 | ai_assert(nullptr != mat); |
1141 | 0 | mat->FromEulerAnglesXYZ(x, y, z); |
1142 | 0 | } |
1143 | | |
1144 | | // ------------------------------------------------------------------------------------------------ |
1145 | | ASSIMP_API void aiMatrix4RotationX( |
1146 | | C_STRUCT aiMatrix4x4 *mat, |
1147 | 0 | const float angle) { |
1148 | 0 | ai_assert(nullptr != mat); |
1149 | 0 | aiMatrix4x4::RotationX(angle, *mat); |
1150 | 0 | } |
1151 | | |
1152 | | // ------------------------------------------------------------------------------------------------ |
1153 | | ASSIMP_API void aiMatrix4RotationY( |
1154 | | C_STRUCT aiMatrix4x4 *mat, |
1155 | 0 | const float angle) { |
1156 | 0 | ai_assert(nullptr != mat); |
1157 | 0 | aiMatrix4x4::RotationY(angle, *mat); |
1158 | 0 | } |
1159 | | |
1160 | | // ------------------------------------------------------------------------------------------------ |
1161 | | ASSIMP_API void aiMatrix4RotationZ( |
1162 | | C_STRUCT aiMatrix4x4 *mat, |
1163 | 0 | const float angle) { |
1164 | 0 | ai_assert(nullptr != mat); |
1165 | 0 | aiMatrix4x4::RotationZ(angle, *mat); |
1166 | 0 | } |
1167 | | |
1168 | | // ------------------------------------------------------------------------------------------------ |
1169 | | ASSIMP_API void aiMatrix4FromRotationAroundAxis( |
1170 | | C_STRUCT aiMatrix4x4 *mat, |
1171 | | const C_STRUCT aiVector3D *axis, |
1172 | 0 | const float angle) { |
1173 | 0 | ai_assert(nullptr != mat); |
1174 | 0 | ai_assert(nullptr != axis); |
1175 | 0 | aiMatrix4x4::Rotation(angle, *axis, *mat); |
1176 | 0 | } |
1177 | | |
1178 | | // ------------------------------------------------------------------------------------------------ |
1179 | | ASSIMP_API void aiMatrix4Translation( |
1180 | | C_STRUCT aiMatrix4x4 *mat, |
1181 | 0 | const C_STRUCT aiVector3D *translation) { |
1182 | 0 | ai_assert(nullptr != mat); |
1183 | 0 | ai_assert(nullptr != translation); |
1184 | 0 | aiMatrix4x4::Translation(*translation, *mat); |
1185 | 0 | } |
1186 | | |
1187 | | // ------------------------------------------------------------------------------------------------ |
1188 | | ASSIMP_API void aiMatrix4Scaling( |
1189 | | C_STRUCT aiMatrix4x4 *mat, |
1190 | 0 | const C_STRUCT aiVector3D *scaling) { |
1191 | 0 | ai_assert(nullptr != mat); |
1192 | 0 | ai_assert(nullptr != scaling); |
1193 | 0 | aiMatrix4x4::Scaling(*scaling, *mat); |
1194 | 0 | } |
1195 | | |
1196 | | // ------------------------------------------------------------------------------------------------ |
1197 | | ASSIMP_API void aiMatrix4FromTo( |
1198 | | C_STRUCT aiMatrix4x4 *mat, |
1199 | | const C_STRUCT aiVector3D *from, |
1200 | 0 | const C_STRUCT aiVector3D *to) { |
1201 | 0 | ai_assert(nullptr != mat); |
1202 | 0 | ai_assert(nullptr != from); |
1203 | 0 | ai_assert(nullptr != to); |
1204 | 0 | aiMatrix4x4::FromToMatrix(*from, *to, *mat); |
1205 | 0 | } |
1206 | | |
1207 | | // ------------------------------------------------------------------------------------------------ |
1208 | | ASSIMP_API void aiQuaternionFromEulerAngles( |
1209 | | C_STRUCT aiQuaternion *q, |
1210 | 0 | float x, float y, float z) { |
1211 | 0 | ai_assert(nullptr != q); |
1212 | 0 | *q = aiQuaternion(x, y, z); |
1213 | 0 | } |
1214 | | |
1215 | | // ------------------------------------------------------------------------------------------------ |
1216 | | ASSIMP_API void aiQuaternionFromAxisAngle( |
1217 | | C_STRUCT aiQuaternion *q, |
1218 | | const C_STRUCT aiVector3D *axis, |
1219 | 0 | const float angle) { |
1220 | 0 | ai_assert(nullptr != q); |
1221 | 0 | ai_assert(nullptr != axis); |
1222 | 0 | *q = aiQuaternion(*axis, angle); |
1223 | 0 | } |
1224 | | |
1225 | | // ------------------------------------------------------------------------------------------------ |
1226 | | ASSIMP_API void aiQuaternionFromNormalizedQuaternion( |
1227 | | C_STRUCT aiQuaternion *q, |
1228 | 0 | const C_STRUCT aiVector3D *normalized) { |
1229 | 0 | ai_assert(nullptr != q); |
1230 | 0 | ai_assert(nullptr != normalized); |
1231 | 0 | *q = aiQuaternion(*normalized); |
1232 | 0 | } |
1233 | | |
1234 | | // ------------------------------------------------------------------------------------------------ |
1235 | | ASSIMP_API int aiQuaternionAreEqual( |
1236 | | const C_STRUCT aiQuaternion *a, |
1237 | 0 | const C_STRUCT aiQuaternion *b) { |
1238 | 0 | ai_assert(nullptr != a); |
1239 | 0 | ai_assert(nullptr != b); |
1240 | 0 | return *a == *b; |
1241 | 0 | } |
1242 | | |
1243 | | // ------------------------------------------------------------------------------------------------ |
1244 | | ASSIMP_API int aiQuaternionAreEqualEpsilon( |
1245 | | const C_STRUCT aiQuaternion *a, |
1246 | | const C_STRUCT aiQuaternion *b, |
1247 | 0 | const float epsilon) { |
1248 | 0 | ai_assert(nullptr != a); |
1249 | 0 | ai_assert(nullptr != b); |
1250 | 0 | return a->Equal(*b, epsilon); |
1251 | 0 | } |
1252 | | |
1253 | | // ------------------------------------------------------------------------------------------------ |
1254 | | ASSIMP_API void aiQuaternionNormalize( |
1255 | 0 | C_STRUCT aiQuaternion *q) { |
1256 | 0 | ai_assert(nullptr != q); |
1257 | 0 | q->Normalize(); |
1258 | 0 | } |
1259 | | |
1260 | | // ------------------------------------------------------------------------------------------------ |
1261 | | ASSIMP_API void aiQuaternionConjugate( |
1262 | 0 | C_STRUCT aiQuaternion *q) { |
1263 | 0 | ai_assert(nullptr != q); |
1264 | 0 | q->Conjugate(); |
1265 | 0 | } |
1266 | | |
1267 | | // ------------------------------------------------------------------------------------------------ |
1268 | | ASSIMP_API void aiQuaternionMultiply( |
1269 | | C_STRUCT aiQuaternion *dst, |
1270 | 0 | const C_STRUCT aiQuaternion *q) { |
1271 | 0 | ai_assert(nullptr != dst); |
1272 | 0 | ai_assert(nullptr != q); |
1273 | 0 | *dst = (*dst) * (*q); |
1274 | 0 | } |
1275 | | |
1276 | | // ------------------------------------------------------------------------------------------------ |
1277 | | ASSIMP_API void aiQuaternionInterpolate( |
1278 | | C_STRUCT aiQuaternion *dst, |
1279 | | const C_STRUCT aiQuaternion *start, |
1280 | | const C_STRUCT aiQuaternion *end, |
1281 | 0 | const float factor) { |
1282 | 0 | ai_assert(nullptr != dst); |
1283 | 0 | ai_assert(nullptr != start); |
1284 | | ai_assert(nullptr != end); |
1285 | 0 | aiQuaternion::Interpolate(*dst, *start, *end, factor); |
1286 | 0 | } |
1287 | | |
1288 | | // stb_image is a lightweight image loader. It is shared by: |
1289 | | // - M3D import |
1290 | | // - PBRT export |
1291 | | // Since it's a header-only library, its implementation must be instantiated in some cpp file. |
1292 | | // Don't scatter this task over multiple importers/exporters. Maintain it in a central place (here!). |
1293 | | |
1294 | | #define ASSIMP_HAS_PBRT_EXPORT (!ASSIMP_BUILD_NO_EXPORT && !ASSIMP_BUILD_NO_PBRT_EXPORTER) |
1295 | | #define ASSIMP_HAS_M3D ((!ASSIMP_BUILD_NO_EXPORT && !ASSIMP_BUILD_NO_M3D_EXPORTER) || !ASSIMP_BUILD_NO_M3D_IMPORTER) |
1296 | | |
1297 | | #ifndef STB_USE_HUNTER |
1298 | | #if ASSIMP_HAS_PBRT_EXPORT |
1299 | | #define ASSIMP_NEEDS_STB_IMAGE 1 |
1300 | | #elif ASSIMP_HAS_M3D |
1301 | | #define ASSIMP_NEEDS_STB_IMAGE 1 |
1302 | | #define STBI_ONLY_PNG |
1303 | | #endif |
1304 | | #endif |
1305 | | |
1306 | | // Ensure all symbols are linked correctly |
1307 | | #if ASSIMP_NEEDS_STB_IMAGE |
1308 | | // Share stb_image's PNG loader with other importers/exporters instead of bringing our own copy. |
1309 | | #define STBI_ONLY_PNG |
1310 | | #ifdef ASSIMP_USE_STB_IMAGE_STATIC |
1311 | | #define STB_IMAGE_STATIC |
1312 | | #endif |
1313 | | #define STB_IMAGE_IMPLEMENTATION |
1314 | | #include "Common/StbCommon.h" |
1315 | | #endif |