diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index f79fb0a95..e750822ab 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1,2 @@ patreon: assimp +ko_fi: kimkulling diff --git a/CMakeLists.txt b/CMakeLists.txt index 412628bbe..61251f85a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,7 +173,6 @@ SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VER SET (ASSIMP_SOVERSION 5) SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" ) - if(NOT HUNTER_ENABLED) # Enable C++11 support globally set_property( GLOBAL PROPERTY CXX_STANDARD 11 ) @@ -254,6 +253,7 @@ ELSEIF(MSVC) IF(MSVC12) ADD_COMPILE_OPTIONS(/wd4351) ENDIF() + SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob2 /DEBUG:FULL /Zi") ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" ) IF(NOT HUNTER_ENABLED) SET(CMAKE_CXX_FLAGS "-fPIC -std=c++11 ${CMAKE_CXX_FLAGS}") @@ -271,7 +271,7 @@ ELSEIF( CMAKE_COMPILER_IS_MINGW ) SET(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}") SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}") ENDIF() - SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj ${CMAKE_CXX_FLAGS}") + SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}") SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}") ADD_DEFINITIONS( -U__STRICT_ANSI__ ) ENDIF() @@ -341,7 +341,7 @@ SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE STRING get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG) -IF (INJECT_DEBUG_POSTFIX AND (CMAKE_BUILD_TYPE STREQUAL "Debug")) +IF (INJECT_DEBUG_POSTFIX AND (is_multi_config OR CMAKE_BUILD_TYPE STREQUAL "Debug")) SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfix for lib, samples and tools") ELSE() SET(CMAKE_DEBUG_POSTFIX "" CACHE STRING "Debug Postfix for lib, samples and tools") diff --git a/appveyor.yml b/appveyor.yml index 851d9c096..3729ea028 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,7 +14,6 @@ matrix: fast_finish: true image: - - Visual Studio 2013 - Visual Studio 2015 - Visual Studio 2017 @@ -27,7 +26,6 @@ configuration: Release install: - set PATH=C:\Ruby24-x64\bin;%PATH% - set CMAKE_DEFINES -DASSIMP_WERROR=ON - - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2013" set CMAKE_GENERATOR_NAME=Visual Studio 12 2013 - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015 - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017 - if "%platform%"=="x64" set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% Win64 diff --git a/code/AMF/AMFImporter.cpp b/code/AMF/AMFImporter.cpp index d173bd0f5..dedb6dcdd 100644 --- a/code/AMF/AMFImporter.cpp +++ b/code/AMF/AMFImporter.cpp @@ -83,7 +83,7 @@ void AMFImporter::Clear() mMaterial_Converted.clear(); mTexture_Converted.clear(); // Delete all elements - if(mNodeElement_List.size()) + if(!mNodeElement_List.empty()) { for(CAMFImporter_NodeElement* ne: mNodeElement_List) { delete ne; } diff --git a/code/AMF/AMFImporter_Postprocess.cpp b/code/AMF/AMFImporter_Postprocess.cpp index 2bfe3f78c..79b5e15e2 100644 --- a/code/AMF/AMFImporter_Postprocess.cpp +++ b/code/AMF/AMFImporter_Postprocess.cpp @@ -66,7 +66,7 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /* aiColor4D tcol; // Check if stored data are supported. - if(Composition.size() != 0) + if(!Composition.empty()) { throw DeadlyImportError("IME. GetColor for composition"); } @@ -321,7 +321,7 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list 0) pOutputList_Separated.push_back(face_list_cur); + if(!face_list_cur.empty()) pOutputList_Separated.push_back(face_list_cur); - } while(pInputList.size() > 0); + } while(!pInputList.empty()); } void AMFImporter::Postprocess_AddMetadata(const std::list& metadataList, aiNode& sceneNode) const @@ -712,7 +712,7 @@ std::list mesh_idx; }// for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child) // if meshes was created then assign new indices with current aiNode - if(mesh_idx.size() > 0) + if(!mesh_idx.empty()) { std::list::const_iterator mit = mesh_idx.begin(); @@ -787,7 +787,7 @@ std::list ch_node; }// for(const CAMFImporter_NodeElement* ne: pConstellation.Child) // copy found aiNode's as children - if(ch_node.size() == 0) throw DeadlyImportError(" must have at least one ."); + if(ch_node.empty()) throw DeadlyImportError(" must have at least one ."); size_t ch_idx = 0; @@ -883,13 +883,13 @@ nl_clean_loop: if(node_list.size() > 1) { // walk through all nodes - for(std::list::iterator nl_it = node_list.begin(); nl_it != node_list.end(); nl_it++) + for(std::list::iterator nl_it = node_list.begin(); nl_it != node_list.end(); ++nl_it) { // and try to find them in another top nodes. std::list::const_iterator next_it = nl_it; - next_it++; - for(; next_it != node_list.end(); next_it++) + ++next_it; + for(; next_it != node_list.end(); ++next_it) { if((*next_it)->FindNode((*nl_it)->mName) != nullptr) { @@ -907,7 +907,7 @@ nl_clean_loop: // // // Nodes - if(node_list.size() > 0) + if(!node_list.empty()) { std::list::const_iterator nl_it = node_list.begin(); @@ -924,7 +924,7 @@ nl_clean_loop: // // Meshes - if(mesh_list.size() > 0) + if(!mesh_list.empty()) { std::list::const_iterator ml_it = mesh_list.begin(); diff --git a/code/Collada/ColladaLoader.cpp b/code/Collada/ColladaLoader.cpp index 6ef90c817..0fbc7d599 100644 --- a/code/Collada/ColladaLoader.cpp +++ b/code/Collada/ColladaLoader.cpp @@ -588,7 +588,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser& pParser, const Colla // ------------------------------------------------------------------------------------------------ // Find mesh from either meshes or morph target meshes -aiMesh *ColladaLoader::findMesh(std::string meshid) { +aiMesh *ColladaLoader::findMesh(const std::string& meshid) { for (unsigned int i = 0; i < mMeshes.size(); ++i) { if (std::string(mMeshes[i]->mName.data) == meshid) { return mMeshes[i]; @@ -688,7 +688,7 @@ aiMesh* ColladaLoader::CreateMesh(const ColladaParser& pParser, const Collada::M Collada::MorphMethod method = Collada::Normalized; for (std::map::const_iterator it = pParser.mControllerLibrary.begin(); - it != pParser.mControllerLibrary.end(); it++) { + it != pParser.mControllerLibrary.end(); ++it) { const Collada::Controller &c = it->second; const Collada::Mesh* baseMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, c.mMeshId); diff --git a/code/Collada/ColladaLoader.h b/code/Collada/ColladaLoader.h index 92f390f17..dce46e06f 100644 --- a/code/Collada/ColladaLoader.h +++ b/code/Collada/ColladaLoader.h @@ -120,7 +120,7 @@ protected: void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget); - aiMesh *findMesh(std::string meshid); + aiMesh *findMesh(const std::string& meshid); /** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */ aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh, diff --git a/code/Common/BaseImporter.cpp b/code/Common/BaseImporter.cpp index 0a5694aa0..de5018a25 100644 --- a/code/Common/BaseImporter.cpp +++ b/code/Common/BaseImporter.cpp @@ -76,9 +76,25 @@ BaseImporter::~BaseImporter() { // nothing to do here } +void BaseImporter::UpdateImporterScale( Importer* pImp ) +{ + ai_assert(pImp != nullptr); + ai_assert(importerScale != 0.0); + ai_assert(fileScale != 0.0); + + double activeScale = importerScale * fileScale; + + // Set active scaling + pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, activeScale); + + ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale ); +} + // ------------------------------------------------------------------------------------------------ // Imports the given file and returns the imported data. -aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) { +aiScene* BaseImporter::ReadFile(Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) { + + m_progress = pImp->GetProgressHandler(); if (nullptr == m_progress) { return nullptr; @@ -100,6 +116,11 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, { InternReadFile( pFile, sc.get(), &filter); + // Calculate import scale hook - required because pImp not available anywhere else + // passes scale into ScaleProcess + UpdateImporterScale(pImp); + + } catch( const std::exception& err ) { // extract error description m_ErrorText = err.what(); @@ -112,7 +133,7 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, } // ------------------------------------------------------------------------------------------------ -void BaseImporter::SetupProperties(const Importer* /*pImp*/) +void BaseImporter::SetupProperties(const Importer* pImp) { // the default implementation does nothing } @@ -588,6 +609,8 @@ aiScene* BatchLoader::GetImport( unsigned int which ) return nullptr; } + + // ------------------------------------------------------------------------------------------------ void BatchLoader::LoadAll() { diff --git a/code/Common/DefaultIOSystem.cpp b/code/Common/DefaultIOSystem.cpp index d40b67de3..6fdc24dd8 100644 --- a/code/Common/DefaultIOSystem.cpp +++ b/code/Common/DefaultIOSystem.cpp @@ -61,83 +61,66 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; -// maximum path length -// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html -#ifdef PATH_MAX -# define PATHLIMIT PATH_MAX -#else -# define PATHLIMIT 4096 +#ifdef _WIN32 +static std::wstring Utf8ToWide(const char* in) +{ + int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0); + // size includes terminating null; std::wstring adds null automatically + std::wstring out(static_cast(size) - 1, L'\0'); + MultiByteToWideChar(CP_UTF8, 0, in, -1, &out[0], size); + return out; +} + +static std::string WideToUtf8(const wchar_t* in) +{ + int size = WideCharToMultiByte(CP_UTF8, 0, in, -1, nullptr, 0, nullptr, nullptr); + // size includes terminating null; std::string adds null automatically + std::string out(static_cast(size) - 1, '\0'); + WideCharToMultiByte(CP_UTF8, 0, in, -1, &out[0], size, nullptr, nullptr); + return out; +} #endif // ------------------------------------------------------------------------------------------------ // Tests for the existence of a file at the given path. -bool DefaultIOSystem::Exists( const char* pFile) const +bool DefaultIOSystem::Exists(const char* pFile) const { #ifdef _WIN32 - wchar_t fileName16[PATHLIMIT]; - -#ifndef WindowsStore - bool isUnicode = IsTextUnicode(pFile, static_cast(strlen(pFile)), NULL) != 0; - if (isUnicode) { - - MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT); - struct __stat64 filestat; - if (0 != _wstat64(fileName16, &filestat)) { - return false; - } - } else { -#endif - FILE* file = ::fopen(pFile, "rb"); - if (!file) - return false; - - ::fclose(file); -#ifndef WindowsStore + struct __stat64 filestat; + if (_wstat64(Utf8ToWide(pFile).c_str(), &filestat) != 0) { + return false; } -#endif #else - FILE* file = ::fopen( pFile, "rb"); - if( !file) + FILE* file = ::fopen(pFile, "rb"); + if (!file) return false; - ::fclose( file); + ::fclose(file); #endif return true; } // ------------------------------------------------------------------------------------------------ // Open a new file with a given path. -IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode) +IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode) { - ai_assert(NULL != strFile); - ai_assert(NULL != strMode); + ai_assert(strFile != nullptr); + ai_assert(strMode != nullptr); FILE* file; #ifdef _WIN32 - wchar_t fileName16[PATHLIMIT]; -#ifndef WindowsStore - bool isUnicode = IsTextUnicode(strFile, static_cast(strlen(strFile)), NULL) != 0; - if (isUnicode) { - MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT); - std::string mode8(strMode); - file = ::_wfopen(fileName16, std::wstring(mode8.begin(), mode8.end()).c_str()); - } else { -#endif - file = ::fopen(strFile, strMode); -#ifndef WindowsStore - } -#endif + file = ::_wfopen(Utf8ToWide(strFile).c_str(), Utf8ToWide(strMode).c_str()); #else file = ::fopen(strFile, strMode); #endif - if (nullptr == file) + if (!file) return nullptr; - return new DefaultIOStream(file, (std::string) strFile); + return new DefaultIOStream(file, strFile); } // ------------------------------------------------------------------------------------------------ // Closes the given file and releases all resources associated with it. -void DefaultIOSystem::Close( IOStream* pFile) +void DefaultIOSystem::Close(IOStream* pFile) { delete pFile; } @@ -155,78 +138,56 @@ char DefaultIOSystem::getOsSeparator() const // ------------------------------------------------------------------------------------------------ // IOSystem default implementation (ComparePaths isn't a pure virtual function) -bool IOSystem::ComparePaths (const char* one, const char* second) const +bool IOSystem::ComparePaths(const char* one, const char* second) const { - return !ASSIMP_stricmp(one,second); + return !ASSIMP_stricmp(one, second); } // ------------------------------------------------------------------------------------------------ // Convert a relative path into an absolute path -inline static void MakeAbsolutePath (const char* in, char* _out) +inline static std::string MakeAbsolutePath(const char* in) { - ai_assert(in && _out); -#if defined( _MSC_VER ) || defined( __MINGW32__ ) -#ifndef WindowsStore - bool isUnicode = IsTextUnicode(in, static_cast(strlen(in)), NULL) != 0; - if (isUnicode) { - wchar_t out16[PATHLIMIT]; - wchar_t in16[PATHLIMIT]; - MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, in, -1, out16, PATHLIMIT); - wchar_t* ret = ::_wfullpath(out16, in16, PATHLIMIT); - if (ret) { - WideCharToMultiByte(CP_UTF8, MB_PRECOMPOSED, out16, -1, _out, PATHLIMIT, nullptr, nullptr); - } - if (!ret) { - // preserve the input path, maybe someone else is able to fix - // the path before it is accessed (e.g. our file system filter) - ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in)); - strcpy(_out, in); - } - - } else { -#endif - char* ret = :: _fullpath(_out, in, PATHLIMIT); - if (!ret) { - // preserve the input path, maybe someone else is able to fix - // the path before it is accessed (e.g. our file system filter) - ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in)); - strcpy(_out, in); - } -#ifndef WindowsStore + ai_assert(in); + std::string out; +#ifdef _WIN32 + wchar_t* ret = ::_wfullpath(nullptr, Utf8ToWide(in).c_str(), 0); + if (ret) { + out = WideToUtf8(ret); + free(ret); + } +#else + char* ret = realpath(in, nullptr); + if (ret) { + out = ret; + free(ret); } #endif -#else - // use realpath - char* ret = realpath(in, _out); - if(!ret) { + if (!ret) { // preserve the input path, maybe someone else is able to fix // the path before it is accessed (e.g. our file system filter) ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in)); - strcpy(_out,in); + out = in; } -#endif + return out; } // ------------------------------------------------------------------------------------------------ // DefaultIOSystem's more specialized implementation -bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const +bool DefaultIOSystem::ComparePaths(const char* one, const char* second) const { // chances are quite good both paths are formatted identically, // so we can hopefully return here already - if( !ASSIMP_stricmp(one,second) ) + if (!ASSIMP_stricmp(one, second)) return true; - char temp1[PATHLIMIT]; - char temp2[PATHLIMIT]; + std::string temp1 = MakeAbsolutePath(one); + std::string temp2 = MakeAbsolutePath(second); - MakeAbsolutePath (one, temp1); - MakeAbsolutePath (second, temp2); - - return !ASSIMP_stricmp(temp1,temp2); + return !ASSIMP_stricmp(temp1, temp2); } // ------------------------------------------------------------------------------------------------ -std::string DefaultIOSystem::fileName( const std::string &path ) +std::string DefaultIOSystem::fileName(const std::string& path) { std::string ret = path; std::size_t last = ret.find_last_of("\\/"); @@ -235,16 +196,16 @@ std::string DefaultIOSystem::fileName( const std::string &path ) } // ------------------------------------------------------------------------------------------------ -std::string DefaultIOSystem::completeBaseName( const std::string &path ) +std::string DefaultIOSystem::completeBaseName(const std::string& path) { std::string ret = fileName(path); std::size_t pos = ret.find_last_of('.'); - if(pos != ret.npos) ret = ret.substr(0, pos); + if (pos != std::string::npos) ret = ret.substr(0, pos); return ret; } // ------------------------------------------------------------------------------------------------ -std::string DefaultIOSystem::absolutePath( const std::string &path ) +std::string DefaultIOSystem::absolutePath(const std::string& path) { std::string ret = path; std::size_t last = ret.find_last_of("\\/"); @@ -253,5 +214,3 @@ std::string DefaultIOSystem::absolutePath( const std::string &path ) } // ------------------------------------------------------------------------------------------------ - -#undef PATHLIMIT diff --git a/code/Common/Exporter.cpp b/code/Common/Exporter.cpp index 88bd9916f..34d49c472 100644 --- a/code/Common/Exporter.cpp +++ b/code/Common/Exporter.cpp @@ -315,34 +315,6 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha return pimpl->blob; } -// ------------------------------------------------------------------------------------------------ -bool IsVerboseFormat(const aiMesh* mesh) { - // avoid slow vector specialization - std::vector seen(mesh->mNumVertices,0); - for(unsigned int i = 0; i < mesh->mNumFaces; ++i) { - const aiFace& f = mesh->mFaces[i]; - for(unsigned int j = 0; j < f.mNumIndices; ++j) { - if(++seen[f.mIndices[j]] == 2) { - // found a duplicate index - return false; - } - } - } - - return true; -} - -// ------------------------------------------------------------------------------------------------ -bool IsVerboseFormat(const aiScene* pScene) { - for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { - if(!IsVerboseFormat(pScene->mMeshes[i])) { - return false; - } - } - - return true; -} - // ------------------------------------------------------------------------------------------------ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing, const ExportProperties* pProperties) { @@ -352,7 +324,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c // format. They will likely not be aware that there is a flag in the scene to indicate // this, however. To avoid surprises and bug reports, we check for duplicates in // meshes upfront. - const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene); + const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || MakeVerboseFormatProcess::IsVerboseFormat(pScene); pimpl->mProgressHandler->UpdateFileWrite(0, 4); diff --git a/code/Common/SceneCombiner.cpp b/code/Common/SceneCombiner.cpp index e445bd743..4e6bc5b47 100644 --- a/code/Common/SceneCombiner.cpp +++ b/code/Common/SceneCombiner.cpp @@ -1091,6 +1091,35 @@ void SceneCombiner::Copy( aiMesh** _dest, const aiMesh* src ) { aiFace& f = dest->mFaces[i]; GetArrayCopy(f.mIndices,f.mNumIndices); } + + // make a deep copy of all blend shapes + CopyPtrArray(dest->mAnimMeshes, dest->mAnimMeshes, dest->mNumAnimMeshes); +} + +// ------------------------------------------------------------------------------------------------ +void SceneCombiner::Copy(aiAnimMesh** _dest, const aiAnimMesh* src) { + if (nullptr == _dest || nullptr == src) { + return; + } + + aiAnimMesh* dest = *_dest = new aiAnimMesh(); + + // get a flat copy + ::memcpy(dest, src, sizeof(aiAnimMesh)); + + // and reallocate all arrays + GetArrayCopy(dest->mVertices, dest->mNumVertices); + GetArrayCopy(dest->mNormals, dest->mNumVertices); + GetArrayCopy(dest->mTangents, dest->mNumVertices); + GetArrayCopy(dest->mBitangents, dest->mNumVertices); + + unsigned int n = 0; + while (dest->HasTextureCoords(n)) + GetArrayCopy(dest->mTextureCoords[n++], dest->mNumVertices); + + n = 0; + while (dest->HasVertexColors(n)) + GetArrayCopy(dest->mColors[n++], dest->mNumVertices); } // ------------------------------------------------------------------------------------------------ diff --git a/code/FBX/FBXConverter.cpp b/code/FBX/FBXConverter.cpp index 949ba0532..6717b592f 100644 --- a/code/FBX/FBXConverter.cpp +++ b/code/FBX/FBXConverter.cpp @@ -66,6 +66,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include namespace Assimp { @@ -77,7 +78,7 @@ namespace Assimp { #define CONVERT_FBX_TIME(time) static_cast(time) / 46186158000L - FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit ) + FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones ) : defaultMaterialIndex() , lights() , cameras() @@ -89,8 +90,7 @@ namespace Assimp { , mNodeNames() , anim_fps() , out(out) - , doc(doc) - , mCurrentUnit(FbxUnit::cm) { + , doc(doc) { // animations need to be converted first since this will // populate the node_anim_chain_bits map, which is needed // to determine which nodes need to be generated. @@ -118,7 +118,6 @@ namespace Assimp { ConvertGlobalSettings(); TransferDataToScene(); - ConvertToUnitScale(unit); // if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE // to make sure the scene passes assimp's validation. FBX files @@ -684,30 +683,37 @@ namespace Assimp { bool ok; aiMatrix4x4 chain[TransformationComp_MAXIMUM]; + + ai_assert(TransformationComp_MAXIMUM < 32); + std::uint32_t chainBits = 0; + // A node won't need a node chain if it only has these. + const std::uint32_t chainMaskSimple = (1 << TransformationComp_Translation) + (1 << TransformationComp_Scaling) + (1 << TransformationComp_Rotation); + // A node will need a node chain if it has any of these. + const std::uint32_t chainMaskComplex = ((1 << (TransformationComp_MAXIMUM)) - 1) - chainMaskSimple; + std::fill_n(chain, static_cast(TransformationComp_MAXIMUM), aiMatrix4x4()); // generate transformation matrices for all the different transformation components const float zero_epsilon = 1e-6f; const aiVector3D all_ones(1.0f, 1.0f, 1.0f); - bool is_complex = false; const aiVector3D& PreRotation = PropertyGet(props, "PreRotation", ok); if (ok && PreRotation.SquareLength() > zero_epsilon) { - is_complex = true; + chainBits = chainBits | (1 << TransformationComp_PreRotation); GetRotationMatrix(Model::RotOrder::RotOrder_EulerXYZ, PreRotation, chain[TransformationComp_PreRotation]); } const aiVector3D& PostRotation = PropertyGet(props, "PostRotation", ok); if (ok && PostRotation.SquareLength() > zero_epsilon) { - is_complex = true; + chainBits = chainBits | (1 << TransformationComp_PostRotation); GetRotationMatrix(Model::RotOrder::RotOrder_EulerXYZ, PostRotation, chain[TransformationComp_PostRotation]); } const aiVector3D& RotationPivot = PropertyGet(props, "RotationPivot", ok); if (ok && RotationPivot.SquareLength() > zero_epsilon) { - is_complex = true; + chainBits = chainBits | (1 << TransformationComp_RotationPivot) | (1 << TransformationComp_RotationPivotInverse); aiMatrix4x4::Translation(RotationPivot, chain[TransformationComp_RotationPivot]); aiMatrix4x4::Translation(-RotationPivot, chain[TransformationComp_RotationPivotInverse]); @@ -715,21 +721,21 @@ namespace Assimp { const aiVector3D& RotationOffset = PropertyGet(props, "RotationOffset", ok); if (ok && RotationOffset.SquareLength() > zero_epsilon) { - is_complex = true; + chainBits = chainBits | (1 << TransformationComp_RotationOffset); aiMatrix4x4::Translation(RotationOffset, chain[TransformationComp_RotationOffset]); } const aiVector3D& ScalingOffset = PropertyGet(props, "ScalingOffset", ok); if (ok && ScalingOffset.SquareLength() > zero_epsilon) { - is_complex = true; + chainBits = chainBits | (1 << TransformationComp_ScalingOffset); aiMatrix4x4::Translation(ScalingOffset, chain[TransformationComp_ScalingOffset]); } const aiVector3D& ScalingPivot = PropertyGet(props, "ScalingPivot", ok); if (ok && ScalingPivot.SquareLength() > zero_epsilon) { - is_complex = true; + chainBits = chainBits | (1 << TransformationComp_ScalingPivot) | (1 << TransformationComp_ScalingPivotInverse); aiMatrix4x4::Translation(ScalingPivot, chain[TransformationComp_ScalingPivot]); aiMatrix4x4::Translation(-ScalingPivot, chain[TransformationComp_ScalingPivotInverse]); @@ -737,22 +743,28 @@ namespace Assimp { const aiVector3D& Translation = PropertyGet(props, "Lcl Translation", ok); if (ok && Translation.SquareLength() > zero_epsilon) { + chainBits = chainBits | (1 << TransformationComp_Translation); + aiMatrix4x4::Translation(Translation, chain[TransformationComp_Translation]); } const aiVector3D& Scaling = PropertyGet(props, "Lcl Scaling", ok); if (ok && (Scaling - all_ones).SquareLength() > zero_epsilon) { + chainBits = chainBits | (1 << TransformationComp_Scaling); + aiMatrix4x4::Scaling(Scaling, chain[TransformationComp_Scaling]); } const aiVector3D& Rotation = PropertyGet(props, "Lcl Rotation", ok); if (ok && Rotation.SquareLength() > zero_epsilon) { + chainBits = chainBits | (1 << TransformationComp_Rotation); + GetRotationMatrix(rot, Rotation, chain[TransformationComp_Rotation]); } const aiVector3D& GeometricScaling = PropertyGet(props, "GeometricScaling", ok); if (ok && (GeometricScaling - all_ones).SquareLength() > zero_epsilon) { - is_complex = true; + chainBits = chainBits | (1 << TransformationComp_GeometricScaling); aiMatrix4x4::Scaling(GeometricScaling, chain[TransformationComp_GeometricScaling]); aiVector3D GeometricScalingInverse = GeometricScaling; bool canscale = true; @@ -767,13 +779,14 @@ namespace Assimp { } } if (canscale) { + chainBits = chainBits | (1 << TransformationComp_GeometricScalingInverse); aiMatrix4x4::Scaling(GeometricScalingInverse, chain[TransformationComp_GeometricScalingInverse]); } } const aiVector3D& GeometricRotation = PropertyGet(props, "GeometricRotation", ok); if (ok && GeometricRotation.SquareLength() > zero_epsilon) { - is_complex = true; + chainBits = chainBits | (1 << TransformationComp_GeometricRotation) | (1 << TransformationComp_GeometricRotationInverse); GetRotationMatrix(rot, GeometricRotation, chain[TransformationComp_GeometricRotation]); GetRotationMatrix(rot, GeometricRotation, chain[TransformationComp_GeometricRotationInverse]); chain[TransformationComp_GeometricRotationInverse].Inverse(); @@ -781,7 +794,7 @@ namespace Assimp { const aiVector3D& GeometricTranslation = PropertyGet(props, "GeometricTranslation", ok); if (ok && GeometricTranslation.SquareLength() > zero_epsilon) { - is_complex = true; + chainBits = chainBits | (1 << TransformationComp_GeometricTranslation) | (1 << TransformationComp_GeometricTranslationInverse); aiMatrix4x4::Translation(GeometricTranslation, chain[TransformationComp_GeometricTranslation]); aiMatrix4x4::Translation(-GeometricTranslation, chain[TransformationComp_GeometricTranslationInverse]); } @@ -789,12 +802,12 @@ namespace Assimp { // is_complex needs to be consistent with NeedsComplexTransformationChain() // or the interplay between this code and the animation converter would // not be guaranteed. - ai_assert(NeedsComplexTransformationChain(model) == is_complex); + ai_assert(NeedsComplexTransformationChain(model) == ((chainBits & chainMaskComplex) != 0)); // now, if we have more than just Translation, Scaling and Rotation, // we need to generate a full node chain to accommodate for assimp's // lack to express pivots and offsets. - if (is_complex && doc.Settings().preservePivots) { + if ((chainBits & chainMaskComplex) && doc.Settings().preservePivots) { FBXImporter::LogInfo("generating full transformation chain for node: " + name); // query the anim_chain_bits dictionary to find out which chain elements @@ -807,7 +820,7 @@ namespace Assimp { for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i, bit <<= 1) { const TransformationComp comp = static_cast(i); - if (chain[i].IsIdentity() && (anim_chain_bitmask & bit) == 0) { + if ((chainBits & bit) == 0 && (anim_chain_bitmask & bit) == 0) { continue; } @@ -3522,46 +3535,6 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa out->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate()); } - void FBXConverter::ConvertToUnitScale( FbxUnit unit ) { - if (mCurrentUnit == unit) { - return; - } - - ai_real scale = 1.0; - if (mCurrentUnit == FbxUnit::cm) { - if (unit == FbxUnit::m) { - scale = (ai_real)0.01; - } else if (unit == FbxUnit::km) { - scale = (ai_real)0.00001; - } - } else if (mCurrentUnit == FbxUnit::m) { - if (unit == FbxUnit::cm) { - scale = (ai_real)100.0; - } else if (unit == FbxUnit::km) { - scale = (ai_real)0.001; - } - } else if (mCurrentUnit == FbxUnit::km) { - if (unit == FbxUnit::cm) { - scale = (ai_real)100000.0; - } else if (unit == FbxUnit::m) { - scale = (ai_real)1000.0; - } - } - - for (auto mesh : meshes) { - if (nullptr == mesh) { - continue; - } - - if (mesh->HasPositions()) { - for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { - aiVector3D &pos = mesh->mVertices[i]; - pos *= scale; - } - } - } - } - void FBXConverter::TransferDataToScene() { ai_assert(!out->mMeshes); @@ -3615,9 +3588,9 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa } // ------------------------------------------------------------------------------------------------ - void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit) + void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones) { - FBXConverter converter(out, doc, removeEmptyBones, unit); + FBXConverter converter(out, doc, removeEmptyBones); } } // !FBX diff --git a/code/FBX/FBXConverter.h b/code/FBX/FBXConverter.h index fb1a87ca6..77ced1950 100644 --- a/code/FBX/FBXConverter.h +++ b/code/FBX/FBXConverter.h @@ -76,23 +76,13 @@ namespace Assimp { namespace FBX { class Document; - -enum class FbxUnit { - cm = 0, - m, - km, - NumUnits, - - Undefined -}; - /** * Convert a FBX #Document to #aiScene * @param out Empty scene to be populated * @param doc Parsed FBX document * @param removeEmptyBones Will remove bones, which do not have any references to vertices. */ -void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit); +void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones); /** Dummy class to encapsulate the conversion process */ class FBXConverter { @@ -123,7 +113,7 @@ public: }; public: - FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit); + FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones); ~FBXConverter(); private: @@ -430,10 +420,6 @@ private: void ConvertGlobalSettings(); - // ------------------------------------------------------------------------------------------------ - // Will perform the conversion from a given unit to the requested unit. - void ConvertToUnitScale(FbxUnit unit); - // ------------------------------------------------------------------------------------------------ // copy generated meshes, animations, lights, cameras and textures to the output scene void TransferDataToScene(); @@ -470,7 +456,6 @@ private: aiScene* const out; const FBX::Document& doc; - FbxUnit mCurrentUnit; }; } diff --git a/code/FBX/FBXExporter.cpp b/code/FBX/FBXExporter.cpp index 0722a0fba..25d057df1 100644 --- a/code/FBX/FBXExporter.cpp +++ b/code/FBX/FBXExporter.cpp @@ -1134,6 +1134,51 @@ void FBXExporter::WriteObjects () normals.End(outstream, binary, indent, true); } + // colors, if any + // TODO only one color channel currently + const int32_t colorChannelIndex = 0; + if (m->HasVertexColors(colorChannelIndex)) { + FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex)); + vertexcolors.Begin(outstream, binary, indent); + vertexcolors.DumpProperties(outstream, binary, indent); + vertexcolors.EndProperties(outstream, binary, indent); + vertexcolors.BeginChildren(outstream, binary, indent); + indent = 3; + FBX::Node::WritePropertyNode( + "Version", int32_t(101), outstream, binary, indent + ); + char layerName[8]; + sprintf(layerName, "COLOR_%d", colorChannelIndex); + FBX::Node::WritePropertyNode( + "Name", (const char*)layerName, outstream, binary, indent + ); + FBX::Node::WritePropertyNode( + "MappingInformationType", "ByPolygonVertex", + outstream, binary, indent + ); + FBX::Node::WritePropertyNode( + "ReferenceInformationType", "Direct", + outstream, binary, indent + ); + std::vector color_data; + color_data.reserve(4 * polygon_data.size()); + for (size_t fi = 0; fi < m->mNumFaces; ++fi) { + const aiFace &f = m->mFaces[fi]; + for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) { + const aiColor4D &c = m->mColors[colorChannelIndex][f.mIndices[pvi]]; + color_data.push_back(c.r); + color_data.push_back(c.g); + color_data.push_back(c.b); + color_data.push_back(c.a); + } + } + FBX::Node::WritePropertyNode( + "Colors", color_data, outstream, binary, indent + ); + indent = 2; + vertexcolors.End(outstream, binary, indent, true); + } + // uvs, if any for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) { if (m->mNumUVComponents[uvi] > 2) { @@ -1227,6 +1272,11 @@ void FBXExporter::WriteObjects () le.AddChild("Type", "LayerElementNormal"); le.AddChild("TypedIndex", int32_t(0)); layer.AddChild(le); + // TODO only 1 color channel currently + le = FBX::Node("LayerElement"); + le.AddChild("Type", "LayerElementColor"); + le.AddChild("TypedIndex", int32_t(0)); + layer.AddChild(le); le = FBX::Node("LayerElement"); le.AddChild("Type", "LayerElementMaterial"); le.AddChild("TypedIndex", int32_t(0)); @@ -2433,7 +2483,7 @@ void FBXExporter::WriteModelNodes( void FBXExporter::WriteAnimationCurveNode( StreamWriterLE& outstream, int64_t uid, - std::string name, // "T", "R", or "S" + const std::string& name, // "T", "R", or "S" aiVector3D default_value, std::string property_name, // "Lcl Translation" etc int64_t layer_uid, diff --git a/code/FBX/FBXExporter.h b/code/FBX/FBXExporter.h index 71fb55c57..1ae727eda 100644 --- a/code/FBX/FBXExporter.h +++ b/code/FBX/FBXExporter.h @@ -156,7 +156,7 @@ namespace Assimp void WriteAnimationCurveNode( StreamWriterLE& outstream, int64_t uid, - std::string name, // "T", "R", or "S" + const std::string& name, // "T", "R", or "S" aiVector3D default_value, std::string property_name, // "Lcl Translation" etc int64_t animation_layer_uid, diff --git a/code/FBX/FBXImporter.cpp b/code/FBX/FBXImporter.cpp index ec8bbd2b4..c8c1a6853 100644 --- a/code/FBX/FBXImporter.cpp +++ b/code/FBX/FBXImporter.cpp @@ -185,12 +185,15 @@ void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS // take the raw parse-tree and convert it to a FBX DOM Document doc(parser,settings); - FbxUnit unit(FbxUnit::cm); - if (settings.convertToMeters) { - unit = FbxUnit::m; - } // convert the FBX DOM to aiScene - ConvertToAssimpScene(pScene,doc, settings.removeEmptyBones, unit); + ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones); + + // size relative to cm + float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor(); + + // Set FBX file scale is relative to CM must be converted to M for + // assimp universal format (M) + SetFileScale( size_relative_to_cm * 0.01f); std::for_each(tokens.begin(),tokens.end(),Util::delete_fun()); } diff --git a/code/FBX/FBXMeshGeometry.cpp b/code/FBX/FBXMeshGeometry.cpp index e60fc25e2..1386e2383 100644 --- a/code/FBX/FBXMeshGeometry.cpp +++ b/code/FBX/FBXMeshGeometry.cpp @@ -610,8 +610,11 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector& materials_out, cons const std::string& ReferenceInformationType) { const size_t face_count = m_faces.size(); - ai_assert(face_count); - + if( 0 == face_count ) + { + return; + } + // materials are handled separately. First of all, they are assigned per-face // and not per polyvert. Secondly, ReferenceInformationType=IndexToDirect // has a slightly different meaning for materials. @@ -622,16 +625,14 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector& materials_out, cons if (materials_out.empty()) { FBXImporter::LogError(Formatter::format("expected material index, ignoring")); return; - } - else if (materials_out.size() > 1) { + } else if (materials_out.size() > 1) { FBXImporter::LogWarn(Formatter::format("expected only a single material index, ignoring all except the first one")); materials_out.clear(); } materials_out.resize(m_vertices.size()); std::fill(materials_out.begin(), materials_out.end(), materials_out.at(0)); - } - else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") { + } else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") { materials_out.resize(face_count); if(materials_out.size() != face_count) { @@ -640,18 +641,16 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector& materials_out, cons ); return; } - } - else { + } else { FBXImporter::LogError(Formatter::format("ignoring material assignments, access type not implemented: ") << MappingInformationType << "," << ReferenceInformationType); } } // ------------------------------------------------------------------------------------------------ ShapeGeometry::ShapeGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) - : Geometry(id, element, name, doc) -{ - const Scope* sc = element.Compound(); - if (!sc) { +: Geometry(id, element, name, doc) { + const Scope *sc = element.Compound(); + if (nullptr == sc) { DOMError("failed to read Geometry object (class: Shape), no data scope found"); } const Element& Indexes = GetRequiredElement(*sc, "Indexes", &element); diff --git a/code/Importer/IFC/IFCGeometry.cpp b/code/Importer/IFC/IFCGeometry.cpp index 032030112..d1c7aee19 100644 --- a/code/Importer/IFC/IFCGeometry.cpp +++ b/code/Importer/IFC/IFCGeometry.cpp @@ -128,7 +128,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m outer_polygon_it = begin + master_bounds; } else { - for(iit = begin; iit != end; iit++) { + for(iit = begin; iit != end; ++iit) { // find the polygon with the largest area and take it as the outer bound. IfcVector3& n = normals[std::distance(begin,iit)]; const IfcFloat area = n.SquareLength(); diff --git a/code/Obj/ObjFileParser.cpp b/code/Obj/ObjFileParser.cpp index 97ef4af70..699aafe6a 100644 --- a/code/Obj/ObjFileParser.cpp +++ b/code/Obj/ObjFileParser.cpp @@ -244,8 +244,8 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length) { size_t index = 0; m_DataIt = getNextWord(m_DataIt, m_DataItEnd); if ( *m_DataIt == '\\' ) { - m_DataIt++; - m_DataIt++; + ++m_DataIt; + ++m_DataIt; m_DataIt = getNextWord( m_DataIt, m_DataItEnd ); } while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) { diff --git a/code/PostProcessing/CalcTangentsProcess.cpp b/code/PostProcessing/CalcTangentsProcess.cpp index b30f39c27..a3f7dd255 100644 --- a/code/PostProcessing/CalcTangentsProcess.cpp +++ b/code/PostProcessing/CalcTangentsProcess.cpp @@ -212,7 +212,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) // project tangent and bitangent into the plane formed by the vertex' normal aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]); aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]); - localTangent.Normalize(); localBitangent.Normalize(); + localTangent.NormalizeSafe(); localBitangent.NormalizeSafe(); // reconstruct tangent/bitangent according to normal and bitangent/tangent when it's infinite or NaN. bool invalid_tangent = is_special_float(localTangent.x) || is_special_float(localTangent.y) || is_special_float(localTangent.z); @@ -220,10 +220,10 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) if (invalid_tangent != invalid_bitangent) { if (invalid_tangent) { localTangent = meshNorm[p] ^ localBitangent; - localTangent.Normalize(); + localTangent.NormalizeSafe(); } else { localBitangent = localTangent ^ meshNorm[p]; - localBitangent.Normalize(); + localBitangent.NormalizeSafe(); } } diff --git a/code/PostProcessing/JoinVerticesProcess.cpp b/code/PostProcessing/JoinVerticesProcess.cpp index 914ec05b4..f121fc60d 100644 --- a/code/PostProcessing/JoinVerticesProcess.cpp +++ b/code/PostProcessing/JoinVerticesProcess.cpp @@ -431,31 +431,6 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) bone->mWeights = new aiVertexWeight[bone->mNumWeights]; memcpy( bone->mWeights, &newWeights[0], bone->mNumWeights * sizeof( aiVertexWeight)); } - else { - - /* NOTE: - * - * In the algorithm above we're assuming that there are no vertices - * with a different bone weight setup at the same position. That wouldn't - * make sense, but it is not absolutely impossible. SkeletonMeshBuilder - * for example generates such input data if two skeleton points - * share the same position. Again this doesn't make sense but is - * reality for some model formats (MD5 for example uses these special - * nodes as attachment tags for its weapons). - * - * Then it is possible that a bone has no weights anymore .... as a quick - * workaround, we're just removing these bones. If they're animated, - * model geometry might be modified but at least there's no risk of a crash. - */ - delete bone; - --pMesh->mNumBones; - for (unsigned int n = a; n < pMesh->mNumBones; ++n) { - pMesh->mBones[n] = pMesh->mBones[n+1]; - } - - --a; - ASSIMP_LOG_WARN("Removing bone -> no weights remaining"); - } } return pMesh->mNumVertices; } diff --git a/code/PostProcessing/MakeVerboseFormat.cpp b/code/PostProcessing/MakeVerboseFormat.cpp index 50ff5ed93..41f50a5ba 100644 --- a/code/PostProcessing/MakeVerboseFormat.cpp +++ b/code/PostProcessing/MakeVerboseFormat.cpp @@ -224,3 +224,32 @@ bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh) } return (pcMesh->mNumVertices != iOldNumVertices); } + + +// ------------------------------------------------------------------------------------------------ +bool IsMeshInVerboseFormat(const aiMesh* mesh) { + // avoid slow vector specialization + std::vector seen(mesh->mNumVertices,0); + for(unsigned int i = 0; i < mesh->mNumFaces; ++i) { + const aiFace& f = mesh->mFaces[i]; + for(unsigned int j = 0; j < f.mNumIndices; ++j) { + if(++seen[f.mIndices[j]] == 2) { + // found a duplicate index + return false; + } + } + } + + return true; +} + +// ------------------------------------------------------------------------------------------------ +bool MakeVerboseFormatProcess::IsVerboseFormat(const aiScene* pScene) { + for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { + if(!IsMeshInVerboseFormat(pScene->mMeshes[i])) { + return false; + } + } + + return true; +} diff --git a/code/PostProcessing/MakeVerboseFormat.h b/code/PostProcessing/MakeVerboseFormat.h index 1adf8e2f6..8565d5933 100644 --- a/code/PostProcessing/MakeVerboseFormat.h +++ b/code/PostProcessing/MakeVerboseFormat.h @@ -94,6 +94,13 @@ public: * @param pScene The imported data to work at. */ void Execute( aiScene* pScene); +public: + + // ------------------------------------------------------------------- + /** Checks whether the scene is already in verbose format. + * @param pScene The data to check. + * @return true if the scene is already in verbose format. */ + static bool IsVerboseFormat(const aiScene* pScene); private: diff --git a/code/PostProcessing/ScaleProcess.cpp b/code/PostProcessing/ScaleProcess.cpp index 6d458c4b1..ac770c41f 100644 --- a/code/PostProcessing/ScaleProcess.cpp +++ b/code/PostProcessing/ScaleProcess.cpp @@ -39,19 +39,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ -#ifndef ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS - #include "ScaleProcess.h" #include #include +#include namespace Assimp { ScaleProcess::ScaleProcess() : BaseProcess() , mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) { - // empty } ScaleProcess::~ScaleProcess() { @@ -71,10 +69,26 @@ bool ScaleProcess::IsActive( unsigned int pFlags ) const { } void ScaleProcess::SetupProperties( const Importer* pImp ) { - mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 0 ); + // User scaling + mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 1.0f ); + + // File scaling * Application Scaling + float importerScale = pImp->GetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, 1.0f ); + + // apply scale to the scale + // helps prevent bugs with backward compatibility for anyone using normal scaling. + mScale *= importerScale; } void ScaleProcess::Execute( aiScene* pScene ) { + if(mScale == 1.0f) { + return; // nothing to scale + } + + ai_assert( mScale != 0 ); + ai_assert( nullptr != pScene ); + ai_assert( nullptr != pScene->mRootNode ); + if ( nullptr == pScene ) { return; } @@ -82,22 +96,113 @@ void ScaleProcess::Execute( aiScene* pScene ) { if ( nullptr == pScene->mRootNode ) { return; } + + // Process animations and update position transform to new unit system + for( unsigned int animationID = 0; animationID < pScene->mNumAnimations; animationID++ ) + { + aiAnimation* animation = pScene->mAnimations[animationID]; + + for( unsigned int animationChannel = 0; animationChannel < animation->mNumChannels; animationChannel++) + { + aiNodeAnim* anim = animation->mChannels[animationChannel]; + + for( unsigned int posKey = 0; posKey < anim->mNumPositionKeys; posKey++) + { + aiVectorKey& vectorKey = anim->mPositionKeys[posKey]; + vectorKey.mValue *= mScale; + } + } + } + + for( unsigned int meshID = 0; meshID < pScene->mNumMeshes; meshID++) + { + aiMesh *mesh = pScene->mMeshes[meshID]; + + // Reconstruct mesh vertexes to the new unit system + for( unsigned int vertexID = 0; vertexID < mesh->mNumVertices; vertexID++) + { + aiVector3D& vertex = mesh->mVertices[vertexID]; + vertex *= mScale; + } + + + // bone placement / scaling + for( unsigned int boneID = 0; boneID < mesh->mNumBones; boneID++) + { + // Reconstruct matrix by transform rather than by scale + // This prevent scale values being changed which can + // be meaningful in some cases + // like when you want the modeller to see 1:1 compatibility. + aiBone* bone = mesh->mBones[boneID]; + + aiVector3D pos, scale; + aiQuaternion rotation; + + bone->mOffsetMatrix.Decompose( scale, rotation, pos); + + aiMatrix4x4 translation; + aiMatrix4x4::Translation( pos * mScale, translation ); + + aiMatrix4x4 scaling; + aiMatrix4x4::Scaling( aiVector3D(scale), scaling ); + + aiMatrix4x4 RotMatrix = aiMatrix4x4 (rotation.GetMatrix()); + + bone->mOffsetMatrix = translation * RotMatrix * scaling; + } + + + // animation mesh processing + // convert by position rather than scale. + for( unsigned int animMeshID = 0; animMeshID < mesh->mNumAnimMeshes; animMeshID++) + { + aiAnimMesh * animMesh = mesh->mAnimMeshes[animMeshID]; + + for( unsigned int vertexID = 0; vertexID < animMesh->mNumVertices; vertexID++) + { + aiVector3D& vertex = animMesh->mVertices[vertexID]; + vertex *= mScale; + } + } + } traverseNodes( pScene->mRootNode ); } -void ScaleProcess::traverseNodes( aiNode *node ) { +void ScaleProcess::traverseNodes( aiNode *node, unsigned int nested_node_id ) { applyScaling( node ); + + for( size_t i = 0; i < node->mNumChildren; i++) + { + // recurse into the tree until we are done! + traverseNodes( node->mChildren[i], nested_node_id+1 ); + } } void ScaleProcess::applyScaling( aiNode *currentNode ) { if ( nullptr != currentNode ) { - currentNode->mTransformation.a1 = currentNode->mTransformation.a1 * mScale; - currentNode->mTransformation.b2 = currentNode->mTransformation.b2 * mScale; - currentNode->mTransformation.c3 = currentNode->mTransformation.c3 * mScale; + // Reconstruct matrix by transform rather than by scale + // This prevent scale values being changed which can + // be meaningful in some cases + // like when you want the modeller to + // see 1:1 compatibility. + + aiVector3D pos, scale; + aiQuaternion rotation; + currentNode->mTransformation.Decompose( scale, rotation, pos); + + aiMatrix4x4 translation; + aiMatrix4x4::Translation( pos * mScale, translation ); + + aiMatrix4x4 scaling; + + // note: we do not use mScale here, this is on purpose. + aiMatrix4x4::Scaling( scale, scaling ); + + aiMatrix4x4 RotMatrix = aiMatrix4x4 (rotation.GetMatrix()); + + currentNode->mTransformation = translation * RotMatrix * scaling; } } } // Namespace Assimp - -#endif // !! ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS diff --git a/code/PostProcessing/ScaleProcess.h b/code/PostProcessing/ScaleProcess.h index 256737875..468a21673 100644 --- a/code/PostProcessing/ScaleProcess.h +++ b/code/PostProcessing/ScaleProcess.h @@ -39,7 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ -#pragma once +#ifndef SCALE_PROCESS_H_ +#define SCALE_PROCESS_H_ #include "Common/BaseProcess.h" @@ -53,6 +54,11 @@ namespace Assimp { // --------------------------------------------------------------------------- /** ScaleProcess: Class to rescale the whole model. + * Now rescales animations, bones, and blend shapes properly. + * Please note this will not write to 'scale' transform it will rewrite mesh + * and matrixes so that your scale values + * from your model package are preserved, so this is completely intentional + * bugs should be reported as soon as they are found. */ class ASSIMP_API ScaleProcess : public BaseProcess { public: @@ -78,7 +84,7 @@ public: virtual void Execute( aiScene* pScene ); private: - void traverseNodes( aiNode *currentNode ); + void traverseNodes( aiNode *currentNode, unsigned int nested_node_id = 0 ); void applyScaling( aiNode *currentNode ); private: @@ -86,3 +92,6 @@ private: }; } // Namespace Assimp + + +#endif // SCALE_PROCESS_H_ \ No newline at end of file diff --git a/code/X3D/X3DExporter.cpp b/code/X3D/X3DExporter.cpp index 9839e6ca6..e5eeb0886 100644 --- a/code/X3D/X3DExporter.cpp +++ b/code/X3D/X3DExporter.cpp @@ -68,7 +68,7 @@ aiMatrix4x4 out_matr; } // multiplicate all matrices in reverse order - for(std::list::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); rit++) out_matr = out_matr * (*rit); + for(std::list::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); ++rit) out_matr = out_matr * (*rit); return out_matr; } diff --git a/code/X3D/X3DImporter.cpp b/code/X3D/X3DImporter.cpp index 96fcf067a..d1d38e0b6 100644 --- a/code/X3D/X3DImporter.cpp +++ b/code/X3D/X3DImporter.cpp @@ -136,8 +136,8 @@ X3DImporter::~X3DImporter() { void X3DImporter::Clear() { NodeElement_Cur = nullptr; // Delete all elements - if(NodeElement_List.size()) { - for ( std::list::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); it++ ) { + if(!NodeElement_List.empty()) { + for ( std::list::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); ++it ) { delete *it; } NodeElement_List.clear(); @@ -151,7 +151,7 @@ void X3DImporter::Clear() { bool X3DImporter::FindNodeElement_FromRoot(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement) { - for(std::list::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); it++) + for(std::list::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); ++it) { if(((*it)->Type == pType) && ((*it)->ID == pID)) { @@ -182,7 +182,7 @@ bool X3DImporter::FindNodeElement_FromNode(CX3DImporter_NodeElement* pStartNode, }// if((pStartNode->Type() == pType) && (pStartNode->ID() == pID)) // Check childs of pStartNode. - for(std::list::iterator ch_it = pStartNode->Child.begin(); ch_it != pStartNode->Child.end(); ch_it++) + for(std::list::iterator ch_it = pStartNode->Child.begin(); ch_it != pStartNode->Child.end(); ++ch_it) { found = FindNodeElement_FromNode(*ch_it, pID, pType, pElement); if ( found ) @@ -617,7 +617,7 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::ve if(tlist.size() > 0) { pValue.reserve(tlist.size()); - for(std::list::iterator it = tlist.begin(); it != tlist.end(); it++) pValue.push_back(*it); + for(std::list::iterator it = tlist.begin(); it != tlist.end(); ++it) pValue.push_back(*it); } } @@ -647,10 +647,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::ve XML_ReadNode_GetAttrVal_AsListCol4f(pAttrIdx, tlist);// read as list // and copy to array - if(tlist.size() > 0) + if(!tlist.empty()) { pValue.reserve(tlist.size()); - for ( std::list::iterator it = tlist.begin(); it != tlist.end(); it++ ) + for ( std::list::iterator it = tlist.begin(); it != tlist.end(); ++it ) { pValue.push_back( *it ); } @@ -684,10 +684,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::ve XML_ReadNode_GetAttrVal_AsListVec2f(pAttrIdx, tlist);// read as list // and copy to array - if(tlist.size() > 0) + if(!tlist.empty()) { pValue.reserve(tlist.size()); - for ( std::list::iterator it = tlist.begin(); it != tlist.end(); it++ ) + for ( std::list::iterator it = tlist.begin(); it != tlist.end(); ++it ) { pValue.push_back( *it ); } @@ -722,10 +722,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec3f(const int pAttrIdx, std::ve XML_ReadNode_GetAttrVal_AsListVec3f(pAttrIdx, tlist);// read as list // and copy to array - if(tlist.size() > 0) + if(!tlist.empty()) { pValue.reserve(tlist.size()); - for ( std::list::iterator it = tlist.begin(); it != tlist.end(); it++ ) + for ( std::list::iterator it = tlist.begin(); it != tlist.end(); ++it ) { pValue.push_back( *it ); } @@ -823,7 +823,7 @@ void X3DImporter::GeometryHelper_Extend_PointToLine(const std::list& std::list::const_iterator pit = pPoint.begin(); std::list::const_iterator pit_last = pPoint.end(); - pit_last--; + --pit_last; if ( pPoint.size() < 2 ) { @@ -837,7 +837,7 @@ void X3DImporter::GeometryHelper_Extend_PointToLine(const std::list& { pLine.push_back(*pit);// second point of previous line pLine.push_back(*pit);// first point of next line - pit++; + ++pit; } // add last point of last line pLine.push_back(*pit); @@ -855,7 +855,7 @@ void X3DImporter::GeometryHelper_Extend_PolylineIdxToLineIdx(const std::list::const_iterator plit_next; - plit_next = plit, plit_next++; + plit_next = plit, ++plit_next; pLineCoordIdx.push_back(*plit);// second point of previous line. pLineCoordIdx.push_back(-1);// delimiter if((*plit_next == (-1)) || (plit_next == pPolylineCoordIdx.end())) break;// current polyline is finished @@ -910,7 +910,7 @@ void X3DImporter::GeometryHelper_CoordIdxStr2FacesArr(const std::vector pFaces.reserve(f_data.size() / 3); inds.reserve(4); //PrintVectorSet("build. ci", pCoordIdx); - for(std::vector::iterator it = f_data.begin(); it != f_data.end(); it++) + for(std::vector::iterator it = f_data.begin(); it != f_data.end(); ++it) { // when face is got count how many indices in it. if(*it == (-1)) @@ -957,7 +957,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list tcol; // create RGBA array from RGB. - for(std::list::const_iterator it = pColors.begin(); it != pColors.end(); it++) tcol.push_back(aiColor4D((*it).r, (*it).g, (*it).b, 1)); + for(std::list::const_iterator it = pColors.begin(); it != pColors.end(); ++it) tcol.push_back(aiColor4D((*it).r, (*it).g, (*it).b, 1)); // call existing function for adding RGBA colors MeshGeometry_AddColor(pMesh, tcol, pColorPerVertex); @@ -997,7 +997,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list tcol; // create RGBA array from RGB. - for ( std::list::const_iterator it = pColors.begin(); it != pColors.end(); it++ ) + for ( std::list::const_iterator it = pColors.begin(); it != pColors.end(); ++it ) { tcol.push_back( aiColor4D( ( *it ).r, ( *it ).g, ( *it ).b, 1 ) ); } @@ -1031,7 +1031,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector::const_iterator it = pColors.begin(); it != pColors.end(); it++ ) + for ( std::list::const_iterator it = pColors.begin(); it != pColors.end(); ++it ) { col_arr_copy.push_back( *it ); } @@ -1048,7 +1048,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); colidx_it++, coordidx_it++) + for(std::vector::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); ++colidx_it, ++coordidx_it) { if ( *colidx_it == ( -1 ) ) { @@ -1121,7 +1121,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector::const_iterator it = col_tgt_arr.begin(); it != col_tgt_arr.end(); it++) col_tgt_list.push_back(*it); + for(std::vector::const_iterator it = col_tgt_arr.begin(); it != col_tgt_arr.end(); ++it) col_tgt_list.push_back(*it); // add prepared colors list to mesh. MeshGeometry_AddColor(pMesh, col_tgt_list, pColorPerVertex); } @@ -1134,7 +1134,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector::const_iterator it = pNormals.begin(); it != pNormals.end(); it++ ) + for ( std::list::const_iterator it = pNormals.begin(); it != pNormals.end(); ++it ) { norm_arr_copy.push_back( *it ); } @@ -1147,7 +1147,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); it++) + for(std::vector::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); ++it) { if(*it != (-1)) tind.push_back(*it); } @@ -1227,7 +1227,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); it++) + for(std::list::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); ++it) { texcoord_arr_copy.push_back(aiVector3D((*it).x, (*it).y, 0)); } @@ -1291,7 +1291,7 @@ void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); it++ ) + for ( std::list::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); ++it ) { tc_arr_copy.push_back( aiVector3D( ( *it ).x, ( *it ).y, 0 ) ); } @@ -1699,7 +1699,7 @@ void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy // create nodes tree Postprocess_BuildNode(*NodeElement_Cur, *pScene->mRootNode, mesh_list, mat_list, light_list); // copy needed data to scene - if(mesh_list.size() > 0) + if(!mesh_list.empty()) { std::list::const_iterator it = mesh_list.begin(); @@ -1708,7 +1708,7 @@ void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy for(size_t i = 0; i < pScene->mNumMeshes; i++) pScene->mMeshes[i] = *it++; } - if(mat_list.size() > 0) + if(!mat_list.empty()) { std::list::const_iterator it = mat_list.begin(); @@ -1717,7 +1717,7 @@ void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy for(size_t i = 0; i < pScene->mNumMaterials; i++) pScene->mMaterials[i] = *it++; } - if(light_list.size() > 0) + if(!light_list.empty()) { std::list::const_iterator it = light_list.begin(); diff --git a/code/X3D/X3DImporter_Geometry2D.cpp b/code/X3D/X3DImporter_Geometry2D.cpp index b29c80b04..350fd6c40 100644 --- a/code/X3D/X3DImporter_Geometry2D.cpp +++ b/code/X3D/X3DImporter_Geometry2D.cpp @@ -356,7 +356,7 @@ void X3DImporter::ParseNode_Geometry2D_Polyline2D() std::list tlist; // convert vec2 to vec3 - for(std::list::iterator it2 = lineSegments.begin(); it2 != lineSegments.end(); it2++) tlist.push_back(aiVector3D(it2->x, it2->y, 0)); + for(std::list::iterator it2 = lineSegments.begin(); it2 != lineSegments.end(); ++it2) tlist.push_back(aiVector3D(it2->x, it2->y, 0)); // convert point set to line set GeometryHelper_Extend_PointToLine(tlist, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices); @@ -399,7 +399,7 @@ void X3DImporter::ParseNode_Geometry2D_Polypoint2D() if(!def.empty()) ne->ID = def; // convert vec2 to vec3 - for(std::list::iterator it2 = point.begin(); it2 != point.end(); it2++) + for(std::list::iterator it2 = point.begin(); it2 != point.end(); ++it2) { ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0)); } @@ -500,7 +500,7 @@ void X3DImporter::ParseNode_Geometry2D_TriangleSet2D() if(!def.empty()) ne->ID = def; // convert vec2 to vec3 - for(std::list::iterator it2 = vertices.begin(); it2 != vertices.end(); it2++) + for(std::list::iterator it2 = vertices.begin(); it2 != vertices.end(); ++it2) { ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0)); } diff --git a/code/X3D/X3DImporter_Geometry3D.cpp b/code/X3D/X3DImporter_Geometry3D.cpp index 2eecc079d..e12cbd3ab 100644 --- a/code/X3D/X3DImporter_Geometry3D.cpp +++ b/code/X3D/X3DImporter_Geometry3D.cpp @@ -153,11 +153,11 @@ void X3DImporter::ParseNode_Geometry3D_Cone() { StandardShapes::MakeCircle(bottomRadius, tess, tvec); height = -(height / 2); - for(std::vector::iterator it = tvec.begin(); it != tvec.end(); it++) it->y = height;// y - because circle made in oXZ. + for(std::vector::iterator it = tvec.begin(); it != tvec.end(); ++it) it->y = height;// y - because circle made in oXZ. } // copy data from temp array - for(std::vector::iterator it = tvec.begin(); it != tvec.end(); it++) ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it); + for(std::vector::iterator it = tvec.begin(); it != tvec.end(); ++it) ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it); ((CX3DImporter_NodeElement_Geometry3D*)ne)->Solid = solid; ((CX3DImporter_NodeElement_Geometry3D*)ne)->NumIndices = 3; @@ -226,11 +226,11 @@ void X3DImporter::ParseNode_Geometry3D_Cylinder() // copy data from temp arrays std::list& vlist = ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices;// just short alias. - for(std::vector::iterator it = tside.begin(); it != tside.end(); it++) vlist.push_back(*it); + for(std::vector::iterator it = tside.begin(); it != tside.end(); ++it) vlist.push_back(*it); if(top) { - for(std::vector::iterator it = tcir.begin(); it != tcir.end(); it++) + for(std::vector::iterator it = tcir.begin(); it != tcir.end(); ++it) { (*it).y = height;// y - because circle made in oXZ. vlist.push_back(*it); @@ -239,7 +239,7 @@ void X3DImporter::ParseNode_Geometry3D_Cylinder() if(bottom) { - for(std::vector::iterator it = tcir.begin(); it != tcir.end(); it++) + for(std::vector::iterator it = tcir.begin(); it != tcir.end(); ++it) { (*it).y = -height;// y - because circle made in oXZ. vlist.push_back(*it); @@ -336,7 +336,7 @@ void X3DImporter::ParseNode_Geometry3D_ElevationGrid() aiVector3D tvec(xSpacing * xi, *he_it, zSpacing * zi); grid_alias.Vertices.push_back(tvec); - he_it++; + ++he_it; } } }// END: create grid vertices list @@ -977,7 +977,7 @@ void X3DImporter::ParseNode_Geometry3D_Sphere() StandardShapes::MakeSphere(tess, tlist); // copy data from temp array and apply scale - for(std::vector::iterator it = tlist.begin(); it != tlist.end(); it++) + for(std::vector::iterator it = tlist.begin(); it != tlist.end(); ++it) { ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it * radius); } diff --git a/code/X3D/X3DImporter_Networking.cpp b/code/X3D/X3DImporter_Networking.cpp index 89010ae08..a7a200675 100644 --- a/code/X3D/X3DImporter_Networking.cpp +++ b/code/X3D/X3DImporter_Networking.cpp @@ -93,7 +93,7 @@ void X3DImporter::ParseNode_Networking_Inline() // at this place new group mode created and made current, so we can name it. if(!def.empty()) NodeElement_Cur->ID = def; - if(load && (url.size() > 0)) + if(load && !url.empty()) { std::string full_path = mpIOHandler->CurrentDirectory() + url.front(); diff --git a/code/X3D/X3DImporter_Postprocess.cpp b/code/X3D/X3DImporter_Postprocess.cpp index e7686b41e..e113b1bad 100644 --- a/code/X3D/X3DImporter_Postprocess.cpp +++ b/code/X3D/X3DImporter_Postprocess.cpp @@ -81,7 +81,7 @@ aiMatrix4x4 X3DImporter::PostprocessHelper_Matrix_GlobalToCurrent() const } // multiplicate all matrices in reverse order - for(std::list::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); rit++) out_matr = out_matr * (*rit); + for(std::list::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); ++rit) out_matr = out_matr * (*rit); return out_matr; } @@ -89,7 +89,7 @@ aiMatrix4x4 X3DImporter::PostprocessHelper_Matrix_GlobalToCurrent() const void X3DImporter::PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list& pList) const { // walk through childs and find for metadata. - for(std::list::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++) + for(std::list::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); ++el_it) { if(((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaBoolean) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaDouble) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaFloat) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaInteger) || @@ -194,7 +194,7 @@ void X3DImporter::Postprocess_BuildMaterial(const CX3DImporter_NodeElement& pNod aiMaterial& taimat = **pMaterial;// creating alias for convenience. // at this point pNodeElement point to node. Walk through childs and add all stored data. - for(std::list::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++) + for(std::list::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); ++el_it) { if((*el_it)->Type == CX3DImporter_NodeElement::ENET_Material) { @@ -255,7 +255,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle std::vector tarr; tarr.reserve(tnemesh.Vertices.size()); - for(std::list::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); it++) tarr.push_back(*it); + for(std::list::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); ++it) tarr.push_back(*it); *pMesh = StandardShapes::MakeMesh(tarr, static_cast(tnemesh.NumIndices));// create mesh from vertices using Assimp help. return;// mesh is build, nothing to do anymore. @@ -273,7 +273,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle std::vector tarr; tarr.reserve(tnemesh.Vertices.size()); - for(std::list::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); it++) tarr.push_back(*it); + for(std::list::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); ++it) tarr.push_back(*it); *pMesh = StandardShapes::MakeMesh(tarr, static_cast(tnemesh.NumIndices));// create mesh from vertices using Assimp help. @@ -438,7 +438,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size()); for(std::list::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin(); - it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); it++) + it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); ++it) { vec_copy.push_back(*it); } @@ -544,7 +544,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size()); for(std::list::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin(); - it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); it++) + it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); ++it) { vec_copy.push_back(*it); } @@ -554,7 +554,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle } // copy additional information from children - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) + for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) { ai_assert(*pMesh); if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) @@ -580,7 +580,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience // at first search for node and create mesh. - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) + for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) { if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) { @@ -589,7 +589,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle } // copy additional information from children - for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) + for(std::list::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it) { ai_assert(*pMesh); if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) @@ -639,16 +639,16 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle } else { - for(size_t i = 0; i < (size_t)tne_group.Choice; i++) chit_begin++;// forward iterator to chosen node. + for(size_t i = 0; i < (size_t)tne_group.Choice; i++) ++chit_begin;// forward iterator to chosen node. chit_end = chit_begin; - chit_end++;// point end iterator to next element after chosen node. + ++chit_end;// point end iterator to next element after chosen node. } }// if(tne_group.UseChoice) }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Group) // Reserve memory for fast access and check children. - for(std::list::const_iterator it = chit_begin; it != chit_end; it++) + for(std::list::const_iterator it = chit_begin; it != chit_end; ++it) {// in this loop we do not read metadata because it's already read at begin. if((*it)->Type == CX3DImporter_NodeElement::ENET_Group) { @@ -677,7 +677,7 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle }// for(std::list::const_iterator it = chit_begin; it != chit_end; it++) // copy data about children and meshes to aiNode. - if(SceneNode_Child.size() > 0) + if(!SceneNode_Child.empty()) { std::list::const_iterator it = SceneNode_Child.begin(); @@ -686,7 +686,7 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle for(size_t i = 0; i < pSceneNode.mNumChildren; i++) pSceneNode.mChildren[i] = *it++; } - if(SceneNode_Mesh.size() > 0) + if(!SceneNode_Mesh.empty()) { std::list::const_iterator it = SceneNode_Mesh.begin(); @@ -706,7 +706,7 @@ void X3DImporter::Postprocess_BuildShape(const CX3DImporter_NodeElement_Shape& p CX3DImporter_NodeElement::EType mesh_type = CX3DImporter_NodeElement::ENET_Invalid; unsigned int mat_ind = 0; - for(std::list::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); it++) + for(std::list::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); ++it) { if(PostprocessHelper_ElementIsMesh((*it)->Type)) { @@ -779,7 +779,7 @@ void X3DImporter::Postprocess_CollectMetadata(const CX3DImporter_NodeElement& pN // copy collected metadata to output node. pSceneNode.mMetaData = aiMetadata::Alloc( static_cast(meta_list.size()) ); meta_idx = 0; - for(std::list::const_iterator it = meta_list.begin(); it != meta_list.end(); it++, meta_idx++) + for(std::list::const_iterator it = meta_list.begin(); it != meta_list.end(); ++it, ++meta_idx) { CX3DImporter_NodeElement_Meta* cur_meta = (CX3DImporter_NodeElement_Meta*)*it; diff --git a/code/X3D/X3DImporter_Rendering.cpp b/code/X3D/X3DImporter_Rendering.cpp index d0c58030d..6e95c9441 100644 --- a/code/X3D/X3DImporter_Rendering.cpp +++ b/code/X3D/X3DImporter_Rendering.cpp @@ -295,7 +295,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet() ne_alias.CoordIndex.clear(); int counter = 0; int32_t idx[3]; - for(std::vector::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++) + for(std::vector::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it) { idx[2] = *idx_it; if (idx[2] < 0) @@ -413,7 +413,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleSet() ne_alias.CoordIndex.clear(); int counter = 0; int32_t idx[3]; - for(std::vector::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++) + for(std::vector::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it) { idx[counter++] = *idx_it; if (counter > 2) @@ -519,7 +519,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet() ne_alias.CoordIndex.clear(); int counter = 0; int32_t idx[3]; - for(std::vector::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++) + for(std::vector::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it) { idx[2] = *idx_it; if (idx[2] < 0) @@ -617,7 +617,7 @@ void X3DImporter::ParseNode_Rendering_LineSet() size_t coord_num = 0; ne_alias.CoordIndex.clear(); - for(std::vector::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) + for(std::vector::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); ++vc_it) { if(*vc_it < 2) throw DeadlyImportError("LineSet. vertexCount shall be greater than or equal to two."); @@ -765,7 +765,7 @@ void X3DImporter::ParseNode_Rendering_TriangleFanSet() // assign indices for first triangle coord_num_first = 0; coord_num_prev = 1; - for(std::vector::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) + for(std::vector::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); ++vc_it) { if(*vc_it < 3) throw DeadlyImportError("TriangleFanSet. fanCount shall be greater than or equal to three."); @@ -956,7 +956,7 @@ void X3DImporter::ParseNode_Rendering_TriangleStripSet() ne_alias.CoordIndex.clear(); coord_num_sb = 0; - for(std::vector::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) + for(std::vector::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); ++vc_it) { if(*vc_it < 3) throw DeadlyImportError("TriangleStripSet. stripCount shall be greater than or equal to three."); diff --git a/code/X3D/X3DImporter_Texturing.cpp b/code/X3D/X3DImporter_Texturing.cpp index b4e42025a..2eaf3e6bc 100644 --- a/code/X3D/X3DImporter_Texturing.cpp +++ b/code/X3D/X3DImporter_Texturing.cpp @@ -89,7 +89,7 @@ void X3DImporter::ParseNode_Texturing_ImageTexture() ((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatS = repeatS; ((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatT = repeatT; // Attribute "url" can contain list of strings. But we need only one - first. - if(url.size() > 0) + if(!url.empty()) ((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = url.front(); else ((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = ""; diff --git a/code/glTF2/glTF2Importer.cpp b/code/glTF2/glTF2Importer.cpp index c6e998b3a..eacf57c89 100644 --- a/code/glTF2/glTF2Importer.cpp +++ b/code/glTF2/glTF2Importer.cpp @@ -1041,7 +1041,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl delete[] values; } else if (node.rotation.isPresent) { anim->mNumRotationKeys = 1; - anim->mRotationKeys = new aiQuatKey(); + anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys]; anim->mRotationKeys->mTime = 0.f; anim->mRotationKeys->mValue.x = node.rotation.value[0]; anim->mRotationKeys->mValue.y = node.rotation.value[1]; @@ -1064,7 +1064,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl delete[] values; } else if (node.scale.isPresent) { anim->mNumScalingKeys = 1; - anim->mScalingKeys = new aiVectorKey(); + anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys]; anim->mScalingKeys->mTime = 0.f; anim->mScalingKeys->mValue.x = node.scale.value[0]; anim->mScalingKeys->mValue.y = node.scale.value[1]; @@ -1130,6 +1130,7 @@ void glTF2Importer::ImportAnimations(glTF2::Asset& r) // Use the latest keyframe for the duration of the animation double maxDuration = 0; + unsigned int maxNumberOfKeys = 0; for (unsigned int j = 0; j < ai_anim->mNumChannels; ++j) { auto chan = ai_anim->mChannels[j]; if (chan->mNumPositionKeys) { @@ -1137,21 +1138,25 @@ void glTF2Importer::ImportAnimations(glTF2::Asset& r) if (lastPosKey.mTime > maxDuration) { maxDuration = lastPosKey.mTime; } + maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumPositionKeys); } if (chan->mNumRotationKeys) { auto lastRotKey = chan->mRotationKeys[chan->mNumRotationKeys - 1]; if (lastRotKey.mTime > maxDuration) { maxDuration = lastRotKey.mTime; } + maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumRotationKeys); } if (chan->mNumScalingKeys) { auto lastScaleKey = chan->mScalingKeys[chan->mNumScalingKeys - 1]; if (lastScaleKey.mTime > maxDuration) { maxDuration = lastScaleKey.mTime; } + maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumScalingKeys); } } ai_anim->mDuration = maxDuration; + ai_anim->mTicksPerSecond = (maxNumberOfKeys > 0 && maxDuration > 0) ? (maxNumberOfKeys / (maxDuration/1000)) : 30; mScene->mAnimations[i] = ai_anim; } diff --git a/code/res/assimp.rc b/code/res/assimp.rc index 14ffdf4f5..daecf9cf5 100644 --- a/code/res/assimp.rc +++ b/code/res/assimp.rc @@ -52,8 +52,8 @@ BEGIN VALUE "FileDescription", "Open Asset Import Library" VALUE "FileVersion", VER_FILEVERSION VALUE "InternalName", "assimp " - VALUE "LegalCopyright", "Copyright (C) 2006-2010" - VALUE "OriginalFilename", "assimpNN.dll" + VALUE "LegalCopyright", "Copyright (C) 2006-2019" + VALUE "OriginalFilename", VER_ORIGINAL_FILENAME_STR VALUE "ProductName", "Open Asset Import Library" VALUE "ProductVersion", VER_FILEVERSION_STR ,0 diff --git a/contrib/gtest/test/gtest-param-test_test.cc b/contrib/gtest/test/gtest-param-test_test.cc index 8b278bb94..8aacfce72 100644 --- a/contrib/gtest/test/gtest-param-test_test.cc +++ b/contrib/gtest/test/gtest-param-test_test.cc @@ -215,7 +215,7 @@ TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) { // Verifies that prefix and postfix operator++() advance an iterator // all the same. it2 = it; - it++; + ++it; ++it2; EXPECT_TRUE(*it == *it2); } diff --git a/include/assimp/BaseImporter.h b/include/assimp/BaseImporter.h index 48dfc8ed8..55f7fe375 100644 --- a/include/assimp/BaseImporter.h +++ b/include/assimp/BaseImporter.h @@ -48,8 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include #include +#include struct aiScene; struct aiImporterDesc; @@ -80,6 +82,10 @@ class IOStream; class ASSIMP_API BaseImporter { friend class Importer; +private: + /* Pushes state into importer for the importer scale */ + virtual void UpdateImporterScale( Importer* pImp ); + public: /** Constructor to be privately used by #Importer */ @@ -132,7 +138,7 @@ public: * a suitable response to the caller. */ aiScene* ReadFile( - const Importer* pImp, + Importer* pImp, const std::string& pFile, IOSystem* pIOHandler ); @@ -161,14 +167,65 @@ public: * some loader features. Importers must provide this information. */ virtual const aiImporterDesc* GetInfo() const = 0; + /** + * Will be called only by scale process when scaling is requested. + */ + virtual void SetFileScale(double scale) + { + fileScale = scale; + } + + virtual double GetFileScale() const + { + return fileScale; + } + + enum ImporterUnits { + M, + MM, + CM, + INCHES, + FEET + }; + + /** + * Assimp Importer + * unit conversions available + * if you need another measurment unit add it below. + * it's currently defined in assimp that we prefer meters. + * */ + std::map importerUnits = { + {ImporterUnits::M, 1}, + {ImporterUnits::CM, 0.01}, + {ImporterUnits::MM, 0.001}, + {ImporterUnits::INCHES, 0.0254}, + {ImporterUnits::FEET, 0.3048} + }; + + virtual void SetApplicationUnits( const ImporterUnits& unit ) + { + importerScale = importerUnits[unit]; + applicationUnits = unit; + } + + virtual const ImporterUnits& GetApplicationUnits() + { + return applicationUnits; + } + // ------------------------------------------------------------------- /** Called by #Importer::GetExtensionList for each loaded importer. * Take the extension list contained in the structure returned by * #GetInfo and insert all file extensions into the given set. * @param extension set to collect file extensions in*/ void GetExtensionList(std::set& extensions); + +protected: + ImporterUnits applicationUnits = ImporterUnits::M; + double importerScale = 1.0; + double fileScale = 1.0; + -protected: // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. The diff --git a/include/assimp/SceneCombiner.h b/include/assimp/SceneCombiner.h index 679a2acea..f69a25f43 100644 --- a/include/assimp/SceneCombiner.h +++ b/include/assimp/SceneCombiner.h @@ -65,6 +65,7 @@ struct aiLight; struct aiMetadata; struct aiBone; struct aiMesh; +struct aiAnimMesh; struct aiAnimation; struct aiNodeAnim; @@ -363,6 +364,7 @@ public: static void Copy (aiMesh** dest, const aiMesh* src); // similar to Copy(): + static void Copy (aiAnimMesh** dest, const aiAnimMesh* src); static void Copy (aiMaterial** dest, const aiMaterial* src); static void Copy (aiTexture** dest, const aiTexture* src); static void Copy (aiAnimation** dest, const aiAnimation* src); diff --git a/include/assimp/config.h.in b/include/assimp/config.h.in index dad43710e..3a6379bf4 100644 --- a/include/assimp/config.h.in +++ b/include/assimp/config.h.in @@ -999,6 +999,13 @@ enum aiComponent # define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT 1.0f #endif // !! AI_DEBONE_THRESHOLD +#define AI_CONFIG_APP_SCALE_KEY "APP_SCALE_FACTOR" + +#if (!defined AI_CONFIG_APP_SCALE_KEY) +# define AI_CONFIG_APP_SCALE_KEY 1.0 +#endif // AI_CONFIG_APP_SCALE_KEY + + // ---------- All the Build/Compile-time defines ------------ /** @brief Specifies if double precision is supported inside assimp diff --git a/include/assimp/scene.h b/include/assimp/scene.h index e973f6c5b..2667db85b 100644 --- a/include/assimp/scene.h +++ b/include/assimp/scene.h @@ -58,6 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "metadata.h" #ifdef __cplusplus +# include extern "C" { #endif diff --git a/revision.h.in b/revision.h.in index 0ad58feb7..6d09afbc6 100644 --- a/revision.h.in +++ b/revision.h.in @@ -13,6 +13,16 @@ #define STR(x) STR_HELP(x) #define VER_FILEVERSION VER_MAJOR,VER_MINOR,VER_PATCH,VER_BUILD +#if (GitVersion == 0) #define VER_FILEVERSION_STR STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD) +#else +#define VER_FILEVERSION_STR STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD) " (Commit @GIT_COMMIT_HASH@)" +#endif + +#ifdef NDEBUG +#define VER_ORIGINAL_FILENAME_STR "assimp@LIBRARY_SUFFIX@.dll" +#else +#define VER_ORIGINAL_FILENAME_STR "assimp@LIBRARY_SUFFIX@@CMAKE_DEBUG_POSTFIX@.dll" +#endif // NDEBUG #endif // ASSIMP_REVISION_H_INC diff --git a/samples/SimpleOpenGL/Sample_SimpleOpenGL.c b/samples/SimpleOpenGL/Sample_SimpleOpenGL.c index 2dec5bc01..085b95516 100644 --- a/samples/SimpleOpenGL/Sample_SimpleOpenGL.c +++ b/samples/SimpleOpenGL/Sample_SimpleOpenGL.c @@ -26,9 +26,9 @@ #include /* the global Assimp scene object */ -const struct aiScene* scene = NULL; +const C_STRUCT aiScene* scene = NULL; GLuint scene_list = 0; -struct aiVector3D scene_min, scene_max, scene_center; +C_STRUCT aiVector3D scene_min, scene_max, scene_center; /* current rotation angle */ static float angle = 0.f; @@ -49,22 +49,22 @@ void reshape(int width, int height) } /* ---------------------------------------------------------------------------- */ -void get_bounding_box_for_node (const struct aiNode* nd, - struct aiVector3D* min, - struct aiVector3D* max, - struct aiMatrix4x4* trafo +void get_bounding_box_for_node (const amTransformation); for (; n < nd->mNumMeshes; ++n) { - const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]]; + const C_STRUCT aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]]; for (t = 0; t < mesh->mNumVertices; ++t) { - struct aiVector3D tmp = mesh->mVertices[t]; + C_STRUCT aiVector3D tmp = mesh->mVertices[t]; aiTransformVecByMatrix4(&tmp,trafo); min->x = aisgl_min(min->x,tmp.x); @@ -84,9 +84,9 @@ void get_bounding_box_for_node (const struct aiNode* nd, } /* ---------------------------------------------------------------------------- */ -void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max) +void get_bounding_box(C_STRUCT aiVector3D* min, C_STRUCT aiVector3D* max) { - struct aiMatrix4x4 trafo; + aiMatrix4x4 trafo; aiIdentityMatrix4(&trafo); min->x = min->y = min->z = 1e10f; @@ -95,7 +95,7 @@ void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max) } /* ---------------------------------------------------------------------------- */ -void color4_to_float4(const struct aiColor4D *c, float f[4]) +void color4_to_float4(const C_STRUCT aiColor4D *c, float f[4]) { f[0] = c->r; f[1] = c->g; @@ -113,16 +113,16 @@ void set_float4(float f[4], float a, float b, float c, float d) } /* ---------------------------------------------------------------------------- */ -void apply_material(const struct aiMaterial *mtl) +void apply_material(const C_STRUCT aiMaterial *mtl) { float c[4]; GLenum fill_mode; int ret1, ret2; - struct aiColor4D diffuse; - struct aiColor4D specular; - struct aiColor4D ambient; - struct aiColor4D emission; + C_STRUCT aiColor4D diffuse; + C_STRUCT aiColor4D specular; + C_STRUCT aiColor4D ambient; + C_STRUCT aiColor4D emission; ai_real shininess, strength; int two_sided; int wireframe; @@ -179,11 +179,11 @@ void apply_material(const struct aiMaterial *mtl) } /* ---------------------------------------------------------------------------- */ -void recursive_render (const struct aiScene *sc, const struct aiNode* nd) +void recursive_render (const C_STRUCT aiScene *sc, const C_STRUCT aiNode* nd) { unsigned int i; unsigned int n = 0, t; - struct aiMatrix4x4 m = nd->mTransformation; + C_STRUCT aiMatrix4x4 m = nd->mTransformation; /* update transform */ aiTransposeMatrix4(&m); @@ -192,7 +192,7 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd) /* draw all meshes assigned to this node */ for (; n < nd->mNumMeshes; ++n) { - const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]]; + const C_STRUCT aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]]; apply_material(sc->mMaterials[mesh->mMaterialIndex]); @@ -203,7 +203,7 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd) } for (t = 0; t < mesh->mNumFaces; ++t) { - const struct aiFace* face = &mesh->mFaces[t]; + const C_STRUCT aiFace* face = &mesh->mFaces[t]; GLenum face_mode; switch(face->mNumIndices) { @@ -324,7 +324,7 @@ int loadasset (const char* path) /* ---------------------------------------------------------------------------- */ int main(int argc, char **argv) { - struct aiLogStream stream; + C_STRUCT aiLogStream stream; glutInitWindowSize(900,600); glutInitWindowPosition(100,100); diff --git a/test/models/FBX/close_to_identity_transforms.fbx b/test/models/FBX/close_to_identity_transforms.fbx new file mode 100644 index 000000000..c0b990282 --- /dev/null +++ b/test/models/FBX/close_to_identity_transforms.fbx @@ -0,0 +1,855 @@ +; FBX 7.5.0 project file +; ---------------------------------------------------- + +FBXHeaderExtension: { + FBXHeaderVersion: 1003 + FBXVersion: 7500 + CreationTimeStamp: { + Version: 1000 + Year: 2019 + Month: 5 + Day: 14 + Hour: 17 + Minute: 27 + Second: 42 + Millisecond: 70 + } + Creator: "FBX SDK/FBX Plugins version 2018.1.1" + SceneInfo: "SceneInfo::GlobalInfo", "UserData" { + Type: "UserData" + Version: 100 + MetaData: { + Version: 100 + Title: "" + Subject: "" + Author: "" + Keywords: "" + Revision: "" + Comment: "" + } + Properties70: { + P: "DocumentUrl", "KString", "Url", "", "U:\Some\Absolute\Path\cubes_with_mirroring_and_pivot.fbx" + P: "SrcDocumentUrl", "KString", "Url", "", "U:\Some\Absolute\Path\cubes_with_mirroring_and_pivot.fbx" + P: "Original", "Compound", "", "" + P: "Original|ApplicationVendor", "KString", "", "", "Autodesk" + P: "Original|ApplicationName", "KString", "", "", "Maya" + P: "Original|ApplicationVersion", "KString", "", "", "201800" + P: "Original|DateTime_GMT", "DateTime", "", "", "14/05/2019 16:27:42.070" + P: "Original|FileName", "KString", "", "", "U:\Some\Absolute\Path\cubes_with_mirroring_and_pivot.fbx" + P: "LastSaved", "Compound", "", "" + P: "LastSaved|ApplicationVendor", "KString", "", "", "Autodesk" + P: "LastSaved|ApplicationName", "KString", "", "", "Maya" + P: "LastSaved|ApplicationVersion", "KString", "", "", "201800" + P: "LastSaved|DateTime_GMT", "DateTime", "", "", "14/05/2019 16:27:42.070" + P: "Original|ApplicationActiveProject", "KString", "", "", "U:\Some\Absolute\Path" + } + } +} +GlobalSettings: { + Version: 1000 + Properties70: { + P: "UpAxis", "int", "Integer", "",1 + P: "UpAxisSign", "int", "Integer", "",1 + P: "FrontAxis", "int", "Integer", "",2 + P: "FrontAxisSign", "int", "Integer", "",1 + P: "CoordAxis", "int", "Integer", "",0 + P: "CoordAxisSign", "int", "Integer", "",1 + P: "OriginalUpAxis", "int", "Integer", "",1 + P: "OriginalUpAxisSign", "int", "Integer", "",1 + P: "UnitScaleFactor", "double", "Number", "",100 + P: "OriginalUnitScaleFactor", "double", "Number", "",1 + P: "AmbientColor", "ColorRGB", "Color", "",0,0,0 + P: "DefaultCamera", "KString", "", "", "Producer Perspective" + P: "TimeMode", "enum", "", "",11 + P: "TimeProtocol", "enum", "", "",2 + P: "SnapOnFrameMode", "enum", "", "",0 + P: "TimeSpanStart", "KTime", "Time", "",1924423250 + P: "TimeSpanStop", "KTime", "Time", "",384884650000 + P: "CustomFrameRate", "double", "Number", "",-1 + P: "TimeMarker", "Compound", "", "" + P: "CurrentTimeMarker", "int", "Integer", "",-1 + } +} + +; Documents Description +;------------------------------------------------------------------ + +Documents: { + Count: 1 + Document: 1827132552544, "", "Scene" { + Properties70: { + P: "SourceObject", "object", "", "" + P: "ActiveAnimStackName", "KString", "", "", "Take 001" + } + RootNode: 0 + } +} + +; Document References +;------------------------------------------------------------------ + +References: { +} + +; Object definitions +;------------------------------------------------------------------ + +Definitions: { + Version: 100 + Count: 13 + ObjectType: "GlobalSettings" { + Count: 1 + } + ObjectType: "AnimationStack" { + Count: 1 + PropertyTemplate: "FbxAnimStack" { + Properties70: { + P: "Description", "KString", "", "", "" + P: "LocalStart", "KTime", "Time", "",0 + P: "LocalStop", "KTime", "Time", "",0 + P: "ReferenceStart", "KTime", "Time", "",0 + P: "ReferenceStop", "KTime", "Time", "",0 + } + } + } + ObjectType: "AnimationLayer" { + Count: 1 + PropertyTemplate: "FbxAnimLayer" { + Properties70: { + P: "Weight", "Number", "", "A",100 + P: "Mute", "bool", "", "",0 + P: "Solo", "bool", "", "",0 + P: "Lock", "bool", "", "",0 + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "BlendMode", "enum", "", "",0 + P: "RotationAccumulationMode", "enum", "", "",0 + P: "ScaleAccumulationMode", "enum", "", "",0 + P: "BlendModeBypass", "ULongLong", "", "",0 + } + } + } + ObjectType: "Geometry" { + Count: 4 + PropertyTemplate: "FbxMesh" { + Properties70: { + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "BBoxMin", "Vector3D", "Vector", "",0,0,0 + P: "BBoxMax", "Vector3D", "Vector", "",0,0,0 + P: "Primary Visibility", "bool", "", "",1 + P: "Casts Shadows", "bool", "", "",1 + P: "Receive Shadows", "bool", "", "",1 + } + } + } + ObjectType: "Material" { + Count: 2 + PropertyTemplate: "FbxSurfaceLambert" { + Properties70: { + P: "ShadingModel", "KString", "", "", "Lambert" + P: "MultiLayer", "bool", "", "",0 + P: "EmissiveColor", "Color", "", "A",0,0,0 + P: "EmissiveFactor", "Number", "", "A",1 + P: "AmbientColor", "Color", "", "A",0.2,0.2,0.2 + P: "AmbientFactor", "Number", "", "A",1 + P: "DiffuseColor", "Color", "", "A",0.8,0.8,0.8 + P: "DiffuseFactor", "Number", "", "A",1 + P: "Bump", "Vector3D", "Vector", "",0,0,0 + P: "NormalMap", "Vector3D", "Vector", "",0,0,0 + P: "BumpFactor", "double", "Number", "",1 + P: "TransparentColor", "Color", "", "A",0,0,0 + P: "TransparencyFactor", "Number", "", "A",0 + P: "DisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "DisplacementFactor", "double", "Number", "",1 + P: "VectorDisplacementColor", "ColorRGB", "Color", "",0,0,0 + P: "VectorDisplacementFactor", "double", "Number", "",1 + } + } + } + ObjectType: "Model" { + Count: 4 + PropertyTemplate: "FbxNode" { + Properties70: { + P: "QuaternionInterpolate", "enum", "", "",0 + P: "RotationOffset", "Vector3D", "Vector", "",0,0,0 + P: "RotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "ScalingOffset", "Vector3D", "Vector", "",0,0,0 + P: "ScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "TranslationActive", "bool", "", "",0 + P: "TranslationMin", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMax", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMinX", "bool", "", "",0 + P: "TranslationMinY", "bool", "", "",0 + P: "TranslationMinZ", "bool", "", "",0 + P: "TranslationMaxX", "bool", "", "",0 + P: "TranslationMaxY", "bool", "", "",0 + P: "TranslationMaxZ", "bool", "", "",0 + P: "RotationOrder", "enum", "", "",0 + P: "RotationSpaceForLimitOnly", "bool", "", "",0 + P: "RotationStiffnessX", "double", "Number", "",0 + P: "RotationStiffnessY", "double", "Number", "",0 + P: "RotationStiffnessZ", "double", "Number", "",0 + P: "AxisLen", "double", "Number", "",10 + P: "PreRotation", "Vector3D", "Vector", "",0,0,0 + P: "PostRotation", "Vector3D", "Vector", "",0,0,0 + P: "RotationActive", "bool", "", "",0 + P: "RotationMin", "Vector3D", "Vector", "",0,0,0 + P: "RotationMax", "Vector3D", "Vector", "",0,0,0 + P: "RotationMinX", "bool", "", "",0 + P: "RotationMinY", "bool", "", "",0 + P: "RotationMinZ", "bool", "", "",0 + P: "RotationMaxX", "bool", "", "",0 + P: "RotationMaxY", "bool", "", "",0 + P: "RotationMaxZ", "bool", "", "",0 + P: "InheritType", "enum", "", "",0 + P: "ScalingActive", "bool", "", "",0 + P: "ScalingMin", "Vector3D", "Vector", "",0,0,0 + P: "ScalingMax", "Vector3D", "Vector", "",1,1,1 + P: "ScalingMinX", "bool", "", "",0 + P: "ScalingMinY", "bool", "", "",0 + P: "ScalingMinZ", "bool", "", "",0 + P: "ScalingMaxX", "bool", "", "",0 + P: "ScalingMaxY", "bool", "", "",0 + P: "ScalingMaxZ", "bool", "", "",0 + P: "GeometricTranslation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricRotation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricScaling", "Vector3D", "Vector", "",1,1,1 + P: "MinDampRangeX", "double", "Number", "",0 + P: "MinDampRangeY", "double", "Number", "",0 + P: "MinDampRangeZ", "double", "Number", "",0 + P: "MaxDampRangeX", "double", "Number", "",0 + P: "MaxDampRangeY", "double", "Number", "",0 + P: "MaxDampRangeZ", "double", "Number", "",0 + P: "MinDampStrengthX", "double", "Number", "",0 + P: "MinDampStrengthY", "double", "Number", "",0 + P: "MinDampStrengthZ", "double", "Number", "",0 + P: "MaxDampStrengthX", "double", "Number", "",0 + P: "MaxDampStrengthY", "double", "Number", "",0 + P: "MaxDampStrengthZ", "double", "Number", "",0 + P: "PreferedAngleX", "double", "Number", "",0 + P: "PreferedAngleY", "double", "Number", "",0 + P: "PreferedAngleZ", "double", "Number", "",0 + P: "LookAtProperty", "object", "", "" + P: "UpVectorProperty", "object", "", "" + P: "Show", "bool", "", "",1 + P: "NegativePercentShapeSupport", "bool", "", "",1 + P: "DefaultAttributeIndex", "int", "Integer", "",-1 + P: "Freeze", "bool", "", "",0 + P: "LODBox", "bool", "", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0,0,0 + P: "Lcl Rotation", "Lcl Rotation", "", "A",0,0,0 + P: "Lcl Scaling", "Lcl Scaling", "", "A",1,1,1 + P: "Visibility", "Visibility", "", "A",1 + P: "Visibility Inheritance", "Visibility Inheritance", "", "",1 + } + } + } +} + +; Object properties +;------------------------------------------------------------------ + +Objects: { + Geometry: 1827080157856, "Geometry::", "Mesh" { + Vertices: *24 { + a: -0.5,-0.5,0.5,0.5,-0.5,0.5,-0.5,0.5,0.5,0.5,0.5,0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5 + } + PolygonVertexIndex: *24 { + a: 0,1,3,-3,2,3,5,-5,4,5,7,-7,6,7,1,-1,1,7,5,-4,6,0,2,-5 + } + Edges: *12 { + a: 0,1,2,3,5,6,7,9,10,11,13,15 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Normals: *72 { + a: 0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0 + } + NormalsW: *24 { + a: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + } + } + LayerElementBinormal: 0 { + Version: 102 + Name: "map1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Binormals: *72 { + a: 0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,-0,1,0,-0,1,0,0,1,-0,-0,1,0,0,1,0,0,1,0,0,1,0,0,1,0 + } + BinormalsW: *24 { + a: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + } + + } + LayerElementTangent: 0 { + Version: 102 + Name: "map1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Tangents: *72 { + a: 1,-0,-0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,0,0,-1,0,0,-1,0,-0,-1,0,0,-1,0,-0,1,0,-0,1,0,-0,1,0,-0,1 + } + TangentsW: *24 { + a: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "map1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *28 { + a: 0.375,0,0.625,0,0.375,0.25,0.625,0.25,0.375,0.5,0.625,0.5,0.375,0.75,0.625,0.75,0.375,1,0.625,1,0.875,0,0.875,0.25,0.125,0,0.125,0.25 + } + UVIndex: *24 { + a: 0,1,3,2,2,3,5,4,4,5,7,6,6,7,9,8,1,10,11,3,12,0,2,13 + } + } + LayerElementSmoothing: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByEdge" + ReferenceInformationType: "Direct" + Smoothing: *12 { + a: 0,0,0,0,0,0,0,0,0,0,0,0 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "AllSame" + ReferenceInformationType: "IndexToDirect" + Materials: *1 { + a: 0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementBinormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTangent" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementSmoothing" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Geometry: 1827080155296, "Geometry::", "Mesh" { + Vertices: *24 { + a: -0.5,-0.5,0.5,0.5,-0.5,0.5,-0.5,0.5,0.5,0.5,0.5,0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5 + } + PolygonVertexIndex: *24 { + a: 0,1,3,-3,2,3,5,-5,4,5,7,-7,6,7,1,-1,1,7,5,-4,6,0,2,-5 + } + Edges: *12 { + a: 0,1,2,3,5,6,7,9,10,11,13,15 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Normals: *72 { + a: 0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0 + } + NormalsW: *24 { + a: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + } + } + LayerElementBinormal: 0 { + Version: 102 + Name: "map1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Binormals: *72 { + a: 0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,-0,1,0,-0,1,0,0,1,-0,-0,1,0,0,1,0,0,1,0,0,1,0,0,1,0 + } + BinormalsW: *24 { + a: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + } + + } + LayerElementTangent: 0 { + Version: 102 + Name: "map1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Tangents: *72 { + a: 1,-0,-0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,0,0,-1,0,0,-1,0,-0,-1,0,0,-1,0,-0,1,0,-0,1,0,-0,1,0,-0,1 + } + TangentsW: *24 { + a: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "map1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *28 { + a: 0.375,0,0.625,0,0.375,0.25,0.625,0.25,0.375,0.5,0.625,0.5,0.375,0.75,0.625,0.75,0.375,1,0.625,1,0.875,0,0.875,0.25,0.125,0,0.125,0.25 + } + UVIndex: *24 { + a: 0,1,3,2,2,3,5,4,4,5,7,6,6,7,9,8,1,10,11,3,12,0,2,13 + } + } + LayerElementSmoothing: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByEdge" + ReferenceInformationType: "Direct" + Smoothing: *12 { + a: 0,0,0,0,0,0,0,0,0,0,0,0 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "AllSame" + ReferenceInformationType: "IndexToDirect" + Materials: *1 { + a: 0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementBinormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTangent" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementSmoothing" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Geometry: 1827080156320, "Geometry::", "Mesh" { + Vertices: *24 { + a: -0.5,-0.5,0.5,0.5,-0.5,0.5,-0.5,0.5,0.5,0.5,0.5,0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5 + } + PolygonVertexIndex: *24 { + a: 0,1,3,-3,2,3,5,-5,4,5,7,-7,6,7,1,-1,1,7,5,-4,6,0,2,-5 + } + Edges: *12 { + a: 0,1,2,3,5,6,7,9,10,11,13,15 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Normals: *72 { + a: 0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0 + } + NormalsW: *24 { + a: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + } + } + LayerElementBinormal: 0 { + Version: 102 + Name: "map1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Binormals: *72 { + a: 0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,-0,1,0,-0,1,0,0,1,-0,-0,1,0,0,1,0,0,1,0,0,1,0,0,1,0 + } + BinormalsW: *24 { + a: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + } + + } + LayerElementTangent: 0 { + Version: 102 + Name: "map1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Tangents: *72 { + a: 1,-0,-0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,0,0,-1,0,0,-1,0,-0,-1,0,0,-1,0,-0,1,0,-0,1,0,-0,1,0,-0,1 + } + TangentsW: *24 { + a: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "map1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *28 { + a: 0.375,0,0.625,0,0.375,0.25,0.625,0.25,0.375,0.5,0.625,0.5,0.375,0.75,0.625,0.75,0.375,1,0.625,1,0.875,0,0.875,0.25,0.125,0,0.125,0.25 + } + UVIndex: *24 { + a: 0,1,3,2,2,3,5,4,4,5,7,6,6,7,9,8,1,10,11,3,12,0,2,13 + } + } + LayerElementSmoothing: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByEdge" + ReferenceInformationType: "Direct" + Smoothing: *12 { + a: 0,0,0,0,0,0,0,0,0,0,0,0 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "AllSame" + ReferenceInformationType: "IndexToDirect" + Materials: *1 { + a: 0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementBinormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTangent" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementSmoothing" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Geometry: 1827080139424, "Geometry::", "Mesh" { + Vertices: *588 { + a: -0.499999970197678,-0.5,0.5,0.500000059604645,-0.5,0.5,-0.499999970197678,0.5,0.5,0.500000059604645,0.5,0.5,-0.499999970197678,0.5,-0.49999988079071,0.500000059604645,0.5,-0.49999988079071,-0.499999970197678,-0.5,-0.49999988079071,0.500000059604645,-0.5,-0.49999988079071,0,0,0.5,0,-0.5,0.5,0.500000059604645,0,0.5,0,0.5,0.5,-0.499999970197678,0,0.5,0,0.5,1.19209289550781e-07,0.500000059604645,0.5,1.19209289550781e-07,0,0.5,-0.49999988079071,-0.499999970197678,0.5,1.19209289550781e-07,0,0,-0.49999988079071,0.500000059604645,0,-0.49999988079071,0,-0.5,-0.49999988079071,-0.499999970197678,0,-0.49999988079071,0,-0.5,1.19209289550781e-07,0.500000059604645,-0.5,1.19209289550781e-07,-0.499999970197678,-0.5,1.19209289550781e-07,0.500000059604645,0,1.19209289550781e-07,-0.499999970197678,0,1.19209289550781e-07,-0.25,-0.25,0.5,-0.499999970197678,-0.25,0.5,-0.25,-0.5,0.5,0,-0.25,0.5,-0.25,0,0.5,-0.25,0.5,0.25,-0.499999970197678,0.5,0.25,-0.25,0.5,0.5,0,0.5,0.25,-0.25,0.5,1.19209289550781e-07,-0.25,0.25,-0.49999988079071,-0.499999970197678,0.25,-0.49999988079071,-0.25,0.5,-0.49999988079071,0,0.25,-0.49999988079071,-0.25,0,-0.49999988079071,-0.25,-0.5,-0.24999988079071,-0.499999970197678,-0.5,-0.24999988079071,-0.25,-0.5,-0.49999988079071,0,-0.5,-0.24999988079071,-0.25,-0.5,1.19209289550781e-07,0.500000059604645,-0.25,0.25,0.500000059604645,-0.25,0.5,0.500000059604645,-0.5,0.25,0.500000059604645,-0.25,1.19209289550781e-07,0.500000059604645,0,0.25,-0.499999970197678,-0.25,-0.24999988079071,-0.499999970197678,-0.25,-0.49999988079071,-0.499999970197678,-0.25,1.19209289550781e-07,-0.499999970197678,0,-0.24999988079071,0.250000059604645,-0.25,0.5,0.250000059604645,-0.5,0.5,0.250000059604645,0,0.5,0.250000059604645,0.25,0.5,0.500000059604645,0.25,0.5,0.250000059604645,0.5,0.5,0,0.25,0.5,-0.25,0.25,0.5,-0.499999970197678,0.25,0.5,0.250000059604645,0.5,0.25,0.500000059604645,0.5,0.25,0.250000059604645,0.5,1.19209289550781e-07,0.250000059604645,0.5,-0.24999988079071,0.500000059604645,0.5,-0.24999988079071,0.250000059604645,0.5,-0.49999988079071, +0,0.5,-0.24999988079071,-0.25,0.5,-0.24999988079071,-0.499999970197678,0.5,-0.24999988079071,0.250000059604645,0.25,-0.49999988079071,0.500000059604645,0.25,-0.49999988079071,0.250000059604645,0,-0.49999988079071,0.250000059604645,-0.25,-0.49999988079071,0.500000059604645,-0.25,-0.49999988079071,0.250000059604645,-0.5,-0.49999988079071,0,-0.25,-0.49999988079071,-0.25,-0.25,-0.49999988079071,0.250000059604645,-0.5,-0.24999988079071,0.500000059604645,-0.5,-0.24999988079071,0.250000059604645,-0.5,1.19209289550781e-07,0.250000059604645,-0.5,0.25,0,-0.5,0.25,-0.25,-0.5,0.25,-0.499999970197678,-0.5,0.25,0.500000059604645,-0.25,-0.24999988079071,0.500000059604645,0,-0.24999988079071,0.500000059604645,0.25,-0.24999988079071,0.500000059604645,0.25,1.19209289550781e-07,0.500000059604645,0.25,0.25,-0.499999970197678,-0.25,0.25,-0.499999970197678,0,0.25,-0.499999970197678,0.25,0.25,-0.499999970197678,0.25,1.19209289550781e-07,-0.499999970197678,0.25,-0.24999988079071,-0.594913899898529,0,0.594913899898529,-0.152911216020584,0,0.714658200740814,-0.594913899898529,-0.152911216020584,0.594913899898529,-0.152911216020584,-0.152911216020584,0.714658200740814,-0.594913899898529,0.594913899898529,7.29137497046395e-08,-0.152911216020584,0.714658200740814,7.29137497046395e-08,-0.594913899898529,0.594913899898529,0.152911216020584,-0.152911216020584,0.714658200740814,0.152911216020584,-0.594913899898529,0,-0.594913899898529,-0.152911216020584,0,-0.714658200740814,-0.594913899898529,0.152911216020584,-0.594913899898529,-0.152911216020584,0.152911216020584,-0.714658200740814,-0.594913899898529,-0.594913899898529,7.29137497046395e-08,-0.152911216020584,-0.714658200740814,7.29137497046395e-08,-0.594913899898529,-0.594913899898529,-0.152911216020584,-0.152911216020584,-0.714658200740814,-0.152911216020584,0.594913899898529,0,0.594913899898529,0.714658200740814,0,0.152911216020584,0.594913899898529,-0.152911216020584,0.594913899898529,0.714658200740814,-0.152911216020584,0.152911216020584,-0.714658200740814,0,-0.152911216020584,-0.594913899898529,-0.152911216020584,-0.594913899898529, +-0.714658200740814,-0.152911216020584,-0.152911216020584,8.62321627254444e-17,-0.594913899898529,0.594913899898529,8.62321627254444e-17,-0.152911216020584,0.714658200740814,0.152911230921745,-0.594913899898529,0.594913899898529,0.152911230921745,-0.152911216020584,0.714658200740814,0.152911230921745,0,0.714658200740814,0.594913899898529,0.152911216020584,0.594913899898529,0.152911230921745,0.152911216020584,0.714658200740814,8.62321627254444e-17,0.594913899898529,0.594913899898529,8.62321627254444e-17,0.152911216020584,0.714658200740814,-0.152911216020584,0.594913899898529,0.594913899898529,-0.152911216020584,0.152911216020584,0.714658200740814,8.62321627254444e-17,0.714658200740814,0.152911216020584,0.152911230921745,0.594913899898529,0.594913899898529,0.152911230921745,0.714658200740814,0.152911216020584,0.594913899898529,0.594913899898529,7.29137497046395e-08,0.152911230921745,0.714658200740814,7.29137497046395e-08,0.594913899898529,0.594913899898529,-0.152911216020584,0.152911230921745,0.714658200740814,-0.152911216020584,8.62321627254444e-17,0.594913899898529,-0.594913899898529,8.62321627254444e-17,0.714658200740814,-0.152911216020584,-0.152911216020584,0.594913899898529,-0.594913899898529,-0.152911216020584,0.714658200740814,-0.152911216020584,8.62321627254444e-17,0.152911216020584,-0.714658200740814,0.152911230921745,0.594913899898529,-0.594913899898529,0.152911230921745,0.152911216020584,-0.714658200740814,0.594913899898529,0,-0.594913899898529,0.152911230921745,0,-0.714658200740814,0.594913899898529,-0.152911216020584,-0.594913899898529,0.152911230921745,-0.152911216020584,-0.714658200740814,8.62321627254444e-17,-0.594913899898529,-0.594913899898529,8.62321627254444e-17,-0.152911216020584,-0.714658200740814,-0.152911216020584,-0.594913899898529,-0.594913899898529,-0.152911216020584,-0.152911216020584,-0.714658200740814,8.62321627254444e-17,-0.714658200740814,-0.152911216020584,0.152911230921745,-0.594913899898529,-0.594913899898529,0.152911230921745,-0.714658200740814,-0.152911216020584,0.594913899898529,-0.594913899898529,7.29137497046395e-08, +0.152911230921745,-0.714658200740814,7.29137497046395e-08,0.594913899898529,-0.594913899898529,0.152911216020584,0.152911230921745,-0.714658200740814,0.152911216020584,8.62321627254444e-17,-0.714658200740814,0.152911216020584,-0.152911216020584,-0.594913899898529,0.594913899898529,-0.152911216020584,-0.714658200740814,0.152911216020584,0.714658200740814,-0.152911216020584,7.29137497046395e-08,0.594913899898529,-0.594913899898529,-0.152911216020584,0.714658200740814,-0.152911216020584,-0.152911216020584,0.714658200740814,0,-0.152911216020584,0.594913899898529,0.152911216020584,-0.594913899898529,0.714658200740814,0.152911216020584,-0.152911216020584,0.714658200740814,0.152911216020584,7.29137497046395e-08,0.594913899898529,0.594913899898529,0.152911216020584,0.714658200740814,0.152911216020584,0.152911216020584,-0.714658200740814,-0.152911216020584,7.29137497046395e-08,-0.594913899898529,-0.594913899898529,0.152911216020584,-0.714658200740814,-0.152911216020584,0.152911216020584,-0.714658200740814,0,0.152911216020584,-0.594913899898529,0.152911216020584,0.594913899898529,-0.714658200740814,0.152911216020584,0.152911216020584,-0.714658200740814,0.152911216020584,7.29137497046395e-08,-0.594913899898529,0.594913899898529,-0.152911216020584,-0.714658200740814,0.152911216020584,-0.152911216020584,-0.541863918304443,-0.541864037513733,0.541863918304443,8.62321627254444e-17,0,0.714658200740814,-0.541863918304443,0.541863918304443,0.541863918304443,8.62321627254444e-17,0.714658200740814,7.29137497046395e-08,-0.541863918304443,0.541863918304443,-0.541863799095154,8.62321627254444e-17,0,-0.714658200740814,-0.541863918304443,-0.541864037513733,-0.541863799095154,8.62321627254444e-17,-0.714658200740814,7.29137497046395e-08,0.541863977909088,-0.541864037513733,0.541863918304443,0.714658200740814,0,7.29137497046395e-08,-0.714658200740814,0,7.29137497046395e-08,0.541863977909088,0.541863918304443,0.541863918304443,0.541863977909088,0.541863918304443,-0.541863799095154,0.541863977909088,-0.541864037513733,-0.541863799095154 + } + PolygonVertexIndex: *768 { + a: 99,98,100,-102,103,102,104,-106,107,106,108,-110,111,110,112,-114,115,114,116,-118,118,106,119,-121,122,121,123,-125,125,114,126,-128,129,128,130,-132,132,128,133,-135,136,135,137,-139,140,139,141,-143,143,139,144,-146,147,146,148,-150,151,150,152,-154,154,150,155,-157,158,157,159,-161,161,121,162,-164,164,157,165,-167,167,146,168,-170,170,135,171,-173,173,110,174,-176,176,98,177,-179,179,102,180,-182,100,182,162,-102,162,121,122,-102,122,183,99,-102,104,184,130,-106,130,128,132,-106,132,185,103,-106,108,186,141,-110,141,139,143,-110,143,187,107,-110,112,188,152,-114,152,150,154,-114,154,189,111,-114,116,190,159,-118,159,157,164,-118,164,191,115,-118,119,188,112,-121,112,110,173,-121,173,192,118,-121,123,190,116,-125,116,114,125,-125,125,183,122,-125,126,193,133,-128,133,128,129,-128,129,183,125,-128,130,184,177,-132,177,98,99,-132,99,183,129,-132,133,193,171,-135,171,135,136,-135,136,185,132,-135,137,194,144,-139,144,139,140,-139,140,185,136,-139,141,186,180,-143,180,102,103,-143,103,185,140,-143,144,194,168,-146,168,146,147,-146,147,187,143,-146,148,195,155,-150,155,150,151,-150,151,187,147,-150,152,188,119,-154,119,106,107,-154,107,187,151,-154,155,195,165,-157,165,157,158,-157,158,189,154,-157,159,190,123,-161,123,121,161,-161,161,189,158,-161,162,182,174,-164,174,110,111,-164,111,189,161,-164,165,195,148,-167,148,146,167,-167,167,191,164,-167,168,194,137,-170,137,135,170,-170,170,191,167,-170,171,193,126,-173,126,114,115,-173,115,191,170,-173,174,182,100,-176,100,98,176,-176,176,192,173,-176,177,184,104,-179,104,102,179,-179,179,192,176,-179,180,186,108,-182,108,106,118,-182,118,192,179,-182,30,26,27,-13,35,31,32,-17,40,36,37,-21,45,41,42,-24,50,46,47,-11,54,51,52,-21,29,55,56,-10,57,58,59,-11,61,62,33,-12,34,64,60,-12,66,67,68,-15,70,71,38,-16,39,73,69,-16,75,76,77,-19,79,80,43,-20,44,81,78,-20,83,84,48,-23,85,86,28,-10,49,88,82,-23,89,90,74,-19,91,92,65,-15,53,93,87,-24,94,95,63,-13,96,97,72,-17,27,26,28,-1,28,26,29,-10,29,26,30,-9,32,31,33,-3,33,31,34,-12,34,31,35,-14,37,36,38,-5,38,36,39, +-16,39,36,40,-18,42,41,43,-7,43,41,44,-20,44,41,45,-22,47,46,48,-2,48,46,49,-23,49,46,50,-25,52,51,42,-7,42,51,53,-24,53,51,54,-26,56,55,47,-2,47,55,57,-11,57,55,29,-9,59,58,60,-4,60,58,61,-12,61,58,57,-9,33,62,63,-3,63,62,30,-13,30,62,61,-9,60,64,65,-4,65,64,66,-15,66,64,34,-14,68,67,69,-6,69,67,70,-16,70,67,66,-14,38,71,72,-5,72,71,35,-17,35,71,70,-14,69,73,74,-6,74,73,75,-19,75,73,39,-18,77,76,78,-8,78,76,79,-20,79,76,75,-18,43,80,52,-7,52,80,40,-21,40,80,79,-18,78,81,82,-8,82,81,83,-23,83,81,44,-22,48,84,56,-2,56,84,85,-10,85,84,83,-22,28,86,87,-1,87,86,45,-24,45,86,85,-22,82,88,77,-8,77,88,89,-19,89,88,49,-25,74,90,68,-6,68,90,91,-15,91,90,89,-25,65,92,59,-4,59,92,50,-11,50,92,91,-25,87,93,27,-1,27,93,94,-13,94,93,53,-26,63,95,32,-3,32,95,96,-17,96,95,94,-26,72,97,37,-5,37,97,54,-21,54,97,96,-26 + } + Edges: *384 { + a: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,102,104,105,108,109,110,114,116,117,120,121,122,126,128,129,132,133,134,138,140,141,144,145,146,150,152,153,156,158,162,164,165,168,170,174,176,180,181,182,186,188,193,194,198,205,206,210,212,216,217,218,222,224,229,230,234,241,242,246,248,252,253,254,258,260,266,270,277,278,282,284,290,294,296,301,302,306,314,318,320,326,330,332,338,342,350,354,356,362,366,368,374,378,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,481,482,483,485,490,491,493,494,495,497,502,503,505,506,507,509,514,515,517,518,519,521,526,527,529,530,531,533,538,539,541,543,545,550,551,553,555,557,563,565,566,567,569,575,577,578,581,589,590,593,599,601,602,603,605,611,613,614,617,625,626,629,635,637,638,639,641,647,649,653,661,662,665,671,673,677,683,685,686,689,697,701,707,709,713,719,721,725,733,737,743,745,749,755,757,761 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Normals: *2304 { + a: -0.261487126350403,0,0.965206980705261,-0.261487126350403,0,0.965206980705261,-0.261487126350403,0,0.965206980705261,-0.261487126350403,0,0.965206980705261,-0.261487185955048,0.965206921100616,0,-0.261487185955048,0.965206921100616,0,-0.261487185955048,0.965206921100616,0,-0.261487185955048,0.965206921100616,0,-0.261487126350403,0,-0.965206980705261,-0.261487126350403,0,-0.965206980705261,-0.261487126350403,0,-0.965206980705261,-0.261487126350403,0,-0.965206980705261,-0.261487156152725,-0.965206921100616,0,-0.261487156152725,-0.965206921100616,0,-0.261487156152725,-0.965206921100616,0,-0.261487156152725,-0.965206921100616,0,0.965206980705261,0,0.261487185955048,0.965206980705261,0,0.261487185955048,0.965206980705261,0,0.261487185955048,0.965206980705261,0,0.261487185955048,-0.965206980705261,0,-0.261487185955048,-0.965206980705261,0,-0.261487185955048,-0.965206980705261,0,-0.261487185955048,-0.965206980705261,0,-0.261487185955048,0,-0.261487156152725,0.965206921100616,0,-0.261487156152725,0.965206921100616,0,-0.261487156152725,0.965206921100616,0,-0.261487156152725,0.965206921100616,0.261487126350403,0,0.965206980705261,0.261487126350403,0,0.965206980705261,0.261487126350403,0,0.965206980705261,0.261487126350403,0,0.965206980705261,0,0.261487185955048,0.965206980705261,0,0.261487185955048,0.965206980705261,0,0.261487185955048,0.965206980705261,0,0.261487185955048,0.965206980705261,0,0.965206921100616,0.261487156152725,0,0.965206921100616,0.261487156152725,0,0.965206921100616,0.261487156152725,0,0.965206921100616,0.261487156152725,0.261487156152725,0.965206921100616,0,0.261487156152725,0.965206921100616,0,0.261487156152725,0.965206921100616,0,0.261487156152725,0.965206921100616,0,0,0.965206980705261,-0.261487126350403,0,0.965206980705261,-0.261487126350403,0,0.965206980705261,-0.261487126350403,0,0.965206980705261,-0.261487126350403,0,0.261487156152725,-0.965206921100616,0,0.261487156152725,-0.965206921100616,0,0.261487156152725,-0.965206921100616,0,0.261487156152725,-0.965206921100616,0.261487126350403,0,-0.965206980705261, +0.261487126350403,0,-0.965206980705261,0.261487126350403,0,-0.965206980705261,0.261487126350403,0,-0.965206980705261,0,-0.261487185955048,-0.965206980705261,0,-0.261487185955048,-0.965206980705261,0,-0.261487185955048,-0.965206980705261,0,-0.261487185955048,-0.965206980705261,0,-0.965206921100616,-0.261487156152725,0,-0.965206921100616,-0.261487156152725,0,-0.965206921100616,-0.261487156152725,0,-0.965206921100616,-0.261487156152725,0.261487185955048,-0.965206921100616,0,0.261487185955048,-0.965206921100616,0,0.261487185955048,-0.965206921100616,0,0.261487185955048,-0.965206921100616,0,0,-0.965206980705261,0.261487126350403,0,-0.965206980705261,0.261487126350403,0,-0.965206980705261,0.261487126350403,0,-0.965206980705261,0.261487126350403,0.965206980705261,-0.261487066745758,0,0.965206980705261,-0.261487066745758,0,0.965206980705261,-0.261487066745758,0,0.965206980705261,-0.261487066745758,0,0.965206980705261,0,-0.261487185955048,0.965206980705261,0,-0.261487185955048,0.965206980705261,0,-0.261487185955048,0.965206980705261,0,-0.261487185955048,0.965206980705261,0.261487126350403,0,0.965206980705261,0.261487126350403,0,0.965206980705261,0.261487126350403,0,0.965206980705261,0.261487126350403,0,-0.965206980705261,-0.261487126350403,0,-0.965206980705261,-0.261487126350403,0,-0.965206980705261,-0.261487126350403,0,-0.965206980705261,-0.261487126350403,0,-0.965206980705261,0,0.261487185955048,-0.965206980705261,0,0.261487185955048,-0.965206980705261,0,0.261487185955048,-0.965206980705261,0,0.261487185955048,-0.965206980705261,0.261487066745758,0,-0.965206980705261,0.261487066745758,0,-0.965206980705261,0.261487066745758,0,-0.965206980705261,0.261487066745758,0,-0.211917281150818,-0.211917445063591,0.954034626483917,0,0,1,-0.211917281150818,-0.21191743016243,0.954034626483917,-0.211917266249657,-0.211917445063591,0.954034626483917,0,-0.261487185955048,0.965206980705261,0,-0.261487185955048,0.965206980705261,0,-0.261487185955048,0.965206980705261,0,-0.261487185955048,0.965206980705261,0,0,1,0,0,1,0,0,1,0,0,1,-0.211917445063591,0.954034626483917,0.211917281150818, +0,1,0,-0.211917445063591,0.954034626483917,0.211917281150818,-0.211917445063591,0.954034626483917,0.211917266249657,0,0.965206980705261,0.261487126350403,0,0.965206980705261,0.261487126350403,0,0.965206980705261,0.261487126350403,0,0.965206980705261,0.261487126350403,0,1,0,0,1,0,0,1,0,0,1,0,-0.211917594075203,0.211917579174042,-0.954034507274628,0,0,-1,-0.211917594075203,0.211917579174042,-0.954034507274628,-0.211917594075203,0.211917564272881,-0.954034507274628,0,0.261487185955048,-0.965206980705261,0,0.261487185955048,-0.965206980705261,0,0.261487185955048,-0.965206980705261,0,0.261487185955048,-0.965206980705261,0,0,-1,0,0,-1,0,0,-1,0,0,-1,-0.211917325854301,-0.954034626483917,-0.211917325854301,0,-1,0,-0.211917325854301,-0.954034686088562,-0.211917325854301,-0.211917355656624,-0.954034686088562,-0.211917355656624,0,-0.965206980705261,-0.261487126350403,0,-0.965206980705261,-0.261487126350403,0,-0.965206980705261,-0.261487126350403,0,-0.965206980705261,-0.261487126350403,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0.954034626483917,-0.211917251348495,0.21191731095314,1,0,0,0.954034626483917,-0.211917251348495,0.211917340755463,0.954034745693207,-0.211917266249657,0.211917325854301,0.965206980705261,-0.261487126350403,0,0.965206980705261,-0.261487126350403,0,0.965206980705261,-0.261487126350403,0,0.965206980705261,-0.261487126350403,0,1,0,0,1,0,0,1,0,0,1,0,0,-0.954034686088562,-0.211917355656624,-0.211917459964752,-1,0,0,-0.954034626483917,-0.211917325854301,-0.211917445063591,-0.954034686088562,-0.211917355656624,-0.211917474865913,-0.965206980705261,-0.261487066745758,0,-0.965206980705261,-0.261487066745758,0,-0.965206980705261,-0.261487066745758,0,-0.965206980705261,-0.261487066745758,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0.211917281150818,-0.211917400360107,0.954034626483917,0,0,1,0.211917266249657,-0.211917415261269,0.954034626483917,0.211917266249657,-0.211917415261269,0.954034626483917,0.261487126350403,0,0.965206980705261,0.261487126350403,0,0.965206980705261,0.261487126350403,0,0.965206980705261,0.261487126350403,0,0.965206980705261, +0,0,1,0,0,1,0,0,1,0,0,1,0.211917296051979,0.211917415261269,0.954034626483917,0,0,1,0.211917296051979,0.211917415261269,0.954034626483917,0.211917281150818,0.211917415261269,0.954034626483917,0,0.261487156152725,0.965206921100616,0,0.261487156152725,0.965206921100616,0,0.261487156152725,0.965206921100616,0,0.261487156152725,0.965206921100616,0,0,1,0,0,1,0,0,1,0,0,1,-0.211917281150818,0.211917445063591,0.954034626483917,0,0,1,-0.211917281150818,0.211917445063591,0.954034626483917,-0.211917266249657,0.211917445063591,0.954034626483917,-0.261487126350403,0,0.965206980705261,-0.261487126350403,0,0.965206980705261,-0.261487126350403,0,0.965206980705261,-0.261487126350403,0,0.965206980705261,0,0,1,0,0,1,0,0,1,0,0,1,0.211917445063591,0.954034626483917,0.211917445063591,0,1,0,0.211917415261269,0.954034566879272,0.211917415261269,0.211917445063591,0.954034626483917,0.211917445063591,0.261487185955048,0.965206921100616,0,0.261487185955048,0.965206921100616,0,0.261487185955048,0.965206921100616,0,0.261487185955048,0.965206921100616,0,0,1,0,0,1,0,0,1,0,0,1,0,0.211917445063591,0.954034626483917,-0.211917489767075,0,1,0,0.21191743016243,0.954034566879272,-0.211917489767075,0.211917445063591,0.954034566879272,-0.211917474865913,0,0.965206921100616,-0.261487156152725,0,0.965206921100616,-0.261487156152725,0,0.965206921100616,-0.261487156152725,0,0.965206921100616,-0.261487156152725,0,1,0,0,1,0,0,1,0,0,1,0,-0.211917459964752,0.954034686088562,-0.211917340755463,0,1,0,-0.211917445063591,0.954034626483917,-0.21191731095314,-0.211917489767075,0.954034686088562,-0.211917355656624,-0.261487156152725,0.965206921100616,0,-0.261487156152725,0.965206921100616,0,-0.261487156152725,0.965206921100616,0,-0.261487156152725,0.965206921100616,0,0,1,0,0,1,0,0,1,0,0,1,0,0.211917608976364,0.211917579174042,-0.954034507274628,0,0,-1,0.211917608976364,0.211917564272881,-0.954034566879272,0.211917594075203,0.211917579174042,-0.954034507274628,0.261487126350403,0,-0.965206980705261,0.261487126350403,0,-0.965206980705261,0.261487126350403,0,-0.965206980705261, +0.261487126350403,0,-0.965206980705261,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0.211917579174042,-0.211917534470558,-0.954034507274628,0,0,-1,0.211917594075203,-0.211917549371719,-0.954034507274628,0.211917594075203,-0.211917519569397,-0.954034507274628,0,-0.261487156152725,-0.965206921100616,0,-0.261487156152725,-0.965206921100616,0,-0.261487156152725,-0.965206921100616,0,-0.261487156152725,-0.965206921100616,0,0,-1,0,0,-1,0,0,-1,0,0,-1,-0.211917594075203,-0.211917549371719,-0.954034507274628,0,0,-1,-0.211917579174042,-0.211917534470558,-0.954034566879272,-0.211917594075203,-0.211917519569397,-0.954034507274628,-0.261487126350403,0,-0.965206980705261,-0.261487126350403,0,-0.965206980705261,-0.261487126350403,0,-0.965206980705261,-0.261487126350403,0,-0.965206980705261,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0.211917340755463,-0.954034686088562,-0.211917519569397,0,-1,0,0.211917325854301,-0.954034626483917,-0.211917489767075,0.211917325854301,-0.954034686088562,-0.211917489767075,0.261487156152725,-0.965206921100616,0,0.261487156152725,-0.965206921100616,0,0.261487156152725,-0.965206921100616,0,0.261487156152725,-0.965206921100616,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0.211917281150818,-0.954034626483917,0.211917445063591,0,-1,0,0.211917296051979,-0.954034626483917,0.211917445063591,0.211917266249657,-0.954034626483917,0.211917445063591,0,-0.965206921100616,0.261487156152725,0,-0.965206921100616,0.261487156152725,0,-0.965206921100616,0.261487156152725,0,-0.965206921100616,0.261487156152725,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-0.211917296051979,-0.954034626483917,0.211917296051979,0,-1,0,-0.211917296051979,-0.954034626483917,0.211917296051979,-0.211917281150818,-0.954034686088562,0.211917281150818,-0.261487185955048,-0.965206921100616,0,-0.261487185955048,-0.965206921100616,0,-0.261487185955048,-0.965206921100616,0,-0.261487185955048,-0.965206921100616,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0.954034626483917,-0.211917325854301,-0.211917400360107,1,0,0,0.954034686088562,-0.211917340755463,-0.211917400360107,0.954034686088562,-0.211917355656624,-0.21191743016243,0.965206980705261,0,-0.261487185955048, +0.965206980705261,0,-0.261487185955048,0.965206980705261,0,-0.261487185955048,0.965206980705261,0,-0.261487185955048,1,0,0,1,0,0,1,0,0,1,0,0,0.954034686088562,0.211917370557785,-0.211917489767075,1,0,0,0.954034686088562,0.211917355656624,-0.211917445063591,0.954034626483917,0.211917355656624,-0.211917445063591,0.965206980705261,0.261487066745758,0,0.965206980705261,0.261487066745758,0,0.965206980705261,0.261487066745758,0,0.965206980705261,0.261487066745758,0,1,0,0,1,0,0,1,0,0,1,0,0,0.954034626483917,0.211917296051979,0.211917385458946,1,0,0,0.954034626483917,0.211917296051979,0.211917385458946,0.954034626483917,0.211917266249657,0.211917355656624,0.965206980705261,0,0.261487185955048,0.965206980705261,0,0.261487185955048,0.965206980705261,0,0.261487185955048,0.965206980705261,0,0.261487185955048,1,0,0,1,0,0,1,0,0,1,0,0,-0.954034626483917,-0.211917251348495,0.211917400360107,-1,0,0,-0.954034626483917,-0.211917266249657,0.211917400360107,-0.954034626483917,-0.211917251348495,0.211917400360107,-0.965206980705261,0,0.261487185955048,-0.965206980705261,0,0.261487185955048,-0.965206980705261,0,0.261487185955048,-0.965206980705261,0,0.261487185955048,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-0.954034626483917,0.211917281150818,0.211917445063591,-1,0,0,-0.954034626483917,0.211917281150818,0.211917445063591,-0.954034626483917,0.211917266249657,0.211917445063591,-0.965206980705261,0.261487126350403,0,-0.965206980705261,0.261487126350403,0,-0.965206980705261,0.261487126350403,0,-0.965206980705261,0.261487126350403,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-0.954034566879272,0.211917355656624,-0.211917519569397,-1,0,0,-0.954034686088562,0.211917370557785,-0.211917534470558,-0.954034626483917,0.211917355656624,-0.211917504668236,-0.965206980705261,0,-0.261487185955048,-0.965206980705261,0,-0.261487185955048,-0.965206980705261,0,-0.261487185955048,-0.965206980705261,0,-0.261487185955048,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0, +1,0,0,1,0,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0, +-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0 + } + NormalsW: *768 { + a: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + } + } + LayerElementBinormal: 0 { + Version: 102 + Name: "map1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Binormals: *2304 { + a: 0,1,0,0,1,0,0,1,0,0,1,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0.965207040309906,0.261487185955048,0,0.965207040309906,0.261487185955048,0,0.965207040309906,0.261487185955048,0,0.965207040309906,0.261487185955048,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,0.965206980705261,-0.261487185955048,0,0.965206980705261,-0.261487185955048,0,0.965206980705261,-0.261487185955048,0,0.965206980705261,-0.261487185955048,0,0.261487185955048,-0.965207040309906,0,0.261487185955048,-0.965207040309906,0,0.261487185955048,-0.965207040309906,0,0.261487185955048,-0.965207040309906,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-0.261487126350403,-0.965206980705261,0,-0.261487126350403,-0.965206980705261,0,-0.261487126350403,-0.965206980705261,0,-0.261487126350403,-0.965206980705261,0,-0.965207040309906,-0.261487185955048,0,-0.965207040309906,-0.261487185955048,0,-0.965207040309906,-0.261487185955048,0,-0.965207040309906,-0.261487185955048,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-0.965206980705261,0.261487185955048,0,-0.965206980705261,0.261487185955048,0,-0.965206980705261,0.261487185955048,0,-0.965206980705261,0.261487185955048,0,-0.261487185955048,0.965207040309906,0,-0.261487185955048,0.965207040309906,0,-0.261487185955048,0.965207040309906,0,-0.261487185955048,0.965207040309906,0,0,1,0,0,1,0,0,1,0,0,1,0,0.261487126350403,0.965206980705261,0,0.261487126350403,0.965206980705261,0,0.261487126350403,0.965206980705261,0,0.261487126350403,0.965206980705261,0.261487066745758,0.965206980705261,0,0.261487066745758,0.965206980705261,0,0.261487066745758,0.965206980705261,0,0.261487066745758,0.965206980705261,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,0,1,0,0,1,0,0,1,0, +0,1,0,0.261487066745758,0.965206980705261,0,0.261487066745758,0.965206980705261,0,0.261487066745758,0.965206980705261,0,0.261487066745758,0.965206980705261,0,-0.0554696954786777,0.977241098880768,0.204750895500183,0.0677256807684898,0.997704029083252,-0,0.0995207726955414,0.966452240943909,0.236782029271126,0.022095151245594,0.974918127059937,0.221464186906815,0,0.965206980705261,0.261487185955048,0,0.965206980705261,0.261487185955048,0,0.965206980705261,0.261487185955048,0,0.965206980705261,0.261487185955048,0,1,-0,0,1,-0,0,1,-0,0,1,-0,-0.0554696545004845,0.204750746488571,-0.977241158485413,0.0677258297801018,0,-0.997703969478607,0.0995210781693459,0.23678195476532,-0.966452240943909,0.0220953319221735,0.221464082598686,-0.974918246269226,0,0.261487126350403,-0.965206980705261,0,0.261487126350403,-0.965206980705261,0,0.261487126350403,-0.965206980705261,0,0.261487126350403,-0.965206980705261,0,0,-1,0,0,-1,0,0,-1,0,0,-1,-0.055469736456871,-0.977241158485413,-0.204751059412956,0.0677258297801018,-0.997703969478607,0,0.0995209664106369,-0.966452121734619,-0.236782252788544,0.0220952294766903,-0.974918127059937,-0.221464350819588,0,-0.965206980705261,-0.261487185955048,0,-0.965206980705261,-0.261487185955048,0,-0.965206980705261,-0.261487185955048,0,-0.965206980705261,-0.261487185955048,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0.0554696694016457,-0.204750820994377,0.977241218090057,0.0677259787917137,0,0.997703969478607,0.0995214134454727,-0.236782014369965,0.966452121734619,0.0220954976975918,-0.221464157104492,0.974918186664581,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,0,1,0,0,1,0,0,1,0,0,1,0.204750746488571,0.977241218090057,0.0554696507751942,0,0.997704029083252,-0.0677256807684898,0.236781880259514,0.966452300548553,-0.0995208472013474,0.221463993191719,0.974918186664581,-0.0220952127128839,0.261487126350403,0.965206980705261,0,0.261487126350403,0.965206980705261,0,0.261487126350403,0.965206980705261,0,0.261487126350403,0.965206980705261,0, +-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0.204750791192055,0.977241098880768,-0.0554696619510651,0,0.997704029083252,0.0677257031202316,-0.236781939864159,0.966452240943909,0.099520817399025,-0.221464112401009,0.974918246269226,0.022095188498497,-0.261487066745758,0.965206980705261,0,-0.261487066745758,0.965206980705261,0,-0.261487066745758,0.965206980705261,0,-0.261487066745758,0.965206980705261,0,0,1,0,0,1,0,0,1,0,0,1,0,-0.099520780146122,0.966452240943909,0.236781999468803,-0.0677256733179092,0.997704029083252,0,0.0554696880280972,0.977241098880768,0.204750865697861,-0.022095151245594,0.974918127059937,0.221464157104492,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,-0.0554696880280972,0.977241098880768,-0.204750865697861,0.0677258223295212,0.997703969478607,-0,0.0995210558176041,0.966452181339264,-0.236782059073448,0.0220952890813351,0.974918246269226,-0.221464201807976,0,0.965207040309906,-0.261487185955048,0,0.965207040309906,-0.261487185955048,0,0.965207040309906,-0.261487185955048,0,0.965207040309906,-0.261487185955048,0,1,-0,0,1,-0,0,1,-0,0,1,-0,-0.0995210707187653,0.966452240943909,-0.236782118678093,-0.0677258297801018,0.997703969478607,0,0.0554696954786777,0.977241098880768,-0.204750895500183,-0.0220952928066254,0.974918186664581,-0.221464231610298,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,-0.0995210558176041,0.236782118678093,-0.966452240943909,-0.0677258223295212,0,-0.997703969478607,0.0554696917533875,0.204750880599022,-0.977241098880768,-0.0220952853560448,0.221464216709137,-0.974918127059937,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,-0.0554697066545486,-0.204750955104828,-0.977241158485413,0.0677259713411331,0,-0.997703969478607,0.0995213314890862,-0.236782237887383,-0.966452181339264,0.0220954213291407,-0.221464306116104,-0.974918186664581,0,-0.261487185955048,-0.965207040309906,0,-0.261487185955048,-0.965207040309906,0,-0.261487185955048,-0.965207040309906,0,-0.261487185955048,-0.965207040309906,0,0,-1,0,0,-1,0,0,-1,0,0,-1,-0.0995213687419891,-0.236782059073448,-0.966452181339264, +-0.0677259787917137,0,-0.997703969478607,0.0554696545004845,-0.204750776290894,-0.977241158485413,-0.0220954604446888,-0.221464172005653,-0.974918246269226,0,0,-1,0,0,-1,-0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,-0.0995209515094757,-0.966452121734619,-0.236782252788544,-0.0677258223295212,-0.997703969478607,-0,0.0554697290062904,-0.977241098880768,-0.204751014709473,-0.0220952183008194,-0.974918127059937,-0.221464365720749,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0,-0.0554697290062904,-0.977241158485413,0.204751014709473,0.0677256733179092,-0.997704029083252,0,0.099520668387413,-0.966452181339264,0.236782178282738,0.022095087915659,-0.974918127059937,0.221464276313782,0,-0.965207040309906,0.261487185955048,0,-0.965207040309906,0.261487185955048,0,-0.965207040309906,0.261487185955048,0,-0.965207040309906,0.261487185955048,0,-1,0,0,-1,0,0,-1,-0,0,-1,0,-0.0995206907391548,-0.966452181339264,0.236782178282738,-0.0677256807684898,-0.997704029083252,-0,0.0554697178304195,-0.977241098880768,0.20475098490715,-0.0220951028168201,-0.974918127059937,0.221464276313782,0,-1,-0,0,-1,-0,-0,-1,0,0,-1,-0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-0.0995213836431503,-0.23678220808506,0.966452121734619,-0.0677259713411331,0,0.997703969478607,0.0554697066545486,-0.204750940203667,0.977241098880768,-0.0220954623073339,-0.221464291214943,0.974918186664581,-0,0,1,-0,0,1,-0,0,1,-0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0.0554696954786777,0.204750895500183,0.977241098880768,0.0677258223295212,0,0.997703969478607,0.0995211154222488,0.236782103776932,0.966452181339264,0.0220953226089478,0.221464246511459,0.974918186664581,0,0.261487185955048,0.965207040309906,0,0.261487185955048,0.965207040309906,0,0.261487185955048,0.965207040309906,0,0.261487185955048,0.965207040309906,0,0,1,0,0,1,0,0,1,0,0,1,-0.0995211601257324,0.23678195476532,0.966452181339264,-0.0677258297801018,0,0.997703969478607,0.0554696619510651,0.204750776290894,0.977241218090057,-0.022095363587141,0.221464082598686,0.974918246269226,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0.236781939864159,0.966452240943909,0.0995208621025085, +-0,0.997704029083252,0.0677257031202316,0.204750806093216,0.977241158485413,-0.0554696656763554,0.221464112401009,0.974918186664581,0.0220951996743679,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0.204750806093216,0.977241098880768,0.0554696694016457,0,0.997703969478607,-0.0677258521318436,-0.236782044172287,0.966452240943909,-0.0995211452245712,-0.221464172005653,0.974918246269226,-0.0220953542739153,-0.261487066745758,0.965206980705261,0,-0.261487066745758,0.965206980705261,0,-0.261487066745758,0.965206980705261,0,-0.261487066745758,0.965206980705261,0,0,1,-0,-0,1,0,-0,1,0,-0,1,0,-0.236781984567642,0.966452300548553,0.09952113032341,-0,0.997703969478607,0.0677258297801018,-0.204750761389732,0.977241158485413,-0.0554696582257748,-0.221464067697525,0.974918246269226,0.022095350548625,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,1,-0,-0,1,0,-0.236781880259514,0.966452360153198,-0.0995208248496056,0,0.997704029083252,-0.0677256807684898,-0.20475073158741,0.977241158485413,0.0554696470499039,-0.221464022994041,0.974918246269226,-0.0220951903611422,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0.204750746488571,0.977241158485413,-0.0554696545004845,0,0.997703969478607,0.0677258297801018,0.23678195476532,0.966452240943909,0.0995210781693459,0.221464082598686,0.974918246269226,0.0220953319221735,0.261487126350403,0.965206980705261,0,0.261487126350403,0.965206980705261,0,0.261487126350403,0.965206980705261,0,0.261487126350403,0.965206980705261,0,0,1,0,0,1,0,0,1,0,0,1,0,0.236782059073448,0.966452240943909,-0.0995211154222488,0,0.997703969478607,-0.0677258521318436,0.204750806093216,0.977241098880768,0.0554696656763554,0.221464142203331,0.974918186664581,-0.0220953188836575,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,-0,-1,0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,0,-0,-1,0,-0,-1, +0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,-0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1, +-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0 + } + BinormalsW: *768 { + a: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + } + + } + LayerElementTangent: 0 { + Version: 102 + Name: "map1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Tangents: *2304 { + a: 0.965206980705261,-0,0.261487126350403,0.965206980705261,-0,0.261487126350403,0.965206980705261,-0,0.261487126350403,0.965206980705261,-0,0.261487126350403,0.965207040309906,0.26148721575737,0,0.965207040309906,0.26148721575737,0,0.965207040309906,0.26148721575737,0,0.965207040309906,0.26148721575737,0,0.965206980705261,-0,-0.261487126350403,0.965206980705261,-0,-0.261487126350403,0.965206980705261,-0,-0.261487126350403,0.965206980705261,-0,-0.261487126350403,0.965206980705261,-0.261487156152725,-0,0.965206980705261,-0.261487156152725,-0,0.965206980705261,-0.261487156152725,-0,0.965206980705261,-0.261487156152725,-0,0.26148721575737,0,-0.965207040309906,0.26148721575737,0,-0.965207040309906,0.26148721575737,0,-0.965207040309906,0.26148721575737,0,-0.965207040309906,-0.26148721575737,0,0.965207040309906,-0.26148721575737,0,0.965207040309906,-0.26148721575737,0,0.965207040309906,-0.26148721575737,0,0.965207040309906,1,0,-0,1,0,-0,1,0,-0,1,0,-0,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,0,1,-0,0,1,-0,-0,1,-0,0,0.965206980705261,-0.261487156152725,0,0.965206980705261,-0.261487156152725,0,0.965206980705261,-0.261487156152725,0,0.965206980705261,-0.261487156152725,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,0,0,1,0,0,1,-0,0,1,0,0,0.965206980705261,0,0.261487126350403,0.965206980705261,0,0.261487126350403,0.965206980705261,0,0.261487126350403,0.965206980705261,0,0.261487126350403,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0.965207040309906,0.26148721575737,-0,0.965207040309906,0.26148721575737,-0,0.965207040309906,0.26148721575737,-0,0.965207040309906,0.26148721575737,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,-0.26148721575737,-0,-0.965207040309906,-0.26148721575737,-0,-0.965207040309906,-0.26148721575737,-0,-0.965207040309906,-0.26148721575737,-0,-0.965207040309906,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0.26148721575737,-0,0.965207040309906, +0.26148721575737,-0,0.965207040309906,0.26148721575737,-0,0.965207040309906,0.26148721575737,-0,0.965207040309906,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0.97571212053299,0.00952975451946259,0.218849271535873,0.997704029083252,-0.0677256807684898,0,0.972207129001617,-0.145124465227127,0.183717742562294,0.977037787437439,-0.0680116266012192,0.201919630169868,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,0.97571212053299,0.218849420547485,-0.0095297135412693,0.997703969478607,0,0.0677258297801018,0.972207069396973,0.183717846870422,0.145124778151512,0.977037727832794,0.20191977918148,0.0680118054151535,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,0.975712060928345,-0.00952968932688236,-0.21884959936142,0.997703969478607,0.0677258297801018,0,0.972207009792328,0.145124763250351,-0.183717966079712,0.977037727832794,0.0680118054151535,-0.201919928193092,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,-0,0,1,-0,0,1,-0,0,0.97571212053299,-0.218849316239357,0.00952973961830139,0.997703969478607,0,-0.0677259787917137,0.972207069396973,-0.183717638254166,-0.145125105977058,0.977037727832794,-0.201919630169868,-0.068011961877346,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,0.218849301338196,0.00952973961830139,-0.97571212053299,0,-0.0677256807684898,-0.997704029083252,0.1837178170681,-0.145124509930611,-0.972207069396973,0.201919689774513,-0.0680116564035416,-0.977037787437439,-0,0,-1,-0,0,-1,-0,0,-1,-0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,-0.218849420547485,0.0095297172665596,0.97571212053299,0,-0.0677257031202316,0.997704029083252,-0.183717906475067,-0.145124524831772,0.972207069396973,-0.201919823884964,-0.068011686205864,0.977037727832794,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0.972207129001617,0.145124465227127,-0.183717742562294,0.997704029083252,0.0677256733179092,0,0.97571212053299,-0.00952975824475288,-0.218849256634712,0.977037787437439,0.0680116191506386,-0.201919630169868,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403, +1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,0.97571212053299,0.00952975172549486,-0.218849286437035,0.997703969478607,-0.0677258223295212,0,0.972207069396973,-0.14512474834919,-0.183717682957649,0.977037847042084,-0.0680117681622505,-0.20191964507103,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,0,1,-0,0,1,-0,-0,1,-0,0,0.972207069396973,0.14512474834919,0.183717668056488,0.997703969478607,0.0677258297801018,0,0.97571212053299,-0.00952975451946259,0.218849271535873,0.977037847042084,0.0680117756128311,0.201919630169868,0.965206980705261,-0,0.261487126350403,0.965206980705261,-0,0.261487126350403,0.965206980705261,-0,0.261487126350403,0.965206980705261,-0,0.261487126350403,1,-0,-0,1,-0,0,1,-0,0,1,-0,0,0.972207069396973,-0.183717831969261,-0.145124778151512,0.997703969478607,0,-0.0677258223295212,0.97571212053299,-0.218849420547485,0.00952972378581762,0.977037727832794,-0.20191977918148,-0.0680117979645729,0.965207040309906,-0.26148721575737,-0,0.965207040309906,-0.26148721575737,-0,0.965207040309906,-0.26148721575737,-0,0.965207040309906,-0.26148721575737,-0,1,-0,-0,1,-0,-0,1,-0,-0,1,-0,-0,0.97571212053299,-0.218849420547485,-0.0095297247171402,0.997703969478607,0,0.0677259713411331,0.972207009792328,-0.183717742562294,0.145125061273575,0.977037727832794,-0.201919749379158,0.0680119395256042,1,-0,0,1,-0,0,1,-0,0,1,-0,0,1,0,0,1,0,0,1,-0,-0,1,0,0,0.972207009792328,0.183717772364616,-0.145125061273575,0.997703969478607,0,-0.0677259787917137,0.97571212053299,0.218849420547485,0.00952971447259188,0.977037727832794,0.20191977918148,-0.0680119544267654,0.965206980705261,0.261487156152725,0,0.965206980705261,0.261487156152725,0,0.965206980705261,0.261487156152725,-0,0.965206980705261,0.261487156152725,0,1,-0,0,1,0,0,1,0,0,1,0,0,0.972207009792328,-0.14512474834919,0.183717995882034,0.997703969478607,-0.0677258223295212,0,0.975712060928345,0.00952969118952751,0.218849584460258,0.977037727832794,-0.0680117979645729,0.201919928193092,0.965206980705261,0,0.261487126350403,0.965206980705261,0,0.261487126350403,0.965206980705261,0,0.261487126350403,0.965206980705261,0,0.261487126350403, +1,-0,0,1,-0,0,1,-0,0,1,-0,0,0.975712060928345,-0.00952969212085009,0.218849584460258,0.997704029083252,0.0677256733179092,0,0.972207069396973,0.145124465227127,0.183718055486679,0.977037727832794,0.0680116564035416,0.201919972896576,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,0,0,0.972207069396973,-0.145124480128288,-0.183718040585518,0.997704029083252,-0.0677256807684898,0,0.975712060928345,0.00952969398349524,-0.218849569559097,0.977037727832794,-0.0680116713047028,-0.201919972896576,0.965206980705261,0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,0.965206980705261,-0,-0.261487126350403,0.965206980705261,0,-0.261487126350403,1,0,0,1,0,0,1,0,0,1,0,0,0.972207069396973,0.183717623353004,0.145125105977058,0.997703969478607,0,0.0677259713411331,0.97571212053299,0.218849316239357,-0.00952974893152714,0.977037847042084,0.201919630169868,0.0680119544267654,0.965206980705261,0.261487156152725,0,0.965206980705261,0.261487156152725,0,0.965206980705261,0.261487156152725,0,0.965206980705261,0.261487156152725,0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,0.97571212053299,0.218849271535873,0.00952975638210773,0.997703969478607,0,-0.0677258223295212,0.972207069396973,0.183717668056488,-0.145124807953835,0.977037847042084,0.201919630169868,-0.0680118054151535,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,0.972207069396973,-0.183717682957649,0.145124822854996,0.997703969478607,0,0.0677258297801018,0.97571212053299,-0.218849286437035,-0.00952974427491426,0.977037847042084,-0.201919630169868,0.0680118054151535,0.965207040309906,-0.26148721575737,0,0.965207040309906,-0.26148721575737,0,0.965207040309906,-0.26148721575737,0,0.965207040309906,-0.26148721575737,0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,-0.183717846870422,0.145124554634094,-0.972207069396973,0,0.0677257031202316,-0.997704029083252,-0.218849360942841,-0.0095297284424305,-0.97571212053299,-0.20191977918148,0.068011686205864,-0.977037727832794,-0.26148721575737,-0,-0.965207040309906,-0.26148721575737,-0,-0.965207040309906,-0.26148721575737,-0,-0.965207040309906,-0.26148721575737,-0,-0.965207040309906, +0,0,-1,0,0,-1,0,0,-1,0,0,-1,-0.218849450349808,0.00952971167862415,-0.97571212053299,0,-0.0677258521318436,-0.997703969478607,-0.1837178170681,-0.145124852657318,-0.972207069396973,-0.201919764280319,-0.0680118426680565,-0.977037727832794,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-0,-1,0,0,-1,0,0,-1,0,0,-1,0.183717772364616,0.145124807953835,-0.972207069396973,0,0.0677258297801018,-0.997703969478607,0.218849375844002,-0.00952972657978535,-0.97571212053299,0.201919689774513,0.0680118054151535,-0.977037727832794,0.26148721575737,0,-0.965207040309906,0.26148721575737,0,-0.965207040309906,0.26148721575737,0,-0.965207040309906,0.26148721575737,0,-0.965207040309906,0,0,-1,0,0,-1,0,-0,-1,0,0,-1,0.183717876672745,0.145124495029449,0.972207069396973,0,0.0677256807684898,0.997704029083252,0.218849375844002,-0.00952972192317247,0.97571212053299,0.20191977918148,0.0680116564035416,0.977037727832794,0.26148721575737,-0,0.965207040309906,0.26148721575737,-0,0.965207040309906,0.26148721575737,-0,0.965207040309906,0.26148721575737,-0,0.965207040309906,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0.218849420547485,0.0095297135412693,0.97571212053299,0,-0.0677258297801018,0.997703969478607,0.183717846870422,-0.145124778151512,0.972207069396973,0.20191977918148,-0.0680118054151535,0.977037727832794,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,-0.183717906475067,0.145124837756157,0.972207009792328,0,0.0677258521318436,0.997703969478607,-0.21884948015213,-0.00952970236539841,0.97571212053299,-0.201919838786125,0.0680118277668953,0.977037727832794,-0.26148721575737,0,0.965207040309906,-0.26148721575737,0,0.965207040309906,-0.26148721575737,0,0.965207040309906,-0.26148721575737,0,0.965207040309906,0,-0,1,0,-0,1,0,-0,1,0,-0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,0,0,1,0,0,1,0,0,1,-0,-0,1,0,0,1,0,0,1,0,0,1,-0,0,1,0,0,1,0,0,1,0,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,-0,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0, +1,0,0,1,0,0,1,-0,0,1,-0,0,1,-0,-0,1,-0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,0,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,-0,0,1,-0,-0,1,-0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,0,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,1,0,0,1,0,0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,-0,0,1,-0,-0,1,-0,0,1,-0,-0,1,0,0,1,0,0,1,0,0,1,-0,0,1,-0,0,1,-0,-0,1,-0,0,1,-0,-0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,-0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,0,0,1,-0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,0,0,1,-0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,0,0,1,-0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,0,0,1,-0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,0,0,1,0,0,1,0,0,1,0,0,1, +0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1 + } + TangentsW: *768 { + a: 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "map1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *542 { + a: 0.375,0,0.625,0,0.375,0.25,0.625,0.25,0.375,0.5,0.625,0.5,0.375,0.75,0.625,0.75,0.375,1,0.625,1,0.875,0,0.875,0.25,0.125,0,0.125,0.25,0.5,0.125,0.5,0,0.5,1,0.625,0.125,0.5,0.25,0.375,0.125,0.5,0.375,0.625,0.375,0.75,0.25,0.5,0.5,0.375,0.375,0.25,0.25,0.5,0.625,0.625,0.625,0.875,0.125,0.5,0.75,0.375,0.625,0.125,0.125,0.5,0.875,0.625,0.875,0.75,0,0.5,1,0.375,0.875,0.25,0,0.75,0.125,0.75,0,0.875,0.125,0.75,0.25,0.25,0.125,0.25,0,0.25,0.25,0.125,0.125,0.4375,0.0625,0.375,0.0625,0.4375,0,0.4375,1,0.5,0.0625,0.4375,0.125,0.4375,0.3125,0.375,0.3125,0.3125,0.25,0.4375,0.25,0.5,0.3125,0.4375,0.375,0.4375,0.5625,0.375,0.5625,0.125,0.1875,0.4375,0.5,0.5,0.5625,0.4375,0.625,0.4375,0.8125,0.375,0.8125,0.1875,0,0.4375,0.75,0.5,0.8125,0.4375,0.875,0.6875,0.0625,0.625,0.0625,0.625,0.9375,0.6875,0,0.75,0.0625,0.6875,0.125,0.1875,0.0625,0.375,0.6875,0.125,0.0625,0.1875,0,0.25,0.0625,0.1875,0.125,0.5625,0.0625,0.5625,0,0.5625,1,0.5625,0.125,0.5625,0.1875,0.625,0.1875,0.5625,0.25,0.5,0.1875,0.4375,0.1875,0.375,0.1875,0.5625,0.3125,0.625,0.3125,0.6875,0.25,0.5625,0.375,0.5625,0.4375,0.625,0.4375,0.8125,0.25,0.5625,0.5,0.5,0.4375,0.4375,0.4375,0.375,0.4375,0.1875,0.25,0.5625,0.5625,0.625,0.5625,0.875,0.1875,0.5625,0.625,0.5625,0.6875,0.625,0.6875,0.875,0.0625,0.5625,0.75,0.5,0.6875,0.4375,0.6875,0.375,0.6875,0.5625,0.8125,0.625,0.8125,0.8125,0,0.5625,0.875,0.5625,0.9375,0.625,0.9375,0.5625,1,0.5,0.9375,0.4375,0.9375,0.4375,1,0.375,0.9375,0.3125,0,0.8125,0.0625,0.8125,0,0.875,0.0625,0.8125,0.125,0.8125,0.1875,0.875,0.1875,0.8125,0.25,0.75,0.1875,0.6875,0.1875,0.6875,0.25,0.3125,0.0625,0.3125,0,0.3125,0.125,0.3125,0.1875,0.3125,0.25,0.25,0.1875,0.1875,0.1875,0.1875,0.25,0.125,0.1875,0.4375,0.125,0.375,0.125,0.375,0.0625,0.4375,0.0625,0.4375,0.375,0.375,0.375,0.375,0.3125,0.4375,0.3125,0.4375,0.625,0.375,0.625,0.375,0.5625,0.4375,0.5625,0.4375,0.875,0.375,0.875,0.375,0.8125,0.4375,0.8125,0.6875,0.125,0.625,0.125,0.625,0.0625,0.6875,0.0625,0.1875,0.125,0.125,0.125,0.125,0.0625,0.1875,0.0625,0.5,0.0625,0.5,0,0.5625,0, +0.5625,0.0625,0.5625,0.125,0.625,0.1875,0.5625,0.1875,0.5,0.1875,0.5,0.25,0.4375,0.25,0.4375,0.1875,0.5,0.3125,0.5625,0.25,0.5625,0.3125,0.5625,0.375,0.625,0.375,0.625,0.4375,0.5625,0.4375,0.5,0.4375,0.5,0.5,0.4375,0.5,0.4375,0.4375,0.5,0.5625,0.5625,0.5,0.5625,0.5625,0.5625,0.625,0.625,0.625,0.625,0.6875,0.5625,0.6875,0.5,0.6875,0.5,0.75,0.4375,0.75,0.4375,0.6875,0.5,0.8125,0.5625,0.75,0.5625,0.8125,0.5625,0.875,0.625,0.875,0.625,0.9375,0.5625,0.9375,0.5,0.9375,0.5,1,0.4375,1,0.4375,0.9375,0.75,0.0625,0.75,0,0.8125,0,0.8125,0.0625,0.8125,0.125,0.875,0.125,0.875,0.1875,0.8125,0.1875,0.75,0.1875,0.75,0.25,0.6875,0.25,0.6875,0.1875,0.25,0.0625,0.25,0,0.3125,0,0.3125,0.0625,0.3125,0.125,0.375,0.1875,0.3125,0.1875,0.25,0.1875,0.25,0.25,0.1875,0.25,0.1875,0.1875,0.375,0,0.4375,0,0.5,0.125,0.375,0.25,0.5,0.375,0.375,0.5,0.5,0.625,0.375,0.75,0.5,0.875,0.625,0,0.6875,0,0.75,0.125,0.125,0,0.1875,0,0.25,0.125,0.625,0.25,0.625,0.3125,0.625,0.5,0.375,0.4375,0.625,0.5625,0.625,0.75,0.375,0.6875,0.625,0.8125,0.625,1,0.5625,1,0.375,1,0.375,0.9375,0.875,0,0.875,0.0625,0.875,0.25,0.8125,0.25,0.3125,0.25,0.125,0.25,0.125,0.1875 + } + UVIndex: *768 { + a: 51,19,47,46,57,24,53,52,63,30,59,58,69,36,65,64,75,17,71,70,81,45,78,76,50,15,83,82,85,17,87,86,89,18,55,90,56,18,88,92,95,21,97,96,100,23,61,101,62,23,99,104,107,27,109,108,112,29,67,113,68,29,111,115,118,33,120,119,122,35,124,123,74,39,128,127,130,40,132,131,134,41,136,135,80,43,138,137,139,19,91,140,142,44,144,143,47,0,48,46,48,15,50,46,50,14,51,46,53,2,55,52,55,18,56,52,56,20,57,52,59,4,61,58,61,23,62,58,62,26,63,58,65,6,67,64,67,29,68,64,68,32,69,64,71,1,73,70,73,39,74,70,74,38,75,70,78,12,79,76,79,43,80,76,80,42,81,76,83,1,71,82,71,17,85,82,85,14,50,82,87,3,88,86,88,18,89,86,89,14,85,86,55,2,91,90,91,19,51,90,51,14,89,90,88,3,93,92,93,21,95,92,95,20,56,92,97,5,99,96,99,23,100,96,100,20,95,96,61,4,102,101,102,24,57,101,57,20,100,101,99,5,105,104,105,27,107,104,107,26,62,104,109,7,111,108,111,29,112,108,112,26,107,108,67,6,114,113,114,30,63,113,63,26,112,113,111,7,116,115,116,33,118,115,118,32,68,115,120,9,121,119,121,35,122,119,122,32,118,119,124,8,125,123,125,36,69,123,69,32,122,123,128,10,129,127,129,40,130,127,130,38,74,127,132,11,133,131,133,41,134,131,134,38,130,131,136,3,87,135,87,17,75,135,75,38,134,135,138,0,47,137,47,19,139,137,139,42,80,137,91,2,141,140,141,44,142,140,142,42,139,140,144,13,145,143,145,45,81,143,81,42,142,143,146,149,148,147,150,153,152,151,154,157,156,155,158,161,160,159,162,165,164,163,166,169,168,167,170,173,172,171,174,176,175,163,177,180,179,178,181,183,182,178,184,187,186,185,188,191,190,189,192,194,193,189,195,198,197,196,199,202,201,200,203,205,204,200,206,209,208,207,210,213,212,211,214,217,216,215,218,221,220,219,222,225,224,223,226,229,228,227,230,232,231,147,233,236,235,234,148,149,238,237,238,149,170,171,170,149,146,239,152,153,179,240,179,153,181,178,181,153,150,241,156,157,190,242,190,157,192,189,192,157,154,243,160,161,201,244,201,161,203,200,203,161,158,245,164,165,247,246,247,165,214,215,214,165,162,248,168,169,250,249,250,169,226,227,226,169,166,251,172,173,164,246,164,173,174,163,174,173,170,239,175,176,182,252,182,176,177,178,177,176,174,239, +179,180,231,240,231,180,146,147,146,180,177,239,182,183,253,252,253,183,184,185,184,183,181,241,186,187,193,254,193,187,188,189,188,187,184,241,190,191,255,242,255,191,150,151,150,191,188,241,193,194,256,254,256,194,195,196,195,194,192,243,197,198,204,257,204,198,199,200,199,198,195,243,201,202,258,244,258,202,154,155,154,202,199,243,204,205,259,257,259,205,206,207,206,205,203,245,208,209,261,260,261,209,210,211,210,209,206,245,212,213,263,262,263,213,158,159,158,213,210,245,216,217,265,264,265,217,218,219,218,217,214,248,220,221,267,266,267,221,222,223,222,221,218,248,224,225,175,252,175,225,162,163,162,225,222,248,228,229,148,237,148,229,230,147,230,229,226,251,231,232,268,240,268,232,233,234,233,232,230,251,235,236,270,269,270,236,166,167,166,236,233,251 + } + } + LayerElementSmoothing: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByEdge" + ReferenceInformationType: "Direct" + Smoothing: *384 { + a: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "AllSame" + ReferenceInformationType: "IndexToDirect" + Materials: *1 { + a: 0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementBinormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementTangent" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementSmoothing" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Model: 1827098352032, "Model::Cube2", "Mesh" { + Version: 232 + Properties70: { + P: "RotationActive", "bool", "", "",1 + P: "InheritType", "enum", "", "",1 + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",-0.0104023897647858,0.00998288810253143,-0.0104375958442688 + P: "Lcl Scaling", "Lcl Scaling", "", "A",0.1,-0.1,0.1 + P: "currentUVSet", "KString", "", "U", "map1" + } + Shading: T + Culling: "CullingOff" + } + Model: 1827098379872, "Model::Cube1", "Mesh" { + Version: 232 + Properties70: { + P: "RotationActive", "bool", "", "",1 + P: "InheritType", "enum", "", "",1 + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",1.04023897647858,-0.998288810253143,1.04375958442688 + P: "currentUVSet", "KString", "", "U", "map1" + } + Shading: T + Culling: "CullingOff" + } + Model: 1827098382192, "Model::Cube3", "Mesh" { + Version: 232 + Properties70: { + P: "RotationActive", "bool", "", "",1 + P: "InheritType", "enum", "", "",1 + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",-0.0106711769104004,0.00998288810253143,0.0939023494720459 + P: "Lcl Scaling", "Lcl Scaling", "", "A",0.1,0.1,0.1 + P: "currentUVSet", "KString", "", "U", "map1" + } + Shading: T + Culling: "CullingOff" + } + Model: 1827098384512, "Model::Cube1", "Mesh" { + Version: 232 + Properties70: { + P: "RotationPivot", "Vector3D", "Vector", "",0.0,0.0019,0.0 + P: "ScalingOffset", "Vector3D", "Vector", "",0.0,0.0019,0.0 + P: "ScalingPivot", "Vector3D", "Vector", "",0.0,0.0019,0.0 + P: "RotationActive", "bool", "", "",1 + P: "InheritType", "enum", "", "",1 + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0.0,0.0019,0.0 + P: "Lcl Scaling", "Lcl Scaling", "", "A",1.0,1.0019,1.0 + P: "currentUVSet", "KString", "", "U", "map1" + } + Shading: T + Culling: "CullingOff" + } + Material: 1827074508720, "Material::Mat_Green", "" { + Version: 102 + ShadingModel: "lambert" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",0,1,0 + P: "DiffuseFactor", "Number", "", "A",0.800000011920929 + P: "TransparencyFactor", "Number", "", "A",1 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0,0.800000011920929,0 + P: "Opacity", "double", "Number", "",1 + } + } + Material: 1827074501920, "Material::Mat_Red", "" { + Version: 102 + ShadingModel: "lambert" + MultiLayer: 0 + Properties70: { + P: "AmbientColor", "Color", "", "A",0,0,0 + P: "DiffuseColor", "Color", "", "A",1,0,0 + P: "DiffuseFactor", "Number", "", "A",0.800000011920929 + P: "TransparencyFactor", "Number", "", "A",1 + P: "Emissive", "Vector3D", "Vector", "",0,0,0 + P: "Ambient", "Vector3D", "Vector", "",0,0,0 + P: "Diffuse", "Vector3D", "Vector", "",0.800000011920929,0,0 + P: "Opacity", "double", "Number", "",1 + } + } + AnimationStack: 1825586153728, "AnimStack::Take 001", "" { + Properties70: { + P: "LocalStart", "KTime", "Time", "",1924423250 + P: "LocalStop", "KTime", "Time", "",230930790000 + P: "ReferenceStart", "KTime", "Time", "",1924423250 + P: "ReferenceStop", "KTime", "Time", "",230930790000 + } + } + AnimationLayer: 1827070038960, "AnimLayer::BaseLayer", "" { + } +} + +; Object connections +;------------------------------------------------------------------ + +Connections: { + + ;Model::Cube2, Model::RootNode + C: "OO",1827098352032,0 + + ;Model::Cube3, Model::RootNode + C: "OO",1827098382192,0 + + ;AnimLayer::BaseLayer, AnimStack::Take 001 + C: "OO",1827070038960,1825586153728 + + ;Geometry::, Model::Cube2 + C: "OO",1827080157856,1827098352032 + + ;Material::Mat_Green, Model::Cube2 + C: "OO",1827074508720,1827098352032 + + ;Model::Cube1, Model::Cube2 + C: "OO",1827098379872,1827098352032 + + ;Geometry::, Model::Cube1 + C: "OO",1827080155296,1827098379872 + + ;Material::Mat_Green, Model::Cube1 + C: "OO",1827074508720,1827098379872 + + ;Geometry::, Model::Cube3 + C: "OO",1827080156320,1827098382192 + + ;Material::Mat_Red, Model::Cube3 + C: "OO",1827074501920,1827098382192 + + ;Model::Cube1, Model::Cube3 + C: "OO",1827098384512,1827098382192 + + ;Geometry::, Model::Cube1 + C: "OO",1827080139424,1827098384512 + + ;Material::Mat_Red, Model::Cube1 + C: "OO",1827074501920,1827098384512 +} +;Takes section +;---------------------------------------------------- + +Takes: { + Current: "Take 001" + Take: "Take 001" { + FileName: "Take_001.tak" + LocalTime: 1924423250,230930790000 + ReferenceTime: 1924423250,230930790000 + } +} diff --git a/test/models/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube.bin b/test/models/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube.bin new file mode 100644 index 000000000..7b14a1793 Binary files /dev/null and b/test/models/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube.bin differ diff --git a/test/models/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube.gltf b/test/models/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube.gltf new file mode 100644 index 000000000..b1b720147 --- /dev/null +++ b/test/models/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube.gltf @@ -0,0 +1,282 @@ +{ + "accessors": [ + { + "bufferView": 0, + "componentType": 5126, + "count": 24, + "type": "VEC3" + }, + { + "bufferView": 1, + "componentType": 5126, + "count": 24, + "type": "VEC4" + }, + { + "bufferView": 2, + "componentType": 5126, + "count": 24, + "type": "VEC3", + "max": [ + 0.0100000035, + 0.0100000035, + 0.01 + ], + "min": [ + -0.0100000044, + -0.0100000054, + -0.01 + ] + }, + { + "bufferView": 3, + "componentType": 5126, + "count": 24, + "type": "VEC3", + "name": "thin" + }, + { + "bufferView": 4, + "componentType": 5126, + "count": 24, + "type": "VEC3", + "max": [ + 0.0, + 0.01893253, + 0.0 + ], + "min": [ + 0.0, + 0.0, + 0.0 + ], + "name": "thin" + }, + { + "bufferView": 5, + "componentType": 5126, + "count": 24, + "type": "VEC3", + "name": "thin" + }, + { + "bufferView": 6, + "componentType": 5126, + "count": 24, + "type": "VEC3", + "name": "angle" + }, + { + "bufferView": 7, + "componentType": 5126, + "count": 24, + "type": "VEC3", + "max": [ + 0.0, + 0.0198908355, + 0.0 + ], + "min": [ + 0.0, + 0.0, + 0.0 + ], + "name": "angle" + }, + { + "bufferView": 8, + "componentType": 5126, + "count": 24, + "type": "VEC3", + "name": "angle" + }, + { + "bufferView": 9, + "componentType": 5123, + "count": 36, + "type": "SCALAR" + }, + { + "bufferView": 10, + "componentType": 5126, + "count": 127, + "type": "SCALAR", + "max": [ + 4.19999743 + ], + "min": [ + 0.0 + ] + }, + { + "bufferView": 11, + "componentType": 5126, + "count": 254, + "type": "SCALAR" + } + ], + "animations": [ + { + "channels": [ + { + "sampler": 0, + "target": { + "node": 0, + "path": "weights" + } + } + ], + "samplers": [ + { + "input": 10, + "interpolation": "LINEAR", + "output": 11 + } + ], + "name": "Square" + } + ], + "asset": { + "generator": "glTF Tools for Unity", + "version": "2.0" + }, + "bufferViews": [ + { + "buffer": 0, + "byteLength": 288 + }, + { + "buffer": 0, + "byteOffset": 288, + "byteLength": 384 + }, + { + "buffer": 0, + "byteOffset": 672, + "byteLength": 288 + }, + { + "buffer": 0, + "byteOffset": 960, + "byteLength": 288 + }, + { + "buffer": 0, + "byteOffset": 1248, + "byteLength": 288 + }, + { + "buffer": 0, + "byteOffset": 1536, + "byteLength": 288 + }, + { + "buffer": 0, + "byteOffset": 1824, + "byteLength": 288 + }, + { + "buffer": 0, + "byteOffset": 2112, + "byteLength": 288 + }, + { + "buffer": 0, + "byteOffset": 2400, + "byteLength": 288 + }, + { + "buffer": 0, + "byteOffset": 2688, + "byteLength": 72 + }, + { + "buffer": 0, + "byteOffset": 2760, + "byteLength": 508 + }, + { + "buffer": 0, + "byteOffset": 3268, + "byteLength": 1016 + } + ], + "buffers": [ + { + "uri": "AnimatedMorphCube.bin", + "byteLength": 4284 + } + ], + "meshes": [ + { + "primitives": [ + { + "attributes": { + "NORMAL": 0, + "TANGENT": 1, + "POSITION": 2 + }, + "indices": 9, + "material": 0, + "targets": [ + { + "NORMAL": 3, + "POSITION": 4, + "TANGENT": 5 + }, + { + "NORMAL": 6, + "POSITION": 7, + "TANGENT": 8 + } + ] + } + ], + "weights": [ + 0.0, + 0.0 + ], + "name": "Cube" + } + ], + "materials": [ + { + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.6038274, + 0.6038274, + 0.6038274, + 1.0 + ], + "metallicFactor": 0.0, + "roughnessFactor": 0.5 + }, + "name": "Material" + } + ], + "nodes": [ + { + "mesh": 0, + "rotation": [ + 0.0, + 0.7071067, + -0.7071068, + 0.0 + ], + "scale": [ + 100.0, + 100.0, + 100.0 + ], + "name": "AnimatedMorphCube" + } + ], + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ] +} \ No newline at end of file diff --git a/test/unit/SceneDiffer.cpp b/test/unit/SceneDiffer.cpp index fb000db29..684d9fee6 100644 --- a/test/unit/SceneDiffer.cpp +++ b/test/unit/SceneDiffer.cpp @@ -123,7 +123,7 @@ void SceneDiffer::showReport() { return; } - for ( std::vector::iterator it = m_diffs.begin(); it != m_diffs.end(); it++ ) { + for ( std::vector::iterator it = m_diffs.begin(); it != m_diffs.end(); ++it ) { std::cout << *it << "\n"; } diff --git a/test/unit/TestModelFactory.h b/test/unit/TestModelFactory.h index f1ef1701f..0e48fb744 100644 --- a/test/unit/TestModelFactory.h +++ b/test/unit/TestModelFactory.h @@ -89,7 +89,7 @@ public: scene->mMeshes[ 0 ]->mFaces[ 0 ].mIndices[ 1 ] = 1; scene->mMeshes[ 0 ]->mFaces[ 0 ].mIndices[ 2 ] = 2; - scene->mRootNode = new aiNode; + scene->mRootNode = new aiNode(); scene->mRootNode->mNumMeshes = 1; scene->mRootNode->mMeshes = new unsigned int[1]{ 0 }; diff --git a/test/unit/utFBXImporterExporter.cpp b/test/unit/utFBXImporterExporter.cpp index 55471c023..e597b23ff 100644 --- a/test/unit/utFBXImporterExporter.cpp +++ b/test/unit/utFBXImporterExporter.cpp @@ -188,6 +188,14 @@ TEST_F(utFBXImporterExporter, importCubesComplexTransform) { ASSERT_EQ(0u, parent->mNumChildren) << "Leaf node"; } +TEST_F(utFBXImporterExporter, importCloseToIdentityTransforms) { + Assimp::Importer importer; + // This was asserting in FBXConverter.cpp because the transforms appeared to be the identity by one test, but not by another. + // This asset should now load successfully. + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/close_to_identity_transforms.fbx", aiProcess_ValidateDataStructure); + ASSERT_TRUE(scene); +} + TEST_F( utFBXImporterExporter, importPhongMaterial ) { Assimp::Importer importer; const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/FBX/phong_cube.fbx", aiProcess_ValidateDataStructure ); diff --git a/test/unit/utScaleProcess.cpp b/test/unit/utScaleProcess.cpp index fe87daa8d..fd2773c24 100644 --- a/test/unit/utScaleProcess.cpp +++ b/test/unit/utScaleProcess.cpp @@ -69,18 +69,5 @@ TEST_F( utScaleProcess, accessScaleTest ) { EXPECT_FLOAT_EQ( 2.0f, process.getScale() ); } -TEST_F( utScaleProcess, rescaleModelTest ) { - float opacity; - aiScene *testScene = TestModelFacttory::createDefaultTestModel( opacity ); - ai_real v1 = testScene->mRootNode->mTransformation.a1; - ScaleProcess process; - process.setScale( 10.0f ); - process.Execute( testScene ); - ai_real v2 = testScene->mRootNode->mTransformation.a1; - const ai_real scale = v2 / v1; - EXPECT_FLOAT_EQ( scale, 10.0f ); - TestModelFacttory::releaseDefaultTestModel( &testScene ); -} - } // Namespace UnitTest } // Namespace Assimp diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp index 0ba5226cc..1e8e4af9d 100644 --- a/test/unit/utglTF2ImportExport.cpp +++ b/test/unit/utglTF2ImportExport.cpp @@ -380,4 +380,13 @@ TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) { EXPECT_TRUE( exporterTest() ); } +TEST_F( utglTF2ImportExport, crash_in_anim_mesh_destructor ) { + Assimp::Importer importer; + const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube.gltf", + aiProcess_ValidateDataStructure); + ASSERT_NE( nullptr, scene ); + Assimp::Exporter exporter; + ASSERT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube_out.glTF")); +} + #endif // ASSIMP_BUILD_NO_EXPORT diff --git a/tools/assimp_cmd/Main.cpp b/tools/assimp_cmd/Main.cpp index af372582c..9173a756b 100644 --- a/tools/assimp_cmd/Main.cpp +++ b/tools/assimp_cmd/Main.cpp @@ -384,6 +384,7 @@ int ProcessStandardArguments( // -om --optimize-meshes // -db --debone // -sbc --split-by-bone-count + // -gs --global-scale // // -c --config-file= @@ -472,6 +473,9 @@ int ProcessStandardArguments( else if (!strcmp(param, "-embtex") || ! strcmp(param, "--embed-textures")) { fill.ppFlags |= aiProcess_EmbedTextures; } + else if (!strcmp(param, "-gs") || ! strcmp(param, "--global-scale")) { + fill.ppFlags |= aiProcess_GlobalScale; + } else if (! strncmp( param, "-c",2) || ! strncmp( param, "--config=",9)) { const unsigned int ofs = (params[i][1] == '-' ? 9 : 2); diff --git a/tools/assimp_qt_viewer/glview.cpp b/tools/assimp_qt_viewer/glview.cpp index 97eba83a1..6ecdb0f4d 100644 --- a/tools/assimp_qt_viewer/glview.cpp +++ b/tools/assimp_qt_viewer/glview.cpp @@ -203,7 +203,7 @@ void CGLView::Matrix_NodeToRoot(const aiNode* pNode, aiMatrix4x4& pOutMatrix) } // multiply all matrices in reverse order - for ( std::list::reverse_iterator rit = mat_list.rbegin(); rit != mat_list.rend(); rit++) + for ( std::list::reverse_iterator rit = mat_list.rbegin(); rit != mat_list.rend(); ++rit) { pOutMatrix = pOutMatrix * (*rit); } @@ -729,7 +729,7 @@ void CGLView::FreeScene() { GLuint* id_tex = new GLuint[id_tex_size]; QMap::iterator it = mTexture_IDMap.begin(); - for(int idx = 0; idx < id_tex_size; idx++, it++) + for(int idx = 0; idx < id_tex_size; idx++, ++it) { id_tex[idx] = it.value(); }