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/Exporter.cpp b/code/Common/Exporter.cpp index 090b561ae..6ee2e2c57 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/FBX/FBXConverter.cpp b/code/FBX/FBXConverter.cpp index fd7929e19..6717b592f 100644 --- a/code/FBX/FBXConverter.cpp +++ b/code/FBX/FBXConverter.cpp @@ -78,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() @@ -90,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. @@ -119,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 @@ -3537,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); @@ -3630,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/FBXImporter.cpp b/code/FBX/FBXImporter.cpp index 09694a38f..c8c1a6853 100644 --- a/code/FBX/FBXImporter.cpp +++ b/code/FBX/FBXImporter.cpp @@ -185,16 +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); - - // units is relative to CM :) we need it in meters for assimp - SetFileScale( doc.GlobalSettings().UnitScaleFactor() * 0.01f); + 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/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/include/assimp/BaseImporter.h b/include/assimp/BaseImporter.h index 79a9b1b94..55f7fe375 100644 --- a/include/assimp/BaseImporter.h +++ b/include/assimp/BaseImporter.h @@ -82,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 */ @@ -134,7 +138,7 @@ public: * a suitable response to the caller. */ aiScene* ReadFile( - const Importer* pImp, + Importer* pImp, const std::string& pFile, IOSystem* pIOHandler ); @@ -209,14 +213,6 @@ public: return applicationUnits; } - /* Returns scale used by application called by ScaleProcess */ - double GetImporterScale() const - { - ai_assert(importerScale != 0); - ai_assert(fileScale != 0); - return importerScale * fileScale; - } - // ------------------------------------------------------------------- /** Called by #Importer::GetExtensionList for each loaded importer. * Take the extension list contained in the structure returned by @@ -230,6 +226,7 @@ protected: double fileScale = 1.0; + // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. The * function is expected to throw an ImportErrorException if there is