vrshoot
diff libs/assimp/Assimp.cpp @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/assimp/Assimp.cpp Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,593 @@ 1.4 +/* 1.5 +--------------------------------------------------------------------------- 1.6 +Open Asset Import Library (assimp) 1.7 +--------------------------------------------------------------------------- 1.8 + 1.9 +Copyright (c) 2006-2012, assimp team 1.10 + 1.11 +All rights reserved. 1.12 + 1.13 +Redistribution and use of this software in source and binary forms, 1.14 +with or without modification, are permitted provided that the following 1.15 +conditions are met: 1.16 + 1.17 +* Redistributions of source code must retain the above 1.18 + copyright notice, this list of conditions and the 1.19 + following disclaimer. 1.20 + 1.21 +* Redistributions in binary form must reproduce the above 1.22 + copyright notice, this list of conditions and the 1.23 + following disclaimer in the documentation and/or other 1.24 + materials provided with the distribution. 1.25 + 1.26 +* Neither the name of the assimp team, nor the names of its 1.27 + contributors may be used to endorse or promote products 1.28 + derived from this software without specific prior 1.29 + written permission of the assimp team. 1.30 + 1.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.42 +--------------------------------------------------------------------------- 1.43 +*/ 1.44 +/** @file Assimp.cpp 1.45 + * @brief Implementation of the Plain-C API 1.46 + */ 1.47 + 1.48 +#include "AssimpPCH.h" 1.49 +#include "assimp/cimport.h" 1.50 + 1.51 +#include "GenericProperty.h" 1.52 +#include "CInterfaceIOWrapper.h" 1.53 +#include "Importer.h" 1.54 + 1.55 +// ------------------------------------------------------------------------------------------------ 1.56 +#ifdef AI_C_THREADSAFE 1.57 +# include <boost/thread/thread.hpp> 1.58 +# include <boost/thread/mutex.hpp> 1.59 +#endif 1.60 +// ------------------------------------------------------------------------------------------------ 1.61 +using namespace Assimp; 1.62 + 1.63 +namespace Assimp 1.64 +{ 1.65 + // underlying structure for aiPropertyStore 1.66 + typedef BatchLoader::PropertyMap PropertyMap; 1.67 + 1.68 + /** Stores the LogStream objects for all active C log streams */ 1.69 + struct mpred { 1.70 + bool operator () (const aiLogStream& s0, const aiLogStream& s1) const { 1.71 + return s0.callback<s1.callback&&s0.user<s1.user; 1.72 + } 1.73 + }; 1.74 + typedef std::map<aiLogStream, Assimp::LogStream*, mpred> LogStreamMap; 1.75 + 1.76 + /** Stores the LogStream objects allocated by #aiGetPredefinedLogStream */ 1.77 + typedef std::list<Assimp::LogStream*> PredefLogStreamMap; 1.78 + 1.79 + /** Local storage of all active log streams */ 1.80 + static LogStreamMap gActiveLogStreams; 1.81 + 1.82 + /** Local storage of LogStreams allocated by #aiGetPredefinedLogStream */ 1.83 + static PredefLogStreamMap gPredefinedStreams; 1.84 + 1.85 + /** Error message of the last failed import process */ 1.86 + static std::string gLastErrorString; 1.87 + 1.88 + /** Verbose logging active or not? */ 1.89 + static aiBool gVerboseLogging = false; 1.90 +} 1.91 + 1.92 + 1.93 +#ifdef AI_C_THREADSAFE 1.94 +/** Global mutex to manage the access to the logstream map */ 1.95 +static boost::mutex gLogStreamMutex; 1.96 +#endif 1.97 + 1.98 + 1.99 +// ------------------------------------------------------------------------------------------------ 1.100 +// Custom LogStream implementation for the C-API 1.101 +class LogToCallbackRedirector : public LogStream 1.102 +{ 1.103 +public: 1.104 + LogToCallbackRedirector(const aiLogStream& s) 1.105 + : stream (s) { 1.106 + ai_assert(NULL != s.callback); 1.107 + } 1.108 + 1.109 + ~LogToCallbackRedirector() { 1.110 +#ifdef AI_C_THREADSAFE 1.111 + boost::mutex::scoped_lock lock(gLogStreamMutex); 1.112 +#endif 1.113 + // (HACK) Check whether the 'stream.user' pointer points to a 1.114 + // custom LogStream allocated by #aiGetPredefinedLogStream. 1.115 + // In this case, we need to delete it, too. Of course, this 1.116 + // might cause strange problems, but the chance is quite low. 1.117 + 1.118 + PredefLogStreamMap::iterator it = std::find(gPredefinedStreams.begin(), 1.119 + gPredefinedStreams.end(), (Assimp::LogStream*)stream.user); 1.120 + 1.121 + if (it != gPredefinedStreams.end()) { 1.122 + delete *it; 1.123 + gPredefinedStreams.erase(it); 1.124 + } 1.125 + } 1.126 + 1.127 + /** @copydoc LogStream::write */ 1.128 + void write(const char* message) { 1.129 + stream.callback(message,stream.user); 1.130 + } 1.131 + 1.132 +private: 1.133 + aiLogStream stream; 1.134 +}; 1.135 + 1.136 +// ------------------------------------------------------------------------------------------------ 1.137 +void ReportSceneNotFoundError() 1.138 +{ 1.139 + DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. " 1.140 + "The C-API does not accept scenes produced by the C++ API and vice versa"); 1.141 + 1.142 + assert(false); 1.143 +} 1.144 + 1.145 +// ------------------------------------------------------------------------------------------------ 1.146 +// Reads the given file and returns its content. 1.147 +const aiScene* aiImportFile( const char* pFile, unsigned int pFlags) 1.148 +{ 1.149 + return aiImportFileEx(pFile,pFlags,NULL); 1.150 +} 1.151 + 1.152 +// ------------------------------------------------------------------------------------------------ 1.153 +const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags, aiFileIO* pFS) 1.154 +{ 1.155 + return aiImportFileExWithProperties(pFile, pFlags, pFS, NULL); 1.156 +} 1.157 + 1.158 +// ------------------------------------------------------------------------------------------------ 1.159 +const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags, 1.160 + aiFileIO* pFS, 1.161 + const aiPropertyStore* props) 1.162 +{ 1.163 + ai_assert(NULL != pFile); 1.164 + 1.165 + const aiScene* scene = NULL; 1.166 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.167 + 1.168 + // create an Importer for this file 1.169 + Assimp::Importer* imp = new Assimp::Importer(); 1.170 + 1.171 + // copy properties 1.172 + if(props) { 1.173 + const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props); 1.174 + ImporterPimpl* pimpl = imp->Pimpl(); 1.175 + pimpl->mIntProperties = pp->ints; 1.176 + pimpl->mFloatProperties = pp->floats; 1.177 + pimpl->mStringProperties = pp->strings; 1.178 + } 1.179 + // setup a custom IO system if necessary 1.180 + if (pFS) { 1.181 + imp->SetIOHandler( new CIOSystemWrapper (pFS) ); 1.182 + } 1.183 + 1.184 + // and have it read the file 1.185 + scene = imp->ReadFile( pFile, pFlags); 1.186 + 1.187 + // if succeeded, store the importer in the scene and keep it alive 1.188 + if( scene) { 1.189 + ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) ); 1.190 + priv->mOrigImporter = imp; 1.191 + } 1.192 + else { 1.193 + // if failed, extract error code and destroy the import 1.194 + gLastErrorString = imp->GetErrorString(); 1.195 + delete imp; 1.196 + } 1.197 + 1.198 + // return imported data. If the import failed the pointer is NULL anyways 1.199 + ASSIMP_END_EXCEPTION_REGION(const aiScene*); 1.200 + return scene; 1.201 +} 1.202 + 1.203 +// ------------------------------------------------------------------------------------------------ 1.204 +const aiScene* aiImportFileFromMemory( 1.205 + const char* pBuffer, 1.206 + unsigned int pLength, 1.207 + unsigned int pFlags, 1.208 + const char* pHint) 1.209 +{ 1.210 + return aiImportFileFromMemoryWithProperties(pBuffer, pLength, pFlags, pHint, NULL); 1.211 +} 1.212 + 1.213 +// ------------------------------------------------------------------------------------------------ 1.214 +const aiScene* aiImportFileFromMemoryWithProperties( 1.215 + const char* pBuffer, 1.216 + unsigned int pLength, 1.217 + unsigned int pFlags, 1.218 + const char* pHint, 1.219 + const aiPropertyStore* props) 1.220 +{ 1.221 + ai_assert(NULL != pBuffer && 0 != pLength); 1.222 + 1.223 + const aiScene* scene = NULL; 1.224 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.225 + 1.226 + // create an Importer for this file 1.227 + Assimp::Importer* imp = new Assimp::Importer(); 1.228 + 1.229 + // copy properties 1.230 + if(props) { 1.231 + const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props); 1.232 + ImporterPimpl* pimpl = imp->Pimpl(); 1.233 + pimpl->mIntProperties = pp->ints; 1.234 + pimpl->mFloatProperties = pp->floats; 1.235 + pimpl->mStringProperties = pp->strings; 1.236 + } 1.237 + 1.238 + // and have it read the file from the memory buffer 1.239 + scene = imp->ReadFileFromMemory( pBuffer, pLength, pFlags,pHint); 1.240 + 1.241 + // if succeeded, store the importer in the scene and keep it alive 1.242 + if( scene) { 1.243 + ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) ); 1.244 + priv->mOrigImporter = imp; 1.245 + } 1.246 + else { 1.247 + // if failed, extract error code and destroy the import 1.248 + gLastErrorString = imp->GetErrorString(); 1.249 + delete imp; 1.250 + } 1.251 + // return imported data. If the import failed the pointer is NULL anyways 1.252 + ASSIMP_END_EXCEPTION_REGION(const aiScene*); 1.253 + return scene; 1.254 +} 1.255 + 1.256 +// ------------------------------------------------------------------------------------------------ 1.257 +// Releases all resources associated with the given import process. 1.258 +void aiReleaseImport( const aiScene* pScene) 1.259 +{ 1.260 + if (!pScene) { 1.261 + return; 1.262 + } 1.263 + 1.264 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.265 + 1.266 + // find the importer associated with this data 1.267 + const ScenePrivateData* priv = ScenePriv(pScene); 1.268 + if( !priv || !priv->mOrigImporter) { 1.269 + delete pScene; 1.270 + } 1.271 + else { 1.272 + // deleting the Importer also deletes the scene 1.273 + // Note: the reason that this is not written as 'delete priv->mOrigImporter' 1.274 + // is a suspected bug in gcc 4.4+ (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52339) 1.275 + Importer* importer = priv->mOrigImporter; 1.276 + delete importer; 1.277 + } 1.278 + 1.279 + ASSIMP_END_EXCEPTION_REGION(void); 1.280 +} 1.281 + 1.282 +// ------------------------------------------------------------------------------------------------ 1.283 +ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene* pScene, 1.284 + unsigned int pFlags) 1.285 +{ 1.286 + const aiScene* sc = NULL; 1.287 + 1.288 + 1.289 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.290 + 1.291 + // find the importer associated with this data 1.292 + const ScenePrivateData* priv = ScenePriv(pScene); 1.293 + if( !priv || !priv->mOrigImporter) { 1.294 + ReportSceneNotFoundError(); 1.295 + return NULL; 1.296 + } 1.297 + 1.298 + sc = priv->mOrigImporter->ApplyPostProcessing(pFlags); 1.299 + 1.300 + if (!sc) { 1.301 + aiReleaseImport(pScene); 1.302 + return NULL; 1.303 + } 1.304 + 1.305 + ASSIMP_END_EXCEPTION_REGION(const aiScene*); 1.306 + return sc; 1.307 +} 1.308 + 1.309 +// ------------------------------------------------------------------------------------------------ 1.310 +void CallbackToLogRedirector (const char* msg, char* dt) 1.311 +{ 1.312 + ai_assert(NULL != msg && NULL != dt); 1.313 + LogStream* s = (LogStream*)dt; 1.314 + 1.315 + s->write(msg); 1.316 +} 1.317 + 1.318 +// ------------------------------------------------------------------------------------------------ 1.319 +ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream,const char* file) 1.320 +{ 1.321 + aiLogStream sout; 1.322 + 1.323 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.324 + LogStream* stream = LogStream::createDefaultStream(pStream,file); 1.325 + if (!stream) { 1.326 + sout.callback = NULL; 1.327 + sout.user = NULL; 1.328 + } 1.329 + else { 1.330 + sout.callback = &CallbackToLogRedirector; 1.331 + sout.user = (char*)stream; 1.332 + } 1.333 + gPredefinedStreams.push_back(stream); 1.334 + ASSIMP_END_EXCEPTION_REGION(aiLogStream); 1.335 + return sout; 1.336 +} 1.337 + 1.338 +// ------------------------------------------------------------------------------------------------ 1.339 +ASSIMP_API void aiAttachLogStream( const aiLogStream* stream ) 1.340 +{ 1.341 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.342 + 1.343 +#ifdef AI_C_THREADSAFE 1.344 + boost::mutex::scoped_lock lock(gLogStreamMutex); 1.345 +#endif 1.346 + 1.347 + LogStream* lg = new LogToCallbackRedirector(*stream); 1.348 + gActiveLogStreams[*stream] = lg; 1.349 + 1.350 + if (DefaultLogger::isNullLogger()) { 1.351 + DefaultLogger::create(NULL,(gVerboseLogging == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL)); 1.352 + } 1.353 + DefaultLogger::get()->attachStream(lg); 1.354 + ASSIMP_END_EXCEPTION_REGION(void); 1.355 +} 1.356 + 1.357 +// ------------------------------------------------------------------------------------------------ 1.358 +ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream) 1.359 +{ 1.360 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.361 + 1.362 +#ifdef AI_C_THREADSAFE 1.363 + boost::mutex::scoped_lock lock(gLogStreamMutex); 1.364 +#endif 1.365 + // find the logstream associated with this data 1.366 + LogStreamMap::iterator it = gActiveLogStreams.find( *stream); 1.367 + // it should be there... else the user is playing fools with us 1.368 + if( it == gActiveLogStreams.end()) { 1.369 + return AI_FAILURE; 1.370 + } 1.371 + DefaultLogger::get()->detatchStream( it->second ); 1.372 + delete it->second; 1.373 + 1.374 + gActiveLogStreams.erase( it); 1.375 + 1.376 + if (gActiveLogStreams.empty()) { 1.377 + DefaultLogger::kill(); 1.378 + } 1.379 + ASSIMP_END_EXCEPTION_REGION(aiReturn); 1.380 + return AI_SUCCESS; 1.381 +} 1.382 + 1.383 +// ------------------------------------------------------------------------------------------------ 1.384 +ASSIMP_API void aiDetachAllLogStreams(void) 1.385 +{ 1.386 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.387 +#ifdef AI_C_THREADSAFE 1.388 + boost::mutex::scoped_lock lock(gLogStreamMutex); 1.389 +#endif 1.390 + for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) { 1.391 + DefaultLogger::get()->detatchStream( it->second ); 1.392 + delete it->second; 1.393 + } 1.394 + gActiveLogStreams.clear(); 1.395 + DefaultLogger::kill(); 1.396 + ASSIMP_END_EXCEPTION_REGION(void); 1.397 +} 1.398 + 1.399 +// ------------------------------------------------------------------------------------------------ 1.400 +ASSIMP_API void aiEnableVerboseLogging(aiBool d) 1.401 +{ 1.402 + if (!DefaultLogger::isNullLogger()) { 1.403 + DefaultLogger::get()->setLogSeverity((d == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL)); 1.404 + } 1.405 + gVerboseLogging = d; 1.406 +} 1.407 + 1.408 +// ------------------------------------------------------------------------------------------------ 1.409 +// Returns the error text of the last failed import process. 1.410 +const char* aiGetErrorString() 1.411 +{ 1.412 + return gLastErrorString.c_str(); 1.413 +} 1.414 + 1.415 +// ------------------------------------------------------------------------------------------------ 1.416 +// Returns the error text of the last failed import process. 1.417 +aiBool aiIsExtensionSupported(const char* szExtension) 1.418 +{ 1.419 + ai_assert(NULL != szExtension); 1.420 + aiBool candoit=AI_FALSE; 1.421 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.422 + 1.423 + // FIXME: no need to create a temporary Importer instance just for that .. 1.424 + Assimp::Importer tmp; 1.425 + candoit = tmp.IsExtensionSupported(std::string(szExtension)) ? AI_TRUE : AI_FALSE; 1.426 + 1.427 + ASSIMP_END_EXCEPTION_REGION(aiBool); 1.428 + return candoit; 1.429 +} 1.430 + 1.431 +// ------------------------------------------------------------------------------------------------ 1.432 +// Get a list of all file extensions supported by ASSIMP 1.433 +void aiGetExtensionList(aiString* szOut) 1.434 +{ 1.435 + ai_assert(NULL != szOut); 1.436 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.437 + 1.438 + // FIXME: no need to create a temporary Importer instance just for that .. 1.439 + Assimp::Importer tmp; 1.440 + tmp.GetExtensionList(*szOut); 1.441 + 1.442 + ASSIMP_END_EXCEPTION_REGION(void); 1.443 +} 1.444 + 1.445 +// ------------------------------------------------------------------------------------------------ 1.446 +// Get the memory requirements for a particular import. 1.447 +void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn, 1.448 + C_STRUCT aiMemoryInfo* in) 1.449 +{ 1.450 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.451 + 1.452 + // find the importer associated with this data 1.453 + const ScenePrivateData* priv = ScenePriv(pIn); 1.454 + if( !priv || !priv->mOrigImporter) { 1.455 + ReportSceneNotFoundError(); 1.456 + return; 1.457 + } 1.458 + 1.459 + return priv->mOrigImporter->GetMemoryRequirements(*in); 1.460 + ASSIMP_END_EXCEPTION_REGION(void); 1.461 +} 1.462 + 1.463 +// ------------------------------------------------------------------------------------------------ 1.464 +ASSIMP_API aiPropertyStore* aiCreatePropertyStore(void) 1.465 +{ 1.466 + return reinterpret_cast<aiPropertyStore*>( new PropertyMap() ); 1.467 +} 1.468 + 1.469 + 1.470 +// ------------------------------------------------------------------------------------------------ 1.471 +ASSIMP_API void aiReleasePropertyStore(aiPropertyStore* p) 1.472 +{ 1.473 + delete reinterpret_cast<PropertyMap*>(p); 1.474 +} 1.475 + 1.476 +// ------------------------------------------------------------------------------------------------ 1.477 +// Importer::SetPropertyInteger 1.478 +ASSIMP_API void aiSetImportPropertyInteger(aiPropertyStore* p, const char* szName, int value) 1.479 +{ 1.480 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.481 + PropertyMap* pp = reinterpret_cast<PropertyMap*>(p); 1.482 + SetGenericProperty<int>(pp->ints,szName,value,NULL); 1.483 + ASSIMP_END_EXCEPTION_REGION(void); 1.484 +} 1.485 + 1.486 +// ------------------------------------------------------------------------------------------------ 1.487 +// Importer::SetPropertyFloat 1.488 +ASSIMP_API void aiSetImportPropertyFloat(aiPropertyStore* p, const char* szName, float value) 1.489 +{ 1.490 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.491 + PropertyMap* pp = reinterpret_cast<PropertyMap*>(p); 1.492 + SetGenericProperty<float>(pp->floats,szName,value,NULL); 1.493 + ASSIMP_END_EXCEPTION_REGION(void); 1.494 +} 1.495 + 1.496 +// ------------------------------------------------------------------------------------------------ 1.497 +// Importer::SetPropertyString 1.498 +ASSIMP_API void aiSetImportPropertyString(aiPropertyStore* p, const char* szName, 1.499 + const C_STRUCT aiString* st) 1.500 +{ 1.501 + if (!st) { 1.502 + return; 1.503 + } 1.504 + ASSIMP_BEGIN_EXCEPTION_REGION(); 1.505 + PropertyMap* pp = reinterpret_cast<PropertyMap*>(p); 1.506 + SetGenericProperty<std::string>(pp->strings,szName,std::string(st->C_Str()),NULL); 1.507 + ASSIMP_END_EXCEPTION_REGION(void); 1.508 +} 1.509 + 1.510 +// ------------------------------------------------------------------------------------------------ 1.511 +// Rotation matrix to quaternion 1.512 +ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat) 1.513 +{ 1.514 + ai_assert(NULL != quat && NULL != mat); 1.515 + *quat = aiQuaternion(*mat); 1.516 +} 1.517 + 1.518 +// ------------------------------------------------------------------------------------------------ 1.519 +// Matrix decomposition 1.520 +ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat,aiVector3D* scaling, 1.521 + aiQuaternion* rotation, 1.522 + aiVector3D* position) 1.523 +{ 1.524 + ai_assert(NULL != rotation && NULL != position && NULL != scaling && NULL != mat); 1.525 + mat->Decompose(*scaling,*rotation,*position); 1.526 +} 1.527 + 1.528 +// ------------------------------------------------------------------------------------------------ 1.529 +// Matrix transpose 1.530 +ASSIMP_API void aiTransposeMatrix3(aiMatrix3x3* mat) 1.531 +{ 1.532 + ai_assert(NULL != mat); 1.533 + mat->Transpose(); 1.534 +} 1.535 + 1.536 +// ------------------------------------------------------------------------------------------------ 1.537 +ASSIMP_API void aiTransposeMatrix4(aiMatrix4x4* mat) 1.538 +{ 1.539 + ai_assert(NULL != mat); 1.540 + mat->Transpose(); 1.541 +} 1.542 + 1.543 +// ------------------------------------------------------------------------------------------------ 1.544 +// Vector transformation 1.545 +ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec, 1.546 + const aiMatrix3x3* mat) 1.547 +{ 1.548 + ai_assert(NULL != mat && NULL != vec); 1.549 + *vec *= (*mat); 1.550 +} 1.551 + 1.552 +// ------------------------------------------------------------------------------------------------ 1.553 +ASSIMP_API void aiTransformVecByMatrix4(aiVector3D* vec, 1.554 + const aiMatrix4x4* mat) 1.555 +{ 1.556 + ai_assert(NULL != mat && NULL != vec); 1.557 + *vec *= (*mat); 1.558 +} 1.559 + 1.560 +// ------------------------------------------------------------------------------------------------ 1.561 +// Matrix multiplication 1.562 +ASSIMP_API void aiMultiplyMatrix4( 1.563 + aiMatrix4x4* dst, 1.564 + const aiMatrix4x4* src) 1.565 +{ 1.566 + ai_assert(NULL != dst && NULL != src); 1.567 + *dst = (*dst) * (*src); 1.568 +} 1.569 + 1.570 +// ------------------------------------------------------------------------------------------------ 1.571 +ASSIMP_API void aiMultiplyMatrix3( 1.572 + aiMatrix3x3* dst, 1.573 + const aiMatrix3x3* src) 1.574 +{ 1.575 + ai_assert(NULL != dst && NULL != src); 1.576 + *dst = (*dst) * (*src); 1.577 +} 1.578 + 1.579 +// ------------------------------------------------------------------------------------------------ 1.580 +// Matrix identity 1.581 +ASSIMP_API void aiIdentityMatrix3( 1.582 + aiMatrix3x3* mat) 1.583 +{ 1.584 + ai_assert(NULL != mat); 1.585 + *mat = aiMatrix3x3(); 1.586 +} 1.587 + 1.588 +// ------------------------------------------------------------------------------------------------ 1.589 +ASSIMP_API void aiIdentityMatrix4( 1.590 + aiMatrix4x4* mat) 1.591 +{ 1.592 + ai_assert(NULL != mat); 1.593 + *mat = aiMatrix4x4(); 1.594 +} 1.595 + 1.596 +