From c2baa0f59d06cc670c624c388761dd32ec1b8bee Mon Sep 17 00:00:00 2001 From: Giuseppe Barbieri Date: Fri, 8 Sep 2017 15:46:23 +0200 Subject: [PATCH 01/90] Added a link to pure jvm assimp port --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index 88dc6fbc3..a5c31881a 100644 --- a/Readme.md +++ b/Readme.md @@ -119,6 +119,7 @@ Take a look into the `INSTALL` file. Our build system is CMake, if you used CMak * [Pascal](port/AssimpPascal/Readme.md) * [Javascript (Alpha)](https://github.com/makc/assimp2json) * [Unity 3d Plugin] (https://www.assetstore.unity3d.com/en/#!/content/91777) +* [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (currently supported obj, ply, stl, ~collada) ### Other tools ### [open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities. From 2ec46cc1882f5f2ebb4402eee0ff181a7132d169 Mon Sep 17 00:00:00 2001 From: Amit Cirt Date: Sat, 9 Sep 2017 19:04:15 +0300 Subject: [PATCH 02/90] fix name lost in mesh and nodes when load with aiProcess_PreTransformVertices flag --- code/PretransformVertices.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/code/PretransformVertices.cpp b/code/PretransformVertices.cpp index 1339053f7..7bfed4292 100644 --- a/code/PretransformVertices.cpp +++ b/code/PretransformVertices.cpp @@ -160,6 +160,11 @@ void PretransformVertices::CollectData( aiScene* pcScene, aiNode* pcNode, unsign unsigned int& num_ref = num_refs[pcNode->mMeshes[i]]; ai_assert(0 != num_ref); --num_ref; + // Save the name of the last mesh + if (num_ref==0) + { + pcMeshOut->mName = pcMesh->mName; + } if (identity) { // copy positions without modifying them @@ -626,9 +631,10 @@ void PretransformVertices::Execute( aiScene* pScene) // now delete all nodes in the scene and build a new // flat node graph with a root node and some level 1 children + aiNode* newRoot = new aiNode(); + newRoot->mName = pScene->mRootNode->mName; delete pScene->mRootNode; pScene->mRootNode = new aiNode(); - pScene->mRootNode->mName.Set(""); if (1 == pScene->mNumMeshes && !pScene->mNumLights && !pScene->mNumCameras) { @@ -646,7 +652,7 @@ void PretransformVertices::Execute( aiScene* pScene) { aiNode* pcNode = *nodes = new aiNode(); pcNode->mParent = pScene->mRootNode; - pcNode->mName.length = ::ai_snprintf(pcNode->mName.data,MAXLEN,"mesh_%u",i); + pcNode->mName = pScene->mMeshes[i]->mName; // setup mesh indices pcNode->mNumMeshes = 1; From 97b67d5cb5c5ca0ccb9ccf62390dee3dbec1d3ee Mon Sep 17 00:00:00 2001 From: Jared Mulconry Date: Sun, 10 Sep 2017 18:47:24 +1000 Subject: [PATCH 03/90] Fixed warnings when compiling for x64 on MSVC through VS 2017 v15.3.3. --- code/AssbinExporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index e97f27a8a..4ea261718 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -325,7 +325,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size) { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE ); - size_t nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0); + unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0); Write(&chunk,node->mName); Write(&chunk,node->mTransformation); From 98532b45bfab304e579c7aef0b16a6cd00142500 Mon Sep 17 00:00:00 2001 From: Jared Mulconry Date: Sun, 10 Sep 2017 19:04:44 +1000 Subject: [PATCH 04/90] Fixed warnings when compiling for x64 on MSVC through VS 2017 v15.3.3. --- code/ColladaExporter.cpp | 10 +++++----- code/ColladaLoader.cpp | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/code/ColladaExporter.cpp b/code/ColladaExporter.cpp index 745975e5d..06604bc8e 100644 --- a/code/ColladaExporter.cpp +++ b/code/ColladaExporter.cpp @@ -866,8 +866,8 @@ void ColladaExporter::WriteController( size_t pIndex) std::vector bind_poses; bind_poses.reserve(mesh->mNumBones * 16); - for( size_t i = 0; i < mesh->mNumBones; ++i) - for( size_t j = 0; j < 4; ++j) + for(unsigned int i = 0; i < mesh->mNumBones; ++i) + for( unsigned int j = 0; j < 4; ++j) bind_poses.insert(bind_poses.end(), mesh->mBones[i]->mOffsetMatrix[j], mesh->mBones[i]->mOffsetMatrix[j] + 4); WriteFloatArray( idstr + "-skin-bind_poses", FloatType_Mat4x4, (const ai_real*) bind_poses.data(), bind_poses.size() / 16); @@ -924,11 +924,11 @@ void ColladaExporter::WriteController( size_t pIndex) ai_uint weight_index = 0; std::vector joint_weight_indices(2 * joint_weight_indices_length, (ai_int)-1); - for( size_t i = 0; i < mesh->mNumBones; ++i) - for( size_t j = 0; j < mesh->mBones[i]->mNumWeights; ++j) + for( unsigned int i = 0; i < mesh->mNumBones; ++i) + for( unsigned j = 0; j < mesh->mBones[i]->mNumWeights; ++j) { unsigned int vId = mesh->mBones[i]->mWeights[j].mVertexId; - for( size_t k = 0; k < num_influences[vId]; ++k) + for( ai_uint k = 0; k < num_influences[vId]; ++k) { if (joint_weight_indices[2 * (accum_influences[vId] + k)] == -1) { diff --git a/code/ColladaLoader.cpp b/code/ColladaLoader.cpp index c68eb27c9..f7ef903f4 100644 --- a/code/ColladaLoader.cpp +++ b/code/ColladaLoader.cpp @@ -728,7 +728,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada:: ? aiMorphingMethod_MORPH_RELATIVE : aiMorphingMethod_MORPH_NORMALIZED; dstMesh->mAnimMeshes = new aiAnimMesh*[animMeshes.size()]; - dstMesh->mNumAnimMeshes = animMeshes.size(); + dstMesh->mNumAnimMeshes = static_cast(animMeshes.size()); for (unsigned int i = 0; i < animMeshes.size(); i++) dstMesh->mAnimMeshes[i] = animMeshes.at(i); } @@ -1377,9 +1377,9 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars { aiNodeAnim* dstAnim = new aiNodeAnim; dstAnim->mNodeName = nodeName; - dstAnim->mNumPositionKeys = resultTrafos.size(); - dstAnim->mNumRotationKeys= resultTrafos.size(); - dstAnim->mNumScalingKeys = resultTrafos.size(); + dstAnim->mNumPositionKeys = static_cast(resultTrafos.size()); + dstAnim->mNumRotationKeys = static_cast(resultTrafos.size()); + dstAnim->mNumScalingKeys = static_cast(resultTrafos.size()); dstAnim->mPositionKeys = new aiVectorKey[resultTrafos.size()]; dstAnim->mRotationKeys = new aiQuatKey[resultTrafos.size()]; dstAnim->mScalingKeys = new aiVectorKey[resultTrafos.size()]; @@ -1445,11 +1445,11 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars ++morphAnimChannelIndex; } - morphAnim->mNumKeys = morphTimeValues.size(); + morphAnim->mNumKeys = static_cast(morphTimeValues.size()); morphAnim->mKeys = new aiMeshMorphKey[morphAnim->mNumKeys]; for (unsigned int key = 0; key < morphAnim->mNumKeys; key++) { - morphAnim->mKeys[key].mNumValuesAndWeights = morphChannels.size(); + morphAnim->mKeys[key].mNumValuesAndWeights = static_cast(morphChannels.size()); morphAnim->mKeys[key].mValues = new unsigned int [morphChannels.size()]; morphAnim->mKeys[key].mWeights = new double [morphChannels.size()]; @@ -1470,13 +1470,13 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars { aiAnimation* anim = new aiAnimation; anim->mName.Set( pName); - anim->mNumChannels = anims.size(); + anim->mNumChannels = static_cast(anims.size()); if (anim->mNumChannels > 0) { anim->mChannels = new aiNodeAnim*[anims.size()]; std::copy( anims.begin(), anims.end(), anim->mChannels); } - anim->mNumMorphMeshChannels = morphAnims.size(); + anim->mNumMorphMeshChannels = static_cast(morphAnims.size()); if (anim->mNumMorphMeshChannels > 0) { anim->mMorphMeshChannels = new aiMeshMorphAnim*[anim->mNumMorphMeshChannels]; From b7f1277175236b6ce935b9ca9cc2b210b47905b3 Mon Sep 17 00:00:00 2001 From: Jared Mulconry Date: Sun, 10 Sep 2017 19:07:37 +1000 Subject: [PATCH 05/90] Fixed warnings when compiling for x64 on MSVC through VS 2017 v15.3.3. --- code/ObjFileMtlImporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ObjFileMtlImporter.cpp b/code/ObjFileMtlImporter.cpp index 69f35a67d..36bb6c2cb 100644 --- a/code/ObjFileMtlImporter.cpp +++ b/code/ObjFileMtlImporter.cpp @@ -304,7 +304,7 @@ void ObjFileMtlImporter::createMaterial() m_pModel->m_pCurrentMaterial = new ObjFile::Material(); m_pModel->m_pCurrentMaterial->MaterialName.Set( name ); if (m_pModel->m_pCurrentMesh) { - m_pModel->m_pCurrentMesh->m_uiMaterialIndex = m_pModel->m_MaterialLib.size() - 1; + m_pModel->m_pCurrentMesh->m_uiMaterialIndex = static_cast(m_pModel->m_MaterialLib.size() - 1); } m_pModel->m_MaterialLib.push_back( name ); m_pModel->m_MaterialMap[ name ] = m_pModel->m_pCurrentMaterial; From 6e02bcd8d6b187d10f30c536dbd2e3bf3c3af85d Mon Sep 17 00:00:00 2001 From: Jared Mulconry Date: Sun, 10 Sep 2017 19:10:59 +1000 Subject: [PATCH 06/90] Fixed warnings when compiling for x64 on MSVC through VS 2017 v15.3.3. --- code/PlyParser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/PlyParser.cpp b/code/PlyParser.cpp index d978b513b..f4b68a83f 100644 --- a/code/PlyParser.cpp +++ b/code/PlyParser.cpp @@ -618,7 +618,7 @@ bool PLY::DOM::ParseInstanceBinary(IOStreamBuffer &streamBuffer, DOM* p_pc } streamBuffer.getNextBlock(buffer); - unsigned int bufferSize = buffer.size(); + unsigned int bufferSize = static_cast(buffer.size()); const char* pCur = (char*)&buffer[0]; if (!p_pcOut->ParseElementInstanceListsBinary(streamBuffer, buffer, pCur, bufferSize, loader, p_bBE)) { @@ -1025,7 +1025,7 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer &streamBuffer, buffer = std::vector(buffer.end() - bufferSize, buffer.end()); buffer.insert(buffer.end(), nbuffer.begin(), nbuffer.end()); nbuffer.clear(); - bufferSize = buffer.size(); + bufferSize = static_cast(buffer.size()); pCur = (char*)&buffer[0]; } else From 6db0a63d6ef5e2b70014d342810955abc6cec088 Mon Sep 17 00:00:00 2001 From: Jared Mulconry Date: Sun, 10 Sep 2017 19:13:12 +1000 Subject: [PATCH 07/90] Fixed warnings when compiling for x64 on MSVC through VS 2017 v15.3.3. --- code/IFCProfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/IFCProfile.cpp b/code/IFCProfile.cpp index e94d98a04..595159a6b 100644 --- a/code/IFCProfile.cpp +++ b/code/IFCProfile.cpp @@ -128,7 +128,7 @@ void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout.verts.push_back( IfcVector3( std::cos(angle)*radius, std::sin(angle)*radius, 0.f )); } - meshout.vertcnt.push_back(segments); + meshout.vertcnt.push_back(static_cast(segments)); } else if( const IfcIShapeProfileDef* const ishape = def.ToPtr()) { // construct simplified IBeam shape From 1167edaeca09b07a8ea20036d83d626180d48175 Mon Sep 17 00:00:00 2001 From: Jared Mulconry Date: Mon, 11 Sep 2017 00:09:35 +1000 Subject: [PATCH 08/90] Fixed warnings when compiling for x64 on MSVC through VS 2017 v15.3.3. --- code/MMDImporter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/MMDImporter.cpp b/code/MMDImporter.cpp index 149761c34..84797cba2 100644 --- a/code/MMDImporter.cpp +++ b/code/MMDImporter.cpp @@ -278,7 +278,7 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel, bone_vertex_map[vsBDEF2_ptr->bone_index1].push_back( aiVertexWeight(index, vsBDEF2_ptr->bone_weight)); bone_vertex_map[vsBDEF2_ptr->bone_index2].push_back( - aiVertexWeight(index, 1.0 - vsBDEF2_ptr->bone_weight)); + aiVertexWeight(index, 1.0f - vsBDEF2_ptr->bone_weight)); break; case pmx::PmxVertexSkinningType::BDEF4: bone_vertex_map[vsBDEF4_ptr->bone_index1].push_back( @@ -295,7 +295,7 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel, bone_vertex_map[vsSDEF_ptr->bone_index1].push_back( aiVertexWeight(index, vsSDEF_ptr->bone_weight)); bone_vertex_map[vsSDEF_ptr->bone_index2].push_back( - aiVertexWeight(index, 1.0 - vsSDEF_ptr->bone_weight)); + aiVertexWeight(index, 1.0f - vsSDEF_ptr->bone_weight)); break; case pmx::PmxVertexSkinningType::QDEF: const auto vsQDEF_ptr = @@ -325,7 +325,7 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel, aiMatrix4x4::Translation(-pos, pBone->mOffsetMatrix); auto it = bone_vertex_map.find(ii); if (it != bone_vertex_map.end()) { - pBone->mNumWeights = it->second.size(); + pBone->mNumWeights = static_cast(it->second.size()); pBone->mWeights = it->second.data(); it->second.swap(*(new vector)); } From e40cd6c13c0d5c85e932c4d958c4c13d8b6d1d20 Mon Sep 17 00:00:00 2001 From: Jared Mulconry Date: Mon, 11 Sep 2017 00:09:40 +1000 Subject: [PATCH 09/90] Fixed warnings when compiling for x64 on MSVC through VS 2017 v15.3.3. --- code/X3DImporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/X3DImporter.cpp b/code/X3DImporter.cpp index 669f46f95..aaf99b309 100644 --- a/code/X3DImporter.cpp +++ b/code/X3DImporter.cpp @@ -558,7 +558,7 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector WordIterator wordItBegin(val, val + strlen(val)); WordIterator wordItEnd; - std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return atof(match); }); + std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return static_cast(atof(match)); }); } } From 698cd5826d5be44964a24fb32a1c3c92f0d8daac Mon Sep 17 00:00:00 2001 From: Jared Mulconry Date: Mon, 11 Sep 2017 00:16:26 +1000 Subject: [PATCH 10/90] Fixed warnings when compiling for x64 on MSVC through VS 2017 v15.3.3. --- code/glTF2Asset.inl | 2 +- code/glTF2Exporter.cpp | 10 +++++----- code/glTFExporter.cpp | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 44a1cce00..09e647cca 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -242,7 +242,7 @@ Ref LazyDict::Create(const char* id) } T* inst = new T(); inst->id = id; - inst->index = mObjs.size(); + inst->index = static_cast(mObjs.size()); return Add(inst); } diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 11694a89d..7daef7000 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -886,7 +886,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, RefmPositionKeys[frameIndex].mTime / ticksPerSecond; } - Ref timeAccessor = ExportData(mAsset, animId, buffer, numKeyframes, &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT); + Ref timeAccessor = ExportData(mAsset, animId, buffer, static_cast(numKeyframes), &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT); if (timeAccessor) animRef->Parameters.TIME = timeAccessor; } @@ -899,7 +899,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, RefmPositionKeys[frameIndex].mValue; } - Ref tranAccessor = ExportData(mAsset, animId, buffer, numKeyframes, translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); + Ref tranAccessor = ExportData(mAsset, animId, buffer, static_cast(numKeyframes), translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); if ( tranAccessor ) { animRef->Parameters.translation = tranAccessor; } @@ -915,7 +915,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, RefmScalingKeys[frameIndex].mValue; } - Ref scaleAccessor = ExportData(mAsset, animId, buffer, numKeyframes, scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); + Ref scaleAccessor = ExportData(mAsset, animId, buffer, static_cast(numKeyframes), scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); if ( scaleAccessor ) { animRef->Parameters.scale = scaleAccessor; } @@ -934,7 +934,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, RefmRotationKeys[frameIndex].mValue.w; } - Ref rotAccessor = ExportData(mAsset, animId, buffer, numKeyframes, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); + Ref rotAccessor = ExportData(mAsset, animId, buffer, static_cast(numKeyframes), rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); if ( rotAccessor ) { animRef->Parameters.rotation = rotAccessor; } @@ -989,7 +989,7 @@ void glTF2Exporter::ExportAnimations() Animation::AnimChannel tmpAnimChannel; Animation::AnimSampler tmpAnimSampler; - tmpAnimChannel.sampler = animRef->Samplers.size(); + tmpAnimChannel.sampler = static_cast(animRef->Samplers.size()); tmpAnimChannel.target.path = channelType; tmpAnimSampler.output = channelType; tmpAnimSampler.id = name + "_" + channelType; diff --git a/code/glTFExporter.cpp b/code/glTFExporter.cpp index f3fa5e526..8967a7aa7 100644 --- a/code/glTFExporter.cpp +++ b/code/glTFExporter.cpp @@ -875,7 +875,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, RefmPositionKeys[frameIndex].mTime / ticksPerSecond; } - Ref timeAccessor = ExportData(mAsset, animId, buffer, numKeyframes, &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT); + Ref timeAccessor = ExportData(mAsset, animId, buffer, static_cast(numKeyframes), &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT); if (timeAccessor) animRef->Parameters.TIME = timeAccessor; } @@ -888,7 +888,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, RefmPositionKeys[frameIndex].mValue; } - Ref tranAccessor = ExportData(mAsset, animId, buffer, numKeyframes, translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); + Ref tranAccessor = ExportData(mAsset, animId, buffer, static_cast(numKeyframes), translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); if ( tranAccessor ) { animRef->Parameters.translation = tranAccessor; } @@ -904,7 +904,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, RefmScalingKeys[frameIndex].mValue; } - Ref scaleAccessor = ExportData(mAsset, animId, buffer, numKeyframes, scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); + Ref scaleAccessor = ExportData(mAsset, animId, buffer, static_cast(numKeyframes), scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); if ( scaleAccessor ) { animRef->Parameters.scale = scaleAccessor; } @@ -923,7 +923,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, RefmRotationKeys[frameIndex].mValue.w; } - Ref rotAccessor = ExportData(mAsset, animId, buffer, numKeyframes, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); + Ref rotAccessor = ExportData(mAsset, animId, buffer, static_cast(numKeyframes), rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); if ( rotAccessor ) { animRef->Parameters.rotation = rotAccessor; } From 63d3655f1b8b73e3c15799e061baaa8fa95e086f Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Thu, 24 Aug 2017 17:15:48 -0400 Subject: [PATCH 11/90] Duplicate gltfImporter as gltf2Importer; Include glTF2 importer in CMake List --- code/CMakeLists.txt | 2 + code/ImporterRegistry.cpp | 4 +- code/glTF2Importer.cpp | 680 ++++++++++++++++++++++++++++++++++++++ code/glTF2Importer.h | 91 +++++ 4 files changed, 775 insertions(+), 2 deletions(-) create mode 100644 code/glTF2Importer.cpp create mode 100644 code/glTF2Importer.h diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 236e6d7ef..0e7aad6cc 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -665,6 +665,8 @@ ADD_ASSIMP_IMPORTER( GLTF glTF2Asset.inl glTF2AssetWriter.h glTF2AssetWriter.inl + glTF2Importer.cpp + glTF2Importer.h glTF2Exporter.h glTF2Exporter.cpp ) diff --git a/code/ImporterRegistry.cpp b/code/ImporterRegistry.cpp index afc308075..2b5d9c1a0 100644 --- a/code/ImporterRegistry.cpp +++ b/code/ImporterRegistry.cpp @@ -181,7 +181,7 @@ corresponding preprocessor flag to selectively disable formats. # include "AssbinLoader.h" #endif #ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER -# include "glTFImporter.h" +# include "glTF2Importer.h" #endif #ifndef ASSIMP_BUILD_NO_C4D_IMPORTER # include "C4DImporter.h" @@ -335,7 +335,7 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out) out.push_back( new AssbinImporter() ); #endif #if ( !defined ASSIMP_BUILD_NO_GLTF_IMPORTER ) - out.push_back( new glTFImporter() ); + out.push_back( new glTF2Importer() ); #endif #if ( !defined ASSIMP_BUILD_NO_C4D_IMPORTER ) out.push_back( new C4DImporter() ); diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp new file mode 100644 index 000000000..bd4f42600 --- /dev/null +++ b/code/glTF2Importer.cpp @@ -0,0 +1,680 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2017, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER + +#include "glTF2Importer.h" +#include "StringComparison.h" +#include "StringUtils.h" + +#include +#include +#include +#include +#include + +#include + +#include "MakeVerboseFormat.h" + +#include "glTF2Asset.h" +// This is included here so WriteLazyDict's definition is found. +#include "glTF2AssetWriter.h" + +using namespace Assimp; +using namespace glTF2; + + +// +// glTF2Importer +// + +static const aiImporterDesc desc = { + "glTF2 Importer", + "", + "", + "", + aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour + | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental, + 0, + 0, + 0, + 0, + "gltf glb" +}; + +glTF2Importer::glTF2Importer() +: BaseImporter() +, meshOffsets() +, embeddedTexIdxs() +, mScene( NULL ) { + // empty +} + +glTF2Importer::~glTF2Importer() { + // empty +} + +const aiImporterDesc* glTF2Importer::GetInfo() const +{ + return &desc; +} + +bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const +{ + const std::string& extension = GetExtension(pFile); + + if (extension == "gltf" || extension == "glb") + return true; + + if ((checkSig || !extension.length()) && pIOHandler) { + char buffer[4]; + + std::unique_ptr pStream(pIOHandler->Open(pFile)); + if (pStream && pStream->Read(buffer, sizeof(buffer), 1) == 1) { + if (memcmp(buffer, AI_GLB_MAGIC_NUMBER, sizeof(buffer)) == 0) { + return true; // Has GLB header + } + else if (memcmp(buffer, "{\r\n ", sizeof(buffer)) == 0 + || memcmp(buffer, "{\n ", sizeof(buffer)) == 0) { + // seems a JSON file, and we're the only format that can read them + return true; + } + } + } + + return false; +} + + + +//static void CopyValue(const glTF2::vec3& v, aiColor3D& out) +//{ +// out.r = v[0]; out.g = v[1]; out.b = v[2]; +//} + +static void CopyValue(const glTF2::vec4& v, aiColor4D& out) +{ + out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3]; +} + +static void CopyValue(const glTF2::vec4& v, aiColor3D& out) +{ + out.r = v[0]; out.g = v[1]; out.b = v[2]; +} + +static void CopyValue(const glTF2::vec3& v, aiVector3D& out) +{ + out.x = v[0]; out.y = v[1]; out.z = v[2]; +} + +static void CopyValue(const glTF2::vec4& v, aiQuaternion& out) +{ + out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3]; +} + +static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o) +{ + o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3]; + o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7]; + o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11]; + o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15]; +} + +inline void SetMaterialColorProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::TexProperty prop, aiMaterial* mat, + aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx) +{ + if (prop.texture) { + if (prop.texture->source) { + aiString uri(prop.texture->source->uri); + + int texIdx = embeddedTexIdxs[prop.texture->source.GetIndex()]; + if (texIdx != -1) { // embedded + // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture) + uri.data[0] = '*'; + uri.length = 1 + ASSIMP_itoa10(uri.data + 1, MAXLEN - 1, texIdx); + } + + mat->AddProperty(&uri, _AI_MATKEY_TEXTURE_BASE, texType, 0); + } + } + else { + aiColor4D col; + CopyValue(prop.color, col); + mat->AddProperty(&col, 1, pKey, type, idx); + } +} + +void glTF2Importer::ImportMaterials(glTF2::Asset& r) +{ + mScene->mNumMaterials = unsigned(r.materials.Size()); + mScene->mMaterials = new aiMaterial*[mScene->mNumMaterials]; + + for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) { + aiMaterial* aimat = mScene->mMaterials[i] = new aiMaterial(); + + Material& mat = r.materials[i]; + + /*if (!mat.name.empty())*/ { + aiString str(mat.id /*mat.name*/); + aimat->AddProperty(&str, AI_MATKEY_NAME); + } + + SetMaterialColorProperty(embeddedTexIdxs, r, mat.diffuse, aimat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE); + SetMaterialColorProperty(embeddedTexIdxs, r, mat.specular, aimat, aiTextureType_SPECULAR, AI_MATKEY_COLOR_SPECULAR); + SetMaterialColorProperty(embeddedTexIdxs, r, mat.ambient, aimat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT); + + if (mat.shininess > 0.f) { + aimat->AddProperty(&mat.shininess, 1, AI_MATKEY_SHININESS); + } + } +} + + +static inline void SetFace(aiFace& face, int a) +{ + face.mNumIndices = 1; + face.mIndices = new unsigned int[1]; + face.mIndices[0] = a; +} + +static inline void SetFace(aiFace& face, int a, int b) +{ + face.mNumIndices = 2; + face.mIndices = new unsigned int[2]; + face.mIndices[0] = a; + face.mIndices[1] = b; +} + +static inline void SetFace(aiFace& face, int a, int b, int c) +{ + face.mNumIndices = 3; + face.mIndices = new unsigned int[3]; + face.mIndices[0] = a; + face.mIndices[1] = b; + face.mIndices[2] = c; +} + +static inline bool CheckValidFacesIndices(aiFace* faces, unsigned nFaces, unsigned nVerts) +{ + for (unsigned i = 0; i < nFaces; ++i) { + for (unsigned j = 0; j < faces[i].mNumIndices; ++j) { + unsigned idx = faces[i].mIndices[j]; + if (idx >= nVerts) + return false; + } + } + return true; +} + +void glTF2Importer::ImportMeshes(glTF2::Asset& r) +{ + std::vector meshes; + + unsigned int k = 0; + + for (unsigned int m = 0; m < r.meshes.Size(); ++m) { + Mesh& mesh = r.meshes[m]; + + // Check if mesh extensions is used + if(mesh.Extension.size() > 0) + { + for(Mesh::SExtension* cur_ext : mesh.Extension) + { +#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC + if(cur_ext->Type == Mesh::SExtension::EType::Compression_Open3DGC) + { + // Limitations for meshes when using Open3DGC-compression. + // It's a current limitation of sp... Specification have not this part still - about mesh compression. Why only one primitive? + // Because glTF is very flexibly. But in fact it ugly flexible. Every primitive can has own set of accessors and accessors can + // point to a-a-a-a-any part of buffer (through bufferview of course) and even to another buffer. We know that "Open3DGC-compression" + // is applicable only to part of buffer. As we can't guaranty continuity of the data for decoder, we will limit quantity of primitives. + // Yes indices, coordinates etc. still can br stored in different buffers, but with current specification it's a exporter problem. + // Also primitive can has only one of "POSITION", "NORMAL" and less then "AI_MAX_NUMBER_OF_TEXTURECOORDS" of "TEXCOORD". All accessor + // of primitive must point to one continuous region of the buffer. + if(mesh.primitives.size() > 2) throw DeadlyImportError("GLTF: When using Open3DGC compression then only one primitive per mesh are allowed."); + + Mesh::SCompression_Open3DGC* o3dgc_ext = (Mesh::SCompression_Open3DGC*)cur_ext; + Ref buf = r.buffers.Get(o3dgc_ext->Buffer); + + buf->EncodedRegion_SetCurrent(mesh.id); + } + else +#endif + { + throw DeadlyImportError("GLTF: Can not import mesh: unknown mesh extension (code: \"" + to_string(cur_ext->Type) + + "\"), only Open3DGC is supported."); + } + } + }// if(mesh.Extension.size() > 0) + + meshOffsets.push_back(k); + k += unsigned(mesh.primitives.size()); + + for (unsigned int p = 0; p < mesh.primitives.size(); ++p) { + Mesh::Primitive& prim = mesh.primitives[p]; + + aiMesh* aim = new aiMesh(); + meshes.push_back(aim); + + aim->mName = mesh.id; + if (mesh.primitives.size() > 1) { + size_t& len = aim->mName.length; + aim->mName.data[len] = '-'; + len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p); + } + + switch (prim.mode) { + case PrimitiveMode_POINTS: + aim->mPrimitiveTypes |= aiPrimitiveType_POINT; + break; + + case PrimitiveMode_LINES: + case PrimitiveMode_LINE_LOOP: + case PrimitiveMode_LINE_STRIP: + aim->mPrimitiveTypes |= aiPrimitiveType_LINE; + break; + + case PrimitiveMode_TRIANGLES: + case PrimitiveMode_TRIANGLE_STRIP: + case PrimitiveMode_TRIANGLE_FAN: + aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; + break; + } + + Mesh::Primitive::Attributes& attr = prim.attributes; + + if (attr.position.size() > 0 && attr.position[0]) { + aim->mNumVertices = attr.position[0]->count; + attr.position[0]->ExtractData(aim->mVertices); + } + + if (attr.normal.size() > 0 && attr.normal[0]) attr.normal[0]->ExtractData(aim->mNormals); + + for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) { + attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]); + aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents(); + + aiVector3D* values = aim->mTextureCoords[tc]; + for (unsigned int i = 0; i < aim->mNumVertices; ++i) { + values[i].y = 1 - values[i].y; // Flip Y coords + } + } + + + if (prim.indices) { + aiFace* faces = 0; + unsigned int nFaces = 0; + + unsigned int count = prim.indices->count; + + Accessor::Indexer data = prim.indices->GetIndexer(); + ai_assert(data.IsValid()); + + switch (prim.mode) { + case PrimitiveMode_POINTS: { + nFaces = count; + faces = new aiFace[nFaces]; + for (unsigned int i = 0; i < count; ++i) { + SetFace(faces[i], data.GetUInt(i)); + } + break; + } + + case PrimitiveMode_LINES: { + nFaces = count / 2; + faces = new aiFace[nFaces]; + for (unsigned int i = 0; i < count; i += 2) { + SetFace(faces[i / 2], data.GetUInt(i), data.GetUInt(i + 1)); + } + break; + } + + case PrimitiveMode_LINE_LOOP: + case PrimitiveMode_LINE_STRIP: { + nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0); + faces = new aiFace[nFaces]; + SetFace(faces[0], data.GetUInt(0), data.GetUInt(1)); + for (unsigned int i = 2; i < count; ++i) { + SetFace(faces[i - 1], faces[i - 2].mIndices[1], data.GetUInt(i)); + } + if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop + SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]); + } + break; + } + + case PrimitiveMode_TRIANGLES: { + nFaces = count / 3; + faces = new aiFace[nFaces]; + for (unsigned int i = 0; i < count; i += 3) { + SetFace(faces[i / 3], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2)); + } + break; + } + case PrimitiveMode_TRIANGLE_STRIP: { + nFaces = count - 2; + faces = new aiFace[nFaces]; + SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2)); + for (unsigned int i = 3; i < count; ++i) { + SetFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], data.GetUInt(i)); + } + break; + } + case PrimitiveMode_TRIANGLE_FAN: + nFaces = count - 2; + faces = new aiFace[nFaces]; + SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2)); + for (unsigned int i = 3; i < count; ++i) { + SetFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i)); + } + break; + } + + if (faces) { + aim->mFaces = faces; + aim->mNumFaces = nFaces; + ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices)); + } + } + + + if (prim.material) { + aim->mMaterialIndex = prim.material.GetIndex(); + } + } + } + + meshOffsets.push_back(k); + + CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes); +} + +void glTF2Importer::ImportCameras(glTF2::Asset& r) +{ + if (!r.cameras.Size()) return; + + mScene->mNumCameras = r.cameras.Size(); + mScene->mCameras = new aiCamera*[r.cameras.Size()]; + + for (size_t i = 0; i < r.cameras.Size(); ++i) { + Camera& cam = r.cameras[i]; + + aiCamera* aicam = mScene->mCameras[i] = new aiCamera(); + + if (cam.type == Camera::Perspective) { + + aicam->mAspect = cam.cameraProperties.perspective.aspectRatio; + aicam->mHorizontalFOV = cam.cameraProperties.perspective.yfov * aicam->mAspect; + aicam->mClipPlaneFar = cam.cameraProperties.perspective.zfar; + aicam->mClipPlaneNear = cam.cameraProperties.perspective.znear; + } + else { + // assimp does not support orthographic cameras + } + } +} + +void glTF2Importer::ImportLights(glTF2::Asset& r) +{ + if (!r.lights.Size()) return; + + mScene->mNumLights = r.lights.Size(); + mScene->mLights = new aiLight*[r.lights.Size()]; + + for (size_t i = 0; i < r.lights.Size(); ++i) { + Light& l = r.lights[i]; + + aiLight* ail = mScene->mLights[i] = new aiLight(); + + switch (l.type) { + case Light::Type_directional: + ail->mType = aiLightSource_DIRECTIONAL; break; + + case Light::Type_spot: + ail->mType = aiLightSource_SPOT; break; + + case Light::Type_ambient: + ail->mType = aiLightSource_AMBIENT; break; + + default: // Light::Type_point + ail->mType = aiLightSource_POINT; break; + } + + CopyValue(l.color, ail->mColorAmbient); + CopyValue(l.color, ail->mColorDiffuse); + CopyValue(l.color, ail->mColorSpecular); + + ail->mAngleOuterCone = l.falloffAngle; + ail->mAngleInnerCone = l.falloffExponent; // TODO fix this, it does not look right at all + + ail->mAttenuationConstant = l.constantAttenuation; + ail->mAttenuationLinear = l.linearAttenuation; + ail->mAttenuationQuadratic = l.quadraticAttenuation; + } +} + + +aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector& meshOffsets, glTF2::Ref& ptr) +{ + Node& node = *ptr; + + aiNode* ainode = new aiNode(node.id); + + if (!node.children.empty()) { + ainode->mNumChildren = unsigned(node.children.size()); + ainode->mChildren = new aiNode*[ainode->mNumChildren]; + + for (unsigned int i = 0; i < ainode->mNumChildren; ++i) { + aiNode* child = ImportNode(pScene, r, meshOffsets, node.children[i]); + child->mParent = ainode; + ainode->mChildren[i] = child; + } + } + + aiMatrix4x4& matrix = ainode->mTransformation; + if (node.matrix.isPresent) { + CopyValue(node.matrix.value, matrix); + } + else { + if (node.translation.isPresent) { + aiVector3D trans; + CopyValue(node.translation.value, trans); + aiMatrix4x4 t; + aiMatrix4x4::Translation(trans, t); + matrix = t * matrix; + } + + if (node.scale.isPresent) { + aiVector3D scal(1.f); + CopyValue(node.scale.value, scal); + aiMatrix4x4 s; + aiMatrix4x4::Scaling(scal, s); + matrix = s * matrix; + } + + + if (node.rotation.isPresent) { + aiQuaternion rot; + CopyValue(node.rotation.value, rot); + matrix = aiMatrix4x4(rot.GetMatrix()) * matrix; + } + } + + if (!node.meshes.empty()) { + int count = 0; + for (size_t i = 0; i < node.meshes.size(); ++i) { + int idx = node.meshes[i].GetIndex(); + count += meshOffsets[idx + 1] - meshOffsets[idx]; + } + + ainode->mNumMeshes = count; + ainode->mMeshes = new unsigned int[count]; + + int k = 0; + for (size_t i = 0; i < node.meshes.size(); ++i) { + int idx = node.meshes[i].GetIndex(); + for (unsigned int j = meshOffsets[idx]; j < meshOffsets[idx + 1]; ++j, ++k) { + ainode->mMeshes[k] = j; + } + } + } + + if (node.camera) { + pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName; + } + + if (node.light) { + pScene->mLights[node.light.GetIndex()]->mName = ainode->mName; + } + + return ainode; +} + +void glTF2Importer::ImportNodes(glTF2::Asset& r) +{ + if (!r.scene) return; + + std::vector< Ref > rootNodes = r.scene->nodes; + + // The root nodes + unsigned int numRootNodes = unsigned(rootNodes.size()); + if (numRootNodes == 1) { // a single root node: use it + mScene->mRootNode = ImportNode(mScene, r, meshOffsets, rootNodes[0]); + } + else if (numRootNodes > 1) { // more than one root node: create a fake root + aiNode* root = new aiNode("ROOT"); + root->mChildren = new aiNode*[numRootNodes]; + for (unsigned int i = 0; i < numRootNodes; ++i) { + aiNode* node = ImportNode(mScene, r, meshOffsets, rootNodes[i]); + node->mParent = root; + root->mChildren[root->mNumChildren++] = node; + } + mScene->mRootNode = root; + } + + //if (!mScene->mRootNode) { + // mScene->mRootNode = new aiNode("EMPTY"); + //} +} + +void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset& r) +{ + embeddedTexIdxs.resize(r.images.Size(), -1); + + int numEmbeddedTexs = 0; + for (size_t i = 0; i < r.images.Size(); ++i) { + if (r.images[i].HasData()) + numEmbeddedTexs += 1; + } + + if (numEmbeddedTexs == 0) + return; + + mScene->mTextures = new aiTexture*[numEmbeddedTexs]; + + // Add the embedded textures + for (size_t i = 0; i < r.images.Size(); ++i) { + Image img = r.images[i]; + if (!img.HasData()) continue; + + int idx = mScene->mNumTextures++; + embeddedTexIdxs[i] = idx; + + aiTexture* tex = mScene->mTextures[idx] = new aiTexture(); + + size_t length = img.GetDataLength(); + void* data = img.StealData(); + + tex->mWidth = static_cast(length); + tex->mHeight = 0; + tex->pcData = reinterpret_cast(data); + + if (!img.mimeType.empty()) { + const char* ext = strchr(img.mimeType.c_str(), '/') + 1; + if (ext) { + if (strcmp(ext, "jpeg") == 0) ext = "jpg"; + + size_t len = strlen(ext); + if (len <= 3) { + strcpy(tex->achFormatHint, ext); + } + } + } + } +} + +void glTF2Importer::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) { + + this->mScene = pScene; + + // read the asset file + glTF2::Asset asset(pIOHandler); + asset.Load(pFile, GetExtension(pFile) == "glb"); + + + // + // Copy the data out + // + + ImportEmbeddedTextures(asset); + ImportMaterials(asset); + + ImportMeshes(asset); + + ImportCameras(asset); + ImportLights(asset); + + ImportNodes(asset); + + // TODO: it does not split the loaded vertices, should it? + //pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT; + MakeVerboseFormatProcess process; + process.Execute(pScene); + + + if (pScene->mNumMeshes == 0) { + pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; + } +} + +#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER + diff --git a/code/glTF2Importer.h b/code/glTF2Importer.h new file mode 100644 index 000000000..6be7131d1 --- /dev/null +++ b/code/glTF2Importer.h @@ -0,0 +1,91 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2017, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +#ifndef AI_GLTF2IMPORTER_H_INC +#define AI_GLTF2IMPORTER_H_INC + +#include "BaseImporter.h" +#include + +struct aiNode; + + +namespace glTF2 +{ + class Asset; +} + +namespace Assimp { + +/** + * Load the glTF2 format. + * https://github.com/KhronosGroup/glTF/tree/master/specification + */ +class glTF2Importer : public BaseImporter{ +public: + glTF2Importer(); + virtual ~glTF2Importer(); + virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const; + +protected: + virtual const aiImporterDesc* GetInfo() const; + virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ); + +private: + + std::vector meshOffsets; + + std::vector embeddedTexIdxs; + + aiScene* mScene; + + void ImportEmbeddedTextures(glTF2::Asset& a); + void ImportMaterials(glTF2::Asset& a); + void ImportMeshes(glTF2::Asset& a); + void ImportCameras(glTF2::Asset& a); + void ImportLights(glTF2::Asset& a); + void ImportNodes(glTF2::Asset& a); + +}; + +} // Namespace assimp + +#endif // AI_GLTF2IMPORTER_H_INC + From f814acf33a553b38900b7bd2591d2864aeacdb34 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Thu, 24 Aug 2017 17:31:33 -0400 Subject: [PATCH 12/90] Update glTF2 Asset to use indexes --- code/glTF2Asset.h | 6 +- code/glTF2Asset.inl | 309 +++++++++++--------------------------------- 2 files changed, 76 insertions(+), 239 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 52bc18268..2e7a694d8 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -232,7 +232,7 @@ namespace glTF2 case ComponentType_UNSIGNED_BYTE: return 1; default: - throw DeadlyImportError("GLTF: Unsupported Component Type "+t); + throw DeadlyImportError("GLTF: Unsupported Component Type " + std::to_string(t)); } } @@ -629,7 +629,7 @@ namespace glTF2 float zfar; //! The floating-point distance to the far clipping plane. (required) float znear; //! The floating-point distance to the near clipping plane. (required) } ortographic; - }; + } cameraProperties; Camera() {} void Read(Value& obj, Asset& r); @@ -1146,7 +1146,7 @@ namespace glTF2 LazyDict samplers; LazyDict scenes; //LazyDict shaders; - LazyDict skins; + LazyDict skins; //LazyDict techniques; LazyDict textures; diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 09e647cca..268deb8a8 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -128,6 +128,12 @@ namespace { return (it != val.MemberEnd() && it->value.IsString()) ? &it->value : 0; } + inline Value* FindUInt(Value& val, const char* id) + { + Value::MemberIterator it = val.FindMember(id); + return (it != val.MemberEnd() && it->value.IsUint()) ? &it->value : 0; + } + inline Value* FindArray(Value& val, const char* id) { Value::MemberIterator it = val.FindMember(id); @@ -176,7 +182,7 @@ inline void LazyDict::AttachToDocument(Document& doc) } if (container) { - mDict = FindObject(*container, mDictId); + mDict = FindArray(*container, mDictId); } } @@ -189,13 +195,8 @@ inline void LazyDict::DetachFromDocument() template Ref LazyDict::Get(unsigned int i) { - return Ref(mObjs, i); -} -template -Ref LazyDict::Get(const char* id) -{ - id = T::TranslateId(mAsset, id); + std::string id = std::string(mDictId) + "[" + std::to_string(i) + "]"; typename Dict::iterator it = mObjsById.find(id); if (it != mObjsById.end()) { // already created? @@ -207,19 +208,21 @@ Ref LazyDict::Get(const char* id) throw DeadlyImportError("GLTF: Missing section \"" + std::string(mDictId) + "\""); } - Value::MemberIterator obj = mDict->FindMember(id); - if (obj == mDict->MemberEnd()) { - throw DeadlyImportError("GLTF: Missing object with id \"" + std::string(id) + "\" in \"" + mDictId + "\""); + if (!mDict->IsArray()) { + throw DeadlyImportError("GLTF: Field is not an array \"" + std::string(mDictId) + "\""); } - if (!obj->value.IsObject()) { - throw DeadlyImportError("GLTF: Object with id \"" + std::string(id) + "\" is not a JSON object"); + + Value& obj = mDict->operator[](i); + + if (!obj.IsObject()) { + throw DeadlyImportError("GLTF: Object at index \"" + std::to_string(i) + "\" is not a JSON object"); } - // create an instance of the given type T* inst = new T(); inst->id = id; - ReadMember(obj->value, "name", inst->name); - inst->Read(obj->value, mAsset); + ReadMember(obj, "name", inst->name); + inst->Read(obj, mAsset); + return Add(inst); } @@ -437,9 +440,9 @@ inline void Buffer::Grow(size_t amount) inline void BufferView::Read(Value& obj, Asset& r) { - const char* bufferId = MemberOrDefault(obj, "buffer", 0); - if (bufferId) { - buffer = r.buffers.Get(bufferId); + + if (Value* bufferVal = FindUInt(obj, "buffer")) { + buffer = r.buffers.Get(bufferVal->GetUint()); } byteOffset = MemberOrDefault(obj, "byteOffset", 0u); @@ -452,9 +455,9 @@ inline void BufferView::Read(Value& obj, Asset& r) inline void Accessor::Read(Value& obj, Asset& r) { - const char* bufferViewId = MemberOrDefault(obj, "bufferView", 0); - if (bufferViewId) { - bufferView = r.bufferViews.Get(bufferViewId); + + if (Value* bufferViewVal = FindUInt(obj, "bufferView")) { + bufferView = r.bufferViews.Get(bufferViewVal->GetUint()); } byteOffset = MemberOrDefault(obj, "byteOffset", 0u); @@ -611,9 +614,8 @@ inline void Image::Read(Value& obj, Asset& r) ReadMember(*ext, "mimeType", mimeType); - const char* bufferViewId; - if (ReadMember(*ext, "bufferView", bufferViewId)) { - Ref bv = r.bufferViews.Get(bufferViewId); + if (Value* bufferViewVal = FindUInt(*ext, "bufferView")) { + Ref bv = r.bufferViews.Get(bufferViewVal->GetUint()); if (bv) { mDataLength = bv->byteLength; mData = new uint8_t[mDataLength]; @@ -687,23 +689,22 @@ inline void Sampler::SetDefaults() inline void Texture::Read(Value& obj, Asset& r) { - const char* sourcestr; - if (ReadMember(obj, "source", sourcestr)) { - source = r.images.Get(sourcestr); + if (Value* sourceVal = FindUInt(obj, "source")) { + source = r.images.Get(sourceVal->GetUint()); } - const char* samplerstr; - if (ReadMember(obj, "sampler", samplerstr)) { - sampler = r.samplers.Get(samplerstr); + if (Value* samplerVal = FindUInt(obj, "sampler")) { + sampler = r.samplers.Get(samplerVal->GetUint()); } } namespace { inline void ReadMaterialProperty(Asset& r, Value& vals, const char* propName, TexProperty& out) { + //@TODO: update this format if (Value* prop = FindMember(vals, propName)) { - if (prop->IsString()) { - out.texture = r.textures.Get(prop->GetString()); + if (prop->IsUint()) { + out.texture = r.textures.Get(prop->GetUint()); } else { ReadValue(*prop, out.color); @@ -824,22 +825,23 @@ inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root) // Valid attribute semantics include POSITION, NORMAL, TEXCOORD, COLOR, JOINT, JOINTMATRIX, // and WEIGHT.Attribute semantics can be of the form[semantic]_[set_index], e.g., TEXCOORD_0, TEXCOORD_1, etc. + //@TODO: update this int undPos = 0; Mesh::AccessorList* vec = 0; if (GetAttribVector(prim, attr, vec, undPos)) { size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0; if ((*vec).size() <= idx) (*vec).resize(idx + 1); - (*vec)[idx] = pAsset_Root.accessors.Get(it->value.GetString()); + (*vec)[idx] = pAsset_Root.accessors.Get(it->value.GetUint()); } } } - if (Value* indices = FindString(primitive, "indices")) { - prim.indices = pAsset_Root.accessors.Get(indices->GetString()); + if (Value* indices = FindUInt(primitive, "indices")) { + prim.indices = pAsset_Root.accessors.Get(indices->GetUint()); } - if (Value* material = FindString(primitive, "material")) { - prim.material = pAsset_Root.materials.Get(material->GetString()); + if (Value* material = FindUInt(primitive, "material")) { + prim.material = pAsset_Root.materials.Get(material->GetUint()); } } } @@ -914,177 +916,6 @@ mr_skip_extensions: return;// After label some operators must be present. } -#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC -inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC& pCompression_Open3DGC, Asset& pAsset_Root) -{ -typedef unsigned short IndicesType;///< \sa glTFExporter::ExportMeshes. - -o3dgc::SC3DMCDecoder decoder; -o3dgc::IndexedFaceSet ifs; -o3dgc::BinaryStream bstream; -uint8_t* decoded_data; -size_t decoded_data_size = 0; -Ref buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer); - - // Read data from buffer and place it in BinaryStream for decoder. - // Just "Count" because always is used type equivalent to uint8_t. - bstream.LoadFromBuffer(&buf->GetPointer()[pCompression_Open3DGC.Offset], static_cast(pCompression_Open3DGC.Count)); - - // After decoding header we can get size of primitives. - if(decoder.DecodeHeader(ifs, bstream) != o3dgc::O3DGC_OK) throw DeadlyImportError("GLTF: can not decode Open3DGC header."); - - /****************** Get sizes of arrays and check sizes ******************/ - // Note. See "Limitations for meshes when using Open3DGC-compression". - - // Indices - size_t size_coordindex = ifs.GetNCoordIndex() * 3;// See float attributes note. - - if(primitives[0].indices->count != size_coordindex) - throw DeadlyImportError("GLTF: Open3DGC. Compressed indices count (" + std::to_string(size_coordindex) + - ") not equal to uncompressed (" + std::to_string(primitives[0].indices->count) + ")."); - - size_coordindex *= sizeof(IndicesType); - // Coordinates - size_t size_coord = ifs.GetNCoord();// See float attributes note. - - if(primitives[0].attributes.position[0]->count != size_coord) - throw DeadlyImportError("GLTF: Open3DGC. Compressed positions count (" + std::to_string(size_coord) + - ") not equal to uncompressed (" + std::to_string(primitives[0].attributes.position[0]->count) + ")."); - - size_coord *= 3 * sizeof(float); - // Normals - size_t size_normal = ifs.GetNNormal();// See float attributes note. - - if(primitives[0].attributes.normal[0]->count != size_normal) - throw DeadlyImportError("GLTF: Open3DGC. Compressed normals count (" + std::to_string(size_normal) + - ") not equal to uncompressed (" + std::to_string(primitives[0].attributes.normal[0]->count) + ")."); - - size_normal *= 3 * sizeof(float); - // Additional attributes. - std::vector size_floatattr; - std::vector size_intattr; - - size_floatattr.resize(ifs.GetNumFloatAttributes()); - size_intattr.resize(ifs.GetNumIntAttributes()); - - decoded_data_size = size_coordindex + size_coord + size_normal; - for(size_t idx = 0, idx_end = size_floatattr.size(), idx_texcoord = 0; idx < idx_end; idx++) - { - // size = number_of_elements * components_per_element * size_of_component. - // Note. But as you can see above, at first we are use this variable in meaning "count". After checking count of objects... - size_t tval = ifs.GetNFloatAttribute(static_cast(idx)); - - switch(ifs.GetFloatAttributeType(static_cast(idx))) - { - case o3dgc::O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_TEXCOORD: - // Check situation when encoded data contain texture coordinates but primitive not. - if(idx_texcoord < primitives[0].attributes.texcoord.size()) - { - if(primitives[0].attributes.texcoord[idx]->count != tval) - throw DeadlyImportError("GLTF: Open3DGC. Compressed texture coordinates count (" + std::to_string(tval) + - ") not equal to uncompressed (" + std::to_string(primitives[0].attributes.texcoord[idx]->count) + ")."); - - idx_texcoord++; - } - else - { - ifs.SetNFloatAttribute(static_cast(idx), 0ul);// Disable decoding this attribute. - } - - break; - default: - throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + to_string(ifs.GetFloatAttributeType(static_cast(idx)))); - } - - tval *= ifs.GetFloatAttributeDim(static_cast(idx)) * sizeof(o3dgc::Real);// After checking count of objects we can get size of array. - size_floatattr[idx] = tval; - decoded_data_size += tval; - } - - for(size_t idx = 0, idx_end = size_intattr.size(); idx < idx_end; idx++) - { - // size = number_of_elements * components_per_element * size_of_component. See float attributes note. - size_t tval = ifs.GetNIntAttribute(static_cast(idx)); - switch( ifs.GetIntAttributeType(static_cast(idx) ) ) - { - case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_UNKOWN: - case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX: - case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_JOINT_ID: - case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX_BUFFER_ID: - break; - - default: - throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(static_cast(idx)))); - } - - tval *= ifs.GetIntAttributeDim(static_cast(idx)) * sizeof(long);// See float attributes note. - size_intattr[idx] = tval; - decoded_data_size += tval; - } - - // Create array for decoded data. - decoded_data = new uint8_t[decoded_data_size]; - - /****************** Set right array regions for decoder ******************/ - - auto get_buf_offset = [](Ref& pAccessor) -> size_t { return pAccessor->byteOffset + pAccessor->bufferView->byteOffset; }; - - // Indices - ifs.SetCoordIndex((IndicesType* const)(decoded_data + get_buf_offset(primitives[0].indices))); - // Coordinates - ifs.SetCoord((o3dgc::Real* const)(decoded_data + get_buf_offset(primitives[0].attributes.position[0]))); - // Normals - if(size_normal) - { - ifs.SetNormal((o3dgc::Real* const)(decoded_data + get_buf_offset(primitives[0].attributes.normal[0]))); - } - - for(size_t idx = 0, idx_end = size_floatattr.size(), idx_texcoord = 0; idx < idx_end; idx++) - { - switch(ifs.GetFloatAttributeType(static_cast(idx))) - { - case o3dgc::O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_TEXCOORD: - if(idx_texcoord < primitives[0].attributes.texcoord.size()) - { - // See above about absent attributes. - ifs.SetFloatAttribute(static_cast(idx), (o3dgc::Real* const)(decoded_data + get_buf_offset(primitives[0].attributes.texcoord[idx]))); - idx_texcoord++; - } - - break; - default: - throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + to_string(ifs.GetFloatAttributeType(static_cast(idx)))); - } - } - - for(size_t idx = 0, idx_end = size_intattr.size(); idx < idx_end; idx++) { - switch(ifs.GetIntAttributeType(static_cast(idx))) { - case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_UNKOWN: - case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX: - case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_JOINT_ID: - case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX_BUFFER_ID: - break; - - // ifs.SetIntAttribute(idx, (long* const)(decoded_data + get_buf_offset(primitives[0].attributes.joint))); - default: - throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(static_cast(idx)))); - } - } - - // - // Decode data - // - if ( decoder.DecodePayload( ifs, bstream ) != o3dgc::O3DGC_OK ) { - throw DeadlyImportError( "GLTF: can not decode Open3DGC data." ); - } - - // Set encoded region for "buffer". - buf->EncodedRegion_Mark(pCompression_Open3DGC.Offset, pCompression_Open3DGC.Count, decoded_data, decoded_data_size, id); - // No. Do not delete "output_data". After calling "EncodedRegion_Mark" bufferView is owner of "output_data". - // "delete [] output_data;" -} -#endif - inline void Camera::Read(Value& obj, Asset& r) { type = MemberOrDefault(obj, "type", Camera::Perspective); @@ -1095,16 +926,16 @@ inline void Camera::Read(Value& obj, Asset& r) if (!it) throw DeadlyImportError("GLTF: Camera missing its parameters"); if (type == Camera::Perspective) { - perspective.aspectRatio = MemberOrDefault(*it, "aspectRatio", 0.f); - perspective.yfov = MemberOrDefault(*it, "yfov", 3.1415f/2.f); - perspective.zfar = MemberOrDefault(*it, "zfar", 100.f); - perspective.znear = MemberOrDefault(*it, "znear", 0.01f); + cameraProperties.perspective.aspectRatio = MemberOrDefault(*it, "aspectRatio", 0.f); + cameraProperties.perspective.yfov = MemberOrDefault(*it, "yfov", 3.1415f/2.f); + cameraProperties.perspective.zfar = MemberOrDefault(*it, "zfar", 100.f); + cameraProperties.perspective.znear = MemberOrDefault(*it, "znear", 0.01f); } else { - ortographic.xmag = MemberOrDefault(obj, "xmag", 1.f); - ortographic.ymag = MemberOrDefault(obj, "ymag", 1.f); - ortographic.zfar = MemberOrDefault(obj, "zfar", 100.f); - ortographic.znear = MemberOrDefault(obj, "znear", 0.01f); + cameraProperties.ortographic.xmag = MemberOrDefault(obj, "xmag", 1.f); + cameraProperties.ortographic.ymag = MemberOrDefault(obj, "ymag", 1.f); + cameraProperties.ortographic.zfar = MemberOrDefault(obj, "zfar", 100.f); + cameraProperties.ortographic.znear = MemberOrDefault(obj, "znear", 0.01f); } } @@ -1156,13 +987,14 @@ inline void Light::SetDefaults() inline void Node::Read(Value& obj, Asset& r) { + if (Value* children = FindArray(obj, "children")) { this->children.reserve(children->Size()); for (unsigned int i = 0; i < children->Size(); ++i) { Value& child = (*children)[i]; - if (child.IsString()) { + if (child.IsNumber()) { // get/create the child node - Ref chn = r.nodes.Get(child.GetString()); + Ref chn = r.nodes.Get(child.GetUint()); if (chn) this->children.push_back(chn); } } @@ -1185,15 +1017,15 @@ inline void Node::Read(Value& obj, Asset& r) this->meshes.reserve(numMeshes); for (unsigned i = 0; i < numMeshes; ++i) { - if ((*meshes)[i].IsString()) { - Ref mesh = r.meshes.Get((*meshes)[i].GetString()); + if ((*meshes)[i].IsNumber()) { + Ref mesh = r.meshes.Get((*meshes)[i].GetUint()); if (mesh) this->meshes.push_back(mesh); } } } - if (Value* camera = FindString(obj, "camera")) { - this->camera = r.cameras.Get(camera->GetString()); + if (Value* camera = FindUInt(obj, "camera")) { + this->camera = r.cameras.Get(camera->GetUint()); if (this->camera) this->camera->id = this->id; } @@ -1204,8 +1036,8 @@ inline void Node::Read(Value& obj, Asset& r) if (r.extensionsUsed.KHR_materials_common) { if (Value* ext = FindObject(*extensions, "KHR_materials_common")) { - if (Value* light = FindString(*ext, "light")) { - this->light = r.lights.Get(light->GetString()); + if (Value* light = FindUInt(*ext, "light")) { + this->light = r.lights.Get(light->GetUint()); } } @@ -1217,8 +1049,8 @@ inline void Scene::Read(Value& obj, Asset& r) { if (Value* array = FindArray(obj, "nodes")) { for (unsigned int i = 0; i < array->Size(); ++i) { - if (!(*array)[i].IsString()) continue; - Ref node = r.nodes.Get((*array)[i].GetString()); + if (!(*array)[i].IsNumber()) continue; + Ref node = r.nodes.Get((*array)[i].GetUint()); if (node) this->nodes.push_back(node); } @@ -1229,13 +1061,14 @@ inline void Scene::Read(Value& obj, Asset& r) inline void AssetMetadata::Read(Document& doc) { // read the version, etc. - float statedVersion = 0; + std::string statedVersion; + if (Value* obj = FindObject(doc, "asset")) { ReadMember(*obj, "copyright", copyright); ReadMember(*obj, "generator", generator); premultipliedAlpha = MemberOrDefault(*obj, "premultipliedAlpha", false); - statedVersion = MemberOrDefault(*obj, "version", 0); + statedVersion = MemberOrDefault(*obj, "version", "0.0"); if (Value* profile = FindObject(*obj, "profile")) { ReadMember(*profile, "api", this->profile.api); @@ -1243,14 +1076,16 @@ inline void AssetMetadata::Read(Document& doc) } } - version = std::max(statedVersion, version); + float statedFloatVersion = std::strtof(statedVersion.c_str(), 0); + + version = std::max(statedFloatVersion, version); if (version == 0) { - // if missing version, we'll assume version 1.0... - version = 1; + // if missing version, we'll assume version 2.0... + version = 2; } - if (version != 1) { + if (version != 2) { char msg[128]; ai_snprintf(msg, 128, "GLTF: Unsupported glTF version: %.1f", version); throw DeadlyImportError(msg); @@ -1361,12 +1196,14 @@ inline void Asset::Load(const std::string& pFile, bool isBinary) mDicts[i]->AttachToDocument(doc); } - - // Read the "scene" property, which specifies which scene to load // and recursively load everything referenced by it - if (Value* scene = FindString(doc, "scene")) { - this->scene = scenes.Get(scene->GetString()); + if (Value* scene = FindUInt(doc, "scene")) { + unsigned int sceneIndex = scene->GetUint(); + + Ref s = scenes.Get(sceneIndex); + + this->scene = s; } // Clean up From 47c7c3cf506166b483fd4e44e20a58cd1107e763 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Fri, 25 Aug 2017 16:09:07 -0400 Subject: [PATCH 13/90] Disambiguate Get methods --- code/glTF2Asset.h | 4 +-- code/glTF2Asset.inl | 59 +++++++++++++++++++++++++-------------------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 2e7a694d8..2ec2b84eb 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -1046,9 +1046,9 @@ namespace glTF2 LazyDict(Asset& asset, const char* dictId, const char* extId = 0); ~LazyDict(); - Ref Get(const char* id); + Ref Retrieve(unsigned int i); + Ref Get(unsigned int i); - Ref Get(const std::string& pID) { return Get(pID.c_str()); } Ref Create(const char* id); Ref Create(const std::string& id) diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 268deb8a8..97e507ee6 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -194,6 +194,14 @@ inline void LazyDict::DetachFromDocument() template Ref LazyDict::Get(unsigned int i) +{ + + return Ref(mObjs, i); + +} + +template +Ref LazyDict::Retrieve(unsigned int i) { std::string id = std::string(mDictId) + "[" + std::to_string(i) + "]"; @@ -442,7 +450,7 @@ inline void BufferView::Read(Value& obj, Asset& r) { if (Value* bufferVal = FindUInt(obj, "buffer")) { - buffer = r.buffers.Get(bufferVal->GetUint()); + buffer = r.buffers.Retrieve(bufferVal->GetUint()); } byteOffset = MemberOrDefault(obj, "byteOffset", 0u); @@ -457,7 +465,7 @@ inline void Accessor::Read(Value& obj, Asset& r) { if (Value* bufferViewVal = FindUInt(obj, "bufferView")) { - bufferView = r.bufferViews.Get(bufferViewVal->GetUint()); + bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint()); } byteOffset = MemberOrDefault(obj, "byteOffset", 0u); @@ -615,7 +623,7 @@ inline void Image::Read(Value& obj, Asset& r) ReadMember(*ext, "mimeType", mimeType); if (Value* bufferViewVal = FindUInt(*ext, "bufferView")) { - Ref bv = r.bufferViews.Get(bufferViewVal->GetUint()); + Ref bv = r.bufferViews.Retrieve(bufferViewVal->GetUint()); if (bv) { mDataLength = bv->byteLength; mData = new uint8_t[mDataLength]; @@ -690,11 +698,11 @@ inline void Sampler::SetDefaults() inline void Texture::Read(Value& obj, Asset& r) { if (Value* sourceVal = FindUInt(obj, "source")) { - source = r.images.Get(sourceVal->GetUint()); + source = r.images.Retrieve(sourceVal->GetUint()); } if (Value* samplerVal = FindUInt(obj, "sampler")) { - sampler = r.samplers.Get(samplerVal->GetUint()); + sampler = r.samplers.Retrieve(samplerVal->GetUint()); } } @@ -704,7 +712,7 @@ namespace { //@TODO: update this format if (Value* prop = FindMember(vals, propName)) { if (prop->IsUint()) { - out.texture = r.textures.Get(prop->GetUint()); + out.texture = r.textures.Retrieve(prop->GetUint()); } else { ReadValue(*prop, out.color); @@ -820,7 +828,7 @@ inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root) if (Value* attrs = FindObject(primitive, "attributes")) { for (Value::MemberIterator it = attrs->MemberBegin(); it != attrs->MemberEnd(); ++it) { - if (!it->value.IsString()) continue; + if (!it->value.IsUint()) continue; const char* attr = it->name.GetString(); // Valid attribute semantics include POSITION, NORMAL, TEXCOORD, COLOR, JOINT, JOINTMATRIX, // and WEIGHT.Attribute semantics can be of the form[semantic]_[set_index], e.g., TEXCOORD_0, TEXCOORD_1, etc. @@ -831,17 +839,17 @@ inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root) if (GetAttribVector(prim, attr, vec, undPos)) { size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0; if ((*vec).size() <= idx) (*vec).resize(idx + 1); - (*vec)[idx] = pAsset_Root.accessors.Get(it->value.GetUint()); + (*vec)[idx] = pAsset_Root.accessors.Retrieve(it->value.GetUint()); } } } if (Value* indices = FindUInt(primitive, "indices")) { - prim.indices = pAsset_Root.accessors.Get(indices->GetUint()); + prim.indices = pAsset_Root.accessors.Retrieve(indices->GetUint()); } if (Value* material = FindUInt(primitive, "material")) { - prim.material = pAsset_Root.materials.Get(material->GetUint()); + prim.material = pAsset_Root.materials.Retrieve(material->GetUint()); } } } @@ -992,9 +1000,9 @@ inline void Node::Read(Value& obj, Asset& r) this->children.reserve(children->Size()); for (unsigned int i = 0; i < children->Size(); ++i) { Value& child = (*children)[i]; - if (child.IsNumber()) { + if (child.IsUint()) { // get/create the child node - Ref chn = r.nodes.Get(child.GetUint()); + Ref chn = r.nodes.Retrieve(child.GetUint()); if (chn) this->children.push_back(chn); } } @@ -1010,22 +1018,21 @@ inline void Node::Read(Value& obj, Asset& r) ReadMember(obj, "rotation", rotation); } - if (Value* meshes = FindArray(obj, "meshes")) { - unsigned numMeshes = (unsigned)meshes->Size(); + if (Value* mesh = FindUInt(obj, "mesh")) { + //unsigned numMeshes = (unsigned)meshes->Size(); + unsigned numMeshes = 1; - std::vector meshList; + //std::vector meshList; this->meshes.reserve(numMeshes); - for (unsigned i = 0; i < numMeshes; ++i) { - if ((*meshes)[i].IsNumber()) { - Ref mesh = r.meshes.Get((*meshes)[i].GetUint()); - if (mesh) this->meshes.push_back(mesh); - } - } + + Ref meshRef = r.meshes.Retrieve((*mesh).GetUint()); + + if (meshRef) this->meshes.push_back(meshRef); } if (Value* camera = FindUInt(obj, "camera")) { - this->camera = r.cameras.Get(camera->GetUint()); + this->camera = r.cameras.Retrieve(camera->GetUint()); if (this->camera) this->camera->id = this->id; } @@ -1037,7 +1044,7 @@ inline void Node::Read(Value& obj, Asset& r) if (Value* ext = FindObject(*extensions, "KHR_materials_common")) { if (Value* light = FindUInt(*ext, "light")) { - this->light = r.lights.Get(light->GetUint()); + this->light = r.lights.Retrieve(light->GetUint()); } } @@ -1049,8 +1056,8 @@ inline void Scene::Read(Value& obj, Asset& r) { if (Value* array = FindArray(obj, "nodes")) { for (unsigned int i = 0; i < array->Size(); ++i) { - if (!(*array)[i].IsNumber()) continue; - Ref node = r.nodes.Get((*array)[i].GetUint()); + if (!(*array)[i].IsUint()) continue; + Ref node = r.nodes.Retrieve((*array)[i].GetUint()); if (node) this->nodes.push_back(node); } @@ -1201,7 +1208,7 @@ inline void Asset::Load(const std::string& pFile, bool isBinary) if (Value* scene = FindUInt(doc, "scene")) { unsigned int sceneIndex = scene->GetUint(); - Ref s = scenes.Get(sceneIndex); + Ref s = scenes.Retrieve(sceneIndex); this->scene = s; } From 4d59dee5ea25b7f1a7512348de6bc80a09a6d3fa Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Fri, 25 Aug 2017 16:52:44 -0400 Subject: [PATCH 14/90] Cache retrieved items via an original index map --- code/glTF2Asset.h | 15 ++++++++------- code/glTF2Asset.inl | 11 +++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 2ec2b84eb..2b37d6a0e 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -382,6 +382,7 @@ namespace glTF2 struct Object { int index; //!< The index of this object within its property container + int oIndex; //!< The original index of this object defined in the JSON std::string id; //!< The globally unique ID used to reference this object std::string name; //!< The user-defined name of this object @@ -1025,14 +1026,14 @@ namespace glTF2 friend class Asset; friend class AssetWriter; - typedef typename std::gltf_unordered_map< std::string, unsigned int > Dict; + typedef typename std::gltf_unordered_map< unsigned int, unsigned int > Dict; - std::vector mObjs; //! The read objects - Dict mObjsById; //! The read objects accessible by id - const char* mDictId; //! ID of the dictionary object - const char* mExtId; //! ID of the extension defining the dictionary - Value* mDict; //! JSON dictionary object - Asset& mAsset; //! The asset instance + std::vector mObjs; //! The read objects + Dict mObjsByOIndex; //! The read objects accessible by original index + const char* mDictId; //! ID of the dictionary object + const char* mExtId; //! ID of the extension defining the dictionary + Value* mDict; //! JSON dictionary object + Asset& mAsset; //! The asset instance void AttachToDocument(Document& doc); void DetachFromDocument(); diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 97e507ee6..062d8318d 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -204,10 +204,8 @@ template Ref LazyDict::Retrieve(unsigned int i) { - std::string id = std::string(mDictId) + "[" + std::to_string(i) + "]"; - - typename Dict::iterator it = mObjsById.find(id); - if (it != mObjsById.end()) { // already created? + typename Dict::iterator it = mObjsByOIndex.find(i); + if (it != mObjsByOIndex.end()) {// already created? return Ref(mObjs, it->second); } @@ -227,7 +225,8 @@ Ref LazyDict::Retrieve(unsigned int i) } T* inst = new T(); - inst->id = id; + inst->id = std::string(mDictId) + "[" + std::to_string(i) + "]"; + inst->oIndex = i; ReadMember(obj, "name", inst->name); inst->Read(obj, mAsset); @@ -239,7 +238,7 @@ Ref LazyDict::Add(T* obj) { unsigned int idx = unsigned(mObjs.size()); mObjs.push_back(obj); - mObjsById[obj->id] = idx; + mObjsByOIndex[obj->oIndex] = idx; mAsset.mUsedIds[obj->id] = true; return Ref(mObjs, idx); } From 39172feb3e3e9bb0c185209ed996867414ff0f44 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Fri, 25 Aug 2017 17:58:41 -0400 Subject: [PATCH 15/90] Start reading pbr materials --- code/glTF2Asset.inl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 062d8318d..27fdd1c01 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -733,6 +733,12 @@ inline void Material::Read(Value& material, Asset& r) ReadMember(*values, "shininess", shininess); } + if (Value* values = FindObject(material, "pbrMetallicRoughness")) { + ReadMaterialProperty(r, *values, "baseColorFactor", this->diffuse); + } + + ReadMember(material, "doubleSided", doubleSided); + if (Value* extensions = FindObject(material, "extensions")) { if (r.extensionsUsed.KHR_materials_common) { if (Value* ext = FindObject(*extensions, "KHR_materials_common")) { From 67eb3b06087021490e43d6c74e05dcd88c6d921a Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Sun, 27 Aug 2017 23:47:31 -0400 Subject: [PATCH 16/90] temporarily disable gltf exporting of animations and skins --- code/glTF2Exporter.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 7daef7000..68f2f4420 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -128,7 +128,7 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai ExportScene(); - ExportAnimations(); + //ExportAnimations(); AssetWriter writer(*mAsset); @@ -414,7 +414,7 @@ Ref FindSkeletonRootJoint(Ref& skinRef) return parentNodeRef; } -void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref& meshRef, Ref& bufferRef, Ref& skinRef, std::vector& inverseBindMatricesData) +/*void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref& meshRef, Ref& bufferRef, Ref& skinRef, std::vector& inverseBindMatricesData) { if (aimesh->mNumBones < 1) { return; @@ -491,7 +491,7 @@ void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref& meshRef, RefHasBones()) { - ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData); - } + /*************** Skins ****************/ + /*if(aim->HasBones()) { + ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData); + }*/ /****************** Compression ******************/ ///TODO: animation: weights, joints. @@ -942,7 +942,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref bufferRef = mAsset->buffers.Get(unsigned (0)); @@ -963,7 +963,7 @@ void glTF2Exporter::ExportAnimations() name = mAsset->FindUniqueID(name, "animation"); Ref animRef = mAsset->animations.Create(name); - /******************* Parameters ********************/ + // Parameters ExtractAnimationData(*mAsset, name, animRef, bufferRef, nodeChannel, anim->mTicksPerSecond); for (unsigned int j = 0; j < 3; ++j) { @@ -1011,7 +1011,7 @@ void glTF2Exporter::ExportAnimations() // } } // End: for-loop mNumAnimations -} +} */ #endif // ASSIMP_BUILD_NO_GLTF_EXPORTER From b42d785afebd313f8a531dc8cf832d80ecd50910 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Sun, 27 Aug 2017 23:47:54 -0400 Subject: [PATCH 17/90] Start managing and importing gltf2 pbr materials --- code/glTF2Asset.h | 40 +++++++++++++++++++++++++++++----------- code/glTF2Asset.inl | 19 +++++++++++++++---- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 2b37d6a0e..5d99735b2 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -671,11 +671,18 @@ namespace glTF2 inline void SetData(uint8_t* data, size_t length, Asset& r); }; - //! Holds a material property that can be a texture or a color - struct TexProperty + struct ColorProperty + { + union { + vec4, vec3 + } color; + } + + //! Holds a material property that can be a texture or a color (fallback for glTF 1) + struct FallbackTexProperty { Ref texture; - vec4 color; + ColorProperty color; }; //! The material appearance of a primitive. @@ -694,16 +701,27 @@ namespace glTF2 Technique_CONSTANT }; - TexProperty ambient; - TexProperty diffuse; - TexProperty specular; - TexProperty emission; - Ref normal; + //PBR metallic roughness properties + ColorProperty baseColor; + Ref baseColorTexture; + Ref metallicRoughnessTexture; + float metallicFactor; + float roughnessFactor; + //other basic material properties + Ref normalTexture; + Ref occlusionTexture; + Ref emissiveTexture; + ColorProperty emissiveFactor; + std::string alphaMode; + float alphaCutoff; bool doubleSided; - bool transparent; - float transparency; - float shininess; + + //fallback material properties (compatible with non-pbr defintions) + FallbackTexProperty diffuse; + FallbackTexProperty emissive; + FallbackTexProperty specular; + Ref normal; Technique technique; diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 27fdd1c01..bf8cb5a36 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -725,18 +725,29 @@ inline void Material::Read(Value& material, Asset& r) SetDefaults(); if (Value* values = FindObject(material, "values")) { - ReadMaterialProperty(r, *values, "ambient", this->ambient); - ReadMaterialProperty(r, *values, "diffuse", this->diffuse); - ReadMaterialProperty(r, *values, "specular", this->specular); + ReadMember(*values, "transparency", transparency); - ReadMember(*values, "shininess", shininess); } if (Value* values = FindObject(material, "pbrMetallicRoughness")) { + //pbr + ReadMaterialProperty(r, *values, "baseColorFactor", this->baseColor); + ReadMaterialProperty(r, *values, "baseColorTexture", this->baseColorTexture); + + //non-pbr fallback ReadMaterialProperty(r, *values, "baseColorFactor", this->diffuse); + ReadMaterialProperty(r, *values, "baseColorTexture", this->diffuse); + + ReadMember(*values, "metallicFactor", metallicFactor); } + ReadMaterialProperty(r, *values, "normalTexture", this->normalTexture); + ReadMaterialProperty(r, *values, "normalTexture", this->normal); + ReadMaterialProperty(r, *values, "occlusionTexture", this->occlusionTexture); + ReadMaterialProperty(r, *values, "emissiveTexture", this->emissiveTexture); + ReadMember(*values, "metallicFactor", emissiveFactor); + ReadMember(material, "doubleSided", doubleSided); if (Value* extensions = FindObject(material, "extensions")) { From 6b4286abf69a6bdff733dcf88a13891c21892985 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Sun, 27 Aug 2017 23:50:22 -0400 Subject: [PATCH 18/90] check in gltf2 models to test directory Remove un-needed test models --- .../BoxTextured-glTF-Binary/BoxTextured.glb | Bin 0 -> 4696 bytes .../BoxTextured.gltf | 181 +++++++++++ .../BoxTextured.gltf | 197 ++++++++++++ .../BoxTextured0.bin | Bin 0 -> 840 bytes .../CesiumLogoFlat.png | Bin 0 -> 2433 bytes .../BoxTextured.gltf | 282 ++++++++++++++++++ .../BoxTextured0.bin | Bin 0 -> 840 bytes .../BoxTextured0.vert | 17 ++ .../BoxTextured1.frag | 29 ++ .../CesiumLogoFlat.png | Bin 0 -> 2433 bytes .../glTF2/BoxTextured-glTF/BoxTextured.gltf | 181 +++++++++++ .../glTF2/BoxTextured-glTF/BoxTextured0.bin | Bin 0 -> 840 bytes .../glTF2/BoxTextured-glTF/CesiumLogoFlat.png | Bin 0 -> 2433 bytes 13 files changed, 887 insertions(+) create mode 100644 test/models/glTF2/BoxTextured-glTF-Binary/BoxTextured.glb create mode 100644 test/models/glTF2/BoxTextured-glTF-Embedded/BoxTextured.gltf create mode 100644 test/models/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured.gltf create mode 100644 test/models/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured0.bin create mode 100644 test/models/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/CesiumLogoFlat.png create mode 100644 test/models/glTF2/BoxTextured-glTF-techniqueWebGL/BoxTextured.gltf create mode 100644 test/models/glTF2/BoxTextured-glTF-techniqueWebGL/BoxTextured0.bin create mode 100644 test/models/glTF2/BoxTextured-glTF-techniqueWebGL/BoxTextured0.vert create mode 100644 test/models/glTF2/BoxTextured-glTF-techniqueWebGL/BoxTextured1.frag create mode 100644 test/models/glTF2/BoxTextured-glTF-techniqueWebGL/CesiumLogoFlat.png create mode 100644 test/models/glTF2/BoxTextured-glTF/BoxTextured.gltf create mode 100644 test/models/glTF2/BoxTextured-glTF/BoxTextured0.bin create mode 100644 test/models/glTF2/BoxTextured-glTF/CesiumLogoFlat.png diff --git a/test/models/glTF2/BoxTextured-glTF-Binary/BoxTextured.glb b/test/models/glTF2/BoxTextured-glTF-Binary/BoxTextured.glb new file mode 100644 index 0000000000000000000000000000000000000000..03cd2acf941a0838722aa3e7243d33a8f459c22e GIT binary patch literal 4696 zcmbUj2{@GN`cEYsB}<5iNh)L+J7qbxXqXs8A%mG|WXu>dvXy-)rLt?GvUDV*bV!TN z*s_;#$i63}>?+&+|1r~XyXT(nbHC?#|9AV|{r%<{oQJhB8vp=yd;mb&3;<>*q(uM> z?d^@Bz_bEjIE*KTjHVFDFfEt?5`oY+)Q6iOtc_uEFdq!r8&C8E6>xb)*f}|vw<~xV zrlrWFykS}=17My+Hw;86I-YZs`_2WxTumj(q?Nfo0;Z)T z2RnvDnOd77Enr%3IheJPodFVQWq3*vrlkxPiT8BFyFw;lnFO#ln3f77dkh(m_F%^J zL=!+c%pA%B$^q>PT6h!5YaMZ+VzC&qEgo~0;l#y{fUk z)qbd#xn2Jj4bB)UxUr0xuML&tLN>=x&>kLmS1TeFciIyiIJ8zSXm5-G(St~~#`sdG zWN@MZ&2`ULpxTHYx#4*ZX`dV`gnj7Oiz`9^sn(A;(#?ZeDG&R6U zoh745DDagis%WaOan?)@%JQ$EYyQ^w|5$T%HEUo-R^m45IA{|8^+jai8(X)+gwU>m>#!d75AzzgsJ{2=fG0>BPH5D)@k2XNt-g~?Vf z5iT&$R?{PfRv@NBz_Ahh%C)zSgQ)Nr!rG{-t7~a_d1ZCgA!^_1>T2Rc?=Ops=$M1; zoo(b~!@xAl+4*UwXqm^AY3aowF*(@0KN2VBm%=k0?!CB#ja6yxEE2z(-V4IL+!xqo8h_A_Q|rwyqdP+k%`{E53RKB>CWM%;o)JAyxxcP z{XxZpN#(SMFW(={-sou7+k4tOyJE|RZ&iR**9=&KVQl=sxf`>}2S|T<;#ZhL^ct$!PlY`16PdQf zZNFpkCW$JnuM77#E>GiKAUzng%NekUiygiaODc9wvVC&b@jf3q;cBZ~n6p%BnP7yH zNOBE*yHeT=f0>P7y}nQDwddt3EAQSPxjZywT7{O!88Qp#ns}YYy+1q)qagSUHsH)@T0NmLHB1;CE6?2 zk{|fYh|QLFwu;>{=RW6tDj~`khqMZ{$Z?&9QA%~rN8N6B+b8TlrIVhcbUe9>TH{-!*Nu!bTe3}+>czz_ymcmX`E(5&8xkndIUn!8NAs|T9oPKt zFE~SYX$W&+j|WQE1lBst&b^7xWJj3uD0VI)R6SVvd@ab^gfu*u-)0`iQx6ecBm5^)w@56T^J2gSUvw_qUwY9wccdk zd(&7l{BWL?MnHQvUH7=DtOLDH??StDd6eAP5l>l?*=VZOm}tZ=1yk6=#Z4p=!v0jv z>O@$F+G&}tdnhV;;pk1xl=n;QCtR_E@_BG9SRGVZmG%By@~QaLKc0Ur@+h4mXl;VaA22% z)HbheBT1X)LQs{li;ureCZCF6Oa2;uc3jU%;K7kYsQJ>eqLfZ|nx25sg&S^)LK&vk z9UaXggxfYAydtBkL3XD$jeDqq+0KbPDvx{&7m9UCGyrTghE3v$d3ENnngIbtKQV`o zMTy~C1_ex}H4p!3=`MPV3BWJnfIuvxPh8LvkE-dEqEt~e_rKBzpQC*?$L=IM3X-WdKM;SnO2 zOK|7s+P(etq1izhGAM!a>>-OdQk90x-t@DVd_^UHIcsGmPghR4s{J(&p_+g7eG$@s zCK2xvM8)`1wKO6gBM{kHEoaL7nx4iR`&Kt=PnC))*f3ZHaU{ z(Z`-ePkl(`z;W5uqOz;{*mtIPJJMEtiwDKCLL|8Q=#2vTln|@nyIW+s_MQ$l3`piL zTNP5SGK4*z5ZyJopzdd0{=8edGZcQutfuCaG{GpjXIH;oN^ai7m(3loBPjK^S~FEv zNC8<%4RaU~axqWlN3s6mf)?=v)A4v8lFE+jp+fonqk?G*H;W2lNr=x@CdkyHW7p;f zII6L?tycVYUz;D}tiGSNOwU^$Cej_9-Gp@)EBf!2FDKGwoD_slpen?p?nQ7F2b6Lj zjjf{Rxz)c5n=miFEZOBb?~&VL+7M7 zZLO@mF(qYIaX0(QF;<0@dyK^Lw=Eo((Y&28*PP_xyRXo1H|K)(ahY!o=VvTeyn1Ba zy?PX1B0c(7%(6z`H&yvMaHX8J-j`RrG&RxoPE03Dq6>8Z^Qb*H_r6~>^g~*(UXoxdlNdhK+VOk=Cp!ifNI#CMeS-$)D?AWqi`z=7{xu+F_b4KrM}^ z7w6cPzHOm-r0rd_SjLt}g@!NLw7Y^~J8tCV81&oi4jd21={j6xi!2!G%;hQ>nrrtk zyyY(wSi7JIsL!?Fo|%kMG)F5_KJWQ_Vt-uR1T7f&S|>jez?o}!qGiV^*CTq8xXS&L z%i;P<1!j@Twr}3MIqbd2=k_cD(Q8AzF+87Yed!JP^W>B2PYY>! z+k=nF*n95jlyH6rI88bw+;sjFR3vB5&b|~@CR%jgk&u?Tabc$sW z+s03|SsX(46J1hbhW&i1HpC+DlA`;)KkST>o2%S}|019TJlQ<#W!HpD*%Z}q{YoDx zbcA0;!+^UEhr9XcPt^8jNm50rG;31H zropwtw2AMsvOGuRaG|JA;%s=iQ4GfZK{Y0Ss5Up_?a4pH*po7Zx&|idv=MDN-;CJ; z562XbkL5(&dR&j-{Pg>2tg1vP)kUX6^5PrCWW15wML(4dQxr9nc14j$wwjiq^!>CK zodkY*;l?y-p|M8BMiOa=Q!$GbcIIX(v! zHAaLMISNdh+Xub=!Y7KT`fcg8nTz7yjO9B1DjFBR!7yL%!9ZkqJM~qSWTjW*??(;n zF0}5dolo(}ylTp88`0suSFpxDJV#A6e0Xm0@cWzIjgCQoywMW6Bq#>{rvglkEDZC1 Jbq)o|e*xHM<_Q1* literal 0 HcmV?d00001 diff --git a/test/models/glTF2/BoxTextured-glTF-Embedded/BoxTextured.gltf b/test/models/glTF2/BoxTextured-glTF-Embedded/BoxTextured.gltf new file mode 100644 index 000000000..c9c461495 --- /dev/null +++ b/test/models/glTF2/BoxTextured-glTF-Embedded/BoxTextured.gltf @@ -0,0 +1,181 @@ +{ + "asset": { + "generator": "COLLADA2GLTF", + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 2, + "TEXCOORD_0": 3 + }, + "indices": 0, + "mode": 4, + "material": 0 + } + ], + "name": "Mesh" + } + ], + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1.0, + 1.0, + 1.0 + ], + "min": [ + -1.0, + -1.0, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 288, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.5, + 0.5 + ], + "min": [ + -0.5, + -0.5, + -0.5 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 6.0, + 1.0 + ], + "min": [ + 0.0, + 0.0 + ], + "type": "VEC2" + } + ], + "materials": [ + { + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 0 + }, + "metallicFactor": 0.0 + }, + "name": "Texture" + } + ], + "textures": [ + { + "sampler": 0, + "source": 0 + } + ], + "images": [ + { + "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANMAAADTCAMAAAAs2dbrAAAAsVBMVEXc3Nz8/f3+//9chyf///+VsHP4+/thiy3Z29dyl0R8nlH09vJeiCqzxZ6ft4GLqWatwZXw9vyEpFynvYxmjjTS3cNrkjvu8urn8vre7fjY6ffL08K6yqbEz7XT183K4vTQ5fW62fC/zq3J17fn7d/g6NbC3fLb5c/l5eVsrd+wzOF/t+OWw+WGu+TE099vr+CmyON5tOJ0seG50OHL1t7S2d7Z29yOv+Wdx+emzuyx1O6AHuoWAAAIi0lEQVR4XuzUS3LEIAxF0WznIYk/xun9LyxDRqnqGANq4rODW4L39d88Ho/H43HkZPzJVYgoxhiIpDJ7k2z5wJpizSkBv4vCJn1OWTZMeE9gY/Xfx3DE30Q2WfGBvOAa8lZnEKFH0JZ1GEE/MnpGw54R93Cs41ip4k6SjuWPjnC3YJZWtaJdqhJhlJDWLINgJJm/FoUxGpfJ0xAxnvMTv1UWzEF21pG8wzT+2OZIjeTxScZhLmdGz13FfHXoAGbCCmHgVCSHNVwaleSxjh8z4Yxmj09VBGtRGbAOq1G+OSlgvZC3SwLijVE2Qodot7lS4+xGSS1quyS4O/5UIegSSm/SUaENHZ1NDH1qX5SHRmdPUoJOqWPyInS6Pn6HoNlkJxh68T6fqTFXkkrERPL9en0L3ueufKkf6uxmt1EYiAN4sP7i0pNPABeItEIdeV0vJMTA+z/YaqWo3WSS1gn2lP4ewFHEfNqexLi5hAIAvTgKZZ+4myQxpsSZUtomiD75yPM5Pqg8uDK5cbORZzT+p3JDgfxma16LK3WaceLUkxQPJjj6hnGbo2sHpkkxzB4didFgcgp23OJQ5BS4Pn6TeiM5PThYCva2vQmCHDgYCmZXfCbJfMpc9PXQk6QGTE0PMNv7TDSBmaM/IXqSVeKKdsSsy6gjCfMZLijWSVaXvomkzbiwRF/jR0fS3JThXTbTw8aAVVCcbXFW2wRv8oa+hVmaumoWS88YTgKFXNpBYHrd1GXfaaCfyI0CK7u0g0DoSfMCoSduTBF6Zto3bV033ewdiel/L/9+te3G6HOR35d4p/JmcjI9rVI4e9nd0z9XSStc08tAidkmw4cs6khuK3BK6ZlS6huFC6/xZj23z3BHbSiZOceVIto2aCrcp1N1BteByXe3DfQgq/EZNVMKQwUui5ROPscXFoqvL3HLa5R0sjkg/6eGEjcVMQajXuNraqK4XA3ufoey9AhXIURmUzyDhCbUya0/nFN6SHIbyK0vERMCqZZW4ikcXCQOcQ7nlgT1gVPFjvuz+vCXX4UCl/mEd+tAXhSsSDxT9rq/tJjbasJAFEWJm2QwF6NJVNra0hptoFVsERrp/39YXwTrbDWZOcf1GrLDhrMyF45elUMAVTjlR5NvrctNIsniFDB5HVzstJWEB+MUR/I5PdVRahtQcF3hSNxEkoMGhw+SAidmU1bqLjIFI5wwS670IwhPYvzHNCRweweZBiHOeBH8yik8KnBOtWal9GUqcc4T38D6h49gM0zoNLXTlqmGBQ/fXhDOhKyUskyrChYZ78ol4cyCpn+jKlMUw6bkTpJwxjgqJZ93jHgbIQt3Ukou0zOYkDv5rUw1rpDmtE9685VpYn91ZXp1OjiFs0xMpqXUa795z7mTRnjH0jvxuh77pXkP0a/TRh7erdSDh1ItybTERQruJA5nNJTia4+16dvp4C4Th+srxfOeDKHVaccyUTiRNnan6FNNpm6fvhTCmVlil3JTqh3wvDt1ksvE5PTeu5ZM3evTh0o4MxZcY+4eO2QSdeobzpgpK6UjU/d+b68TzszmvqvUhmRa4Aal05mwdQhnClbKU6bG4AYZn91dwv94t+MepYEgCuDTzhSudIFSgKIHKtwlaIBEe5cTv/8XM8ZEIrPtGxzw9zd5TcO83SbbgjKhSsnJXyZtRZfeHOFAmKut7fgF2siFdMyd1qQ0/nB7pZbN9WUacrcPpOwd4bev1B6USeuTdnA0FZqCF67h6Rae95y0r45wTO9SR0+ZtFCR9uIIx2agUv55H5H26gnHqp7906395W/TXWBkGD/7xOGiw/2VwvNeLxhaU8Qeh6eFCrd7ugxLjsbTrWTM2IPtTbeNIdxu9myr1EnNe8lYThFvL65wLAyilcLzPg+MZRTz6gzHRoaTgWYZKxNWUlRzZbi/UpKc4MNlUrHFI0Udrg73Vyo5oKP10pZseCexeR8J9ztXKvrNfvNR/nHeK2px3jC+T2zh/kql6ebPxnhcCph3VCett/zx7dfYHT6lINxTKWWy2aurqnnHdYqrRdLJu2UiAsId+s8S0XJVmbJNTm0+iwLCPZXC0jkbZdQqkRYq3CETq3rGRltqVUhUqsI9wlYAdbqFzB4IDp8O99Ln19iIHaMHhi/N+KbCohaDFZutqUPhWB9864RnP1yQAoav5NurCrjk9dlsRJ16KnzK9zAAN/XUZ7tH6nQ56cWY7yPvWiiSku3CgAD5yy7newmrRFrUFV9jSEAhZ8Uo8P2EQfyvSoYzVtDmZFwlihJku4VM31Vvm/N1pgQVv6PnWZ//g2pby1m6my5+cls3ubHCQBCASypZbiPbIGDYAF7wXpScYO5/tCxZBgb8g78btKpdbZ6kA/708/Vah35kKrbxy+v7/9frX9dOPE/hb2KYi+V5dsYBjk+icIjhc+gZhyz1xQRp+BQ6ALUF5XFYz2eYBIfNmo/gcILnEzQ4QwzLZ2ecstVTELuWpTOCk8LEwq04batm83Zvz5I1gg+IeczftY7L2+FDHUul8DFVzWPaSc8SjTMuCIblsRt2lfSEw0WLZVmsx2Wu5Mqro9FbwR0GlqMX3OLtyztM16n6RgJ8PYu36+qph52zzEwJ7rZoZjUggnViPtohitAwl2lFLIp5NAHxdDZTO8S0GqY2OkQmqp69220T07EDkggtU2lmpOLSRKUHJCTeMro2IK25Z1xmRXqLYTxjJ8jh7QzjGAdBLhJlKu0DcpLO8F7TEJDd1lrexjhBCd7Bj7yDVivKIe56WL/t2jEKwCAMheEsYirEBgNdohl6CO9/tM6FgrRdFPJNWX/I+BIbTMao/MhKYjAlo/3LE8bCChND5RLfLXxPhNl1wMYhxXHOtktDWInWHMr2mHakkEkRVoXaaiUWyVmEqTY1hOX1+z3mnHPOXX/B0DoXjBYdAAAAAElFTkSuQmCC" + } + ], + "samplers": [ + { + "magFilter": 9729, + "minFilter": 9986, + "wrapS": 10497, + "wrapT": 10497 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 768, + "byteLength": 72, + "target": 34963 + }, + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 576, + "byteStride": 12, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 576, + "byteLength": 192, + "byteStride": 8, + "target": 34962 + } + ], + "buffers": [ + { + "byteLength": 840, + "uri": "data:application/octet-stream;base64,AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAC/AADAQAAAAAAAAKBAAAAAAAAAwED+/38/AACgQP7/fz8AAIBAAAAAAAAAoEAAAAAAAACAQAAAgD8AAKBAAACAPwAAAEAAAAAAAACAPwAAAAAAAABAAACAPwAAgD8AAIA/AABAQAAAAAAAAIBAAAAAAAAAQEAAAIA/AACAQAAAgD8AAEBAAAAAAAAAAEAAAAAAAABAQAAAgD8AAABAAACAPwAAAAAAAAAAAAAAAP7/fz8AAIA/AAAAAAAAgD/+/38/AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUA" + } + ] +} diff --git a/test/models/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured.gltf b/test/models/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured.gltf new file mode 100644 index 000000000..b286239fa --- /dev/null +++ b/test/models/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured.gltf @@ -0,0 +1,197 @@ +{ + "asset": { + "generator": "COLLADA2GLTF", + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 2, + "TEXCOORD_0": 3 + }, + "indices": 0, + "mode": 4, + "material": 0 + } + ], + "name": "Mesh" + } + ], + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1.0, + 1.0, + 1.0 + ], + "min": [ + -1.0, + -1.0, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 288, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.5, + 0.5 + ], + "min": [ + -0.5, + -0.5, + -0.5 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 6.0, + 1.0 + ], + "min": [ + 0.0, + 0.0 + ], + "type": "VEC2" + } + ], + "materials": [ + { + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 0 + }, + "metallicFactor": 0.0 + }, + "extensions": { + "KHR_materials_pbrSpecularGlossiness": { + "diffuseTexture": { + "index": 0 + }, + "specularFactor": [ + 0.20000000298023225, + 0.20000000298023225, + 0.20000000298023225 + ], + "glossinessFactor": 1.0 + } + }, + "name": "Texture" + } + ], + "textures": [ + { + "sampler": 0, + "source": 0 + } + ], + "images": [ + { + "uri": "CesiumLogoFlat.png" + } + ], + "samplers": [ + { + "magFilter": 9729, + "minFilter": 9986, + "wrapS": 10497, + "wrapT": 10497 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 768, + "byteLength": 72, + "target": 34963 + }, + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 576, + "byteStride": 12, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 576, + "byteLength": 192, + "byteStride": 8, + "target": 34962 + } + ], + "buffers": [ + { + "byteLength": 840, + "uri": "BoxTextured0.bin" + } + ], + "extensionsUsed": [ + "KHR_materials_pbrSpecularGlossiness" + ] +} diff --git a/test/models/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured0.bin b/test/models/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured0.bin new file mode 100644 index 0000000000000000000000000000000000000000..d2a73551f9456732c7ca85b9d70895f5d9ab8171 GIT binary patch literal 840 zcma)4TMmLS5FAugR8)K(r@fgRg`3F9)Sc2X4N+i|$-K6U9|D@%NdZH8sMCdXhgs?; z>8CE)+Yvq1hwmphbb0bSz9n3Qv{?B+?(fNy1()2HW=AbfwKB4_dS!i9PnJ%1er4>H zi~S!ZIHJM{XG4VxuDIcDxZ(qtxm=$B literal 0 HcmV?d00001 diff --git a/test/models/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/CesiumLogoFlat.png b/test/models/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/CesiumLogoFlat.png new file mode 100644 index 0000000000000000000000000000000000000000..45d502ed2610974189307ad542b05b70df14abd4 GIT binary patch literal 2433 zcmV-{34Zp8P)_WXpT zT&KN^W{xz{-NS2=JMQx8=kogA?fBT~_si45y2_@+&$ZLn&C25R(B<{I+3>&4t;yH7 z=k4F%=+?sB^4sOl<>lpUt>3WB;eWT|mc!+SyX3^v-*2zrrpV)YwBmHJ;knS^%huk~ z+1}aP+>XEHoyX^<&g`+&?tmWZ761SUi%CR5RCr$O)Jt;2APhy(Z08|~KgQ|(FDyew zsp=R5YT~nlTY~rX-#i|V$K!G2Wc)mlWh6Gnqti<0l$mFCVfs>HcWU= zU}N>)$8f~oL^fIRfxO@v@>XXMp-0e`br?ZEGI~bCo)PzOtm9az;!cu|<&TbVw_ui5 zwW3|B5@D2()+~cyB$>Y!g)thJ$B!@Lz8kOX+jvq7OjAoBdRRn8M8L$qkQNB4TV7-vHO9JAJQ8q${ zXt%jig;B>Q5c8=c(DHB(vwdB7l^b%9eG_ZB*eh` zKiF!esNH0e)(Q5M{vNJS(>_P z7E8|>Y{ee=q-j zwe7~}bCKVdc&GAaaxy)wQaF3r-P1o;Nh@5_%Rq_QCc}p;>PT)Ya7yW!QtBIp3$O8J zJ-5$rM{OvXImeYE+BRq^+^17@2G@bfcef4nAgl2iHB$;h1ulz}PCmyM7K*Pgam#Cz zbh0@h|EGo$Hx)4kqh8}{YNEJY4eox2vh)a7Aw*_VJcEQL)XA+soKt#8avR94FA)<0 zsg_paDI8oR4sj0WmIU>IQ^k(^v-HmLNUj*xHHJLfb^%}CnhO;skj$V~R0982UN0V=@%S|H5 z;uJ7>9bD|Rm4pZ56i4zoJ=IZa8&Ggv;Yi#>l7j|^50U~WW>Z$`E;0opoG?qS^dksQ zV*JN6Byf8NnFb-wcoF={DLg80PPJyG^kph>&J*9j`iGBTGfe0-wbPcVh6NAbUJ%ZN ztdz1$s|pqw@5&|N%z~zWqbgGr!=~g;l5oa2DkYzHjCdO%3wKgVF4HrZkUROUOf{~M z=Cn_G^Ob30e|2SgbvihOvrJ5;rPOP`dC$3%MtH~4JMp?6`=xmg(XZ1+9^S3ggNITr z$+W~p3hpEhXEc=JYmc?*+v(sg6Nl?7#q*vFq19=}GEq2@Hg>1zQ%$CBpS~2rnOS0& za#N}u@Vq;9lFP*8^xnIcOx^3#he|jz7F=WQ9y??bb?O_=m?Mn?1{t5-UBdr(x8okAfglRt)6NvGbb(TUq6aG6C1`*| zdzTZx{}(gHL?W~88yxWWH+fCNyxk_-f-<2>$;n?PZAF*f9N|EitF7($1=`4kbj+RB zq%{6;d!?4m^<^4zw-2Q39pSgH)E<;c>yvhHG!>eH7p~#y7M}N7(e^O;iAL+mBRC0FBn==#2$yIg$lQO zx(rK>#?!52%-DnNO}C99+-~-4tJF!&d&yW%5pOT9a4Za>mBRBr4~%6L^Xd%8MuwAt zW*I9JR#H@RWw^gmlAPefWm2)lBSjsq4)<3oIiREU(w1y^C$V`S3HLi!D*DZS^HKhB z-YaTx-Y~vTY~lV&rRnC+#&}!`n0Hhst+)K~?bp~HKBXYsQz>P#*{iFndB=5%t3}eu zyJaE*!X5h0647#1nX*kzZ9aFxt9r&pTWVEERI0)~!d3uv zx`oUh2o9eP_tNLr*oYmY2Zk@r_@=_57K0U=t*JxdSRZ`rgl9iokOGFUU25j#hC9S?^-C5lI_BP0Qt)<=X(jOL|W7pUt>r>A!o%X z@co2A{I5!eGgi>%WLzbR5@frDOy5;+oAY(11Qoxd=UJcsgKAsLS-P7pesWtkxv|1P z5P(Z6S#BfSAYj-4UhrO&oM7&Mv@BT$2KrjZJwk9{`B+pT8DmQDz@><>-+!L z>tEMSJWt_oVwj8Nd3MGDj!&X+h~abS8HX(O#RO^i6gmL41?6#A&u5qfhs~Og;BbQH z6ErwO49jO{oU+wZ5WAM8GlG-C#KNsOZL4PUc5ly;HG&U_dCcFnj?3HOLmf+{@G(`* zW72SF|pWh(6ha+1#Q zUegee-PT&(#yCL<-ocN&gH|ibA?|uuzwO#F3cw%?h2bn>D#Qi@U7{I!2=9Ni&V_=s zT@><7S%1j*5*tj$sQk!EVlXA6{mT=^!U_{Z0U#c|HIOG8+R)*Q8CE)+Yvq1hwmphbb0bSz9n3Qv{?B+?(fNy1()2HW=AbfwKB4_dS!i9PnJ%1er4>H zi~S!ZIHJM{XG4VxuDIcDxZ(qtxm=$B literal 0 HcmV?d00001 diff --git a/test/models/glTF2/BoxTextured-glTF-techniqueWebGL/BoxTextured0.vert b/test/models/glTF2/BoxTextured-glTF-techniqueWebGL/BoxTextured0.vert new file mode 100644 index 000000000..05d5e82c2 --- /dev/null +++ b/test/models/glTF2/BoxTextured-glTF-techniqueWebGL/BoxTextured0.vert @@ -0,0 +1,17 @@ +precision highp float; +uniform mat4 u_modelViewMatrix; +uniform mat4 u_projectionMatrix; +uniform mat3 u_normalMatrix; +attribute vec3 a_position; +varying vec3 v_position; +attribute vec3 a_normal; +varying vec3 v_normal; +attribute vec2 a_texcoord0; +varying vec2 v_texcoord0; +void main(void) { + vec4 pos = u_modelViewMatrix * vec4(a_position,1.0); + v_position = pos.xyz; + gl_Position = u_projectionMatrix * pos; + v_normal = u_normalMatrix * a_normal; + v_texcoord0 = a_texcoord0; +} diff --git a/test/models/glTF2/BoxTextured-glTF-techniqueWebGL/BoxTextured1.frag b/test/models/glTF2/BoxTextured-glTF-techniqueWebGL/BoxTextured1.frag new file mode 100644 index 000000000..3850980a0 --- /dev/null +++ b/test/models/glTF2/BoxTextured-glTF-techniqueWebGL/BoxTextured1.frag @@ -0,0 +1,29 @@ +precision highp float; +uniform sampler2D u_diffuse; +uniform vec4 u_specular; +uniform float u_shininess; +uniform float u_transparency; +varying vec3 v_position; +varying vec3 v_normal; +varying vec2 v_texcoord0; +void main(void) { + vec3 normal = normalize(v_normal); + vec4 diffuse = texture2D(u_diffuse, v_texcoord0); + vec3 diffuseLight = vec3(0.0, 0.0, 0.0); + vec3 specular = u_specular.rgb; + vec3 specularLight = vec3(0.0, 0.0, 0.0); + vec3 ambient = diffuse.rgb; + vec3 viewDir = -normalize(v_position); + vec3 ambientLight = vec3(0.0, 0.0, 0.0); + ambientLight += vec3(0.2, 0.2, 0.2); + vec3 l = vec3(0.0, 0.0, 1.0); + diffuseLight += vec3(1.0, 1.0, 1.0) * max(dot(normal, l), 0.); + vec3 reflectDir = reflect(-l, normal); + float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess)); + specularLight += vec3(1.0, 1.0, 1.0) * specularIntensity; + vec3 color = vec3(0.0, 0.0, 0.0); + color += diffuse.rgb * diffuseLight; + color += specular * specularLight; + color += ambient * ambientLight; + gl_FragColor = vec4(color * diffuse.a * u_transparency, diffuse.a * u_transparency); +} diff --git a/test/models/glTF2/BoxTextured-glTF-techniqueWebGL/CesiumLogoFlat.png b/test/models/glTF2/BoxTextured-glTF-techniqueWebGL/CesiumLogoFlat.png new file mode 100644 index 0000000000000000000000000000000000000000..45d502ed2610974189307ad542b05b70df14abd4 GIT binary patch literal 2433 zcmV-{34Zp8P)_WXpT zT&KN^W{xz{-NS2=JMQx8=kogA?fBT~_si45y2_@+&$ZLn&C25R(B<{I+3>&4t;yH7 z=k4F%=+?sB^4sOl<>lpUt>3WB;eWT|mc!+SyX3^v-*2zrrpV)YwBmHJ;knS^%huk~ z+1}aP+>XEHoyX^<&g`+&?tmWZ761SUi%CR5RCr$O)Jt;2APhy(Z08|~KgQ|(FDyew zsp=R5YT~nlTY~rX-#i|V$K!G2Wc)mlWh6Gnqti<0l$mFCVfs>HcWU= zU}N>)$8f~oL^fIRfxO@v@>XXMp-0e`br?ZEGI~bCo)PzOtm9az;!cu|<&TbVw_ui5 zwW3|B5@D2()+~cyB$>Y!g)thJ$B!@Lz8kOX+jvq7OjAoBdRRn8M8L$qkQNB4TV7-vHO9JAJQ8q${ zXt%jig;B>Q5c8=c(DHB(vwdB7l^b%9eG_ZB*eh` zKiF!esNH0e)(Q5M{vNJS(>_P z7E8|>Y{ee=q-j zwe7~}bCKVdc&GAaaxy)wQaF3r-P1o;Nh@5_%Rq_QCc}p;>PT)Ya7yW!QtBIp3$O8J zJ-5$rM{OvXImeYE+BRq^+^17@2G@bfcef4nAgl2iHB$;h1ulz}PCmyM7K*Pgam#Cz zbh0@h|EGo$Hx)4kqh8}{YNEJY4eox2vh)a7Aw*_VJcEQL)XA+soKt#8avR94FA)<0 zsg_paDI8oR4sj0WmIU>IQ^k(^v-HmLNUj*xHHJLfb^%}CnhO;skj$V~R0982UN0V=@%S|H5 z;uJ7>9bD|Rm4pZ56i4zoJ=IZa8&Ggv;Yi#>l7j|^50U~WW>Z$`E;0opoG?qS^dksQ zV*JN6Byf8NnFb-wcoF={DLg80PPJyG^kph>&J*9j`iGBTGfe0-wbPcVh6NAbUJ%ZN ztdz1$s|pqw@5&|N%z~zWqbgGr!=~g;l5oa2DkYzHjCdO%3wKgVF4HrZkUROUOf{~M z=Cn_G^Ob30e|2SgbvihOvrJ5;rPOP`dC$3%MtH~4JMp?6`=xmg(XZ1+9^S3ggNITr z$+W~p3hpEhXEc=JYmc?*+v(sg6Nl?7#q*vFq19=}GEq2@Hg>1zQ%$CBpS~2rnOS0& za#N}u@Vq;9lFP*8^xnIcOx^3#he|jz7F=WQ9y??bb?O_=m?Mn?1{t5-UBdr(x8okAfglRt)6NvGbb(TUq6aG6C1`*| zdzTZx{}(gHL?W~88yxWWH+fCNyxk_-f-<2>$;n?PZAF*f9N|EitF7($1=`4kbj+RB zq%{6;d!?4m^<^4zw-2Q39pSgH)E<;c>yvhHG!>eH7p~#y7M}N7(e^O;iAL+mBRC0FBn==#2$yIg$lQO zx(rK>#?!52%-DnNO}C99+-~-4tJF!&d&yW%5pOT9a4Za>mBRBr4~%6L^Xd%8MuwAt zW*I9JR#H@RWw^gmlAPefWm2)lBSjsq4)<3oIiREU(w1y^C$V`S3HLi!D*DZS^HKhB z-YaTx-Y~vTY~lV&rRnC+#&}!`n0Hhst+)K~?bp~HKBXYsQz>P#*{iFndB=5%t3}eu zyJaE*!X5h0647#1nX*kzZ9aFxt9r&pTWVEERI0)~!d3uv zx`oUh2o9eP_tNLr*oYmY2Zk@r_@=_57K0U=t*JxdSRZ`rgl9iokOGFUU25j#hC9S?^-C5lI_BP0Qt)<=X(jOL|W7pUt>r>A!o%X z@co2A{I5!eGgi>%WLzbR5@frDOy5;+oAY(11Qoxd=UJcsgKAsLS-P7pesWtkxv|1P z5P(Z6S#BfSAYj-4UhrO&oM7&Mv@BT$2KrjZJwk9{`B+pT8DmQDz@><>-+!L z>tEMSJWt_oVwj8Nd3MGDj!&X+h~abS8HX(O#RO^i6gmL41?6#A&u5qfhs~Og;BbQH z6ErwO49jO{oU+wZ5WAM8GlG-C#KNsOZL4PUc5ly;HG&U_dCcFnj?3HOLmf+{@G(`* zW72SF|pWh(6ha+1#Q zUegee-PT&(#yCL<-ocN&gH|ibA?|uuzwO#F3cw%?h2bn>D#Qi@U7{I!2=9Ni&V_=s zT@><7S%1j*5*tj$sQk!EVlXA6{mT=^!U_{Z0U#c|HIOG8+R)*Q8CE)+Yvq1hwmphbb0bSz9n3Qv{?B+?(fNy1()2HW=AbfwKB4_dS!i9PnJ%1er4>H zi~S!ZIHJM{XG4VxuDIcDxZ(qtxm=$B literal 0 HcmV?d00001 diff --git a/test/models/glTF2/BoxTextured-glTF/CesiumLogoFlat.png b/test/models/glTF2/BoxTextured-glTF/CesiumLogoFlat.png new file mode 100644 index 0000000000000000000000000000000000000000..45d502ed2610974189307ad542b05b70df14abd4 GIT binary patch literal 2433 zcmV-{34Zp8P)_WXpT zT&KN^W{xz{-NS2=JMQx8=kogA?fBT~_si45y2_@+&$ZLn&C25R(B<{I+3>&4t;yH7 z=k4F%=+?sB^4sOl<>lpUt>3WB;eWT|mc!+SyX3^v-*2zrrpV)YwBmHJ;knS^%huk~ z+1}aP+>XEHoyX^<&g`+&?tmWZ761SUi%CR5RCr$O)Jt;2APhy(Z08|~KgQ|(FDyew zsp=R5YT~nlTY~rX-#i|V$K!G2Wc)mlWh6Gnqti<0l$mFCVfs>HcWU= zU}N>)$8f~oL^fIRfxO@v@>XXMp-0e`br?ZEGI~bCo)PzOtm9az;!cu|<&TbVw_ui5 zwW3|B5@D2()+~cyB$>Y!g)thJ$B!@Lz8kOX+jvq7OjAoBdRRn8M8L$qkQNB4TV7-vHO9JAJQ8q${ zXt%jig;B>Q5c8=c(DHB(vwdB7l^b%9eG_ZB*eh` zKiF!esNH0e)(Q5M{vNJS(>_P z7E8|>Y{ee=q-j zwe7~}bCKVdc&GAaaxy)wQaF3r-P1o;Nh@5_%Rq_QCc}p;>PT)Ya7yW!QtBIp3$O8J zJ-5$rM{OvXImeYE+BRq^+^17@2G@bfcef4nAgl2iHB$;h1ulz}PCmyM7K*Pgam#Cz zbh0@h|EGo$Hx)4kqh8}{YNEJY4eox2vh)a7Aw*_VJcEQL)XA+soKt#8avR94FA)<0 zsg_paDI8oR4sj0WmIU>IQ^k(^v-HmLNUj*xHHJLfb^%}CnhO;skj$V~R0982UN0V=@%S|H5 z;uJ7>9bD|Rm4pZ56i4zoJ=IZa8&Ggv;Yi#>l7j|^50U~WW>Z$`E;0opoG?qS^dksQ zV*JN6Byf8NnFb-wcoF={DLg80PPJyG^kph>&J*9j`iGBTGfe0-wbPcVh6NAbUJ%ZN ztdz1$s|pqw@5&|N%z~zWqbgGr!=~g;l5oa2DkYzHjCdO%3wKgVF4HrZkUROUOf{~M z=Cn_G^Ob30e|2SgbvihOvrJ5;rPOP`dC$3%MtH~4JMp?6`=xmg(XZ1+9^S3ggNITr z$+W~p3hpEhXEc=JYmc?*+v(sg6Nl?7#q*vFq19=}GEq2@Hg>1zQ%$CBpS~2rnOS0& za#N}u@Vq;9lFP*8^xnIcOx^3#he|jz7F=WQ9y??bb?O_=m?Mn?1{t5-UBdr(x8okAfglRt)6NvGbb(TUq6aG6C1`*| zdzTZx{}(gHL?W~88yxWWH+fCNyxk_-f-<2>$;n?PZAF*f9N|EitF7($1=`4kbj+RB zq%{6;d!?4m^<^4zw-2Q39pSgH)E<;c>yvhHG!>eH7p~#y7M}N7(e^O;iAL+mBRC0FBn==#2$yIg$lQO zx(rK>#?!52%-DnNO}C99+-~-4tJF!&d&yW%5pOT9a4Za>mBRBr4~%6L^Xd%8MuwAt zW*I9JR#H@RWw^gmlAPefWm2)lBSjsq4)<3oIiREU(w1y^C$V`S3HLi!D*DZS^HKhB z-YaTx-Y~vTY~lV&rRnC+#&}!`n0Hhst+)K~?bp~HKBXYsQz>P#*{iFndB=5%t3}eu zyJaE*!X5h0647#1nX*kzZ9aFxt9r&pTWVEERI0)~!d3uv zx`oUh2o9eP_tNLr*oYmY2Zk@r_@=_57K0U=t*JxdSRZ`rgl9iokOGFUU25j#hC9S?^-C5lI_BP0Qt)<=X(jOL|W7pUt>r>A!o%X z@co2A{I5!eGgi>%WLzbR5@frDOy5;+oAY(11Qoxd=UJcsgKAsLS-P7pesWtkxv|1P z5P(Z6S#BfSAYj-4UhrO&oM7&Mv@BT$2KrjZJwk9{`B+pT8DmQDz@><>-+!L z>tEMSJWt_oVwj8Nd3MGDj!&X+h~abS8HX(O#RO^i6gmL41?6#A&u5qfhs~Og;BbQH z6ErwO49jO{oU+wZ5WAM8GlG-C#KNsOZL4PUc5ly;HG&U_dCcFnj?3HOLmf+{@G(`* zW72SF|pWh(6ha+1#Q zUegee-PT&(#yCL<-ocN&gH|ibA?|uuzwO#F3cw%?h2bn>D#Qi@U7{I!2=9Ni&V_=s zT@><7S%1j*5*tj$sQk!EVlXA6{mT=^!U_{Z0U#c|HIOG8+R)*Q Date: Wed, 30 Aug 2017 17:25:11 -0400 Subject: [PATCH 19/90] Working read, import, export, and write of gltf2 (pbr) material --- code/glTF2Asset.h | 51 ++++++++------ code/glTF2Asset.inl | 115 +++++++++++++++++++----------- code/glTF2AssetWriter.inl | 145 ++++++++++++++++++++++++++++++++------ code/glTF2Exporter.cpp | 50 +++++++------ code/glTF2Exporter.h | 10 ++- code/glTF2Importer.cpp | 93 +++++++++++++++++------- 6 files changed, 329 insertions(+), 135 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 5d99735b2..509fef115 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -133,7 +133,6 @@ namespace glTF2 struct Light; struct Skin; - // Vec/matrix types, as raw float arrays typedef float (vec3)[3]; typedef float (vec4)[4]; @@ -671,20 +670,30 @@ namespace glTF2 inline void SetData(uint8_t* data, size_t length, Asset& r); }; - struct ColorProperty - { - union { - vec4, vec3 - } color; - } - - //! Holds a material property that can be a texture or a color (fallback for glTF 1) - struct FallbackTexProperty + struct TextureInfo { Ref texture; - ColorProperty color; + unsigned int index; + unsigned int texCoord = 0; }; + struct NormalTextureInfo : TextureInfo + { + float scale = 1; + }; + + struct OcclusionTextureInfo : TextureInfo + { + float strength = 1; + }; + + //! Holds a material property that can be a texture or a color (fallback for glTF 1) + /*struct FallbackTexProperty + { + Ref texture; + vec4 color; + };*/ + //! The material appearance of a primitive. struct Material : public Object { @@ -702,26 +711,26 @@ namespace glTF2 }; //PBR metallic roughness properties - ColorProperty baseColor; - Ref baseColorTexture; - Ref metallicRoughnessTexture; + vec4 baseColorFactor; + TextureInfo baseColorTexture; + TextureInfo metallicRoughnessTexture; float metallicFactor; float roughnessFactor; //other basic material properties - Ref normalTexture; - Ref occlusionTexture; - Ref emissiveTexture; - ColorProperty emissiveFactor; + NormalTextureInfo normalTexture; + OcclusionTextureInfo occlusionTexture; + TextureInfo emissiveTexture; + vec3 emissiveFactor; std::string alphaMode; float alphaCutoff; bool doubleSided; //fallback material properties (compatible with non-pbr defintions) - FallbackTexProperty diffuse; - FallbackTexProperty emissive; + /*FallbackTexProperty diffuse; + FallbackTexProperty emission; FallbackTexProperty specular; - Ref normal; + Ref normal;*/ Technique technique; diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index bf8cb5a36..94858044d 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -128,6 +128,12 @@ namespace { return (it != val.MemberEnd() && it->value.IsString()) ? &it->value : 0; } + inline Value* FindNumber(Value& val, const char* id) + { + Value::MemberIterator it = val.FindMember(id); + return (it != val.MemberEnd() && it->value.IsNumber()) ? &it->value : 0; + } + inline Value* FindUInt(Value& val, const char* id) { Value::MemberIterator it = val.FindMember(id); @@ -225,7 +231,7 @@ Ref LazyDict::Retrieve(unsigned int i) } T* inst = new T(); - inst->id = std::string(mDictId) + "[" + std::to_string(i) + "]"; + inst->id = std::string(mDictId) + "_" + std::to_string(i); inst->oIndex = i; ReadMember(obj, "name", inst->name); inst->Read(obj, mAsset); @@ -706,15 +712,42 @@ inline void Texture::Read(Value& obj, Asset& r) } namespace { - inline void ReadMaterialProperty(Asset& r, Value& vals, const char* propName, TexProperty& out) + inline void SetTextureProperties(Asset& r, Value* prop, TextureInfo& out) + { + if (Value* index = FindUInt(*prop, "index")) { + out.texture = r.textures.Retrieve(index->GetUint()); + } + + if (Value* texcoord = FindUInt(*prop, "texCoord")) { + out.texCoord = texcoord->GetUint(); + } + } + + inline void ReadTextureProperty(Asset& r, Value& vals, const char* propName, TextureInfo& out) { - //@TODO: update this format if (Value* prop = FindMember(vals, propName)) { - if (prop->IsUint()) { - out.texture = r.textures.Retrieve(prop->GetUint()); + SetTextureProperties(r, prop, out); + } + } + + inline void ReadTextureProperty(Asset& r, Value& vals, const char* propName, NormalTextureInfo& out) + { + if (Value* prop = FindMember(vals, propName)) { + SetTextureProperties(r, prop, out); + + if (Value* scale = FindNumber(*prop, "scale")) { + out.scale = scale->GetDouble(); } - else { - ReadValue(*prop, out.color); + } + } + + inline void ReadTextureProperty(Asset& r, Value& vals, const char* propName, OcclusionTextureInfo& out) + { + if (Value* prop = FindMember(vals, propName)) { + SetTextureProperties(r, prop, out); + + if (Value* strength = FindNumber(*prop, "strength")) { + out.strength = strength->GetDouble(); } } } @@ -724,33 +757,24 @@ inline void Material::Read(Value& material, Asset& r) { SetDefaults(); - if (Value* values = FindObject(material, "values")) { - - - ReadMember(*values, "transparency", transparency); - } - if (Value* values = FindObject(material, "pbrMetallicRoughness")) { - //pbr - ReadMaterialProperty(r, *values, "baseColorFactor", this->baseColor); - ReadMaterialProperty(r, *values, "baseColorTexture", this->baseColorTexture); - - //non-pbr fallback - ReadMaterialProperty(r, *values, "baseColorFactor", this->diffuse); - ReadMaterialProperty(r, *values, "baseColorTexture", this->diffuse); - - ReadMember(*values, "metallicFactor", metallicFactor); + ReadMember(*values, "baseColorFactor", this->baseColorFactor); + ReadTextureProperty(r, *values, "baseColorTexture", this->baseColorTexture); + ReadTextureProperty(r, *values, "metallicRoughnessTexture", this->metallicRoughnessTexture); + ReadMember(*values, "metallicFactor", this->metallicFactor); + ReadMember(*values, "roughnessFactor", this->roughnessFactor); } - ReadMaterialProperty(r, *values, "normalTexture", this->normalTexture); - ReadMaterialProperty(r, *values, "normalTexture", this->normal); - ReadMaterialProperty(r, *values, "occlusionTexture", this->occlusionTexture); - ReadMaterialProperty(r, *values, "emissiveTexture", this->emissiveTexture); - ReadMember(*values, "metallicFactor", emissiveFactor); + ReadTextureProperty(r, material, "normalTexture", this->normalTexture); + ReadTextureProperty(r, material, "occlusionTexture", this->occlusionTexture); + ReadTextureProperty(r, material, "emissiveTexture", this->emissiveTexture); + ReadMember(material, "emissiveFactor", this->emissiveFactor); - ReadMember(material, "doubleSided", doubleSided); + ReadMember(material, "doubleSided", this->doubleSided); + ReadMember(material, "alphaMode", this->alphaMode); + ReadMember(material, "alphaCutoff", this->alphaCutoff); - if (Value* extensions = FindObject(material, "extensions")) { + /* if (Value* extensions = FindObject(material, "extensions")) { if (r.extensionsUsed.KHR_materials_common) { if (Value* ext = FindObject(*extensions, "KHR_materials_common")) { if (Value* tnq = FindString(*ext, "technique")) { @@ -762,9 +786,9 @@ inline void Material::Read(Value& material, Asset& r) } if (Value* values = FindObject(*ext, "values")) { - ReadMaterialProperty(r, *values, "ambient", this->ambient); - ReadMaterialProperty(r, *values, "diffuse", this->diffuse); - ReadMaterialProperty(r, *values, "specular", this->specular); + ReadTextureProperty(r, *values, "ambient", this->ambient); + ReadTextureProperty(r, *values, "diffuse", this->diffuse); + ReadTextureProperty(r, *values, "specular", this->specular); ReadMember(*values, "doubleSided", doubleSided); ReadMember(*values, "transparent", transparent); @@ -773,25 +797,28 @@ inline void Material::Read(Value& material, Asset& r) } } } - } + } */ } namespace { void SetVector(vec4& v, float x, float y, float z, float w) { v[0] = x; v[1] = y; v[2] = z; v[3] = w; } + + void SetVector(vec3& v, float x, float y, float z) + { v[0] = x; v[1] = y; v[2] = z; } } inline void Material::SetDefaults() { - SetVector(ambient.color, 0, 0, 0, 1); - SetVector(diffuse.color, 0, 0, 0, 1); - SetVector(specular.color, 0, 0, 0, 1); - SetVector(emission.color, 0, 0, 0, 1); + //pbr materials + SetVector(baseColorFactor, 1, 1, 1, 1); + SetVector(emissiveFactor, 0, 0, 0); + metallicFactor = 1.0; + roughnessFactor = 1.0; + alphaMode = "OPAQUE"; + alphaCutoff = 0.5; doubleSided = false; - transparent = false; - transparency = 1.0; - shininess = 0.0; technique = Technique_undefined; } @@ -833,6 +860,10 @@ namespace { inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root) { + if (Value* name = FindMember(pJSON_Object, "name")) { + this->name = name->GetString(); + } + /****************** Mesh primitives ******************/ if (Value* primitives = FindArray(pJSON_Object, "primitives")) { this->primitives.resize(primitives->Size()); @@ -1055,7 +1086,7 @@ inline void Node::Read(Value& obj, Asset& r) // TODO load "skeletons", "skin", "jointName" - if (Value* extensions = FindObject(obj, "extensions")) { + /*if (Value* extensions = FindObject(obj, "extensions")) { if (r.extensionsUsed.KHR_materials_common) { if (Value* ext = FindObject(*extensions, "KHR_materials_common")) { @@ -1065,7 +1096,7 @@ inline void Node::Read(Value& obj, Asset& r) } } - } + }*/ } inline void Scene::Read(Value& obj, Asset& r) diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index ed8ee80ea..a939e38d6 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -72,6 +72,12 @@ namespace glTF2 { return val; } + inline Value& MakeValue(Value& val, float r, MemoryPoolAllocator<>& al) { + val.SetDouble(r); + + return val; + } + template inline void AddRefsVector(Value& obj, const char* fieldId, std::vector< Ref >& v, MemoryPoolAllocator<>& al) { if (v.empty()) return; @@ -196,51 +202,148 @@ namespace glTF2 { } namespace { - inline void WriteTex(Value& obj, Ref texture, const char* propName, MemoryPoolAllocator<>& al) + inline void SetTexBasic(TextureInfo t, Value& tex, MemoryPoolAllocator<>& al) { - if (texture) { + tex.SetObject(); + tex.AddMember("index", t.texture->index, al); + + if (t.texCoord != 0) { + tex.AddMember("texCoord", t.texCoord, al); + } + } + + inline void WriteTex(Value& obj, TextureInfo t, const char* propName, MemoryPoolAllocator<>& al) + { + + if (t.texture) { Value tex; - tex.SetObject(); - tex.AddMember("index", texture->index, al); + + SetTexBasic(t, tex, al); + obj.AddMember(StringRef(propName), tex, al); } } - inline void WriteColorOrTex(Value& obj, TexProperty& prop, const char* propName, MemoryPoolAllocator<>& al) + inline void WriteTex(Value& obj, NormalTextureInfo t, const char* propName, MemoryPoolAllocator<>& al) { - WriteTex(obj, prop.texture, propName, al); - if (!prop.texture) { - Value col; - obj.AddMember(StringRef(propName), MakeValue(col, prop.color, al), al); + + if (t.texture) { + Value tex; + + SetTexBasic(t, tex, al); + + if (t.scale != 1) { + tex.AddMember("scale", t.scale, al); + } + + obj.AddMember(StringRef(propName), tex, al); } } + + inline void WriteTex(Value& obj, OcclusionTextureInfo t, const char* propName, MemoryPoolAllocator<>& al) + { + + if (t.texture) { + Value tex; + + SetTexBasic(t, tex, al); + + if (t.strength != 1) { + tex.AddMember("strength", t.strength, al); + } + + obj.AddMember(StringRef(propName), tex, al); + } + } + + template + inline void WriteVec(Value& obj, float(&prop)[N], const char* propName, MemoryPoolAllocator<>& al) + { + Value arr; + obj.AddMember(StringRef(propName), MakeValue(arr, prop, al), al); + } + + template + inline void WriteVec(Value& obj, float(&prop)[N], const char* propName, float(&defaultVal)[N], MemoryPoolAllocator<>& al) + { + if (!std::equal(std::begin(prop), std::end(prop), std::begin(defaultVal))) { + WriteVec(obj, prop, propName, al); + } + } + + inline void WriteFloat(Value& obj, float prop, const char* propName, MemoryPoolAllocator<>& al) + { + Value num; + obj.AddMember(StringRef(propName), MakeValue(num, prop, al), al); + } } inline void Write(Value& obj, Material& m, AssetWriter& w) { - if (m.transparent) { - obj.AddMember("alphaMode", "BLEND", w.mAl); + if (!m.name.empty()) { + obj.AddMember("name", m.name, w.mAl); } - Value v; + Value pbrMetallicRoughness; + pbrMetallicRoughness.SetObject(); + { + WriteTex(pbrMetallicRoughness, m.baseColorTexture, "baseColorTexture", w.mAl); + WriteTex(pbrMetallicRoughness, m.metallicRoughnessTexture, "metallicRoughnessTexture", w.mAl); + + //@TODO: define this as a constant? + vec4 defaultEmissiveFactor = {1, 1, 1, 1}; + WriteVec(pbrMetallicRoughness, m.baseColorFactor, "baseColorFactor", defaultEmissiveFactor, w.mAl); + + if (m.metallicFactor != 1) { + WriteFloat(pbrMetallicRoughness, m.metallicFactor, "metallicFactor", w.mAl); + } + + if (m.roughnessFactor != 1) { + WriteFloat(pbrMetallicRoughness, m.roughnessFactor, "roughnessFactor", w.mAl); + } + } + + if (pbrMetallicRoughness.MemberCount() > 0) { + obj.AddMember("pbrMetallicRoughness", pbrMetallicRoughness, w.mAl); + } + + WriteTex(obj, m.normalTexture, "normalTexture", w.mAl); + WriteTex(obj, m.emissiveTexture, "emissiveTexture", w.mAl); + WriteTex(obj, m.occlusionTexture, "occlusionTexture", w.mAl); + + //@TODO: define this as a constant? + vec3 defaultEmissiveFactor = {0, 0, 0}; + WriteVec(obj, m.emissiveFactor, "emissiveFactor", defaultEmissiveFactor, w.mAl); + + if (m.alphaCutoff != 0.5) { + WriteFloat(obj, m.alphaCutoff, "alphaCutoff", w.mAl); + } + + if (m.alphaMode != "OPAQUE") { + obj.AddMember("alphaMode", m.alphaMode, w.mAl); + } + + if (m.doubleSided) { + obj.AddMember("doubleSided", m.doubleSided, w.mAl); + } + + /*Value v; v.SetObject(); { if (m.transparent && !m.diffuse.texture) { m.diffuse.color[3] = m.transparency; } - WriteColorOrTex(v, m.ambient, m.ambient.texture ? "ambientTexture" : "ambientFactor", w.mAl); - WriteColorOrTex(v, m.diffuse, m.diffuse.texture ? "diffuseTexture" : "diffuseFactor", w.mAl); - WriteColorOrTex(v, m.specular, m.specular.texture ? "specularTexture" : "specularFactor", w.mAl); - WriteColorOrTex(v, m.emission, m.emission.texture ? "emissionTexture" : "emissionFactor", w.mAl); + WriteVecOrTex(v, m.ambient, m.ambient.texture ? "ambientTexture" : "ambientFactor", w.mAl); + WriteVecOrTex(v, m.diffuse, m.diffuse.texture ? "diffuseTexture" : "diffuseFactor", w.mAl); + WriteVecOrTex(v, m.specular, m.specular.texture ? "specularTexture" : "specularFactor", w.mAl); + WriteVecOrTex(v, m.emission, m.emission.texture ? "emissionTexture" : "emissionFactor", w.mAl); v.AddMember("shininessFactor", m.shininess, w.mAl); } v.AddMember("type", "commonPhong", w.mAl); Value ext; ext.SetObject(); ext.AddMember("KHR_materials_common", v, w.mAl); - obj.AddMember("extensions", ext, w.mAl); - - WriteTex(obj, m.normal, "normalTexture", w.mAl); + obj.AddMember("extensions", ext, w.mAl);*/ } namespace { @@ -263,8 +366,6 @@ namespace glTF2 { inline void Write(Value& obj, Mesh& m, AssetWriter& w) { - /********************* Name **********************/ - obj.AddMember("name", m.name, w.mAl); /**************** Mesh extensions ****************/ if(m.Extension.size() > 0) @@ -617,7 +718,7 @@ namespace glTF2 { exts.PushBack(StringRef("KHR_binary_glTF"), mAl); // This is used to export common materials with GLTF 2. - exts.PushBack(StringRef("KHR_materials_common"), mAl); + //exts.PushBack(StringRef("KHR_materials_common"), mAl); } if (!exts.Empty()) diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 68f2f4420..f59c280f1 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -234,12 +234,6 @@ inline Ref ExportData(Asset& a, std::string& meshName, Ref& bu return acc; } -namespace { - void GetMatScalar(const aiMaterial* mat, float& val, const char* propName, int type, int idx) { - if (mat->Get(propName, type, idx, val) == AI_SUCCESS) {} - } -} - void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref texture) { std::string samplerId = mAsset->FindUniqueID("", "sampler"); @@ -286,11 +280,11 @@ void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref texture) texture->sampler->minFilter = SamplerMinFilter_Linear_Mipmap_Linear; } -void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref& texture, aiTextureType tt) +void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref& texture, aiTextureType tt, unsigned int slot = 0) { aiString tex; if (mat->GetTextureCount(tt) > 0) { - if (mat->Get(AI_MATKEY_TEXTURE(tt, 0), tex) == AI_SUCCESS) { + if (mat->Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) { std::string path = tex.C_Str(); if (path.size() > 0) { @@ -332,15 +326,21 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref& texture, aiTe } } -void glTF2Exporter::GetMatColorOrTex(const aiMaterial* mat, TexProperty& prop, const char* propName, int type, int idx, aiTextureType tt) +void glTF2Exporter::GetMatColor(const aiMaterial* mat, vec4& prop, const char* propName, int type, int idx) { aiColor4D col; if (mat->Get(propName, type, idx, col) == AI_SUCCESS) { - prop.color[0] = col.r; prop.color[1] = col.g; prop.color[2] = col.b; prop.color[3] = col.a; + prop[0] = col.r; prop[1] = col.g; prop[2] = col.b; prop[3] = col.a; } - GetMatTex(mat, prop.texture, tt); } +void glTF2Exporter::GetMatColor(const aiMaterial* mat, vec3& prop, const char* propName, int type, int idx) +{ + aiColor3D col; + if (mat->Get(propName, type, idx, col) == AI_SUCCESS) { + prop[0] = col.r; prop[1] = col.g; prop[2] = col.b; + } +} void glTF2Exporter::ExportMaterials() { @@ -348,7 +348,6 @@ void glTF2Exporter::ExportMaterials() for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) { const aiMaterial* mat = mScene->mMaterials[i]; - std::string name; if (mat->Get(AI_MATKEY_NAME, aiName) == AI_SUCCESS) { name = aiName.C_Str(); @@ -357,15 +356,20 @@ void glTF2Exporter::ExportMaterials() Ref m = mAsset->materials.Create(name); - GetMatColorOrTex(mat, m->ambient, AI_MATKEY_COLOR_AMBIENT, aiTextureType_AMBIENT); - GetMatColorOrTex(mat, m->diffuse, AI_MATKEY_COLOR_DIFFUSE, aiTextureType_DIFFUSE); - GetMatColorOrTex(mat, m->specular, AI_MATKEY_COLOR_SPECULAR, aiTextureType_SPECULAR); - GetMatColorOrTex(mat, m->emission, AI_MATKEY_COLOR_EMISSIVE, aiTextureType_EMISSIVE); - GetMatTex(mat, m->normal, aiTextureType_NORMALS); + GetMatTex(mat, m->baseColorTexture.texture, aiTextureType_DIFFUSE); + GetMatTex(mat, m->metallicRoughnessTexture.texture, aiTextureType_UNKNOWN, 0);//get unknown slot + GetMatTex(mat, m->emissiveTexture.texture, aiTextureType_EMISSIVE); + GetMatTex(mat, m->normalTexture.texture, aiTextureType_NORMALS); + GetMatTex(mat, m->occlusionTexture.texture, aiTextureType_LIGHTMAP); - m->transparent = mat->Get(AI_MATKEY_OPACITY, m->transparency) == aiReturn_SUCCESS && m->transparency != 1.0; + GetMatColor(mat, m->baseColorFactor, AI_MATKEY_COLOR_DIFFUSE); + GetMatColor(mat, m->emissiveFactor, AI_MATKEY_COLOR_EMISSIVE); - GetMatScalar(mat, m->shininess, AI_MATKEY_SHININESS); + mat->Get(AI_MATKEY_TWOSIDED, m->doubleSided); + mat->Get("$mat.gltf.alphaCutoff", 0, 0, m->alphaCutoff); + mat->Get("$mat.gltf.metallicFactor", 0, 0, m->metallicFactor); + mat->Get("$mat.gltf.roughnessFactor", 0, 0, m->roughnessFactor); + mat->Get("$mat.gltf.alphaMode", 0, 0, m->alphaMode); } } @@ -566,13 +570,17 @@ void glTF2Exporter::ExportMeshes() DefaultLogger::get()->warn("GLTF: can not use Open3DGC-compression: " + msg); comp_allow = false; - } + } - std::string meshId = mAsset->FindUniqueID(aim->mName.C_Str(), "mesh"); + std::string name = aim->mName.C_Str(); + + std::string meshId = mAsset->FindUniqueID(name, "mesh"); Ref m = mAsset->meshes.Create(meshId); m->primitives.resize(1); Mesh::Primitive& p = m->primitives.back(); + m->name = name; + p.material = mAsset->materials.Get(aim->mMaterialIndex); /******************* Vertices ********************/ diff --git a/code/glTF2Exporter.h b/code/glTF2Exporter.h index 17cc9cfdc..2ba0143bf 100644 --- a/code/glTF2Exporter.h +++ b/code/glTF2Exporter.h @@ -66,8 +66,13 @@ namespace glTF2 class Asset; struct TexProperty; + struct TextureInfo; struct Node; struct Texture; + + // Vec/matrix types, as raw float arrays + typedef float (vec3)[3]; + typedef float (vec4)[4]; } namespace Assimp @@ -102,8 +107,9 @@ namespace Assimp void WriteBinaryData(IOStream* outfile, std::size_t sceneLength); void GetTexSampler(const aiMaterial* mat, glTF2::Ref texture); - void GetMatTex(const aiMaterial* mat, glTF2::Ref& texture, aiTextureType tt); - void GetMatColorOrTex(const aiMaterial* mat, glTF2::TexProperty& prop, const char* propName, int type, int idx, aiTextureType tt); + void GetMatTex(const aiMaterial* mat, glTF2::Ref& texture, aiTextureType tt, unsigned int slot); + void GetMatColor(const aiMaterial* mat, glTF2::vec4& prop, const char* propName, int type, int idx); + void GetMatColor(const aiMaterial* mat, glTF2::vec3& prop, const char* propName, int type, int idx); void ExportMetadata(); void ExportMaterials(); void ExportMeshes(); diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index bd4f42600..25cb39168 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -141,6 +141,11 @@ static void CopyValue(const glTF2::vec4& v, aiColor3D& out) out.r = v[0]; out.g = v[1]; out.b = v[2]; } +static void CopyValue(const glTF2::vec3& v, aiColor4D& out) +{ + out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = 1.0; +} + static void CopyValue(const glTF2::vec3& v, aiVector3D& out) { out.x = v[0]; out.y = v[1]; out.z = v[2]; @@ -159,28 +164,56 @@ static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o) o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15]; } -inline void SetMaterialColorProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::TexProperty prop, aiMaterial* mat, - aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx) +inline void SetMaterialColorProperty(Asset& r, vec4& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx) { - if (prop.texture) { - if (prop.texture->source) { - aiString uri(prop.texture->source->uri); + aiColor4D col; + CopyValue(prop, col); + mat->AddProperty(&col, 1, pKey, type, idx); +} - int texIdx = embeddedTexIdxs[prop.texture->source.GetIndex()]; - if (texIdx != -1) { // embedded - // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture) - uri.data[0] = '*'; - uri.length = 1 + ASSIMP_itoa10(uri.data + 1, MAXLEN - 1, texIdx); - } +inline void SetMaterialColorProperty(Asset& r, vec3& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx) +{ + vec4 prop4; + prop4[0] = prop[0]; + prop4[1] = prop[1]; + prop4[2] = prop[2]; + prop4[3] = 1; + + return SetMaterialColorProperty(r, prop4, mat, pKey, type, idx); +} + +inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::TextureInfo prop, aiMaterial* mat, aiTextureType texType, int texSlot) +{ + if (prop.texture && prop.texture->source) { + aiString uri(prop.texture->source->uri); + + int texIdx = embeddedTexIdxs[prop.texture->source.GetIndex()]; + if (texIdx != -1) { // embedded + // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture) + uri.data[0] = '*'; + uri.length = 1 + ASSIMP_itoa10(uri.data + 1, MAXLEN - 1, texIdx); + } + + if (texSlot < 0) { mat->AddProperty(&uri, _AI_MATKEY_TEXTURE_BASE, texType, 0); } + else { + mat->AddProperty(&uri, AI_MATKEY_TEXTURE(texType, + texSlot)); + } } - else { - aiColor4D col; - CopyValue(prop.color, col); - mat->AddProperty(&col, 1, pKey, type, idx); - } +} + +//import textures that are only supported in pbr contexts +inline void SetMaterialPBRTextureProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::TextureInfo prop, aiMaterial* mat, unsigned int texSlot) +{ + return SetMaterialTextureProperty(embeddedTexIdxs, r, prop, mat, aiTextureType_UNKNOWN, texSlot); +} + +inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::TextureInfo prop, aiMaterial* mat, aiTextureType texType) +{ + return SetMaterialTextureProperty(embeddedTexIdxs, r, prop, mat, texType, -1); } void glTF2Importer::ImportMaterials(glTF2::Asset& r) @@ -193,18 +226,23 @@ void glTF2Importer::ImportMaterials(glTF2::Asset& r) Material& mat = r.materials[i]; - /*if (!mat.name.empty())*/ { - aiString str(mat.id /*mat.name*/); - aimat->AddProperty(&str, AI_MATKEY_NAME); - } + aiString str(mat.id); + aimat->AddProperty(&str, AI_MATKEY_NAME); - SetMaterialColorProperty(embeddedTexIdxs, r, mat.diffuse, aimat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE); - SetMaterialColorProperty(embeddedTexIdxs, r, mat.specular, aimat, aiTextureType_SPECULAR, AI_MATKEY_COLOR_SPECULAR); - SetMaterialColorProperty(embeddedTexIdxs, r, mat.ambient, aimat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT); + SetMaterialColorProperty(r, mat.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.baseColorTexture, aimat, aiTextureType_DIFFUSE); + SetMaterialPBRTextureProperty(embeddedTexIdxs, r, mat.metallicRoughnessTexture, aimat, 0); + aimat->AddProperty(&mat.metallicFactor, 1, "$mat.gltf.metallicFactor"); + aimat->AddProperty(&mat.roughnessFactor, 1, "$mat.gltf.roughnessFactor"); - if (mat.shininess > 0.f) { - aimat->AddProperty(&mat.shininess, 1, AI_MATKEY_SHININESS); - } + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.normalTexture, aimat, aiTextureType_NORMALS); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.occlusionTexture, aimat, aiTextureType_LIGHTMAP); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.emissiveTexture, aimat, aiTextureType_EMISSIVE); + SetMaterialColorProperty(r, mat.emissiveFactor, aimat, AI_MATKEY_COLOR_EMISSIVE); + + aimat->AddProperty(&mat.doubleSided, 1, AI_MATKEY_TWOSIDED); + aimat->AddProperty(&mat.alphaMode, 1, "$mat.gltf.alphaMode"); + aimat->AddProperty(&mat.alphaCutoff, 1, "$mat.gltf.alphaCutoff"); } } @@ -295,7 +333,8 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r) aiMesh* aim = new aiMesh(); meshes.push_back(aim); - aim->mName = mesh.id; + aim->mName = mesh.name.empty() ? mesh.id : mesh.name; + if (mesh.primitives.size() > 1) { size_t& len = aim->mName.length; aim->mName.data[len] = '-'; From 0cf69479c30c97a6f4bfeb00ffdceab5749b2b5f Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Wed, 30 Aug 2017 21:50:06 -0400 Subject: [PATCH 20/90] Use `!ObjectEmpty()` vs. `MemberCount() > 0` --- code/glTF2AssetWriter.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index a939e38d6..bd16a7023 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -303,7 +303,7 @@ namespace glTF2 { } } - if (pbrMetallicRoughness.MemberCount() > 0) { + if (!pbrMetallicRoughness.ObjectEmpty()) { obj.AddMember("pbrMetallicRoughness", pbrMetallicRoughness, w.mAl); } From 7615a97cd3164d624f3762dd3edf49f6e461a88d Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Wed, 30 Aug 2017 23:51:52 -0400 Subject: [PATCH 21/90] Remove redundant function --- code/glTF2Importer.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 25cb39168..b1bbf8349 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -205,12 +205,6 @@ inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& } } -//import textures that are only supported in pbr contexts -inline void SetMaterialPBRTextureProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::TextureInfo prop, aiMaterial* mat, unsigned int texSlot) -{ - return SetMaterialTextureProperty(embeddedTexIdxs, r, prop, mat, aiTextureType_UNKNOWN, texSlot); -} - inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::TextureInfo prop, aiMaterial* mat, aiTextureType texType) { return SetMaterialTextureProperty(embeddedTexIdxs, r, prop, mat, texType, -1); @@ -231,7 +225,7 @@ void glTF2Importer::ImportMaterials(glTF2::Asset& r) SetMaterialColorProperty(r, mat.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); SetMaterialTextureProperty(embeddedTexIdxs, r, mat.baseColorTexture, aimat, aiTextureType_DIFFUSE); - SetMaterialPBRTextureProperty(embeddedTexIdxs, r, mat.metallicRoughnessTexture, aimat, 0); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.metallicRoughnessTexture, aimat, aiTextureType_UNKNOWN, 0); aimat->AddProperty(&mat.metallicFactor, 1, "$mat.gltf.metallicFactor"); aimat->AddProperty(&mat.roughnessFactor, 1, "$mat.gltf.roughnessFactor"); From 863458cd4a30632350685f8aee88ed420118f577 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Thu, 31 Aug 2017 01:35:10 -0400 Subject: [PATCH 22/90] Start removing materials common, and adding pbrSpecularGlossiness --- code/glTF2Asset.h | 69 +++++---------------------------------- code/glTF2Asset.inl | 64 ++++++++++++------------------------ code/glTF2AssetWriter.h | 2 +- code/glTF2AssetWriter.inl | 42 +++++++++++++++--------- code/glTF2Importer.cpp | 7 ++++ 5 files changed, 63 insertions(+), 121 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 509fef115..b19de747a 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -44,7 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * glTF Extensions Support: * KHR_binary_glTF: full - * KHR_materials_common: full */ #ifndef GLTF2ASSET_H_INC #define GLTF2ASSET_H_INC @@ -697,19 +696,6 @@ namespace glTF2 //! The material appearance of a primitive. struct Material : public Object { - //Ref source; //!< The ID of the technique. - //std::gltf_unordered_map values; //!< A dictionary object of parameter values. - - //! Techniques defined by KHR_materials_common - enum Technique - { - Technique_undefined = 0, - Technique_BLINN, - Technique_PHONG, - Technique_LAMBERT, - Technique_CONSTANT - }; - //PBR metallic roughness properties vec4 baseColorFactor; TextureInfo baseColorTexture; @@ -726,13 +712,12 @@ namespace glTF2 float alphaCutoff; bool doubleSided; - //fallback material properties (compatible with non-pbr defintions) - /*FallbackTexProperty diffuse; - FallbackTexProperty emission; - FallbackTexProperty specular; - Ref normal;*/ - - Technique technique; + //extension: KHR_materials_pbrSpecularGlossiness + vec4 diffuseFactor; + vec3 specularFactor; + float glossinessFactor; + TextureInfo diffuseTexture; + TextureInfo specularGlossinessTexture; Material() { SetDefaults(); } void Read(Value& obj, Asset& r); @@ -943,35 +928,6 @@ namespace glTF2 void Read(Value& obj, Asset& r); }; - - //! A light (from KHR_materials_common extension) - struct Light : public Object - { - enum Type - { - Type_undefined, - Type_ambient, - Type_directional, - Type_point, - Type_spot - }; - - Type type; - - vec4 color; - float distance; - float constantAttenuation; - float linearAttenuation; - float quadraticAttenuation; - float falloffAngle; - float falloffExponent; - - Light() {} - void Read(Value& obj, Asset& r); - - void SetDefaults(); - }; - struct Animation : public Object { struct AnimSampler { @@ -1152,7 +1108,7 @@ namespace glTF2 struct Extensions { bool KHR_binary_glTF; - bool KHR_materials_common; + bool KHR_materials_pbrSpecularGlossiness; } extensionsUsed; @@ -1170,16 +1126,11 @@ namespace glTF2 LazyDict materials; LazyDict meshes; LazyDict nodes; - //LazyDict programs; LazyDict samplers; LazyDict scenes; - //LazyDict shaders; LazyDict skins; - //LazyDict techniques; LazyDict textures; - LazyDict lights; // KHR_materials_common ext - Ref scene; public: @@ -1195,14 +1146,10 @@ namespace glTF2 , materials (*this, "materials") , meshes (*this, "meshes") , nodes (*this, "nodes") - //, programs (*this, "programs") , samplers (*this, "samplers") , scenes (*this, "scenes") - //, shaders (*this, "shaders") - , skins (*this, "skins") - //, techniques (*this, "techniques") + , skins (*this, "skins") , textures (*this, "textures") - , lights (*this, "lights", "KHR_materials_common") { memset(&extensionsUsed, 0, sizeof(extensionsUsed)); } diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 94858044d..3d53bfccf 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -757,12 +757,12 @@ inline void Material::Read(Value& material, Asset& r) { SetDefaults(); - if (Value* values = FindObject(material, "pbrMetallicRoughness")) { - ReadMember(*values, "baseColorFactor", this->baseColorFactor); - ReadTextureProperty(r, *values, "baseColorTexture", this->baseColorTexture); - ReadTextureProperty(r, *values, "metallicRoughnessTexture", this->metallicRoughnessTexture); - ReadMember(*values, "metallicFactor", this->metallicFactor); - ReadMember(*values, "roughnessFactor", this->roughnessFactor); + if (Value* pbrMetallicRoughness = FindObject(material, "pbrMetallicRoughness")) { + ReadMember(*pbrMetallicRoughness, "baseColorFactor", this->baseColorFactor); + ReadTextureProperty(r, *pbrMetallicRoughness, "baseColorTexture", this->baseColorTexture); + ReadTextureProperty(r, *pbrMetallicRoughness, "metallicRoughnessTexture", this->metallicRoughnessTexture); + ReadMember(*pbrMetallicRoughness, "metallicFactor", this->metallicFactor); + ReadMember(*pbrMetallicRoughness, "roughnessFactor", this->roughnessFactor); } ReadTextureProperty(r, material, "normalTexture", this->normalTexture); @@ -774,30 +774,17 @@ inline void Material::Read(Value& material, Asset& r) ReadMember(material, "alphaMode", this->alphaMode); ReadMember(material, "alphaCutoff", this->alphaCutoff); - /* if (Value* extensions = FindObject(material, "extensions")) { - if (r.extensionsUsed.KHR_materials_common) { - if (Value* ext = FindObject(*extensions, "KHR_materials_common")) { - if (Value* tnq = FindString(*ext, "technique")) { - const char* t = tnq->GetString(); - if (strcmp(t, "BLINN") == 0) technique = Technique_BLINN; - else if (strcmp(t, "PHONG") == 0) technique = Technique_PHONG; - else if (strcmp(t, "LAMBERT") == 0) technique = Technique_LAMBERT; - else if (strcmp(t, "CONSTANT") == 0) technique = Technique_CONSTANT; - } - - if (Value* values = FindObject(*ext, "values")) { - ReadTextureProperty(r, *values, "ambient", this->ambient); - ReadTextureProperty(r, *values, "diffuse", this->diffuse); - ReadTextureProperty(r, *values, "specular", this->specular); - - ReadMember(*values, "doubleSided", doubleSided); - ReadMember(*values, "transparent", transparent); - ReadMember(*values, "transparency", transparency); - ReadMember(*values, "shininess", shininess); - } + if (Value* extensions = FindObject(material, "extensions")) { + if (r.extensionsUsed.KHR_materials_pbrSpecularGlossiness) { + if (Value* pbrSpecularGlossiness = FindObject(*extensions, "KHR_materials_pbrSpecularGlossiness")) { + ReadMember(*pbrSpecularGlossiness, "diffuseFactor", this->diffuseFactor); + ReadTextureProperty(r, *pbrSpecularGlossiness, "diffuseTexture", this->diffuseTexture); + ReadTextureProperty(r, *pbrSpecularGlossiness, "specularGlossinessTexture", this->specularGlossinessTexture); + ReadMember(*pbrSpecularGlossiness, "specularFactor", this->specularFactor); + ReadMember(*pbrSpecularGlossiness, "glossinessFactor", this->glossinessFactor); } } - } */ + } } namespace { @@ -820,7 +807,10 @@ inline void Material::SetDefaults() alphaCutoff = 0.5; doubleSided = false; - technique = Technique_undefined; + //pbrSpecularGlossiness properties + SetVector(diffuseFactor, 1, 1, 1, 1); + SetVector(specularFactor, 1, 1, 1); + glossinessFactor = 1.0; } namespace { @@ -1083,20 +1073,6 @@ inline void Node::Read(Value& obj, Asset& r) if (this->camera) this->camera->id = this->id; } - - // TODO load "skeletons", "skin", "jointName" - - /*if (Value* extensions = FindObject(obj, "extensions")) { - if (r.extensionsUsed.KHR_materials_common) { - - if (Value* ext = FindObject(*extensions, "KHR_materials_common")) { - if (Value* light = FindUInt(*ext, "light")) { - this->light = r.lights.Retrieve(light->GetUint()); - } - } - - } - }*/ } inline void Scene::Read(Value& obj, Asset& r) @@ -1293,7 +1269,7 @@ inline void Asset::ReadExtensionsUsed(Document& doc) if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true; CHECK_EXT(KHR_binary_glTF); - CHECK_EXT(KHR_materials_common); + CHECK_EXT(KHR_materials_pbrSpecularGlossiness); #undef CHECK_EXT } diff --git a/code/glTF2AssetWriter.h b/code/glTF2AssetWriter.h index 976f23f9a..97efbeab5 100644 --- a/code/glTF2AssetWriter.h +++ b/code/glTF2AssetWriter.h @@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * glTF Extensions Support: * KHR_binary_glTF: full - * KHR_materials_common: full + * KHR_materials_pbrSpecularGlossiness: full */ #ifndef GLTF2ASSETWRITER_H_INC #define GLTF2ASSETWRITER_H_INC diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index bd16a7023..33625816e 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -327,23 +327,35 @@ namespace glTF2 { obj.AddMember("doubleSided", m.doubleSided, w.mAl); } - /*Value v; - v.SetObject(); + Value pbrSpecularGlossiness; + pbrSpecularGlossiness.SetObject(); { - if (m.transparent && !m.diffuse.texture) { - m.diffuse.color[3] = m.transparency; + //pbrSpecularGlossiness + + vec4 defaultDiffuseFactor = {1, 1, 1, 1}; + WriteVec(pbrSpecularGlossiness, m.diffuseFactor, "diffuseFactor", defaultDiffuseFactor, w.mAl); + + vec3 defaultSpecularFactor = {1, 1, 1}; + WriteVec(pbrSpecularGlossiness, m.specularFactor, "specularFactor", defaultSpecularFactor, w.mAl); + + if (m.glossinessFactor != 1) { + WriteFloat(obj, m.glossinessFactor, "glossinessFactor", w.mAl); } - WriteVecOrTex(v, m.ambient, m.ambient.texture ? "ambientTexture" : "ambientFactor", w.mAl); - WriteVecOrTex(v, m.diffuse, m.diffuse.texture ? "diffuseTexture" : "diffuseFactor", w.mAl); - WriteVecOrTex(v, m.specular, m.specular.texture ? "specularTexture" : "specularFactor", w.mAl); - WriteVecOrTex(v, m.emission, m.emission.texture ? "emissionTexture" : "emissionFactor", w.mAl); - v.AddMember("shininessFactor", m.shininess, w.mAl); + + WriteTex(obj, m.diffuseTexture, "diffuseTexture", w.mAl); + WriteTex(obj, m.specularGlossinessTexture, "specularGlossinessTexture", w.mAl); } - v.AddMember("type", "commonPhong", w.mAl); + Value ext; ext.SetObject(); - ext.AddMember("KHR_materials_common", v, w.mAl); - obj.AddMember("extensions", ext, w.mAl);*/ + + if (!pbrSpecularGlossiness.ObjectEmpty()) { + ext.AddMember("KHR_materials_pbrSpecularGlossiness", pbrSpecularGlossiness, w.mAl); + } + + if (!ext.ObjectEmpty()) { + obj.AddMember("extensions", ext, w.mAl); + } } namespace { @@ -714,11 +726,11 @@ namespace glTF2 { Value exts; exts.SetArray(); { - if (false) - exts.PushBack(StringRef("KHR_binary_glTF"), mAl); + //if (false) + // exts.PushBack(StringRef("KHR_binary_glTF"), mAl); // This is used to export common materials with GLTF 2. - //exts.PushBack(StringRef("KHR_materials_common"), mAl); + //exts.PushBack(StringRef("KHR_materials_pbrSpecularGlossiness"), mAl); } if (!exts.Empty()) diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index b1bbf8349..316970fa5 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -237,6 +237,13 @@ void glTF2Importer::ImportMaterials(glTF2::Asset& r) aimat->AddProperty(&mat.doubleSided, 1, AI_MATKEY_TWOSIDED); aimat->AddProperty(&mat.alphaMode, 1, "$mat.gltf.alphaMode"); aimat->AddProperty(&mat.alphaCutoff, 1, "$mat.gltf.alphaCutoff"); + + //pbrSpecularGlossiness + SetMaterialColorProperty(r, mat.diffuseFactor, aimat, "$clr.diffuse", 0, 1); + SetMaterialColorProperty(r, mat.specularFactor, aimat, "$clr.specular", 0, 1); + aimat->AddProperty(&mat.glossinessFactor, 1, "$mat.gltf.glossinessFactor"); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.diffuseTexture, aimat, aiTextureType_DIFFUSE, 1); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.specularGlossinessTexture, aimat, aiTextureType_UNKNOWN, 1); } } From 7532d6aac1f18aba3b7e33e7f706c143b6430d4d Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Thu, 31 Aug 2017 18:26:50 -0400 Subject: [PATCH 23/90] Remove Light, Technique references --- code/glTF2Asset.h | 23 ------------------- code/glTF2Asset.inl | 46 -------------------------------------- code/glTF2AssetWriter.inl | 10 --------- code/glTF2Importer.cpp | 47 ++------------------------------------- 4 files changed, 2 insertions(+), 124 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index b19de747a..a4b833f58 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -129,7 +129,6 @@ namespace glTF2 struct BufferView; // here due to cross-reference struct Texture; - struct Light; struct Skin; // Vec/matrix types, as raw float arrays @@ -835,7 +834,6 @@ namespace glTF2 Nullable scale; Ref camera; - Ref light; std::vector< Ref > skeletons; //!< The ID of skeleton nodes. Each of which is the root of a node hierarchy. Ref skin; //!< The ID of the skin referenced by this node. @@ -891,27 +889,6 @@ namespace glTF2 void Read(Value& obj, Asset& r); }; - struct Technique : public Object - { - struct Parameters - { - - }; - - struct States - { - - }; - - struct Functions - { - - }; - - Technique() {} - void Read(Value& obj, Asset& r); - }; - //! A texture and its sampler. struct Texture : public Object { diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 3d53bfccf..eab0b8373 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -984,52 +984,6 @@ inline void Camera::Read(Value& obj, Asset& r) } } -inline void Light::Read(Value& obj, Asset& r) -{ - SetDefaults(); - - if (Value* type = FindString(obj, "type")) { - const char* t = type->GetString(); - if (strcmp(t, "ambient") == 0) this->type = Type_ambient; - else if (strcmp(t, "directional") == 0) this->type = Type_directional; - else if (strcmp(t, "point") == 0) this->type = Type_point; - else if (strcmp(t, "spot") == 0) this->type = Type_spot; - - if (this->type != Type_undefined) { - if (Value* vals = FindString(obj, t)) { - ReadMember(*vals, "color", color); - - ReadMember(*vals, "constantAttenuation", constantAttenuation); - ReadMember(*vals, "linearAttenuation", linearAttenuation); - ReadMember(*vals, "quadraticAttenuation", quadraticAttenuation); - ReadMember(*vals, "distance", distance); - - ReadMember(*vals, "falloffAngle", falloffAngle); - ReadMember(*vals, "falloffExponent", falloffExponent); - } - } - } -} - -inline void Light::SetDefaults() -{ - #ifndef M_PI - const float M_PI = 3.14159265358979323846f; - #endif - - type = Type_undefined; - - SetVector(color, 0.f, 0.f, 0.f, 1.f); - - constantAttenuation = 0.f; - linearAttenuation = 1.f; - quadraticAttenuation = 1.f; - distance = 0.f; - - falloffAngle = static_cast(M_PI / 2.f); - falloffExponent = 0.f; -} - inline void Node::Read(Value& obj, Asset& r) { diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index 33625816e..a8ee16c82 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -557,11 +557,6 @@ namespace glTF2 { } - inline void Write(Value& obj, Technique& b, AssetWriter& w) - { - - } - inline void Write(Value& obj, Texture& tex, AssetWriter& w) { if (tex.source) { @@ -572,11 +567,6 @@ namespace glTF2 { } } - inline void Write(Value& obj, Light& b, AssetWriter& w) - { - - } - inline AssetWriter::AssetWriter(Asset& a) : mDoc() diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 316970fa5..b4fd96948 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -493,46 +493,6 @@ void glTF2Importer::ImportCameras(glTF2::Asset& r) } } -void glTF2Importer::ImportLights(glTF2::Asset& r) -{ - if (!r.lights.Size()) return; - - mScene->mNumLights = r.lights.Size(); - mScene->mLights = new aiLight*[r.lights.Size()]; - - for (size_t i = 0; i < r.lights.Size(); ++i) { - Light& l = r.lights[i]; - - aiLight* ail = mScene->mLights[i] = new aiLight(); - - switch (l.type) { - case Light::Type_directional: - ail->mType = aiLightSource_DIRECTIONAL; break; - - case Light::Type_spot: - ail->mType = aiLightSource_SPOT; break; - - case Light::Type_ambient: - ail->mType = aiLightSource_AMBIENT; break; - - default: // Light::Type_point - ail->mType = aiLightSource_POINT; break; - } - - CopyValue(l.color, ail->mColorAmbient); - CopyValue(l.color, ail->mColorDiffuse); - CopyValue(l.color, ail->mColorSpecular); - - ail->mAngleOuterCone = l.falloffAngle; - ail->mAngleInnerCone = l.falloffExponent; // TODO fix this, it does not look right at all - - ail->mAttenuationConstant = l.constantAttenuation; - ail->mAttenuationLinear = l.linearAttenuation; - ail->mAttenuationQuadratic = l.quadraticAttenuation; - } -} - - aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector& meshOffsets, glTF2::Ref& ptr) { Node& node = *ptr; @@ -602,10 +562,6 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector& pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName; } - if (node.light) { - pScene->mLights[node.light.GetIndex()]->mName = ainode->mName; - } - return ainode; } @@ -695,13 +651,14 @@ void glTF2Importer::InternReadFile(const std::string& pFile, aiScene* pScene, IO // Copy the data out // + + ImportEmbeddedTextures(asset); ImportMaterials(asset); ImportMeshes(asset); ImportCameras(asset); - ImportLights(asset); ImportNodes(asset); From 562920fbb8811bd8b47eb9eb5755ad25c0b98973 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Thu, 31 Aug 2017 18:30:43 -0400 Subject: [PATCH 24/90] Changes to GLTF2 materials pbrMetallicRoughness and pbrSpecularGlossiness as structs; persist textureinfo properties from start to finish; persist pbrSpecularGlossiness (via extensionsUsed) usage from start to finish --- code/glTF2Asset.h | 27 +++++++--- code/glTF2Asset.inl | 36 +++++++------ code/glTF2AssetWriter.inl | 64 +++++++++++----------- code/glTF2Exporter.cpp | 109 +++++++++++++++++++++++++++++++++----- code/glTF2Exporter.h | 8 +++ code/glTF2Importer.cpp | 48 +++++++++-------- 6 files changed, 200 insertions(+), 92 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index a4b833f58..3faea0938 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -692,15 +692,30 @@ namespace glTF2 vec4 color; };*/ - //! The material appearance of a primitive. - struct Material : public Object + struct PbrMetallicRoughness { - //PBR metallic roughness properties vec4 baseColorFactor; TextureInfo baseColorTexture; TextureInfo metallicRoughnessTexture; float metallicFactor; float roughnessFactor; + }; + + struct PbrSpecularGlossiness + { + bool on = false; + vec4 diffuseFactor; + vec3 specularFactor; + float glossinessFactor; + TextureInfo diffuseTexture; + TextureInfo specularGlossinessTexture; + }; + + //! The material appearance of a primitive. + struct Material : public Object + { + //PBR metallic roughness properties + PbrMetallicRoughness pbrMetallicRoughness; //other basic material properties NormalTextureInfo normalTexture; @@ -712,11 +727,7 @@ namespace glTF2 bool doubleSided; //extension: KHR_materials_pbrSpecularGlossiness - vec4 diffuseFactor; - vec3 specularFactor; - float glossinessFactor; - TextureInfo diffuseTexture; - TextureInfo specularGlossinessTexture; + PbrSpecularGlossiness pbrSpecularGlossiness; Material() { SetDefaults(); } void Read(Value& obj, Asset& r); diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index eab0b8373..632401576 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -758,11 +758,11 @@ inline void Material::Read(Value& material, Asset& r) SetDefaults(); if (Value* pbrMetallicRoughness = FindObject(material, "pbrMetallicRoughness")) { - ReadMember(*pbrMetallicRoughness, "baseColorFactor", this->baseColorFactor); - ReadTextureProperty(r, *pbrMetallicRoughness, "baseColorTexture", this->baseColorTexture); - ReadTextureProperty(r, *pbrMetallicRoughness, "metallicRoughnessTexture", this->metallicRoughnessTexture); - ReadMember(*pbrMetallicRoughness, "metallicFactor", this->metallicFactor); - ReadMember(*pbrMetallicRoughness, "roughnessFactor", this->roughnessFactor); + ReadMember(*pbrMetallicRoughness, "baseColorFactor", this->pbrMetallicRoughness.baseColorFactor); + ReadTextureProperty(r, *pbrMetallicRoughness, "baseColorTexture", this->pbrMetallicRoughness.baseColorTexture); + ReadTextureProperty(r, *pbrMetallicRoughness, "metallicRoughnessTexture", this->pbrMetallicRoughness.metallicRoughnessTexture); + ReadMember(*pbrMetallicRoughness, "metallicFactor", this->pbrMetallicRoughness.metallicFactor); + ReadMember(*pbrMetallicRoughness, "roughnessFactor", this->pbrMetallicRoughness.roughnessFactor); } ReadTextureProperty(r, material, "normalTexture", this->normalTexture); @@ -777,11 +777,13 @@ inline void Material::Read(Value& material, Asset& r) if (Value* extensions = FindObject(material, "extensions")) { if (r.extensionsUsed.KHR_materials_pbrSpecularGlossiness) { if (Value* pbrSpecularGlossiness = FindObject(*extensions, "KHR_materials_pbrSpecularGlossiness")) { - ReadMember(*pbrSpecularGlossiness, "diffuseFactor", this->diffuseFactor); - ReadTextureProperty(r, *pbrSpecularGlossiness, "diffuseTexture", this->diffuseTexture); - ReadTextureProperty(r, *pbrSpecularGlossiness, "specularGlossinessTexture", this->specularGlossinessTexture); - ReadMember(*pbrSpecularGlossiness, "specularFactor", this->specularFactor); - ReadMember(*pbrSpecularGlossiness, "glossinessFactor", this->glossinessFactor); + this->pbrSpecularGlossiness.on = true; + + ReadMember(*pbrSpecularGlossiness, "diffuseFactor", this->pbrSpecularGlossiness.diffuseFactor); + ReadTextureProperty(r, *pbrSpecularGlossiness, "diffuseTexture", this->pbrSpecularGlossiness.diffuseTexture); + ReadTextureProperty(r, *pbrSpecularGlossiness, "specularGlossinessTexture", this->pbrSpecularGlossiness.specularGlossinessTexture); + ReadMember(*pbrSpecularGlossiness, "specularFactor", this->pbrSpecularGlossiness.specularFactor); + ReadMember(*pbrSpecularGlossiness, "glossinessFactor", this->pbrSpecularGlossiness.glossinessFactor); } } } @@ -798,19 +800,19 @@ namespace { inline void Material::SetDefaults() { //pbr materials - SetVector(baseColorFactor, 1, 1, 1, 1); - SetVector(emissiveFactor, 0, 0, 0); - metallicFactor = 1.0; - roughnessFactor = 1.0; + SetVector(pbrMetallicRoughness.baseColorFactor, 1, 1, 1, 1); + pbrMetallicRoughness.metallicFactor = 1.0; + pbrMetallicRoughness.roughnessFactor = 1.0; + SetVector(emissiveFactor, 0, 0, 0); alphaMode = "OPAQUE"; alphaCutoff = 0.5; doubleSided = false; //pbrSpecularGlossiness properties - SetVector(diffuseFactor, 1, 1, 1, 1); - SetVector(specularFactor, 1, 1, 1); - glossinessFactor = 1.0; + SetVector(pbrSpecularGlossiness.diffuseFactor, 1, 1, 1, 1); + SetVector(pbrSpecularGlossiness.specularFactor, 1, 1, 1); + pbrSpecularGlossiness.glossinessFactor = 1.0; } namespace { diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index a8ee16c82..ce2e7c41d 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -287,19 +287,19 @@ namespace glTF2 { Value pbrMetallicRoughness; pbrMetallicRoughness.SetObject(); { - WriteTex(pbrMetallicRoughness, m.baseColorTexture, "baseColorTexture", w.mAl); - WriteTex(pbrMetallicRoughness, m.metallicRoughnessTexture, "metallicRoughnessTexture", w.mAl); + WriteTex(pbrMetallicRoughness, m.pbrMetallicRoughness.baseColorTexture, "baseColorTexture", w.mAl); + WriteTex(pbrMetallicRoughness, m.pbrMetallicRoughness.metallicRoughnessTexture, "metallicRoughnessTexture", w.mAl); //@TODO: define this as a constant? vec4 defaultEmissiveFactor = {1, 1, 1, 1}; - WriteVec(pbrMetallicRoughness, m.baseColorFactor, "baseColorFactor", defaultEmissiveFactor, w.mAl); + WriteVec(pbrMetallicRoughness, m.pbrMetallicRoughness.baseColorFactor, "baseColorFactor", defaultEmissiveFactor, w.mAl); - if (m.metallicFactor != 1) { - WriteFloat(pbrMetallicRoughness, m.metallicFactor, "metallicFactor", w.mAl); + if (m.pbrMetallicRoughness.metallicFactor != 1) { + WriteFloat(pbrMetallicRoughness, m.pbrMetallicRoughness.metallicFactor, "metallicFactor", w.mAl); } - if (m.roughnessFactor != 1) { - WriteFloat(pbrMetallicRoughness, m.roughnessFactor, "roughnessFactor", w.mAl); + if (m.pbrMetallicRoughness.roughnessFactor != 1) { + WriteFloat(pbrMetallicRoughness, m.pbrMetallicRoughness.roughnessFactor, "roughnessFactor", w.mAl); } } @@ -327,34 +327,36 @@ namespace glTF2 { obj.AddMember("doubleSided", m.doubleSided, w.mAl); } - Value pbrSpecularGlossiness; - pbrSpecularGlossiness.SetObject(); - { - //pbrSpecularGlossiness + Value exts; + exts.SetObject(); - vec4 defaultDiffuseFactor = {1, 1, 1, 1}; - WriteVec(pbrSpecularGlossiness, m.diffuseFactor, "diffuseFactor", defaultDiffuseFactor, w.mAl); + if (m.pbrSpecularGlossiness.on) { + Value pbrSpecularGlossiness; + pbrSpecularGlossiness.SetObject(); + { + //pbrSpecularGlossiness - vec3 defaultSpecularFactor = {1, 1, 1}; - WriteVec(pbrSpecularGlossiness, m.specularFactor, "specularFactor", defaultSpecularFactor, w.mAl); + vec4 defaultDiffuseFactor = {1, 1, 1, 1}; + WriteVec(pbrSpecularGlossiness, m.pbrSpecularGlossiness.diffuseFactor, "diffuseFactor", defaultDiffuseFactor, w.mAl); - if (m.glossinessFactor != 1) { - WriteFloat(obj, m.glossinessFactor, "glossinessFactor", w.mAl); + vec3 defaultSpecularFactor = {1, 1, 1}; + WriteVec(pbrSpecularGlossiness, m.pbrSpecularGlossiness.specularFactor, "specularFactor", defaultSpecularFactor, w.mAl); + + if (m.pbrSpecularGlossiness.glossinessFactor != 1) { + WriteFloat(obj, m.pbrSpecularGlossiness.glossinessFactor, "glossinessFactor", w.mAl); + } + + WriteTex(obj, m.pbrSpecularGlossiness.diffuseTexture, "diffuseTexture", w.mAl); + WriteTex(obj, m.pbrSpecularGlossiness.specularGlossinessTexture, "specularGlossinessTexture", w.mAl); } - WriteTex(obj, m.diffuseTexture, "diffuseTexture", w.mAl); - WriteTex(obj, m.specularGlossinessTexture, "specularGlossinessTexture", w.mAl); + if (!pbrSpecularGlossiness.ObjectEmpty()) { + exts.AddMember("KHR_materials_pbrSpecularGlossiness", pbrSpecularGlossiness, w.mAl); + } } - Value ext; - ext.SetObject(); - - if (!pbrSpecularGlossiness.ObjectEmpty()) { - ext.AddMember("KHR_materials_pbrSpecularGlossiness", pbrSpecularGlossiness, w.mAl); - } - - if (!ext.ObjectEmpty()) { - obj.AddMember("extensions", ext, w.mAl); + if (!exts.ObjectEmpty()) { + obj.AddMember("extensions", exts, w.mAl); } } @@ -719,8 +721,10 @@ namespace glTF2 { //if (false) // exts.PushBack(StringRef("KHR_binary_glTF"), mAl); - // This is used to export common materials with GLTF 2. - //exts.PushBack(StringRef("KHR_materials_pbrSpecularGlossiness"), mAl); + // This is used to export pbrSpecularGlossiness materials with GLTF 2. + if (this->mAsset.extensionsUsed.KHR_materials_pbrSpecularGlossiness) { + exts.PushBack(StringRef("KHR_materials_pbrSpecularGlossiness"), mAl); + } } if (!exts.Empty()) diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index f59c280f1..9e04da76c 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -112,9 +112,9 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai ExportMetadata(); - //for (unsigned int i = 0; i < pScene->mNumCameras; ++i) {} - - //for (unsigned int i = 0; i < pScene->mNumLights; ++i) {} + if (mScene->mRootNode) { + ExportExtensions(mScene->mRootNode); + } ExportMaterials(); @@ -124,8 +124,6 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai ExportMeshes(); - //for (unsigned int i = 0; i < pScene->mNumTextures; ++i) {} - ExportScene(); //ExportAnimations(); @@ -280,10 +278,26 @@ void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref texture) texture->sampler->minFilter = SamplerMinFilter_Linear_Mipmap_Linear; } +void glTF2Exporter::GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int slot) +{ + const char* key = (std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName).c_str(); + + mat->Get(key, tt, slot, prop); +} + +void glTF2Exporter::GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int slot) +{ + const char* key = (std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName).c_str(); + + mat->Get(key, tt, slot, prop); +} + void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref& texture, aiTextureType tt, unsigned int slot = 0) { - aiString tex; + if (mat->GetTextureCount(tt) > 0) { + aiString tex; + if (mat->Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) { std::string path = tex.C_Str(); @@ -326,6 +340,41 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref& texture, aiTe } } +void glTF2Exporter::GetMatTex(const aiMaterial* mat, TextureInfo& prop, aiTextureType tt, unsigned int slot = 0) +{ + Ref& texture = prop.texture; + + GetMatTex(mat, texture, tt, slot); + + if (texture) { + GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); + } +} + +void glTF2Exporter::GetMatTex(const aiMaterial* mat, NormalTextureInfo& prop, aiTextureType tt, unsigned int slot = 0) +{ + Ref& texture = prop.texture; + + GetMatTex(mat, texture, tt, slot); + + if (texture) { + GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); + GetMatTexProp(mat, prop.scale, "scale", tt, slot); + } +} + +void glTF2Exporter::GetMatTex(const aiMaterial* mat, OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot = 0) +{ + Ref& texture = prop.texture; + + GetMatTex(mat, texture, tt, slot); + + if (texture) { + GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); + GetMatTexProp(mat, prop.strength, "strength", tt, slot); + } +} + void glTF2Exporter::GetMatColor(const aiMaterial* mat, vec4& prop, const char* propName, int type, int idx) { aiColor4D col; @@ -344,6 +393,8 @@ void glTF2Exporter::GetMatColor(const aiMaterial* mat, vec3& prop, const char* p void glTF2Exporter::ExportMaterials() { + bool& KHR_materials_pbrSpecularGlossiness = mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness; + aiString aiName; for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) { const aiMaterial* mat = mScene->mMaterials[i]; @@ -356,20 +407,36 @@ void glTF2Exporter::ExportMaterials() Ref m = mAsset->materials.Create(name); - GetMatTex(mat, m->baseColorTexture.texture, aiTextureType_DIFFUSE); - GetMatTex(mat, m->metallicRoughnessTexture.texture, aiTextureType_UNKNOWN, 0);//get unknown slot - GetMatTex(mat, m->emissiveTexture.texture, aiTextureType_EMISSIVE); - GetMatTex(mat, m->normalTexture.texture, aiTextureType_NORMALS); - GetMatTex(mat, m->occlusionTexture.texture, aiTextureType_LIGHTMAP); + GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_DIFFUSE); + GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, aiTextureType_UNKNOWN, 0);//get unknown slot + GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE); - GetMatColor(mat, m->baseColorFactor, AI_MATKEY_COLOR_DIFFUSE); + GetMatTex(mat, m->normalTexture, aiTextureType_NORMALS); + GetMatTex(mat, m->occlusionTexture, aiTextureType_LIGHTMAP); + GetMatTex(mat, m->emissiveTexture, aiTextureType_EMISSIVE); GetMatColor(mat, m->emissiveFactor, AI_MATKEY_COLOR_EMISSIVE); mat->Get(AI_MATKEY_TWOSIDED, m->doubleSided); mat->Get("$mat.gltf.alphaCutoff", 0, 0, m->alphaCutoff); - mat->Get("$mat.gltf.metallicFactor", 0, 0, m->metallicFactor); - mat->Get("$mat.gltf.roughnessFactor", 0, 0, m->roughnessFactor); + mat->Get("$mat.gltf.metallicFactor", 0, 0, m->pbrMetallicRoughness.metallicFactor); + mat->Get("$mat.gltf.roughnessFactor", 0, 0, m->pbrMetallicRoughness.roughnessFactor); mat->Get("$mat.gltf.alphaMode", 0, 0, m->alphaMode); + + bool hasPbrSpecularGlossiness; + mat->Get("$mat.gltf.pbrSpecularGlossiness.on", 0, 0, hasPbrSpecularGlossiness); + + if (hasPbrSpecularGlossiness) { + + if (!KHR_materials_pbrSpecularGlossiness) { + KHR_materials_pbrSpecularGlossiness = true; + } + + GetMatColor(mat, m->pbrSpecularGlossiness.diffuseFactor, "$clr.diffuse", 0, 1); + GetMatColor(mat, m->pbrSpecularGlossiness.specularFactor, "$clr.specular", 0, 1); + mat->Get("$mat.gltf.glossinessFactor", 0, 0, m->pbrSpecularGlossiness.glossinessFactor); + GetMatTex(mat, m->pbrSpecularGlossiness.diffuseTexture, aiTextureType_DIFFUSE, 1); + GetMatTex(mat, m->pbrSpecularGlossiness.specularGlossinessTexture, aiTextureType_UNKNOWN, 1); + } } } @@ -862,6 +929,20 @@ void glTF2Exporter::ExportMetadata() asset.generator = buffer; } +void glTF2Exporter::ExportExtensions(const aiNode* n) +{ + aiMetadata* mMetaData = n->mMetaData; + + if (mMetaData != nullptr) { + bool pbrSpecularGlossiness; + + if (mMetaData->Get("extensionsUsed.pbrSpecularGlossiness", pbrSpecularGlossiness)) { + mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness = pbrSpecularGlossiness; + } + } + +} + inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref& animRef, Ref& buffer, const aiNodeAnim* nodeChannel, float ticksPerSecond) { // Loop over the data and check to see if it exactly matches an existing buffer. diff --git a/code/glTF2Exporter.h b/code/glTF2Exporter.h index 2ba0143bf..827189f29 100644 --- a/code/glTF2Exporter.h +++ b/code/glTF2Exporter.h @@ -67,6 +67,8 @@ namespace glTF2 class Asset; struct TexProperty; struct TextureInfo; + struct NormalTextureInfo; + struct OcclusionTextureInfo; struct Node; struct Texture; @@ -107,10 +109,16 @@ namespace Assimp void WriteBinaryData(IOStream* outfile, std::size_t sceneLength); void GetTexSampler(const aiMaterial* mat, glTF2::Ref texture); + void GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int idx); + void GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int idx); void GetMatTex(const aiMaterial* mat, glTF2::Ref& texture, aiTextureType tt, unsigned int slot); + void GetMatTex(const aiMaterial* mat, glTF2::TextureInfo& prop, aiTextureType tt, unsigned int slot); + void GetMatTex(const aiMaterial* mat, glTF2::NormalTextureInfo& prop, aiTextureType tt, unsigned int slot); + void GetMatTex(const aiMaterial* mat, glTF2::OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot); void GetMatColor(const aiMaterial* mat, glTF2::vec4& prop, const char* propName, int type, int idx); void GetMatColor(const aiMaterial* mat, glTF2::vec3& prop, const char* propName, int type, int idx); void ExportMetadata(); + void ExportExtensions(const aiNode* n); void ExportMaterials(); void ExportMeshes(); unsigned int ExportNodeHierarchy(const aiNode* n); diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index b4fd96948..97901fc01 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -183,7 +183,7 @@ inline void SetMaterialColorProperty(Asset& r, vec3& prop, aiMaterial* mat, cons return SetMaterialColorProperty(r, prop4, mat, pKey, type, idx); } -inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::TextureInfo prop, aiMaterial* mat, aiTextureType texType, int texSlot) +inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::TextureInfo prop, aiMaterial* mat, aiTextureType texType, unsigned int texSlot = 0) { if (prop.texture && prop.texture->source) { aiString uri(prop.texture->source->uri); @@ -195,19 +195,11 @@ inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& uri.length = 1 + ASSIMP_itoa10(uri.data + 1, MAXLEN - 1, texIdx); } - if (texSlot < 0) { - mat->AddProperty(&uri, _AI_MATKEY_TEXTURE_BASE, texType, 0); - } - else { - mat->AddProperty(&uri, AI_MATKEY_TEXTURE(texType, - texSlot)); - } - } -} + mat->AddProperty(&uri, AI_MATKEY_TEXTURE(texType, texSlot)); -inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::TextureInfo prop, aiMaterial* mat, aiTextureType texType) -{ - return SetMaterialTextureProperty(embeddedTexIdxs, r, prop, mat, texType, -1); + const char *texCoordName = (std::string(_AI_MATKEY_TEXTURE_BASE) + ".texCoord").c_str(); + mat->AddProperty(&prop.texCoord, 1, texCoordName, texType, texSlot); + } } void glTF2Importer::ImportMaterials(glTF2::Asset& r) @@ -223,11 +215,11 @@ void glTF2Importer::ImportMaterials(glTF2::Asset& r) aiString str(mat.id); aimat->AddProperty(&str, AI_MATKEY_NAME); - SetMaterialColorProperty(r, mat.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.baseColorTexture, aimat, aiTextureType_DIFFUSE); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.metallicRoughnessTexture, aimat, aiTextureType_UNKNOWN, 0); - aimat->AddProperty(&mat.metallicFactor, 1, "$mat.gltf.metallicFactor"); - aimat->AddProperty(&mat.roughnessFactor, 1, "$mat.gltf.roughnessFactor"); + SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, aiTextureType_UNKNOWN); + aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, "$mat.gltf.pbrMetallicRoughness.metallicFactor"); + aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, "$mat.gltf.pbrMetallicRoughness.roughnessFactor"); SetMaterialTextureProperty(embeddedTexIdxs, r, mat.normalTexture, aimat, aiTextureType_NORMALS); SetMaterialTextureProperty(embeddedTexIdxs, r, mat.occlusionTexture, aimat, aiTextureType_LIGHTMAP); @@ -239,11 +231,14 @@ void glTF2Importer::ImportMaterials(glTF2::Asset& r) aimat->AddProperty(&mat.alphaCutoff, 1, "$mat.gltf.alphaCutoff"); //pbrSpecularGlossiness - SetMaterialColorProperty(r, mat.diffuseFactor, aimat, "$clr.diffuse", 0, 1); - SetMaterialColorProperty(r, mat.specularFactor, aimat, "$clr.specular", 0, 1); - aimat->AddProperty(&mat.glossinessFactor, 1, "$mat.gltf.glossinessFactor"); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.diffuseTexture, aimat, aiTextureType_DIFFUSE, 1); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.specularGlossinessTexture, aimat, aiTextureType_UNKNOWN, 1); + if (mat.pbrSpecularGlossiness.on) { + aimat->AddProperty(&mat.pbrSpecularGlossiness.on, 1, "$mat.gltf.pbrSpecularGlossiness.on"); + SetMaterialColorProperty(r, mat.pbrSpecularGlossiness.diffuseFactor, aimat, "$clr.diffuse", 0, 1); + SetMaterialColorProperty(r, mat.pbrSpecularGlossiness.specularFactor, aimat, "$clr.specular", 0, 1); + aimat->AddProperty(&mat.pbrSpecularGlossiness.glossinessFactor, 1, "$mat.gltf.pbrSpecularGlossiness.glossinessFactor"); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrSpecularGlossiness.diffuseTexture, aimat, aiTextureType_DIFFUSE, 1); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrSpecularGlossiness.specularGlossinessTexture, aimat, aiTextureType_UNKNOWN, 1); + } } } @@ -590,6 +585,13 @@ void glTF2Importer::ImportNodes(glTF2::Asset& r) //if (!mScene->mRootNode) { // mScene->mRootNode = new aiNode("EMPTY"); //} + + //initialize mMetaData; + aiMetadata* mMetaData = new aiMetadata(); + + //store used glTF extensions on the root node, for a lack of a better place. + mMetaData->Add("extensionsUsed.pbrSpecularGlossiness", r.extensionsUsed.KHR_materials_pbrSpecularGlossiness); + mScene->mRootNode->mMetaData = mMetaData; } void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset& r) From 2d54019b8fb10e46f2b1d4e98e3f1a904de15309 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Thu, 31 Aug 2017 23:38:10 -0400 Subject: [PATCH 25/90] Remove OPEN3DGC and compression references --- code/glTF2Asset.h | 71 ------------------- code/glTF2Asset.inl | 74 -------------------- code/glTF2AssetWriter.inl | 51 -------------- code/glTF2Exporter.cpp | 142 +------------------------------------- code/glTF2Importer.cpp | 32 --------- 5 files changed, 1 insertion(+), 369 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 3faea0938..dd348de1a 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -752,86 +752,15 @@ namespace glTF2 Ref material; }; - /// \struct SExtension - /// Extension used for mesh. - struct SExtension - { - /// \enum EType - /// Type of extension. - enum EType - { - #ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC - Compression_Open3DGC,///< Compression of mesh data using Open3DGC algorithm. - #endif - - Unknown - }; - - EType Type;///< Type of extension. - - /// \fn SExtension - /// Constructor. - /// \param [in] pType - type of extension. - SExtension(const EType pType) - : Type(pType) - {} - - virtual ~SExtension() { - // empty - } - }; - - #ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC - /// \struct SCompression_Open3DGC - /// Compression of mesh data using Open3DGC algorithm. - struct SCompression_Open3DGC : public SExtension - { - using SExtension::Type; - - std::string Buffer;///< ID of "buffer" used for storing compressed data. - size_t Offset;///< Offset in "bufferView" where compressed data are stored. - size_t Count;///< Count of elements in compressed data. Is always equivalent to size in bytes: look comments for "Type" and "Component_Type". - bool Binary;///< If true then "binary" mode is used for coding, if false - "ascii" mode. - size_t IndicesCount;///< Count of indices in mesh. - size_t VerticesCount;///< Count of vertices in mesh. - // AttribType::Value Type;///< Is always "SCALAR". - // ComponentType Component_Type;///< Is always "ComponentType_UNSIGNED_BYTE" (5121). - - /// \fn SCompression_Open3DGC - /// Constructor. - SCompression_Open3DGC() - : SExtension(Compression_Open3DGC) { - // empty - } - - virtual ~SCompression_Open3DGC() { - // empty - } - }; - #endif - std::vector primitives; - std::list Extension;///< List of extensions used in mesh. Mesh() {} - /// \fn ~Mesh() - /// Destructor. - ~Mesh() { for(std::list::iterator it = Extension.begin(), it_end = Extension.end(); it != it_end; it++) { delete *it; }; } - /// \fn void Read(Value& pJSON_Object, Asset& pAsset_Root) /// Get mesh data from JSON-object and place them to root asset. /// \param [in] pJSON_Object - reference to pJSON-object from which data are read. /// \param [out] pAsset_Root - reference to root assed where data will be stored. void Read(Value& pJSON_Object, Asset& pAsset_Root); - - #ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC - /// \fn void Decode_O3DGC(const SCompression_Open3DGC& pCompression_Open3DGC, Asset& pAsset_Root) - /// Decode part of "buffer" which encoded with Open3DGC algorithm. - /// \param [in] pCompression_Open3DGC - reference to structure which describe encoded region. - /// \param [out] pAsset_Root - reference to root assed where data will be stored. - void Decode_O3DGC(const SCompression_Open3DGC& pCompression_Open3DGC, Asset& pAsset_Root); - #endif }; struct Node : public Object diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 632401576..dd110ebb7 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -44,11 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Header files, Assimp #include -#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC - // Header files, Open3DGC. -# include -#endif - using namespace Assimp; namespace glTF2 { @@ -892,75 +887,6 @@ inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root) } } } - - /****************** Mesh extensions ******************/ - Value* json_extensions = FindObject(pJSON_Object, "extensions"); - - if(json_extensions == nullptr) goto mr_skip_extensions; - - for(Value::MemberIterator it_memb = json_extensions->MemberBegin(); it_memb != json_extensions->MemberEnd(); it_memb++) - { -#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC - if(it_memb->name.GetString() == std::string("Open3DGC-compression")) - { - // Search for compressed data. - // Compressed data contain description of part of "buffer" which is encoded. This part must be decoded and - // new data will replace old encoded part by request. In fact \"compressedData\" is kind of "accessor" structure. - Value* comp_data = FindObject(it_memb->value, "compressedData"); - - if(comp_data == nullptr) throw DeadlyImportError("GLTF: \"Open3DGC-compression\" must has \"compressedData\"."); - - DefaultLogger::get()->info("GLTF: Decompressing Open3DGC data."); - - /************** Read data from JSON-document **************/ - #define MESH_READ_COMPRESSEDDATA_MEMBER(pFieldName, pOut) \ - if(!ReadMember(*comp_data, pFieldName, pOut)) \ - { \ - throw DeadlyImportError(std::string("GLTF: \"compressedData\" must has \"") + pFieldName + "\"."); \ - } - - const char* mode_str; - const char* type_str; - ComponentType component_type; - SCompression_Open3DGC* ext_o3dgc = new SCompression_Open3DGC; - - MESH_READ_COMPRESSEDDATA_MEMBER("buffer", ext_o3dgc->Buffer); - MESH_READ_COMPRESSEDDATA_MEMBER("byteOffset", ext_o3dgc->Offset); - MESH_READ_COMPRESSEDDATA_MEMBER("componentType", component_type); - MESH_READ_COMPRESSEDDATA_MEMBER("type", type_str); - MESH_READ_COMPRESSEDDATA_MEMBER("count", ext_o3dgc->Count); - MESH_READ_COMPRESSEDDATA_MEMBER("mode", mode_str); - MESH_READ_COMPRESSEDDATA_MEMBER("indicesCount", ext_o3dgc->IndicesCount); - MESH_READ_COMPRESSEDDATA_MEMBER("verticesCount", ext_o3dgc->VerticesCount); - - #undef MESH_READ_COMPRESSEDDATA_MEMBER - - // Check some values - if(strcmp(type_str, "SCALAR")) throw DeadlyImportError("GLTF: only \"SCALAR\" type is supported for compressed data."); - if(component_type != ComponentType_UNSIGNED_BYTE) throw DeadlyImportError("GLTF: only \"UNSIGNED_BYTE\" component type is supported for compressed data."); - - // Set read/write data mode. - if(strcmp(mode_str, "binary") == 0) - ext_o3dgc->Binary = true; - else if(strcmp(mode_str, "ascii") == 0) - ext_o3dgc->Binary = false; - else - throw DeadlyImportError(std::string("GLTF: for compressed data supported modes is: \"ascii\", \"binary\". Not the: \"") + mode_str + "\"."); - - /************************ Decoding ************************/ - Decode_O3DGC(*ext_o3dgc, pAsset_Root); - Extension.push_back(ext_o3dgc);// store info in mesh extensions list. - }// if(it_memb->name.GetString() == "Open3DGC-compression") - else -#endif - { - throw DeadlyImportError(std::string("GLTF: Unknown mesh extension: \"") + it_memb->name.GetString() + "\"."); - } - }// for(Value::MemberIterator it_memb = json_extensions->MemberBegin(); it_memb != json_extensions->MemberEnd(); json_extensions++) - -mr_skip_extensions: - - return;// After label some operators must be present. } inline void Camera::Read(Value& obj, Asset& r) diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index ce2e7c41d..c74ea4031 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -380,57 +380,6 @@ namespace glTF2 { inline void Write(Value& obj, Mesh& m, AssetWriter& w) { - - /**************** Mesh extensions ****************/ - if(m.Extension.size() > 0) - { - Value json_extensions; - - json_extensions.SetObject(); - for(Mesh::SExtension* ptr_ext : m.Extension) - { - switch(ptr_ext->Type) - { -#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC - case Mesh::SExtension::EType::Compression_Open3DGC: - { - Value json_comp_data; - Mesh::SCompression_Open3DGC* ptr_ext_comp = (Mesh::SCompression_Open3DGC*)ptr_ext; - - // filling object "compressedData" - json_comp_data.SetObject(); - json_comp_data.AddMember("buffer", ptr_ext_comp->Buffer, w.mAl); - json_comp_data.AddMember("byteOffset", ptr_ext_comp->Offset, w.mAl); - json_comp_data.AddMember("componentType", 5121, w.mAl); - json_comp_data.AddMember("type", "SCALAR", w.mAl); - json_comp_data.AddMember("count", ptr_ext_comp->Count, w.mAl); - if(ptr_ext_comp->Binary) - json_comp_data.AddMember("mode", "binary", w.mAl); - else - json_comp_data.AddMember("mode", "ascii", w.mAl); - - json_comp_data.AddMember("indicesCount", ptr_ext_comp->IndicesCount, w.mAl); - json_comp_data.AddMember("verticesCount", ptr_ext_comp->VerticesCount, w.mAl); - // filling object "Open3DGC-compression" - Value json_o3dgc; - - json_o3dgc.SetObject(); - json_o3dgc.AddMember("compressedData", json_comp_data, w.mAl); - // add member to object "extensions" - json_extensions.AddMember("Open3DGC-compression", json_o3dgc, w.mAl); - } - - break; -#endif - default: - throw DeadlyImportError("GLTF: Can not write mesh: unknown mesh extension, only Open3DGC is supported."); - }// switch(ptr_ext->Type) - }// for(Mesh::SExtension* ptr_ext : m.Extension) - - // Add extensions to mesh - obj.AddMember("extensions", json_extensions, w.mAl); - }// if(m.Extension.size() > 0) - /****************** Primitives *******************/ Value primitives; primitives.SetArray(); diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 9e04da76c..2b7e4c33d 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -62,11 +62,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "glTF2AssetWriter.h" -#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC - // Header files, Open3DGC. -# include -#endif - using namespace rapidjson; using namespace Assimp; @@ -573,15 +568,6 @@ void glTF2Exporter::ExportMeshes() // because "ComponentType_UNSIGNED_SHORT" used for indices. And it's a maximal type according to glTF specification. typedef unsigned short IndicesType; - // Variables needed for compression. BEGIN. - // Indices, not pointers - because pointer to buffer is changing while writing to it. - size_t idx_srcdata_begin;// Index of buffer before writing mesh data. Also, index of begin of coordinates array in buffer. - size_t idx_srcdata_normal = SIZE_MAX;// Index of begin of normals array in buffer. SIZE_MAX - mean that mesh has no normals. - std::vector idx_srcdata_tc;// Array of indices. Every index point to begin of texture coordinates array in buffer. - size_t idx_srcdata_ind;// Index of begin of coordinates indices array in buffer. - bool comp_allow;// Point that data of current mesh can be compressed. - // Variables needed for compression. END. - std::string fname = std::string(mFilename); std::string bufferIdPrefix = fname.substr(0, fname.rfind(".gltf")); std::string bufferId = mAsset->FindUniqueID("", bufferIdPrefix.c_str()); @@ -614,31 +600,6 @@ void glTF2Exporter::ExportMeshes() for (unsigned int idx_mesh = 0; idx_mesh < mScene->mNumMeshes; ++idx_mesh) { const aiMesh* aim = mScene->mMeshes[idx_mesh]; - // Check if compressing requested and mesh can be encoded. -#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC - comp_allow = mProperties->GetPropertyBool("extensions.Open3DGC.use", false); -#else - comp_allow = false; -#endif - - if(comp_allow && (aim->mPrimitiveTypes == aiPrimitiveType_TRIANGLE) && (aim->mNumVertices > 0) && (aim->mNumFaces > 0)) - { - idx_srcdata_tc.clear(); - idx_srcdata_tc.reserve(AI_MAX_NUMBER_OF_TEXTURECOORDS); - } - else - { - std::string msg; - - if(aim->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) - msg = "all primitives of the mesh must be a triangles."; - else - msg = "mesh must has vertices and faces."; - - DefaultLogger::get()->warn("GLTF: can not use Open3DGC-compression: " + msg); - comp_allow = false; - } - std::string name = aim->mName.C_Str(); std::string meshId = mAsset->FindUniqueID(name, "mesh"); @@ -651,15 +612,10 @@ void glTF2Exporter::ExportMeshes() p.material = mAsset->materials.Get(aim->mMaterialIndex); /******************* Vertices ********************/ - // If compression is used then you need parameters of uncompressed region: begin and size. At this step "begin" is stored. - if(comp_allow) idx_srcdata_begin = b->byteLength; - Ref v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); if (v) p.attributes.position.push_back(v); /******************** Normals ********************/ - if(comp_allow && (aim->mNormals != 0)) idx_srcdata_normal = b->byteLength;// Store index of normals array. - Ref n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); if (n) p.attributes.normal.push_back(n); @@ -675,16 +631,12 @@ void glTF2Exporter::ExportMeshes() if (aim->mNumUVComponents[i] > 0) { AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3; - if(comp_allow) idx_srcdata_tc.push_back(b->byteLength);// Store index of texture coordinates array. - Ref tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, false); if (tc) p.attributes.texcoord.push_back(tc); } } /*************** Vertices indices ****************/ - idx_srcdata_ind = b->byteLength;// Store index of indices array. - if (aim->mNumFaces > 0) { std::vector indices; unsigned int nIndicesPerFace = aim->mFaces[0].mNumIndices; @@ -713,99 +665,7 @@ void glTF2Exporter::ExportMeshes() /*if(aim->HasBones()) { ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData); }*/ - - /****************** Compression ******************/ - ///TODO: animation: weights, joints. - if(comp_allow) - { -#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC - // Only one type of compression supported at now - Open3DGC. - // - o3dgc::BinaryStream bs; - o3dgc::SC3DMCEncoder encoder; - o3dgc::IndexedFaceSet comp_o3dgc_ifs; - o3dgc::SC3DMCEncodeParams comp_o3dgc_params; - - // - // Fill data for encoder. - // - // Quantization - unsigned quant_coord = mProperties->GetPropertyInteger("extensions.Open3DGC.quantization.POSITION", 12); - unsigned quant_normal = mProperties->GetPropertyInteger("extensions.Open3DGC.quantization.NORMAL", 10); - unsigned quant_texcoord = mProperties->GetPropertyInteger("extensions.Open3DGC.quantization.TEXCOORD", 10); - - // Prediction - o3dgc::O3DGCSC3DMCPredictionMode prediction_position = o3dgc::O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION; - o3dgc::O3DGCSC3DMCPredictionMode prediction_normal = o3dgc::O3DGC_SC3DMC_SURF_NORMALS_PREDICTION; - o3dgc::O3DGCSC3DMCPredictionMode prediction_texcoord = o3dgc::O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION; - - // IndexedFacesSet: "Crease angle", "solid", "convex" are set to default. - comp_o3dgc_ifs.SetCCW(true); - comp_o3dgc_ifs.SetIsTriangularMesh(true); - comp_o3dgc_ifs.SetNumFloatAttributes(0); - // Coordinates - comp_o3dgc_params.SetCoordQuantBits(quant_coord); - comp_o3dgc_params.SetCoordPredMode(prediction_position); - comp_o3dgc_ifs.SetNCoord(aim->mNumVertices); - comp_o3dgc_ifs.SetCoord((o3dgc::Real* const)&b->GetPointer()[idx_srcdata_begin]); - // Normals - if(idx_srcdata_normal != SIZE_MAX) - { - comp_o3dgc_params.SetNormalQuantBits(quant_normal); - comp_o3dgc_params.SetNormalPredMode(prediction_normal); - comp_o3dgc_ifs.SetNNormal(aim->mNumVertices); - comp_o3dgc_ifs.SetNormal((o3dgc::Real* const)&b->GetPointer()[idx_srcdata_normal]); - } - - // Texture coordinates - for(size_t num_tc = 0; num_tc < idx_srcdata_tc.size(); num_tc++) - { - size_t num = comp_o3dgc_ifs.GetNumFloatAttributes(); - - comp_o3dgc_params.SetFloatAttributeQuantBits(static_cast(num), quant_texcoord); - comp_o3dgc_params.SetFloatAttributePredMode(static_cast(num), prediction_texcoord); - comp_o3dgc_ifs.SetNFloatAttribute(static_cast(num), aim->mNumVertices);// number of elements. - comp_o3dgc_ifs.SetFloatAttributeDim(static_cast(num), aim->mNumUVComponents[num_tc]);// components per element: aiVector3D => x * float - comp_o3dgc_ifs.SetFloatAttributeType(static_cast(num), o3dgc::O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_TEXCOORD); - comp_o3dgc_ifs.SetFloatAttribute(static_cast(num), (o3dgc::Real* const)&b->GetPointer()[idx_srcdata_tc[num_tc]]); - comp_o3dgc_ifs.SetNumFloatAttributes(static_cast(num + 1)); - } - - // Coordinates indices - comp_o3dgc_ifs.SetNCoordIndex(aim->mNumFaces); - comp_o3dgc_ifs.SetCoordIndex((IndicesType* const)&b->GetPointer()[idx_srcdata_ind]); - // Prepare to enconding - comp_o3dgc_params.SetNumFloatAttributes(comp_o3dgc_ifs.GetNumFloatAttributes()); - if(mProperties->GetPropertyBool("extensions.Open3DGC.binary", true)) - comp_o3dgc_params.SetStreamType(o3dgc::O3DGC_STREAM_TYPE_BINARY); - else - comp_o3dgc_params.SetStreamType(o3dgc::O3DGC_STREAM_TYPE_ASCII); - - comp_o3dgc_ifs.ComputeMinMax(o3dgc::O3DGC_SC3DMC_MAX_ALL_DIMS); - // - // Encoding - // - encoder.Encode(comp_o3dgc_params, comp_o3dgc_ifs, bs); - // Replace data in buffer. - b->ReplaceData(idx_srcdata_begin, b->byteLength - idx_srcdata_begin, bs.GetBuffer(), bs.GetSize()); - // - // Add information about extension to mesh. - // - // Create extension structure. - Mesh::SCompression_Open3DGC* ext = new Mesh::SCompression_Open3DGC; - - // Fill it. - ext->Buffer = b->id; - ext->Offset = idx_srcdata_begin; - ext->Count = b->byteLength - idx_srcdata_begin; - ext->Binary = mProperties->GetPropertyBool("extensions.Open3DGC.binary"); - ext->IndicesCount = comp_o3dgc_ifs.GetNCoordIndex() * 3; - ext->VerticesCount = comp_o3dgc_ifs.GetNCoord(); - // And assign to mesh. - m->Extension.push_back(ext); -#endif - }// if(comp_allow) - }// for (unsigned int i = 0; i < mScene->mNumMeshes; ++i) + } //---------------------------------------- // Finish the skin diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 97901fc01..a2c0911bd 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -288,38 +288,6 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r) for (unsigned int m = 0; m < r.meshes.Size(); ++m) { Mesh& mesh = r.meshes[m]; - // Check if mesh extensions is used - if(mesh.Extension.size() > 0) - { - for(Mesh::SExtension* cur_ext : mesh.Extension) - { -#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC - if(cur_ext->Type == Mesh::SExtension::EType::Compression_Open3DGC) - { - // Limitations for meshes when using Open3DGC-compression. - // It's a current limitation of sp... Specification have not this part still - about mesh compression. Why only one primitive? - // Because glTF is very flexibly. But in fact it ugly flexible. Every primitive can has own set of accessors and accessors can - // point to a-a-a-a-any part of buffer (through bufferview of course) and even to another buffer. We know that "Open3DGC-compression" - // is applicable only to part of buffer. As we can't guaranty continuity of the data for decoder, we will limit quantity of primitives. - // Yes indices, coordinates etc. still can br stored in different buffers, but with current specification it's a exporter problem. - // Also primitive can has only one of "POSITION", "NORMAL" and less then "AI_MAX_NUMBER_OF_TEXTURECOORDS" of "TEXCOORD". All accessor - // of primitive must point to one continuous region of the buffer. - if(mesh.primitives.size() > 2) throw DeadlyImportError("GLTF: When using Open3DGC compression then only one primitive per mesh are allowed."); - - Mesh::SCompression_Open3DGC* o3dgc_ext = (Mesh::SCompression_Open3DGC*)cur_ext; - Ref buf = r.buffers.Get(o3dgc_ext->Buffer); - - buf->EncodedRegion_SetCurrent(mesh.id); - } - else -#endif - { - throw DeadlyImportError("GLTF: Can not import mesh: unknown mesh extension (code: \"" + to_string(cur_ext->Type) + - "\"), only Open3DGC is supported."); - } - } - }// if(mesh.Extension.size() > 0) - meshOffsets.push_back(k); k += unsigned(mesh.primitives.size()); From 8bef546b41b1069effb64fd53682172fb7187607 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Thu, 31 Aug 2017 23:40:44 -0400 Subject: [PATCH 26/90] mention pbrSpecularGlossiness support --- code/glTF2Asset.h | 1 + 1 file changed, 1 insertion(+) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index dd348de1a..1f9f48e18 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * glTF Extensions Support: * KHR_binary_glTF: full + * KHR_materials_pbrSpecularGlossiness full */ #ifndef GLTF2ASSET_H_INC #define GLTF2ASSET_H_INC From feee7528d6c8323e0cdb7aeb4c38bb62909d6a51 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Fri, 1 Sep 2017 02:42:09 -0400 Subject: [PATCH 27/90] Make sure `on` flag for specularGlossiness is being persisted --- code/glTF2Exporter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 2b7e4c33d..ae610d16d 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -426,6 +426,7 @@ void glTF2Exporter::ExportMaterials() KHR_materials_pbrSpecularGlossiness = true; } + m->pbrSpecularGlossiness.on = true; GetMatColor(mat, m->pbrSpecularGlossiness.diffuseFactor, "$clr.diffuse", 0, 1); GetMatColor(mat, m->pbrSpecularGlossiness.specularFactor, "$clr.specular", 0, 1); mat->Get("$mat.gltf.glossinessFactor", 0, 0, m->pbrSpecularGlossiness.glossinessFactor); From f09892ab63fcd919f1489bd8853963c020b3ca80 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Fri, 1 Sep 2017 02:42:26 -0400 Subject: [PATCH 28/90] Write specularGlossiness textures on the specularGlossiness object --- code/glTF2AssetWriter.inl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index c74ea4031..9aa00729c 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -346,8 +346,8 @@ namespace glTF2 { WriteFloat(obj, m.pbrSpecularGlossiness.glossinessFactor, "glossinessFactor", w.mAl); } - WriteTex(obj, m.pbrSpecularGlossiness.diffuseTexture, "diffuseTexture", w.mAl); - WriteTex(obj, m.pbrSpecularGlossiness.specularGlossinessTexture, "specularGlossinessTexture", w.mAl); + WriteTex(pbrSpecularGlossiness, m.pbrSpecularGlossiness.diffuseTexture, "diffuseTexture", w.mAl); + WriteTex(pbrSpecularGlossiness, m.pbrSpecularGlossiness.specularGlossinessTexture, "specularGlossinessTexture", w.mAl); } if (!pbrSpecularGlossiness.ObjectEmpty()) { From ab08a7c3cbc27add5c10ea44786018c9b5c8ff47 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Fri, 1 Sep 2017 17:49:04 -0400 Subject: [PATCH 29/90] reenable animation and skins exports Currently incorrect, however. May need to be removed --- code/glTF2Asset.h | 3 +++ code/glTF2Asset.inl | 36 ++++++++++++++++++++++++++---------- code/glTF2Exporter.cpp | 14 +++++++------- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 1f9f48e18..8e3a6dd7a 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -928,9 +928,11 @@ namespace glTF2 friend class AssetWriter; typedef typename std::gltf_unordered_map< unsigned int, unsigned int > Dict; + typedef typename std::gltf_unordered_map< std::string, unsigned int > IdDict; std::vector mObjs; //! The read objects Dict mObjsByOIndex; //! The read objects accessible by original index + IdDict mObjsById; //! The read objects accessible by id const char* mDictId; //! ID of the dictionary object const char* mExtId; //! ID of the extension defining the dictionary Value* mDict; //! JSON dictionary object @@ -951,6 +953,7 @@ namespace glTF2 Ref Retrieve(unsigned int i); Ref Get(unsigned int i); + Ref Get(const char* id); Ref Create(const char* id); Ref Create(const std::string& id) diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index dd110ebb7..5316b5e26 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -1,4 +1,4 @@ -/* +/* Open Asset Import Library (assimp) ---------------------------------------------------------------------- @@ -193,14 +193,6 @@ inline void LazyDict::DetachFromDocument() mDict = 0; } -template -Ref LazyDict::Get(unsigned int i) -{ - - return Ref(mObjs, i); - -} - template Ref LazyDict::Retrieve(unsigned int i) { @@ -234,12 +226,34 @@ Ref LazyDict::Retrieve(unsigned int i) return Add(inst); } +template +Ref LazyDict::Get(unsigned int i) +{ + + return Ref(mObjs, i); + +} + +template +Ref LazyDict::Get(const char* id) +{ + id = T::TranslateId(mAsset, id); + + typename IdDict::iterator it = mObjsById.find(id); + if (it != mObjsById.end()) { // already created? + return Ref(mObjs, it->second); + } + + throw std::out_of_range("id \"" + std::string(id) + "\" Doesn't exist"); +} + template Ref LazyDict::Add(T* obj) { unsigned int idx = unsigned(mObjs.size()); mObjs.push_back(obj); mObjsByOIndex[obj->oIndex] = idx; + mObjsById[obj->id] = idx; mAsset.mUsedIds[obj->id] = true; return Ref(mObjs, idx); } @@ -252,8 +266,10 @@ Ref LazyDict::Create(const char* id) throw DeadlyImportError("GLTF: two objects with the same ID exist"); } T* inst = new T(); + unsigned int idx = unsigned(mObjs.size()); inst->id = id; - inst->index = static_cast(mObjs.size()); + inst->index = idx; + inst->oIndex = idx; return Add(inst); } diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index ae610d16d..164b559fd 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -121,7 +121,7 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai ExportScene(); - //ExportAnimations(); + ExportAnimations(); AssetWriter writer(*mAsset); @@ -481,7 +481,7 @@ Ref FindSkeletonRootJoint(Ref& skinRef) return parentNodeRef; } -/*void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref& meshRef, Ref& bufferRef, Ref& skinRef, std::vector& inverseBindMatricesData) +void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref& meshRef, Ref& bufferRef, Ref& skinRef, std::vector& inverseBindMatricesData) { if (aimesh->mNumBones < 1) { return; @@ -558,7 +558,7 @@ Ref FindSkeletonRootJoint(Ref& skinRef) delete[] jointsPerVertex; delete[] vertexWeightData; delete[] vertexJointData; -}*/ +} void glTF2Exporter::ExportMeshes() { @@ -663,9 +663,9 @@ void glTF2Exporter::ExportMeshes() } /*************** Skins ****************/ - /*if(aim->HasBones()) { + if(aim->HasBones()) { ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData); - }*/ + } } //---------------------------------------- @@ -892,7 +892,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref bufferRef = mAsset->buffers.Get(unsigned (0)); @@ -961,7 +961,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref Date: Fri, 1 Sep 2017 17:56:13 -0400 Subject: [PATCH 30/90] store node mesh vs. meshes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit glTF nodes can only hold one mesh. this simply assigns to and check’s a Node’s Mesh --- code/glTF2Asset.h | 2 +- code/glTF2Asset.inl | 9 +-------- code/glTF2AssetWriter.inl | 4 +++- code/glTF2Exporter.cpp | 19 +++++++++---------- code/glTF2Importer.cpp | 21 +++++++-------------- 5 files changed, 21 insertions(+), 34 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 8e3a6dd7a..9facef6a7 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -767,7 +767,7 @@ namespace glTF2 struct Node : public Object { std::vector< Ref > children; - std::vector< Ref > meshes; + Ref mesh; Nullable matrix; Nullable translation; diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 5316b5e26..bebaeba53 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -954,16 +954,9 @@ inline void Node::Read(Value& obj, Asset& r) } if (Value* mesh = FindUInt(obj, "mesh")) { - //unsigned numMeshes = (unsigned)meshes->Size(); - unsigned numMeshes = 1; - - //std::vector meshList; - - this->meshes.reserve(numMeshes); - Ref meshRef = r.meshes.Retrieve((*mesh).GetUint()); - if (meshRef) this->meshes.push_back(meshRef); + if (meshRef) this->mesh = meshRef; } if (Value* camera = FindUInt(obj, "camera")) { diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index 9aa00729c..4a2aa9f39 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -441,7 +441,9 @@ namespace glTF2 { AddRefsVector(obj, "children", n.children, w.mAl); - AddRefsVector(obj, "meshes", n.meshes, w.mAl); + if (n.mesh) { + obj.AddMember("mesh", n.mesh->index, w.mAl); + } AddRefsVector(obj, "skeletons", n.skeletons, w.mAl); diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 164b559fd..7daedd4a3 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -442,16 +442,15 @@ void glTF2Exporter::ExportMaterials() */ bool FindMeshNode(Ref& nodeIn, Ref& meshNode, std::string meshID) { - for (unsigned int i = 0; i < nodeIn->meshes.size(); ++i) { - if (meshID.compare(nodeIn->meshes[i]->id) == 0) { - meshNode = nodeIn; - return true; - } + + if (nodeIn->mesh && meshID.compare(nodeIn->mesh->id) == 0) { + meshNode = nodeIn; + return true; } for (unsigned int i = 0; i < nodeIn->children.size(); ++i) { if(FindMeshNode(nodeIn->children[i], meshNode, meshID)) { - return true; + return true; } } @@ -722,8 +721,8 @@ unsigned int glTF2Exporter::ExportNodeHierarchy(const aiNode* n) CopyValue(n->mTransformation, node->matrix.value); } - for (unsigned int i = 0; i < n->mNumMeshes; ++i) { - node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i])); + if (n->mNumMeshes > 0) { + node->mesh = mAsset->meshes.Get(n->mMeshes[0]); } for (unsigned int i = 0; i < n->mNumChildren; ++i) { @@ -751,8 +750,8 @@ unsigned int glTF2Exporter::ExportNode(const aiNode* n, Ref& parent) CopyValue(n->mTransformation, node->matrix.value); } - for (unsigned int i = 0; i < n->mNumMeshes; ++i) { - node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i])); + if (n->mNumMeshes > 0) { + node->mesh = mAsset->meshes.Get(n->mMeshes[0]); } for (unsigned int i = 0; i < n->mNumChildren; ++i) { diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index a2c0911bd..90ae849bd 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -502,22 +502,15 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector& } } - if (!node.meshes.empty()) { - int count = 0; - for (size_t i = 0; i < node.meshes.size(); ++i) { - int idx = node.meshes[i].GetIndex(); - count += meshOffsets[idx + 1] - meshOffsets[idx]; - } - - ainode->mNumMeshes = count; - ainode->mMeshes = new unsigned int[count]; + if (node.mesh) { + ainode->mNumMeshes = 1; + ainode->mMeshes = new unsigned int[1]; int k = 0; - for (size_t i = 0; i < node.meshes.size(); ++i) { - int idx = node.meshes[i].GetIndex(); - for (unsigned int j = meshOffsets[idx]; j < meshOffsets[idx + 1]; ++j, ++k) { - ainode->mMeshes[k] = j; - } + int idx = node.mesh.GetIndex(); + + for (unsigned int j = meshOffsets[idx]; j < meshOffsets[idx + 1]; ++j, ++k) { + ainode->mMeshes[k] = j; } } From 7f01e3f48f0008a43a64d90c94d6c8288de83498 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Fri, 1 Sep 2017 17:56:42 -0400 Subject: [PATCH 31/90] Only export byteStride if not 0 --- code/glTF2AssetWriter.inl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index 4a2aa9f39..69d54d97b 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -97,7 +97,11 @@ namespace glTF2 { { obj.AddMember("bufferView", a.bufferView->index, w.mAl); obj.AddMember("byteOffset", a.byteOffset, w.mAl); - obj.AddMember("byteStride", a.byteStride, w.mAl); + + if (a.byteStride != 0) { + obj.AddMember("byteStride", a.byteStride, w.mAl); + } + obj.AddMember("componentType", int(a.componentType), w.mAl); obj.AddMember("count", a.count, w.mAl); obj.AddMember("type", StringRef(AttribType::ToString(a.type)), w.mAl); From d277995a972dedcccc5258105b543b5b65fa89c9 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Fri, 1 Sep 2017 17:56:48 -0400 Subject: [PATCH 32/90] Formatting --- code/glTF2Asset.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 9facef6a7..875594254 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -777,7 +777,7 @@ namespace glTF2 Ref camera; std::vector< Ref > skeletons; //!< The ID of skeleton nodes. Each of which is the root of a node hierarchy. - Ref skin; //!< The ID of the skin referenced by this node. + Ref skin; //!< The ID of the skin referenced by this node. std::string jointName; //!< Name used when this node is a joint in a skin. Ref parent; //!< This is not part of the glTF specification. Used as a helper. From 63ef19d9ad1b5a6404fb2520209bb7c0f1e05005 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Fri, 1 Sep 2017 17:56:30 -0400 Subject: [PATCH 33/90] Export extensions --- code/glTF2Exporter.cpp | 18 ------------------ code/glTF2Exporter.h | 1 - code/glTF2Importer.cpp | 7 ------- 3 files changed, 26 deletions(-) diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 7daedd4a3..9a2c1cd75 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -107,10 +107,6 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai ExportMetadata(); - if (mScene->mRootNode) { - ExportExtensions(mScene->mRootNode); - } - ExportMaterials(); if (mScene->mRootNode) { @@ -789,20 +785,6 @@ void glTF2Exporter::ExportMetadata() asset.generator = buffer; } -void glTF2Exporter::ExportExtensions(const aiNode* n) -{ - aiMetadata* mMetaData = n->mMetaData; - - if (mMetaData != nullptr) { - bool pbrSpecularGlossiness; - - if (mMetaData->Get("extensionsUsed.pbrSpecularGlossiness", pbrSpecularGlossiness)) { - mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness = pbrSpecularGlossiness; - } - } - -} - inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref& animRef, Ref& buffer, const aiNodeAnim* nodeChannel, float ticksPerSecond) { // Loop over the data and check to see if it exactly matches an existing buffer. diff --git a/code/glTF2Exporter.h b/code/glTF2Exporter.h index 827189f29..4b9fe0ce0 100644 --- a/code/glTF2Exporter.h +++ b/code/glTF2Exporter.h @@ -118,7 +118,6 @@ namespace Assimp void GetMatColor(const aiMaterial* mat, glTF2::vec4& prop, const char* propName, int type, int idx); void GetMatColor(const aiMaterial* mat, glTF2::vec3& prop, const char* propName, int type, int idx); void ExportMetadata(); - void ExportExtensions(const aiNode* n); void ExportMaterials(); void ExportMeshes(); unsigned int ExportNodeHierarchy(const aiNode* n); diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 90ae849bd..36fe8b70e 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -546,13 +546,6 @@ void glTF2Importer::ImportNodes(glTF2::Asset& r) //if (!mScene->mRootNode) { // mScene->mRootNode = new aiNode("EMPTY"); //} - - //initialize mMetaData; - aiMetadata* mMetaData = new aiMetadata(); - - //store used glTF extensions on the root node, for a lack of a better place. - mMetaData->Add("extensionsUsed.pbrSpecularGlossiness", r.extensionsUsed.KHR_materials_pbrSpecularGlossiness); - mScene->mRootNode->mMetaData = mMetaData; } void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset& r) From 2abdbdb55e2801f284d1a8fc2a090e9da28a4557 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Fri, 1 Sep 2017 18:29:30 -0400 Subject: [PATCH 34/90] Fix unused CopyValue --- code/glTF2Importer.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 36fe8b70e..08145f5fe 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -136,10 +136,10 @@ static void CopyValue(const glTF2::vec4& v, aiColor4D& out) out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3]; } -static void CopyValue(const glTF2::vec4& v, aiColor3D& out) +/*static void CopyValue(const glTF2::vec4& v, aiColor3D& out) { out.r = v[0]; out.g = v[1]; out.b = v[2]; -} +}*/ static void CopyValue(const glTF2::vec3& v, aiColor4D& out) { @@ -173,14 +173,9 @@ inline void SetMaterialColorProperty(Asset& r, vec4& prop, aiMaterial* mat, cons inline void SetMaterialColorProperty(Asset& r, vec3& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx) { - vec4 prop4; - - prop4[0] = prop[0]; - prop4[1] = prop[1]; - prop4[2] = prop[2]; - prop4[3] = 1; - - return SetMaterialColorProperty(r, prop4, mat, pKey, type, idx); + aiColor4D col; + CopyValue(prop, col); + mat->AddProperty(&col, 1, pKey, type, idx); } inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::TextureInfo prop, aiMaterial* mat, aiTextureType texType, unsigned int texSlot = 0) From 7245cceead0ea647a61cebafc32191e2f588c7ea Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Sun, 3 Sep 2017 22:03:02 -0400 Subject: [PATCH 35/90] Set default values on Sampler --- code/glTF2Asset.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 875594254..711e8231b 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -800,7 +800,7 @@ namespace glTF2 SamplerWrap wrapS; //!< The texture wrapping in the S direction. (required) SamplerWrap wrapT; //!< The texture wrapping in the T direction. (required) - Sampler() {} + Sampler() { SetDefaults(); } void Read(Value& obj, Asset& r); void SetDefaults(); }; From a9c4fa84b5f48fccfc099d8c300144d5ba1807eb Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Sun, 3 Sep 2017 22:09:48 -0400 Subject: [PATCH 36/90] Sampler improvements; Add new LazyDict method Samplers are now imported into assimp internal format from textures; Samplers have defaults as per spec; Sampler enums are strongly typed with UNSET values; Samplers are exported properly; Sampler filters are exported as well; Samplers are re-used across textures on export Default sampler values are not written --- code/glTF2Asset.h | 25 ++++++----- code/glTF2Asset.inl | 28 +++++++----- code/glTF2AssetWriter.inl | 23 ++++++---- code/glTF2Exporter.cpp | 91 +++++++++++++++++++++++---------------- code/glTF2Exporter.h | 2 +- code/glTF2Importer.cpp | 21 +++++++++ 6 files changed, 123 insertions(+), 67 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 711e8231b..aabd462d8 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -242,15 +242,17 @@ namespace glTF2 }; //! Values for the Sampler::magFilter field - enum SamplerMagFilter + enum class SamplerMagFilter: unsigned int { + UNSET = 0, SamplerMagFilter_Nearest = 9728, SamplerMagFilter_Linear = 9729 }; //! Values for the Sampler::minFilter field - enum SamplerMinFilter + enum class SamplerMinFilter: unsigned int { + UNSET = 0, SamplerMinFilter_Nearest = 9728, SamplerMinFilter_Linear = 9729, SamplerMinFilter_Nearest_Mipmap_Nearest = 9984, @@ -260,11 +262,12 @@ namespace glTF2 }; //! Values for the Sampler::wrapS and Sampler::wrapT field - enum SamplerWrap + enum class SamplerWrap: unsigned int { - SamplerWrap_Clamp_To_Edge = 33071, - SamplerWrap_Mirrored_Repeat = 33648, - SamplerWrap_Repeat = 10497 + UNSET = 0, + Clamp_To_Edge = 33071, + Mirrored_Repeat = 33648, + Repeat = 10497 }; //! Values for the Texture::format and Texture::internalFormat fields @@ -795,10 +798,10 @@ namespace glTF2 struct Sampler : public Object { - SamplerMagFilter magFilter; //!< The texture magnification filter. (required) - SamplerMinFilter minFilter; //!< The texture minification filter. (required) - SamplerWrap wrapS; //!< The texture wrapping in the S direction. (required) - SamplerWrap wrapT; //!< The texture wrapping in the T direction. (required) + SamplerMagFilter magFilter; //!< The texture magnification filter. + SamplerMinFilter minFilter; //!< The texture minification filter. + SamplerWrap wrapS; //!< The texture wrapping in the S direction. + SamplerWrap wrapT; //!< The texture wrapping in the T direction. Sampler() { SetDefaults(); } void Read(Value& obj, Asset& r); @@ -955,6 +958,8 @@ namespace glTF2 Ref Get(unsigned int i); Ref Get(const char* id); + bool Has(const char* id); + Ref Create(const char* id); Ref Create(const std::string& id) { return Create(id.c_str()); } diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index bebaeba53..5764c6ff6 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -244,7 +244,17 @@ Ref LazyDict::Get(const char* id) return Ref(mObjs, it->second); } - throw std::out_of_range("id \"" + std::string(id) + "\" Doesn't exist"); + return Create(id); +} + +template +bool LazyDict::Has(const char* id) +{ + id = T::TranslateId(mAsset, id); + + typename IdDict::iterator it = mObjsById.find(id); + + return it != mObjsById.end(); } template @@ -697,6 +707,7 @@ inline void Sampler::Read(Value& obj, Asset& r) { SetDefaults(); + ReadMember(obj, "name", name); ReadMember(obj, "magFilter", magFilter); ReadMember(obj, "minFilter", minFilter); ReadMember(obj, "wrapS", wrapS); @@ -705,10 +716,11 @@ inline void Sampler::Read(Value& obj, Asset& r) inline void Sampler::SetDefaults() { - magFilter = SamplerMagFilter_Linear; - minFilter = SamplerMinFilter_Linear; - wrapS = SamplerWrap_Repeat; - wrapT = SamplerWrap_Repeat; + //only wrapping modes have defaults + wrapS = SamplerWrap::Repeat; + wrapT = SamplerWrap::Repeat; + magFilter = SamplerMagFilter::UNSET; + minFilter = SamplerMinFilter::UNSET; } inline void Texture::Read(Value& obj, Asset& r) @@ -883,7 +895,6 @@ inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root) // Valid attribute semantics include POSITION, NORMAL, TEXCOORD, COLOR, JOINT, JOINTMATRIX, // and WEIGHT.Attribute semantics can be of the form[semantic]_[set_index], e.g., TEXCOORD_0, TEXCOORD_1, etc. - //@TODO: update this int undPos = 0; Mesh::AccessorList* vec = 0; if (GetAttribVector(prim, attr, vec, undPos)) { @@ -943,7 +954,6 @@ inline void Node::Read(Value& obj, Asset& r) } } - if (Value* matrix = FindArray(obj, "matrix")) { ReadValue(*matrix, this->matrix); } @@ -978,7 +988,6 @@ inline void Scene::Read(Value& obj, Asset& r) } } - inline void AssetMetadata::Read(Document& doc) { // read the version, etc. @@ -1013,8 +1022,6 @@ inline void AssetMetadata::Read(Document& doc) } } - - // // Asset methods implementation // @@ -1142,7 +1149,6 @@ inline void Asset::SetAsBinary() } } - inline void Asset::ReadExtensionsUsed(Document& doc) { Value* extsUsed = FindArray(doc, "extensionsUsed"); diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index 69d54d97b..f7943172e 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -467,17 +467,24 @@ namespace glTF2 { inline void Write(Value& obj, Sampler& b, AssetWriter& w) { - if (b.wrapS) { - obj.AddMember("wrapS", b.wrapS, w.mAl); + if (!b.name.empty()) { + obj.AddMember("name", b.name, w.mAl); } - if (b.wrapT) { - obj.AddMember("wrapT", b.wrapT, w.mAl); + + if (b.wrapS != SamplerWrap::UNSET && b.wrapS != SamplerWrap::Repeat) { + obj.AddMember("wrapS", static_cast(b.wrapS), w.mAl); } - if (b.magFilter) { - obj.AddMember("magFilter", b.magFilter, w.mAl); + + if (b.wrapT != SamplerWrap::UNSET && b.wrapT != SamplerWrap::Repeat) { + obj.AddMember("wrapT", static_cast(b.wrapT), w.mAl); } - if (b.minFilter) { - obj.AddMember("minFilter", b.minFilter, w.mAl); + + if (b.magFilter != SamplerMagFilter::UNSET) { + obj.AddMember("magFilter", static_cast(b.magFilter), w.mAl); + } + + if (b.minFilter != SamplerMinFilter::UNSET) { + obj.AddMember("minFilter", static_cast(b.minFilter), w.mAl); } } diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 9a2c1cd75..fec7236e3 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -223,50 +223,63 @@ inline Ref ExportData(Asset& a, std::string& meshName, Ref& bu return acc; } -void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref texture) +inline void SetSamplerWrap(SamplerWrap& wrap, aiTextureMapMode map) { - std::string samplerId = mAsset->FindUniqueID("", "sampler"); - texture->sampler = mAsset->samplers.Create(samplerId); - - aiTextureMapMode mapU, mapV; - aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0),(int*)&mapU); - aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0),(int*)&mapV); - - switch (mapU) { - case aiTextureMapMode_Wrap: - texture->sampler->wrapS = SamplerWrap_Repeat; - break; + switch (map) { case aiTextureMapMode_Clamp: - texture->sampler->wrapS = SamplerWrap_Clamp_To_Edge; + wrap = SamplerWrap::Clamp_To_Edge; break; case aiTextureMapMode_Mirror: - texture->sampler->wrapS = SamplerWrap_Mirrored_Repeat; + wrap = SamplerWrap::Mirrored_Repeat; break; - case aiTextureMapMode_Decal: - default: - texture->sampler->wrapS = SamplerWrap_Repeat; - break; - }; - - switch (mapV) { case aiTextureMapMode_Wrap: - texture->sampler->wrapT = SamplerWrap_Repeat; - break; - case aiTextureMapMode_Clamp: - texture->sampler->wrapT = SamplerWrap_Clamp_To_Edge; - break; - case aiTextureMapMode_Mirror: - texture->sampler->wrapT = SamplerWrap_Mirrored_Repeat; - break; case aiTextureMapMode_Decal: default: - texture->sampler->wrapT = SamplerWrap_Repeat; + wrap = SamplerWrap::Repeat; break; }; +} - // Hard coded Texture filtering options because I do not know where to find them in the aiMaterial. - texture->sampler->magFilter = SamplerMagFilter_Linear; - texture->sampler->minFilter = SamplerMinFilter_Linear_Mipmap_Linear; +void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref texture, aiTextureType tt, unsigned int slot) +{ + aiString aId; + std::string id; + if (aiGetMaterialString(mat, (std::string(_AI_MATKEY_MAPPING_BASE) + "id").c_str(), tt, slot, &aId) == AI_SUCCESS) { + id = aId.C_Str(); + } + + if (mAsset->samplers.Has(id.c_str())) { + texture->sampler = mAsset->samplers.Get(id.c_str()); + } else { + id = mAsset->FindUniqueID(id, "sampler"); + + texture->sampler = mAsset->samplers.Create(id.c_str()); + + aiTextureMapMode mapU, mapV; + SamplerMagFilter filterMag; + SamplerMinFilter filterMin; + + if (aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_U(tt, slot), (int*)&mapU) == AI_SUCCESS) { + SetSamplerWrap(texture->sampler->wrapS, mapU); + } + + if (aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_V(tt, slot), (int*)&mapV) == AI_SUCCESS) { + SetSamplerWrap(texture->sampler->wrapT, mapV); + } + + if (aiGetMaterialInteger(mat, (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermag").c_str(), tt, slot, (int*)&filterMag) == AI_SUCCESS) { + texture->sampler->magFilter = filterMag; + } + + if (aiGetMaterialInteger(mat, (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermin").c_str(), tt, slot, (int*)&filterMin) == AI_SUCCESS) { + texture->sampler->minFilter = filterMin; + } + + aiString name; + if (aiGetMaterialString(mat, (std::string(_AI_MATKEY_MAPPING_BASE) + "name").c_str(), tt, slot, &name) == AI_SUCCESS) { + texture->sampler->name = name.C_Str(); + } + } } void glTF2Exporter::GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int slot) @@ -324,7 +337,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref& texture, aiTe texture->source->uri = path; } - GetTexSampler(mat, texture); + GetTexSampler(mat, texture, tt, slot); } } } @@ -390,17 +403,23 @@ void glTF2Exporter::ExportMaterials() for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) { const aiMaterial* mat = mScene->mMaterials[i]; + std::string id = "material_" + std::to_string(i); + + Ref m = mAsset->materials.Create(id); + std::string name; if (mat->Get(AI_MATKEY_NAME, aiName) == AI_SUCCESS) { name = aiName.C_Str(); } name = mAsset->FindUniqueID(name, "material"); - Ref m = mAsset->materials.Create(name); + m->name = name; GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_DIFFUSE); GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, aiTextureType_UNKNOWN, 0);//get unknown slot GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE); + mat->Get("$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0, m->pbrMetallicRoughness.metallicFactor); + mat->Get("$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0, m->pbrMetallicRoughness.roughnessFactor); GetMatTex(mat, m->normalTexture, aiTextureType_NORMALS); GetMatTex(mat, m->occlusionTexture, aiTextureType_LIGHTMAP); @@ -409,8 +428,6 @@ void glTF2Exporter::ExportMaterials() mat->Get(AI_MATKEY_TWOSIDED, m->doubleSided); mat->Get("$mat.gltf.alphaCutoff", 0, 0, m->alphaCutoff); - mat->Get("$mat.gltf.metallicFactor", 0, 0, m->pbrMetallicRoughness.metallicFactor); - mat->Get("$mat.gltf.roughnessFactor", 0, 0, m->pbrMetallicRoughness.roughnessFactor); mat->Get("$mat.gltf.alphaMode", 0, 0, m->alphaMode); bool hasPbrSpecularGlossiness; diff --git a/code/glTF2Exporter.h b/code/glTF2Exporter.h index 4b9fe0ce0..420c2afa6 100644 --- a/code/glTF2Exporter.h +++ b/code/glTF2Exporter.h @@ -108,7 +108,7 @@ namespace Assimp void WriteBinaryData(IOStream* outfile, std::size_t sceneLength); - void GetTexSampler(const aiMaterial* mat, glTF2::Ref texture); + void GetTexSampler(const aiMaterial* mat, glTF2::Ref texture, aiTextureType tt, unsigned int slot); void GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int idx); void GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int idx); void GetMatTex(const aiMaterial* mat, glTF2::Ref& texture, aiTextureType tt, unsigned int slot); diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 08145f5fe..86301a3f4 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -194,6 +194,27 @@ inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& const char *texCoordName = (std::string(_AI_MATKEY_TEXTURE_BASE) + ".texCoord").c_str(); mat->AddProperty(&prop.texCoord, 1, texCoordName, texType, texSlot); + + if (prop.texture->sampler) { + Ref sampler = prop.texture->sampler; + + aiString name(sampler->name); + aiString id(sampler->id); + + mat->AddProperty(&name, (std::string(_AI_MATKEY_MAPPING_BASE) + "name").c_str(), texType, texSlot); + mat->AddProperty(&id, (std::string(_AI_MATKEY_MAPPING_BASE) + "id").c_str(), texType, texSlot); + + mat->AddProperty(&sampler->wrapS, 1, AI_MATKEY_MAPPINGMODE_U(texType, texSlot)); + mat->AddProperty(&sampler->wrapT, 1, AI_MATKEY_MAPPINGMODE_V(texType, texSlot)); + + if (sampler->magFilter != SamplerMagFilter::UNSET) { + mat->AddProperty(&sampler->magFilter, 1, (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermag").c_str(), texType, texSlot); + } + + if (sampler->minFilter != SamplerMinFilter::UNSET) { + mat->AddProperty(&sampler->minFilter, 1, (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermin").c_str(), texType, texSlot); + } + } } } From 37527849b771552c9003dc488a5a97d76a196123 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Sun, 3 Sep 2017 22:11:20 -0400 Subject: [PATCH 37/90] Export material names properly --- code/glTF2AssetWriter.inl | 4 ---- code/glTF2Importer.cpp | 8 +++++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index f7943172e..c10a6a08b 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -284,10 +284,6 @@ namespace glTF2 { inline void Write(Value& obj, Material& m, AssetWriter& w) { - if (!m.name.empty()) { - obj.AddMember("name", m.name, w.mAl); - } - Value pbrMetallicRoughness; pbrMetallicRoughness.SetObject(); { diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 86301a3f4..82ea5f3e7 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -125,7 +125,6 @@ bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool } - //static void CopyValue(const glTF2::vec3& v, aiColor3D& out) //{ // out.r = v[0]; out.g = v[1]; out.b = v[2]; @@ -228,8 +227,11 @@ void glTF2Importer::ImportMaterials(glTF2::Asset& r) Material& mat = r.materials[i]; - aiString str(mat.id); - aimat->AddProperty(&str, AI_MATKEY_NAME); + if (!mat.name.empty()) { + aiString str(mat.name); + + aimat->AddProperty(&str, AI_MATKEY_NAME); + } SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE); From 21259e08357c0b8487ab33ffd87d5f9118420dd7 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Tue, 5 Sep 2017 14:39:52 -0400 Subject: [PATCH 38/90] Use different form of index accessor --- code/glTF2Asset.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 5764c6ff6..88dbfcfdb 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -211,7 +211,7 @@ Ref LazyDict::Retrieve(unsigned int i) throw DeadlyImportError("GLTF: Field is not an array \"" + std::string(mDictId) + "\""); } - Value& obj = mDict->operator[](i); + Value &obj = (*mDict)[i]; if (!obj.IsObject()) { throw DeadlyImportError("GLTF: Object at index \"" + std::to_string(i) + "\" is not a JSON object"); From 1a5823700f17caa6c6cdedfd34ce5bbd3ba85556 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Tue, 5 Sep 2017 14:40:27 -0400 Subject: [PATCH 39/90] Remove need for Has by returning an empty Ref in Get --- code/glTF2Asset.h | 2 -- code/glTF2Asset.inl | 12 +----------- code/glTF2Exporter.cpp | 4 ++-- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index aabd462d8..9a70ff4ff 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -958,8 +958,6 @@ namespace glTF2 Ref Get(unsigned int i); Ref Get(const char* id); - bool Has(const char* id); - Ref Create(const char* id); Ref Create(const std::string& id) { return Create(id.c_str()); } diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 88dbfcfdb..1c75d0040 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -244,17 +244,7 @@ Ref LazyDict::Get(const char* id) return Ref(mObjs, it->second); } - return Create(id); -} - -template -bool LazyDict::Has(const char* id) -{ - id = T::TranslateId(mAsset, id); - - typename IdDict::iterator it = mObjsById.find(id); - - return it != mObjsById.end(); + return Ref(); } template diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index fec7236e3..073309b06 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -248,8 +248,8 @@ void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref texture, a id = aId.C_Str(); } - if (mAsset->samplers.Has(id.c_str())) { - texture->sampler = mAsset->samplers.Get(id.c_str()); + if (Ref ref = mAsset->samplers.Get(id.c_str())) { + texture->sampler = ref; } else { id = mAsset->FindUniqueID(id, "sampler"); From 03cfa04ee4a4ef85a3eeefa879bec4e088418287 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Tue, 5 Sep 2017 15:45:32 -0400 Subject: [PATCH 40/90] Define default material values as static constants for reuse --- code/glTF2Asset.h | 10 +++++++--- code/glTF2Asset.inl | 16 ++++++++-------- code/glTF2AssetWriter.inl | 14 ++------------ 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 9a70ff4ff..486e23bc0 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -135,8 +135,7 @@ namespace glTF2 // Vec/matrix types, as raw float arrays typedef float (vec3)[3]; typedef float (vec4)[4]; - typedef float (mat4)[16]; - + typedef float (mat4)[16]; namespace Util { @@ -670,7 +669,12 @@ namespace glTF2 inline uint8_t* StealData(); inline void SetData(uint8_t* data, size_t length, Asset& r); - }; + }; + + const vec4 defaultBaseColor = {1, 1, 1, 1}; + const vec3 defaultEmissiveFactor = {0, 0, 0}; + const vec4 defaultDiffuseFactor = {1, 1, 1, 1}; + const vec3 defaultSpecularFactor = {1, 1, 1}; struct TextureInfo { diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 1c75d0040..07e0a5e8e 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -803,28 +803,28 @@ inline void Material::Read(Value& material, Asset& r) } namespace { - void SetVector(vec4& v, float x, float y, float z, float w) - { v[0] = x; v[1] = y; v[2] = z; v[3] = w; } + void SetVector(vec4& v, const float(&in)[4]) + { v[0] = in[0]; v[1] = in[1]; v[2] = in[2]; v[3] = in[3]; } - void SetVector(vec3& v, float x, float y, float z) - { v[0] = x; v[1] = y; v[2] = z; } + void SetVector(vec3& v, const float(&in)[3]) + { v[0] = in[0]; v[1] = in[1]; v[2] = in[2]; } } inline void Material::SetDefaults() { //pbr materials - SetVector(pbrMetallicRoughness.baseColorFactor, 1, 1, 1, 1); + SetVector(pbrMetallicRoughness.baseColorFactor, defaultBaseColor); pbrMetallicRoughness.metallicFactor = 1.0; pbrMetallicRoughness.roughnessFactor = 1.0; - SetVector(emissiveFactor, 0, 0, 0); + SetVector(emissiveFactor, defaultEmissiveFactor); alphaMode = "OPAQUE"; alphaCutoff = 0.5; doubleSided = false; //pbrSpecularGlossiness properties - SetVector(pbrSpecularGlossiness.diffuseFactor, 1, 1, 1, 1); - SetVector(pbrSpecularGlossiness.specularFactor, 1, 1, 1); + SetVector(pbrSpecularGlossiness.diffuseFactor, defaultDiffuseFactor); + SetVector(pbrSpecularGlossiness.specularFactor, defaultSpecularFactor); pbrSpecularGlossiness.glossinessFactor = 1.0; } diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index c10a6a08b..475c7a0d9 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -268,7 +268,7 @@ namespace glTF2 { } template - inline void WriteVec(Value& obj, float(&prop)[N], const char* propName, float(&defaultVal)[N], MemoryPoolAllocator<>& al) + inline void WriteVec(Value& obj, float(&prop)[N], const char* propName, const float(&defaultVal)[N], MemoryPoolAllocator<>& al) { if (!std::equal(std::begin(prop), std::end(prop), std::begin(defaultVal))) { WriteVec(obj, prop, propName, al); @@ -289,10 +289,7 @@ namespace glTF2 { { WriteTex(pbrMetallicRoughness, m.pbrMetallicRoughness.baseColorTexture, "baseColorTexture", w.mAl); WriteTex(pbrMetallicRoughness, m.pbrMetallicRoughness.metallicRoughnessTexture, "metallicRoughnessTexture", w.mAl); - - //@TODO: define this as a constant? - vec4 defaultEmissiveFactor = {1, 1, 1, 1}; - WriteVec(pbrMetallicRoughness, m.pbrMetallicRoughness.baseColorFactor, "baseColorFactor", defaultEmissiveFactor, w.mAl); + WriteVec(pbrMetallicRoughness, m.pbrMetallicRoughness.baseColorFactor, "baseColorFactor", defaultBaseColor, w.mAl); if (m.pbrMetallicRoughness.metallicFactor != 1) { WriteFloat(pbrMetallicRoughness, m.pbrMetallicRoughness.metallicFactor, "metallicFactor", w.mAl); @@ -310,9 +307,6 @@ namespace glTF2 { WriteTex(obj, m.normalTexture, "normalTexture", w.mAl); WriteTex(obj, m.emissiveTexture, "emissiveTexture", w.mAl); WriteTex(obj, m.occlusionTexture, "occlusionTexture", w.mAl); - - //@TODO: define this as a constant? - vec3 defaultEmissiveFactor = {0, 0, 0}; WriteVec(obj, m.emissiveFactor, "emissiveFactor", defaultEmissiveFactor, w.mAl); if (m.alphaCutoff != 0.5) { @@ -335,11 +329,7 @@ namespace glTF2 { pbrSpecularGlossiness.SetObject(); { //pbrSpecularGlossiness - - vec4 defaultDiffuseFactor = {1, 1, 1, 1}; WriteVec(pbrSpecularGlossiness, m.pbrSpecularGlossiness.diffuseFactor, "diffuseFactor", defaultDiffuseFactor, w.mAl); - - vec3 defaultSpecularFactor = {1, 1, 1}; WriteVec(pbrSpecularGlossiness, m.pbrSpecularGlossiness.specularFactor, "specularFactor", defaultSpecularFactor, w.mAl); if (m.pbrSpecularGlossiness.glossinessFactor != 1) { From 44757af34a0047e974ba6d30b9b027d0fffecc5d Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Tue, 5 Sep 2017 16:29:00 -0400 Subject: [PATCH 41/90] Implement pbrSpecularGlossiness property as Nullable --- code/glTF2Asset.h | 8 +++++--- code/glTF2Asset.inl | 23 ++++++++++++++--------- code/glTF2AssetWriter.inl | 21 +++++++++++---------- code/glTF2Exporter.cpp | 15 +++++++++------ code/glTF2Importer.cpp | 14 +++++++------- 5 files changed, 46 insertions(+), 35 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 486e23bc0..07f8614ab 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -711,12 +711,14 @@ namespace glTF2 struct PbrSpecularGlossiness { - bool on = false; vec4 diffuseFactor; vec3 specularFactor; float glossinessFactor; TextureInfo diffuseTexture; - TextureInfo specularGlossinessTexture; + TextureInfo specularGlossinessTexture; + + PbrSpecularGlossiness() { SetDefaults(); } + void SetDefaults(); }; //! The material appearance of a primitive. @@ -735,7 +737,7 @@ namespace glTF2 bool doubleSided; //extension: KHR_materials_pbrSpecularGlossiness - PbrSpecularGlossiness pbrSpecularGlossiness; + Nullable pbrSpecularGlossiness; Material() { SetDefaults(); } void Read(Value& obj, Asset& r); diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 07e0a5e8e..e2d812563 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -790,13 +790,15 @@ inline void Material::Read(Value& material, Asset& r) if (Value* extensions = FindObject(material, "extensions")) { if (r.extensionsUsed.KHR_materials_pbrSpecularGlossiness) { if (Value* pbrSpecularGlossiness = FindObject(*extensions, "KHR_materials_pbrSpecularGlossiness")) { - this->pbrSpecularGlossiness.on = true; + PbrSpecularGlossiness pbrSG; - ReadMember(*pbrSpecularGlossiness, "diffuseFactor", this->pbrSpecularGlossiness.diffuseFactor); - ReadTextureProperty(r, *pbrSpecularGlossiness, "diffuseTexture", this->pbrSpecularGlossiness.diffuseTexture); - ReadTextureProperty(r, *pbrSpecularGlossiness, "specularGlossinessTexture", this->pbrSpecularGlossiness.specularGlossinessTexture); - ReadMember(*pbrSpecularGlossiness, "specularFactor", this->pbrSpecularGlossiness.specularFactor); - ReadMember(*pbrSpecularGlossiness, "glossinessFactor", this->pbrSpecularGlossiness.glossinessFactor); + ReadMember(*pbrSpecularGlossiness, "diffuseFactor", pbrSG.diffuseFactor); + ReadTextureProperty(r, *pbrSpecularGlossiness, "diffuseTexture", pbrSG.diffuseTexture); + ReadTextureProperty(r, *pbrSpecularGlossiness, "specularGlossinessTexture", pbrSG.specularGlossinessTexture); + ReadMember(*pbrSpecularGlossiness, "specularFactor", pbrSG.specularFactor); + ReadMember(*pbrSpecularGlossiness, "glossinessFactor", pbrSG.glossinessFactor); + + this->pbrSpecularGlossiness = Nullable(pbrSG); } } } @@ -821,11 +823,14 @@ inline void Material::SetDefaults() alphaMode = "OPAQUE"; alphaCutoff = 0.5; doubleSided = false; +} +inline void PbrSpecularGlossiness::SetDefaults() +{ //pbrSpecularGlossiness properties - SetVector(pbrSpecularGlossiness.diffuseFactor, defaultDiffuseFactor); - SetVector(pbrSpecularGlossiness.specularFactor, defaultSpecularFactor); - pbrSpecularGlossiness.glossinessFactor = 1.0; + SetVector(diffuseFactor, defaultDiffuseFactor); + SetVector(specularFactor, defaultSpecularFactor); + glossinessFactor = 1.0; } namespace { diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index 475c7a0d9..ad68a14e1 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -324,22 +324,23 @@ namespace glTF2 { Value exts; exts.SetObject(); - if (m.pbrSpecularGlossiness.on) { + if (m.pbrSpecularGlossiness.isPresent) { Value pbrSpecularGlossiness; pbrSpecularGlossiness.SetObject(); - { - //pbrSpecularGlossiness - WriteVec(pbrSpecularGlossiness, m.pbrSpecularGlossiness.diffuseFactor, "diffuseFactor", defaultDiffuseFactor, w.mAl); - WriteVec(pbrSpecularGlossiness, m.pbrSpecularGlossiness.specularFactor, "specularFactor", defaultSpecularFactor, w.mAl); - if (m.pbrSpecularGlossiness.glossinessFactor != 1) { - WriteFloat(obj, m.pbrSpecularGlossiness.glossinessFactor, "glossinessFactor", w.mAl); - } + PbrSpecularGlossiness &pbrSG = m.pbrSpecularGlossiness.value; - WriteTex(pbrSpecularGlossiness, m.pbrSpecularGlossiness.diffuseTexture, "diffuseTexture", w.mAl); - WriteTex(pbrSpecularGlossiness, m.pbrSpecularGlossiness.specularGlossinessTexture, "specularGlossinessTexture", w.mAl); + //pbrSpecularGlossiness + WriteVec(pbrSpecularGlossiness, pbrSG.diffuseFactor, "diffuseFactor", defaultDiffuseFactor, w.mAl); + WriteVec(pbrSpecularGlossiness, pbrSG.specularFactor, "specularFactor", defaultSpecularFactor, w.mAl); + + if (pbrSG.glossinessFactor != 1) { + WriteFloat(obj, pbrSG.glossinessFactor, "glossinessFactor", w.mAl); } + WriteTex(pbrSpecularGlossiness, pbrSG.diffuseTexture, "diffuseTexture", w.mAl); + WriteTex(pbrSpecularGlossiness, pbrSG.specularGlossinessTexture, "specularGlossinessTexture", w.mAl); + if (!pbrSpecularGlossiness.ObjectEmpty()) { exts.AddMember("KHR_materials_pbrSpecularGlossiness", pbrSpecularGlossiness, w.mAl); } diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 073309b06..600e2b3d4 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -439,12 +439,15 @@ void glTF2Exporter::ExportMaterials() KHR_materials_pbrSpecularGlossiness = true; } - m->pbrSpecularGlossiness.on = true; - GetMatColor(mat, m->pbrSpecularGlossiness.diffuseFactor, "$clr.diffuse", 0, 1); - GetMatColor(mat, m->pbrSpecularGlossiness.specularFactor, "$clr.specular", 0, 1); - mat->Get("$mat.gltf.glossinessFactor", 0, 0, m->pbrSpecularGlossiness.glossinessFactor); - GetMatTex(mat, m->pbrSpecularGlossiness.diffuseTexture, aiTextureType_DIFFUSE, 1); - GetMatTex(mat, m->pbrSpecularGlossiness.specularGlossinessTexture, aiTextureType_UNKNOWN, 1); + PbrSpecularGlossiness pbrSG; + + GetMatColor(mat, pbrSG.diffuseFactor, "$clr.diffuse", 0, 1); + GetMatColor(mat, pbrSG.specularFactor, "$clr.specular", 0, 1); + mat->Get("$mat.gltf.glossinessFactor", 0, 0, pbrSG.glossinessFactor); + GetMatTex(mat, pbrSG.diffuseTexture, aiTextureType_DIFFUSE, 1); + GetMatTex(mat, pbrSG.specularGlossinessTexture, aiTextureType_UNKNOWN, 1); + + m->pbrSpecularGlossiness = Nullable(pbrSG); } } } diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 82ea5f3e7..ff806257f 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -249,13 +249,13 @@ void glTF2Importer::ImportMaterials(glTF2::Asset& r) aimat->AddProperty(&mat.alphaCutoff, 1, "$mat.gltf.alphaCutoff"); //pbrSpecularGlossiness - if (mat.pbrSpecularGlossiness.on) { - aimat->AddProperty(&mat.pbrSpecularGlossiness.on, 1, "$mat.gltf.pbrSpecularGlossiness.on"); - SetMaterialColorProperty(r, mat.pbrSpecularGlossiness.diffuseFactor, aimat, "$clr.diffuse", 0, 1); - SetMaterialColorProperty(r, mat.pbrSpecularGlossiness.specularFactor, aimat, "$clr.specular", 0, 1); - aimat->AddProperty(&mat.pbrSpecularGlossiness.glossinessFactor, 1, "$mat.gltf.pbrSpecularGlossiness.glossinessFactor"); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrSpecularGlossiness.diffuseTexture, aimat, aiTextureType_DIFFUSE, 1); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrSpecularGlossiness.specularGlossinessTexture, aimat, aiTextureType_UNKNOWN, 1); + if (mat.pbrSpecularGlossiness.isPresent) { + aimat->AddProperty(&mat.pbrSpecularGlossiness.isPresent, 1, "$mat.gltf.pbrSpecularGlossiness.on"); + SetMaterialColorProperty(r, mat.pbrSpecularGlossiness.value.diffuseFactor, aimat, "$clr.diffuse", 0, 1); + SetMaterialColorProperty(r, mat.pbrSpecularGlossiness.value.specularFactor, aimat, "$clr.specular", 0, 1); + aimat->AddProperty(&mat.pbrSpecularGlossiness.value.glossinessFactor, 1, "$mat.gltf.pbrSpecularGlossiness.glossinessFactor"); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrSpecularGlossiness.value.diffuseTexture, aimat, aiTextureType_DIFFUSE, 1); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrSpecularGlossiness.value.specularGlossinessTexture, aimat, aiTextureType_UNKNOWN, 1); } } } From 54dd4804cda6f5f6a6e08781ee4e42325f12755a Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Tue, 5 Sep 2017 16:39:34 -0400 Subject: [PATCH 42/90] Fix indentation --- code/glTF2Importer.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index ff806257f..742088042 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -306,7 +306,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r) for (unsigned int m = 0; m < r.meshes.Size(); ++m) { Mesh& mesh = r.meshes[m]; - meshOffsets.push_back(k); + meshOffsets.push_back(k); k += unsigned(mesh.primitives.size()); for (unsigned int p = 0; p < mesh.primitives.size(); ++p) { @@ -339,16 +339,17 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r) case PrimitiveMode_TRIANGLE_FAN: aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; break; + } Mesh::Primitive::Attributes& attr = prim.attributes; - if (attr.position.size() > 0 && attr.position[0]) { + if (attr.position.size() > 0 && attr.position[0]) { aim->mNumVertices = attr.position[0]->count; attr.position[0]->ExtractData(aim->mVertices); - } + } - if (attr.normal.size() > 0 && attr.normal[0]) attr.normal[0]->ExtractData(aim->mNormals); + if (attr.normal.size() > 0 && attr.normal[0]) attr.normal[0]->ExtractData(aim->mNormals); for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) { attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]); @@ -362,7 +363,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r) if (prim.indices) { - aiFace* faces = 0; + aiFace* faces = 0; unsigned int nFaces = 0; unsigned int count = prim.indices->count; @@ -638,7 +639,7 @@ void glTF2Importer::InternReadFile(const std::string& pFile, aiScene* pScene, IO // TODO: it does not split the loaded vertices, should it? //pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT; - MakeVerboseFormatProcess process; + MakeVerboseFormatProcess process; process.Execute(pScene); From 3ba00ca4219ea12fdcab9f20c32720cb533b26b2 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Tue, 5 Sep 2017 18:04:09 -0400 Subject: [PATCH 43/90] Define gltf material property names as constants --- code/glTF2Asset.h | 26 +++++++++++++++++++++++++- code/glTF2Exporter.cpp | 30 +++++++++++++++--------------- code/glTF2Importer.cpp | 36 ++++++++++++++++++------------------ 3 files changed, 58 insertions(+), 34 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 07f8614ab..b4369fe71 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -163,7 +163,31 @@ namespace glTF2 //! Magic number for GLB files - #define AI_GLB_MAGIC_NUMBER "glTF" + #define AI_GLB_MAGIC_NUMBER "glTF" + + #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0,0 + #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0 + #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 0 + #define AI_MATKEY_GLTF_ALPHAMODE "$mat.gltf.alphaMode", 0, 0 + #define AI_MATKEY_GLTF_ALPHACUTOFF "$mat.gltf.alphaCutoff", 0, 0 + #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0 + #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_DIFFUSE_FACTOR "$clr.diffuse", 0, 1 + #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_SPECULAR_FACTOR "$clr.specular", 0, 1 + #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0,0 + #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_DIFFUSE_TEXTURE aiTextureType_DIFFUSE, 1 + #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_SPECULARGLOSSINESS_TEXTURE aiTextureType_UNKNOWN, 1 + + #define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE (std::string(_AI_MATKEY_TEXTURE_BASE) + ".texCoord").c_str() + #define _AI_MATKEY_GLTF_MAPPINGNAME_BASE (std::string(_AI_MATKEY_MAPPING_BASE) + "name").c_str() + #define _AI_MATKEY_GLTF_MAPPINGID_BASE (std::string(_AI_MATKEY_MAPPING_BASE) + "id").c_str() + #define _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermag").c_str() + #define _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermin").c_str() + + #define AI_MATKEY_GLTF_TEXTURE_TEXCOORD _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, type, N + #define AI_MATKEY_GLTF_MAPPINGNAME(type, N) _AI_MATKEY_GLTF_MAPPINGNAME_BASE, type, N + #define AI_MATKEY_GLTF_MAPPINGID(type, N) _AI_MATKEY_GLTF_MAPPINGID_BASE, type, N + #define AI_MATKEY_GLTF_MAPPINGFILTER_MAG(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE, type, N + #define AI_MATKEY_GLTF_MAPPINGFILTER_MIN(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE, type, N #ifdef ASSIMP_API #include "./../include/assimp/Compiler/pushpack1.h" diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 600e2b3d4..931e491e3 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -244,7 +244,7 @@ void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref texture, a { aiString aId; std::string id; - if (aiGetMaterialString(mat, (std::string(_AI_MATKEY_MAPPING_BASE) + "id").c_str(), tt, slot, &aId) == AI_SUCCESS) { + if (aiGetMaterialString(mat, AI_MATKEY_GLTF_MAPPINGID(tt, slot), &aId) == AI_SUCCESS) { id = aId.C_Str(); } @@ -267,16 +267,16 @@ void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref texture, a SetSamplerWrap(texture->sampler->wrapT, mapV); } - if (aiGetMaterialInteger(mat, (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermag").c_str(), tt, slot, (int*)&filterMag) == AI_SUCCESS) { + if (aiGetMaterialInteger(mat, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(tt, slot), (int*)&filterMag) == AI_SUCCESS) { texture->sampler->magFilter = filterMag; } - if (aiGetMaterialInteger(mat, (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermin").c_str(), tt, slot, (int*)&filterMin) == AI_SUCCESS) { + if (aiGetMaterialInteger(mat, AI_MATKEY_GLTF_MAPPINGFILTER_MIN(tt, slot), (int*)&filterMin) == AI_SUCCESS) { texture->sampler->minFilter = filterMin; } aiString name; - if (aiGetMaterialString(mat, (std::string(_AI_MATKEY_MAPPING_BASE) + "name").c_str(), tt, slot, &name) == AI_SUCCESS) { + if (aiGetMaterialString(mat, AI_MATKEY_GLTF_MAPPINGNAME(tt, slot), &name) == AI_SUCCESS) { texture->sampler->name = name.C_Str(); } } @@ -416,10 +416,10 @@ void glTF2Exporter::ExportMaterials() m->name = name; GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_DIFFUSE); - GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, aiTextureType_UNKNOWN, 0);//get unknown slot + GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE); GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE); - mat->Get("$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0, m->pbrMetallicRoughness.metallicFactor); - mat->Get("$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0, m->pbrMetallicRoughness.roughnessFactor); + mat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR, m->pbrMetallicRoughness.metallicFactor); + mat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR, m->pbrMetallicRoughness.roughnessFactor); GetMatTex(mat, m->normalTexture, aiTextureType_NORMALS); GetMatTex(mat, m->occlusionTexture, aiTextureType_LIGHTMAP); @@ -427,11 +427,11 @@ void glTF2Exporter::ExportMaterials() GetMatColor(mat, m->emissiveFactor, AI_MATKEY_COLOR_EMISSIVE); mat->Get(AI_MATKEY_TWOSIDED, m->doubleSided); - mat->Get("$mat.gltf.alphaCutoff", 0, 0, m->alphaCutoff); - mat->Get("$mat.gltf.alphaMode", 0, 0, m->alphaMode); + mat->Get(AI_MATKEY_GLTF_ALPHACUTOFF, m->alphaCutoff); + mat->Get(AI_MATKEY_GLTF_ALPHAMODE, m->alphaMode); bool hasPbrSpecularGlossiness; - mat->Get("$mat.gltf.pbrSpecularGlossiness.on", 0, 0, hasPbrSpecularGlossiness); + mat->Get(AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS, hasPbrSpecularGlossiness); if (hasPbrSpecularGlossiness) { @@ -441,11 +441,11 @@ void glTF2Exporter::ExportMaterials() PbrSpecularGlossiness pbrSG; - GetMatColor(mat, pbrSG.diffuseFactor, "$clr.diffuse", 0, 1); - GetMatColor(mat, pbrSG.specularFactor, "$clr.specular", 0, 1); - mat->Get("$mat.gltf.glossinessFactor", 0, 0, pbrSG.glossinessFactor); - GetMatTex(mat, pbrSG.diffuseTexture, aiTextureType_DIFFUSE, 1); - GetMatTex(mat, pbrSG.specularGlossinessTexture, aiTextureType_UNKNOWN, 1); + GetMatColor(mat, pbrSG.diffuseFactor, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_DIFFUSE_FACTOR); + GetMatColor(mat, pbrSG.specularFactor, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_SPECULAR_FACTOR); + mat->Get(AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR, pbrSG.glossinessFactor); + GetMatTex(mat, pbrSG.diffuseTexture, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_DIFFUSE_TEXTURE); + GetMatTex(mat, pbrSG.specularGlossinessTexture, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_SPECULARGLOSSINESS_TEXTURE); m->pbrSpecularGlossiness = Nullable(pbrSG); } diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 742088042..860974243 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -190,9 +190,7 @@ inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& } mat->AddProperty(&uri, AI_MATKEY_TEXTURE(texType, texSlot)); - - const char *texCoordName = (std::string(_AI_MATKEY_TEXTURE_BASE) + ".texCoord").c_str(); - mat->AddProperty(&prop.texCoord, 1, texCoordName, texType, texSlot); + mat->AddProperty(&prop.texCoord, 1, _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, texType, texSlot); if (prop.texture->sampler) { Ref sampler = prop.texture->sampler; @@ -200,18 +198,18 @@ inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& aiString name(sampler->name); aiString id(sampler->id); - mat->AddProperty(&name, (std::string(_AI_MATKEY_MAPPING_BASE) + "name").c_str(), texType, texSlot); - mat->AddProperty(&id, (std::string(_AI_MATKEY_MAPPING_BASE) + "id").c_str(), texType, texSlot); + mat->AddProperty(&name, AI_MATKEY_GLTF_MAPPINGNAME(texType, texSlot)); + mat->AddProperty(&id, AI_MATKEY_GLTF_MAPPINGID(texType, texSlot)); mat->AddProperty(&sampler->wrapS, 1, AI_MATKEY_MAPPINGMODE_U(texType, texSlot)); mat->AddProperty(&sampler->wrapT, 1, AI_MATKEY_MAPPINGMODE_V(texType, texSlot)); if (sampler->magFilter != SamplerMagFilter::UNSET) { - mat->AddProperty(&sampler->magFilter, 1, (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermag").c_str(), texType, texSlot); + mat->AddProperty(&sampler->magFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(texType, texSlot)); } if (sampler->minFilter != SamplerMinFilter::UNSET) { - mat->AddProperty(&sampler->minFilter, 1, (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermin").c_str(), texType, texSlot); + mat->AddProperty(&sampler->minFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MIN(texType, texSlot)); } } } @@ -235,9 +233,9 @@ void glTF2Importer::ImportMaterials(glTF2::Asset& r) SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, aiTextureType_UNKNOWN); - aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, "$mat.gltf.pbrMetallicRoughness.metallicFactor"); - aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, "$mat.gltf.pbrMetallicRoughness.roughnessFactor"); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE); + aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR); + aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR); SetMaterialTextureProperty(embeddedTexIdxs, r, mat.normalTexture, aimat, aiTextureType_NORMALS); SetMaterialTextureProperty(embeddedTexIdxs, r, mat.occlusionTexture, aimat, aiTextureType_LIGHTMAP); @@ -245,17 +243,19 @@ void glTF2Importer::ImportMaterials(glTF2::Asset& r) SetMaterialColorProperty(r, mat.emissiveFactor, aimat, AI_MATKEY_COLOR_EMISSIVE); aimat->AddProperty(&mat.doubleSided, 1, AI_MATKEY_TWOSIDED); - aimat->AddProperty(&mat.alphaMode, 1, "$mat.gltf.alphaMode"); - aimat->AddProperty(&mat.alphaCutoff, 1, "$mat.gltf.alphaCutoff"); + aimat->AddProperty(&mat.alphaMode, 1, AI_MATKEY_GLTF_ALPHAMODE); + aimat->AddProperty(&mat.alphaCutoff, 1, AI_MATKEY_GLTF_ALPHACUTOFF); //pbrSpecularGlossiness if (mat.pbrSpecularGlossiness.isPresent) { - aimat->AddProperty(&mat.pbrSpecularGlossiness.isPresent, 1, "$mat.gltf.pbrSpecularGlossiness.on"); - SetMaterialColorProperty(r, mat.pbrSpecularGlossiness.value.diffuseFactor, aimat, "$clr.diffuse", 0, 1); - SetMaterialColorProperty(r, mat.pbrSpecularGlossiness.value.specularFactor, aimat, "$clr.specular", 0, 1); - aimat->AddProperty(&mat.pbrSpecularGlossiness.value.glossinessFactor, 1, "$mat.gltf.pbrSpecularGlossiness.glossinessFactor"); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrSpecularGlossiness.value.diffuseTexture, aimat, aiTextureType_DIFFUSE, 1); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrSpecularGlossiness.value.specularGlossinessTexture, aimat, aiTextureType_UNKNOWN, 1); + PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value; + + aimat->AddProperty(&mat.pbrSpecularGlossiness.isPresent, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS); + SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_DIFFUSE_FACTOR); + SetMaterialColorProperty(r, pbrSG.specularFactor, aimat, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_SPECULAR_FACTOR); + aimat->AddProperty(&pbrSG.glossinessFactor, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR); + SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.diffuseTexture, aimat, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_DIFFUSE_TEXTURE); + SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.specularGlossinessTexture, aimat, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_SPECULARGLOSSINESS_TEXTURE); } } } From da6a252efbb433e25d61e0dbdae9873d3829da76 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Tue, 5 Sep 2017 18:06:59 -0400 Subject: [PATCH 44/90] Fix METALLIC_FACTOR typo --- code/glTF2Asset.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index b4369fe71..d894e9473 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -166,7 +166,7 @@ namespace glTF2 #define AI_GLB_MAGIC_NUMBER "glTF" #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0,0 - #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0 + #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0 #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 0 #define AI_MATKEY_GLTF_ALPHAMODE "$mat.gltf.alphaMode", 0, 0 #define AI_MATKEY_GLTF_ALPHACUTOFF "$mat.gltf.alphaCutoff", 0, 0 From 37582131f494babbf3ad4ba878796fb0384dc085 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Wed, 6 Sep 2017 14:16:52 -0400 Subject: [PATCH 45/90] =?UTF-8?q?Set=20the=20metallicFactor=20to=200=20if?= =?UTF-8?q?=20source=20file=20doesn=E2=80=99t=20have=20metallicFactor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise, the models have full metallic materials and appear very dim --- code/glTF2Exporter.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 931e491e3..a5c74fd46 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -418,7 +418,12 @@ void glTF2Exporter::ExportMaterials() GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_DIFFUSE); GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE); GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE); - mat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR, m->pbrMetallicRoughness.metallicFactor); + + if (mat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR, m->pbrMetallicRoughness.metallicFactor) != AI_SUCCESS) { + //if metallicFactor wasn't defined, then the source is likely not a PBR file, and the metallicFactor should be 0 + m->pbrMetallicRoughness.metallicFactor = 0; + } + mat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR, m->pbrMetallicRoughness.roughnessFactor); GetMatTex(mat, m->normalTexture, aiTextureType_NORMALS); From 0a8183531e0fc43780e51008c04bb2d34ecb5eb5 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Wed, 6 Sep 2017 14:17:24 -0400 Subject: [PATCH 46/90] =?UTF-8?q?Set=20alphaMode,=20baseColorFactor=20opac?= =?UTF-8?q?ity=20when=20model=E2=80=99s=20opacity=20isn=E2=80=99t=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/glTF2Exporter.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index a5c74fd46..9130c750c 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -433,7 +433,17 @@ void glTF2Exporter::ExportMaterials() mat->Get(AI_MATKEY_TWOSIDED, m->doubleSided); mat->Get(AI_MATKEY_GLTF_ALPHACUTOFF, m->alphaCutoff); - mat->Get(AI_MATKEY_GLTF_ALPHAMODE, m->alphaMode); + + if (mat->Get(AI_MATKEY_GLTF_ALPHAMODE, m->alphaMode) != AI_SUCCESS) { + float opacity; + + if (mat->Get(AI_MATKEY_OPACITY, opacity) == AI_SUCCESS) { + if (opacity < 1) { + m->alphaMode = "MASK"; + m->pbrMetallicRoughness.baseColorFactor[3] *= opacity; + } + } + } bool hasPbrSpecularGlossiness; mat->Get(AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS, hasPbrSpecularGlossiness); From a5e8e0b2bd8fbdd625920ccf448d9475f327fed5 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Wed, 6 Sep 2017 14:17:37 -0400 Subject: [PATCH 47/90] Remove commented out code --- code/glTF2Asset.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index d894e9473..12cad25ba 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -717,13 +717,6 @@ namespace glTF2 float strength = 1; }; - //! Holds a material property that can be a texture or a color (fallback for glTF 1) - /*struct FallbackTexProperty - { - Ref texture; - vec4 color; - };*/ - struct PbrMetallicRoughness { vec4 baseColorFactor; From 2ee7991558be791115087670026b9039cfac6bff Mon Sep 17 00:00:00 2001 From: John Senneker Date: Wed, 6 Sep 2017 14:49:25 -0400 Subject: [PATCH 48/90] Restrict search for OFF header to first 3 bytes --- code/OFFLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/OFFLoader.cpp b/code/OFFLoader.cpp index 2723beb0e..5038176e2 100644 --- a/code/OFFLoader.cpp +++ b/code/OFFLoader.cpp @@ -94,7 +94,7 @@ bool OFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool { if (!pIOHandler)return true; const char* tokens[] = {"off"}; - return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1); + return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1,3); } return false; } From 19876e98227ebf3a76ad994cd1f190c1b382ca82 Mon Sep 17 00:00:00 2001 From: John Senneker Date: Wed, 6 Sep 2017 14:50:02 -0400 Subject: [PATCH 49/90] Add support for importing both glTF and glTF2 files --- code/ImporterRegistry.cpp | 2 ++ code/glTF2Importer.cpp | 28 ++++++++++++---------------- code/glTFAsset.inl | 4 ---- code/glTFImporter.cpp | 26 ++++++++++---------------- 4 files changed, 24 insertions(+), 36 deletions(-) diff --git a/code/ImporterRegistry.cpp b/code/ImporterRegistry.cpp index 2b5d9c1a0..b4d2c3dcf 100644 --- a/code/ImporterRegistry.cpp +++ b/code/ImporterRegistry.cpp @@ -181,6 +181,7 @@ corresponding preprocessor flag to selectively disable formats. # include "AssbinLoader.h" #endif #ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER +# include "glTFImporter.h" # include "glTF2Importer.h" #endif #ifndef ASSIMP_BUILD_NO_C4D_IMPORTER @@ -335,6 +336,7 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out) out.push_back( new AssbinImporter() ); #endif #if ( !defined ASSIMP_BUILD_NO_GLTF_IMPORTER ) + out.push_back( new glTFImporter() ); out.push_back( new glTF2Importer() ); #endif #if ( !defined ASSIMP_BUILD_NO_C4D_IMPORTER ) diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 860974243..1ab23fd18 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -58,6 +58,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "glTF2Asset.h" // This is included here so WriteLazyDict's definition is found. #include "glTF2AssetWriter.h" +#include +#include using namespace Assimp; using namespace glTF2; @@ -100,24 +102,18 @@ const aiImporterDesc* glTF2Importer::GetInfo() const bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const { - const std::string& extension = GetExtension(pFile); + const std::string &extension = GetExtension(pFile); - if (extension == "gltf" || extension == "glb") - return true; + if (extension != "gltf") // We currently can't read glTF2 binary files (.glb) + return false; - if ((checkSig || !extension.length()) && pIOHandler) { - char buffer[4]; - - std::unique_ptr pStream(pIOHandler->Open(pFile)); - if (pStream && pStream->Read(buffer, sizeof(buffer), 1) == 1) { - if (memcmp(buffer, AI_GLB_MAGIC_NUMBER, sizeof(buffer)) == 0) { - return true; // Has GLB header - } - else if (memcmp(buffer, "{\r\n ", sizeof(buffer)) == 0 - || memcmp(buffer, "{\n ", sizeof(buffer)) == 0) { - // seems a JSON file, and we're the only format that can read them - return true; - } + if (checkSig && pIOHandler) { + glTF2::Asset asset(pIOHandler); + try { + asset.Load(pFile, extension == "glb"); + return asset.asset.version >= 2; + } catch (...) { + return false; } } diff --git a/code/glTFAsset.inl b/code/glTFAsset.inl index 91d36c59b..32fe77288 100644 --- a/code/glTFAsset.inl +++ b/code/glTFAsset.inl @@ -1243,10 +1243,6 @@ inline void AssetMetadata::Read(Document& doc) } version = std::max(statedVersion, version); - if (version == 0) { - // if missing version, we'll assume version 1... - version = 1; - } if (version != 1) { char msg[128]; diff --git a/code/glTFImporter.cpp b/code/glTFImporter.cpp index 0ded26294..6dbeb7e91 100644 --- a/code/glTFImporter.cpp +++ b/code/glTFImporter.cpp @@ -100,24 +100,18 @@ const aiImporterDesc* glTFImporter::GetInfo() const bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const { - const std::string& extension = GetExtension(pFile); + const std::string &extension = GetExtension(pFile); - if (extension == "gltf" || extension == "glb") - return true; + if (extension != "gltf" && extension != "glb") + return false; - if ((checkSig || !extension.length()) && pIOHandler) { - char buffer[4]; - - std::unique_ptr pStream(pIOHandler->Open(pFile)); - if (pStream && pStream->Read(buffer, sizeof(buffer), 1) == 1) { - if (memcmp(buffer, AI_GLB_MAGIC_NUMBER, sizeof(buffer)) == 0) { - return true; // Has GLB header - } - else if (memcmp(buffer, "{\r\n ", sizeof(buffer)) == 0 - || memcmp(buffer, "{\n ", sizeof(buffer)) == 0) { - // seems a JSON file, and we're the only format that can read them - return true; - } + if (checkSig && pIOHandler) { + glTF::Asset asset(pIOHandler); + try { + asset.Load(pFile, extension == "glb"); + return asset.asset.version < 2; + } catch (...) { + return false; } } From 140b903d7a062216016597ef30f4885b28e5c767 Mon Sep 17 00:00:00 2001 From: John Senneker Date: Wed, 6 Sep 2017 15:32:44 -0400 Subject: [PATCH 50/90] Fix parsing of glTF version Handle version as int in gltf Fix format specifiers in glTF version parser --- code/glTF2Asset.h | 4 ++-- code/glTF2Asset.inl | 29 ++++++++++++----------------- code/glTF2AssetWriter.inl | 9 ++------- code/glTF2Exporter.cpp | 2 +- code/glTF2Importer.cpp | 3 ++- code/glTFAsset.h | 4 ++-- code/glTFAsset.inl | 29 ++++++++++++++++++++--------- code/glTFAssetWriter.inl | 9 ++------- code/glTFImporter.cpp | 3 ++- 9 files changed, 45 insertions(+), 47 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 12cad25ba..1711b930b 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -1005,13 +1005,13 @@ namespace glTF2 std::string version; //!< Specifies the target rendering API (default: "1.0.3") } profile; //!< Specifies the target rendering API and version, e.g., WebGL 1.0.3. (default: {}) - float version; //!< The glTF format version + std::string version; //!< The glTF format version void Read(Document& doc); AssetMetadata() : premultipliedAlpha(false) - , version(0) + , version("") { } }; diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index e2d812563..bc8261317 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -985,15 +985,21 @@ inline void Scene::Read(Value& obj, Asset& r) inline void AssetMetadata::Read(Document& doc) { - // read the version, etc. - std::string statedVersion; - if (Value* obj = FindObject(doc, "asset")) { ReadMember(*obj, "copyright", copyright); ReadMember(*obj, "generator", generator); premultipliedAlpha = MemberOrDefault(*obj, "premultipliedAlpha", false); - statedVersion = MemberOrDefault(*obj, "version", "0.0"); + + if (Value* versionString = FindString(*obj, "version")) { + version = versionString->GetString(); + } else if (Value* versionNumber = FindNumber (*obj, "version")) { + char buf[4]; + + ai_snprintf(buf, 4, "%.1f", versionNumber->GetDouble()); + + version = buf; + } if (Value* profile = FindObject(*obj, "profile")) { ReadMember(*profile, "api", this->profile.api); @@ -1001,19 +1007,8 @@ inline void AssetMetadata::Read(Document& doc) } } - float statedFloatVersion = std::strtof(statedVersion.c_str(), 0); - - version = std::max(statedFloatVersion, version); - - if (version == 0) { - // if missing version, we'll assume version 2.0... - version = 2; - } - - if (version != 2) { - char msg[128]; - ai_snprintf(msg, 128, "GLTF: Unsupported glTF version: %.1f", version); - throw DeadlyImportError(msg); + if (version.empty() || version[0] != '2') { + throw DeadlyImportError("GLTF: Unsupported glTF version: " + version); } } diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index ad68a14e1..1665bee02 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -652,13 +652,8 @@ namespace glTF2 { { Value asset; asset.SetObject(); - { - char versionChar[10]; - ai_snprintf(versionChar, sizeof(versionChar), "%.1f", mAsset.asset.version); - asset.AddMember("version", Value(versionChar, mAl).Move(), mAl); - - asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl); - } + asset.AddMember("version", Value(mAsset.asset.version, mAl).Move(), mAl); + asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl); mDoc.AddMember("asset", asset, mAl); } diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 9130c750c..f3e083543 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -811,7 +811,7 @@ void glTF2Exporter::ExportScene() void glTF2Exporter::ExportMetadata() { AssetMetadata& asset = mAsset->asset; - asset.version = 2; + asset.version = "2.0"; char buffer[256]; ai_snprintf(buffer, 256, "Open Asset Import Library (assimp v%d.%d.%d)", diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 1ab23fd18..34144b9e2 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -111,7 +111,8 @@ bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool glTF2::Asset asset(pIOHandler); try { asset.Load(pFile, extension == "glb"); - return asset.asset.version >= 2; + std::string version = asset.asset.version; + return !version.empty() && version[0] == '2'; } catch (...) { return false; } diff --git a/code/glTFAsset.h b/code/glTFAsset.h index 30d0bc056..60107bee6 100644 --- a/code/glTFAsset.h +++ b/code/glTFAsset.h @@ -1058,13 +1058,13 @@ namespace glTF std::string version; //!< Specifies the target rendering API (default: "1.0.3") } profile; //!< Specifies the target rendering API and version, e.g., WebGL 1.0.3. (default: {}) - float version; //!< The glTF format version (should be 1.0) + std::string version; //!< The glTF format version (should be 1.0) void Read(Document& doc); AssetMetadata() : premultipliedAlpha(false) - , version(0) + , version("") { } }; diff --git a/code/glTFAsset.inl b/code/glTFAsset.inl index 32fe77288..bb4bb50aa 100644 --- a/code/glTFAsset.inl +++ b/code/glTFAsset.inl @@ -40,6 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "StringUtils.h" +#include // Header files, Assimp #include @@ -128,6 +129,12 @@ namespace { return (it != val.MemberEnd() && it->value.IsString()) ? &it->value : 0; } + inline Value* FindNumber(Value& val, const char* id) + { + Value::MemberIterator it = val.FindMember(id); + return (it != val.MemberEnd() && it->value.IsNumber()) ? &it->value : 0; + } + inline Value* FindArray(Value& val, const char* id) { Value::MemberIterator it = val.FindMember(id); @@ -1228,13 +1235,21 @@ inline void Scene::Read(Value& obj, Asset& r) inline void AssetMetadata::Read(Document& doc) { // read the version, etc. - float statedVersion = 0; if (Value* obj = FindObject(doc, "asset")) { ReadMember(*obj, "copyright", copyright); ReadMember(*obj, "generator", generator); premultipliedAlpha = MemberOrDefault(*obj, "premultipliedAlpha", false); - statedVersion = MemberOrDefault(*obj, "version", 0); + + if (Value* versionString = FindString(*obj, "version")) { + version = versionString->GetString(); + } else if (Value* versionNumber = FindNumber (*obj, "version")) { + char buf[4]; + + ai_snprintf(buf, 4, "%.1f", versionNumber->GetDouble()); + + version = buf; + } if (Value* profile = FindObject(*obj, "profile")) { ReadMember(*profile, "api", this->profile.api); @@ -1242,12 +1257,8 @@ inline void AssetMetadata::Read(Document& doc) } } - version = std::max(statedVersion, version); - - if (version != 1) { - char msg[128]; - ai_snprintf(msg, 128, "GLTF: Unsupported glTF version: %.0f", version); - throw DeadlyImportError(msg); + if (version.empty() || version[0] != '1') { + throw DeadlyImportError("GLTF: Unsupported glTF version: " + version); } } @@ -1269,7 +1280,7 @@ inline void Asset::ReadBinaryHeader(IOStream& stream) } AI_SWAP4(header.version); - asset.version = header.version; + asset.version = std::to_string(header.version); if (header.version != 1) { throw DeadlyImportError("GLTF: Unsupported binary glTF version"); } diff --git a/code/glTFAssetWriter.inl b/code/glTFAssetWriter.inl index 166b84fd1..698f0ba8f 100644 --- a/code/glTFAssetWriter.inl +++ b/code/glTFAssetWriter.inl @@ -606,13 +606,8 @@ namespace glTF { { Value asset; asset.SetObject(); - { - char versionChar[10]; - ai_snprintf(versionChar, sizeof(versionChar), "%.0f", mAsset.asset.version); - asset.AddMember("version", Value(versionChar, mAl).Move(), mAl); - - asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl); - } + asset.AddMember("version", Value(mAsset.asset.version, mAl).Move(), mAl); + asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl); mDoc.AddMember("asset", asset, mAl); } diff --git a/code/glTFImporter.cpp b/code/glTFImporter.cpp index 6dbeb7e91..1b5c953be 100644 --- a/code/glTFImporter.cpp +++ b/code/glTFImporter.cpp @@ -109,7 +109,8 @@ bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool glTF::Asset asset(pIOHandler); try { asset.Load(pFile, extension == "glb"); - return asset.asset.version < 2; + std::string version = asset.asset.version; + return !version.empty() && version[0] == '1'; } catch (...) { return false; } From a438ece655ced52835bda0dcb492cab8394de14f Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Wed, 6 Sep 2017 23:43:43 -0400 Subject: [PATCH 51/90] Remove premultipliedAlpha from gltf2 --- code/glTF2Asset.h | 7 +------ code/glTF2Asset.inl | 2 -- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 1711b930b..8b226dacb 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -998,7 +998,6 @@ namespace glTF2 { std::string copyright; //!< A copyright message suitable for display to credit the content creator. std::string generator; //!< Tool that generated this glTF model.Useful for debugging. - bool premultipliedAlpha; //!< Specifies if the shaders were generated with premultiplied alpha. (default: false) struct { std::string api; //!< Specifies the target rendering API (default: "WebGL") @@ -1009,11 +1008,7 @@ namespace glTF2 void Read(Document& doc); - AssetMetadata() - : premultipliedAlpha(false) - , version("") - { - } + AssetMetadata() : version("") {} }; // diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index bc8261317..3d4a4ee42 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -989,8 +989,6 @@ inline void AssetMetadata::Read(Document& doc) ReadMember(*obj, "copyright", copyright); ReadMember(*obj, "generator", generator); - premultipliedAlpha = MemberOrDefault(*obj, "premultipliedAlpha", false); - if (Value* versionString = FindString(*obj, "version")) { version = versionString->GetString(); } else if (Value* versionNumber = FindNumber (*obj, "version")) { From 5cb13aa4b3b4dc282ed970ffd57238b823492f47 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Thu, 7 Sep 2017 14:55:44 -0400 Subject: [PATCH 52/90] Load gltf .bin files from correct directory --- code/glTF2Asset.inl | 4 +++- code/glTFAsset.inl | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 3d4a4ee42..03c2279e8 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -337,7 +337,9 @@ inline void Buffer::Read(Value& obj, Asset& r) } else { // Local file if (byteLength > 0) { - IOStream* file = r.OpenFile(uri, "rb"); + std::string dir = !r.mCurrentAssetDir.empty() ? (r.mCurrentAssetDir + "/") : ""; + + IOStream* file = r.OpenFile(dir + uri, "rb"); if (file) { bool ok = LoadFromStream(*file, byteLength); delete file; diff --git a/code/glTFAsset.inl b/code/glTFAsset.inl index bb4bb50aa..9284ccb02 100644 --- a/code/glTFAsset.inl +++ b/code/glTFAsset.inl @@ -316,7 +316,9 @@ inline void Buffer::Read(Value& obj, Asset& r) } else { // Local file if (byteLength > 0) { - IOStream* file = r.OpenFile(uri, "rb"); + std::string dir = !r.mCurrentAssetDir.empty() ? (r.mCurrentAssetDir + "/") : ""; + + IOStream* file = r.OpenFile(dir + uri, "rb"); if (file) { bool ok = LoadFromStream(*file, byteLength); delete file; From d518289e7217f1966b8abd33bd574943781fab31 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Thu, 7 Sep 2017 15:48:11 -0400 Subject: [PATCH 53/90] more specific token search for Collada Loader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit collada can appear in many files, such as glTFs via the “generator” field (in the form of collada2gltf) --- code/ColladaLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ColladaLoader.cpp b/code/ColladaLoader.cpp index f7ef903f4..0e970b468 100644 --- a/code/ColladaLoader.cpp +++ b/code/ColladaLoader.cpp @@ -119,7 +119,7 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo * might be NULL and it's our duty to return true here. */ if (!pIOHandler)return true; - const char* tokens[] = {"collada"}; + const char* tokens[] = {" Date: Thu, 7 Sep 2017 15:50:35 -0400 Subject: [PATCH 54/90] Add gltf2 basic unit test --- test/CMakeLists.txt | 5 ++- test/unit/utglTF2ImportExport.cpp | 75 +++++++++++++++++++++++++++++++ test/unit/utglTFImportExport.cpp | 2 +- 3 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 test/unit/utglTF2ImportExport.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index cb559deb3..3520f9782 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -65,7 +65,7 @@ SET( TEST_SRCS unit/ut3DSImportExport.cpp unit/utACImportExport.cpp unit/utAMFImportExport.cpp - unit/utASEImportExport.cpp + unit/utASEImportExport.cpp unit/utAnim.cpp unit/AssimpAPITest.cpp unit/utB3DImportExport.cpp @@ -88,6 +88,7 @@ SET( TEST_SRCS unit/utFixInfacingNormals.cpp unit/utGenNormals.cpp unit/utglTFImportExport.cpp + unit/utglTF2ImportExport.cpp unit/utHMPImportExport.cpp unit/utIFCImportExport.cpp unit/utImporter.cpp @@ -146,7 +147,7 @@ add_executable( unit ) add_definitions(-DASSIMP_TEST_MODELS_DIR="${CMAKE_CURRENT_LIST_DIR}/models") - + SET_PROPERTY( TARGET assimp PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX} ) IF( WIN32 ) diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp new file mode 100644 index 000000000..09c43131d --- /dev/null +++ b/test/unit/utglTF2ImportExport.cpp @@ -0,0 +1,75 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2017, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ +#include "UnitTestPCH.h" +#include "AbstractImportExportBase.h" + +#include +#include + +using namespace Assimp; + +class utglTF2ImportExport : public AbstractImportExportBase { +public: + virtual bool importerTest() { + Assimp::Importer importer; + const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured.gltf", 0); + return nullptr != scene; + } + + virtual bool exporterTest() { + Assimp::Importer importer; + Assimp::Exporter exporter; + const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured.gltf", 0 ); + EXPECT_NE( nullptr, scene ); + EXPECT_EQ( aiReturn_SUCCESS, exporter.Export( scene, "gltf2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured_out.gltf" ) ); + + return true; + } +}; + +TEST_F( utglTF2ImportExport, importglTF2FromFileTest ) { + EXPECT_TRUE( importerTest() ); +} + +TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) { + EXPECT_TRUE( exporterTest() ); +} diff --git a/test/unit/utglTFImportExport.cpp b/test/unit/utglTFImportExport.cpp index 349dddafa..18c348299 100644 --- a/test/unit/utglTFImportExport.cpp +++ b/test/unit/utglTFImportExport.cpp @@ -55,6 +55,6 @@ public: } }; -TEST_F( utglTFImportExport, importglTFromFileTest ) { +TEST_F( utglTFImportExport, importglTFFromFileTest ) { EXPECT_TRUE( importerTest() ); } From b4f5033d899f443b55d756a65c6369204dfffae1 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Thu, 7 Sep 2017 17:15:05 -0400 Subject: [PATCH 55/90] Remove compresssed file format flag --- code/glTF2Importer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 34144b9e2..d234afab3 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -74,8 +74,7 @@ static const aiImporterDesc desc = { "", "", "", - aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour - | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental, + aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental, 0, 0, 0, From 816e6909ca87dd8f77a8375d3fa38de004371556 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Thu, 7 Sep 2017 17:32:41 -0400 Subject: [PATCH 56/90] Remove KHR_binary_glTF code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Binary glTF is now part of the glTF2 spec. However, it’s implemented incorrectly, so will be temporarily removed --- code/glTF2Asset.h | 21 +-------- code/glTF2Asset.inl | 84 ++---------------------------------- code/glTF2AssetWriter.h | 2 - code/glTF2AssetWriter.inl | 90 +-------------------------------------- code/glTF2Exporter.cpp | 10 +---- code/glTF2Importer.cpp | 11 ++--- 6 files changed, 10 insertions(+), 208 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index 8b226dacb..b093ec027 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * Declares a glTF class to handle gltf/glb files * * glTF Extensions Support: - * KHR_binary_glTF: full * KHR_materials_pbrSpecularGlossiness full */ #ifndef GLTF2ASSET_H_INC @@ -193,17 +192,6 @@ namespace glTF2 #include "./../include/assimp/Compiler/pushpack1.h" #endif - //! For the KHR_binary_glTF extension (binary .glb file) - //! 20-byte header (+ the JSON + a "body" data section) - struct GLB_Header - { - uint8_t magic[4]; //!< Magic number: "glTF" - uint32_t version; //!< Version number - uint32_t length; //!< Total length of the Binary glTF, including header, scene, and body, in bytes - uint32_t sceneLength; //!< Length, in bytes, of the glTF scene - uint32_t sceneFormat; //!< Specifies the format of the glTF scene (see the SceneFormat enum) - } PACK_STRUCT; - #ifdef ASSIMP_API #include "./../include/assimp/Compiler/poppack1.h" #endif @@ -1049,7 +1037,6 @@ namespace glTF2 //! Keeps info about the enabled extensions struct Extensions { - bool KHR_binary_glTF; bool KHR_materials_pbrSpecularGlossiness; } extensionsUsed; @@ -1097,10 +1084,7 @@ namespace glTF2 } //! Main function - void Load(const std::string& file, bool isBinary = false); - - //! Enables the "KHR_binary_glTF" extension on the asset - void SetAsBinary(); + void Load(const std::string& file); //! Search for an available name, starting from the given strings std::string FindUniqueID(const std::string& str, const char* suffix); @@ -1109,11 +1093,8 @@ namespace glTF2 { return mBodyBuffer; } private: - void ReadBinaryHeader(IOStream& stream); - void ReadExtensionsUsed(Document& doc); - IOStream* OpenFile(std::string path, const char* mode, bool absolute = false); }; diff --git a/code/glTF2Asset.inl b/code/glTF2Asset.inl index 03c2279e8..cbdac5d80 100644 --- a/code/glTF2Asset.inl +++ b/code/glTF2Asset.inl @@ -290,11 +290,6 @@ inline Buffer::~Buffer() inline const char* Buffer::TranslateId(Asset& r, const char* id) { - // Compatibility with old spec - if (r.extensionsUsed.KHR_binary_glTF && strcmp(id, "KHR_binary_glTF") == 0) { - return "binary_glTF"; - } - return id; } @@ -630,28 +625,6 @@ inline Image::Image() inline void Image::Read(Value& obj, Asset& r) { - // Check for extensions first (to detect binary embedded data) - if (Value* extensions = FindObject(obj, "extensions")) { - if (r.extensionsUsed.KHR_binary_glTF) { - if (Value* ext = FindObject(*extensions, "KHR_binary_glTF")) { - - width = MemberOrDefault(*ext, "width", 0); - height = MemberOrDefault(*ext, "height", 0); - - ReadMember(*ext, "mimeType", mimeType); - - if (Value* bufferViewVal = FindUInt(*ext, "bufferView")) { - Ref bv = r.bufferViews.Retrieve(bufferViewVal->GetUint()); - if (bv) { - mDataLength = bv->byteLength; - mData = new uint8_t[mDataLength]; - memcpy(mData, bv->buffer->GetPointer() + bv->byteOffset, mDataLength); - } - } - } - } - } - if (!mDataLength) { if (Value* uri = FindString(obj, "uri")) { const char* uristr = uri->GetString(); @@ -1016,40 +989,7 @@ inline void AssetMetadata::Read(Document& doc) // Asset methods implementation // -inline void Asset::ReadBinaryHeader(IOStream& stream) -{ - GLB_Header header; - if (stream.Read(&header, sizeof(header), 1) != 1) { - throw DeadlyImportError("GLTF: Unable to read the file header"); - } - - if (strncmp((char*)header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)) != 0) { - throw DeadlyImportError("GLTF: Invalid binary glTF file"); - } - - AI_SWAP4(header.version); - asset.version = header.version; - if (header.version != 1) { - throw DeadlyImportError("GLTF: Unsupported binary glTF version"); - } - - AI_SWAP4(header.sceneFormat); - if (header.sceneFormat != SceneFormat_JSON) { - throw DeadlyImportError("GLTF: Unsupported binary glTF scene format"); - } - - AI_SWAP4(header.length); - AI_SWAP4(header.sceneLength); - - mSceneLength = static_cast(header.sceneLength); - - mBodyOffset = sizeof(header)+mSceneLength; - mBodyOffset = (mBodyOffset + 3) & ~3; // Round up to next multiple of 4 - - mBodyLength = header.length - mBodyOffset; -} - -inline void Asset::Load(const std::string& pFile, bool isBinary) +inline void Asset::Load(const std::string& pFile) { mCurrentAssetDir.clear(); int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\'))); @@ -1060,16 +1000,8 @@ inline void Asset::Load(const std::string& pFile, bool isBinary) throw DeadlyImportError("GLTF: Could not open file for reading"); } - // is binary? then read the header - if (isBinary) { - SetAsBinary(); // also creates the body buffer - ReadBinaryHeader(*stream); - } - else { - mSceneLength = stream->FileSize(); - mBodyLength = 0; - } - + mSceneLength = stream->FileSize(); + mBodyLength = 0; // read the scene data @@ -1130,15 +1062,6 @@ inline void Asset::Load(const std::string& pFile, bool isBinary) } } -inline void Asset::SetAsBinary() -{ - if (!extensionsUsed.KHR_binary_glTF) { - extensionsUsed.KHR_binary_glTF = true; - mBodyBuffer = buffers.Create("binary_glTF"); - mBodyBuffer->MarkAsSpecial(); - } -} - inline void Asset::ReadExtensionsUsed(Document& doc) { Value* extsUsed = FindArray(doc, "extensionsUsed"); @@ -1155,7 +1078,6 @@ inline void Asset::ReadExtensionsUsed(Document& doc) #define CHECK_EXT(EXT) \ if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true; - CHECK_EXT(KHR_binary_glTF); CHECK_EXT(KHR_materials_pbrSpecularGlossiness); #undef CHECK_EXT diff --git a/code/glTF2AssetWriter.h b/code/glTF2AssetWriter.h index 97efbeab5..bce2b1bd1 100644 --- a/code/glTF2AssetWriter.h +++ b/code/glTF2AssetWriter.h @@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * Declares a class to write gltf/glb files * * glTF Extensions Support: - * KHR_binary_glTF: full * KHR_materials_pbrSpecularGlossiness: full */ #ifndef GLTF2ASSETWRITER_H_INC @@ -82,7 +81,6 @@ public: AssetWriter(Asset& asset); void WriteFile(const char* path); - void WriteGLBFile(const char* path); }; } diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index 1665bee02..e62f2377e 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -179,21 +179,7 @@ namespace glTF2 { inline void Write(Value& obj, Image& img, AssetWriter& w) { std::string uri; - if (w.mAsset.extensionsUsed.KHR_binary_glTF && img.bufferView) { - Value exts, ext; - exts.SetObject(); - ext.SetObject(); - - ext.AddMember("bufferView", img.bufferView->index, w.mAl); - - if (!img.mimeType.empty()) - ext.AddMember("mimeType", StringRef(img.mimeType), w.mAl); - - exts.AddMember("KHR_binary_glTF", ext, w.mAl); - obj.AddMember("extensions", exts, w.mAl); - return; - } - else if (img.HasData()) { + if (img.HasData()) { uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType); uri += ";base64,"; Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri); @@ -577,77 +563,6 @@ namespace glTF2 { } } - inline void AssetWriter::WriteGLBFile(const char* path) - { - std::unique_ptr outfile(mAsset.OpenFile(path, "wb", true)); - - if (outfile == 0) { - throw DeadlyExportError("Could not open output file: " + std::string(path)); - } - - // we will write the header later, skip its size - outfile->Seek(sizeof(GLB_Header), aiOrigin_SET); - - StringBuffer docBuffer; - Writer writer(docBuffer); - mDoc.Accept(writer); - - if (outfile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) { - throw DeadlyExportError("Failed to write scene data!"); - } - - WriteBinaryData(outfile.get(), docBuffer.GetSize()); - } - - inline void AssetWriter::WriteBinaryData(IOStream* outfile, size_t sceneLength) - { - // - // write the body data - // - - size_t bodyLength = 0; - if (Ref b = mAsset.GetBodyBuffer()) { - bodyLength = b->byteLength; - - if (bodyLength > 0) { - size_t bodyOffset = sizeof(GLB_Header) + sceneLength; - bodyOffset = (bodyOffset + 3) & ~3; // Round up to next multiple of 4 - - outfile->Seek(bodyOffset, aiOrigin_SET); - - if (outfile->Write(b->GetPointer(), b->byteLength, 1) != 1) { - throw DeadlyExportError("Failed to write body data!"); - } - } - } - - // - // write the header - // - - GLB_Header header; - memcpy(header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)); - - header.version = 2; - AI_SWAP4(header.version); - - header.length = uint32_t(sizeof(header) + sceneLength + bodyLength); - AI_SWAP4(header.length); - - header.sceneLength = uint32_t(sceneLength); - AI_SWAP4(header.sceneLength); - - header.sceneFormat = SceneFormat_JSON; - AI_SWAP4(header.sceneFormat); - - outfile->Seek(0, aiOrigin_SET); - - if (outfile->Write(&header, 1, sizeof(header)) != sizeof(header)) { - throw DeadlyExportError("Failed to write the header!"); - } - } - - inline void AssetWriter::WriteMetadata() { Value asset; @@ -662,9 +577,6 @@ namespace glTF2 { Value exts; exts.SetArray(); { - //if (false) - // exts.PushBack(StringRef("KHR_binary_glTF"), mAl); - // This is used to export pbrSpecularGlossiness materials with GLTF 2. if (this->mAsset.extensionsUsed.KHR_materials_pbrSpecularGlossiness) { exts.PushBack(StringRef("KHR_materials_pbrSpecularGlossiness"), mAl); diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index f3e083543..e8c42128e 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -101,10 +101,6 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai mAsset.reset( new Asset( pIOSystem ) ); - if (isBinary) { - mAsset->SetAsBinary(); - } - ExportMetadata(); ExportMaterials(); @@ -121,11 +117,7 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai AssetWriter writer(*mAsset); - if (isBinary) { - writer.WriteGLBFile(filename); - } else { - writer.WriteFile(filename); - } + writer.WriteFile(filename); } /* diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index d234afab3..34f12b5af 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -74,7 +74,7 @@ static const aiImporterDesc desc = { "", "", "", - aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental, + aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental, 0, 0, 0, @@ -103,13 +103,13 @@ bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool { const std::string &extension = GetExtension(pFile); - if (extension != "gltf") // We currently can't read glTF2 binary files (.glb) + if (extension != "gltf") // We currently can't read glTF2 binary files (.glb), yet return false; if (checkSig && pIOHandler) { glTF2::Asset asset(pIOHandler); try { - asset.Load(pFile, extension == "glb"); + asset.Load(pFile); std::string version = asset.asset.version; return !version.empty() && version[0] == '2'; } catch (...) { @@ -615,15 +615,12 @@ void glTF2Importer::InternReadFile(const std::string& pFile, aiScene* pScene, IO // read the asset file glTF2::Asset asset(pIOHandler); - asset.Load(pFile, GetExtension(pFile) == "glb"); - + asset.Load(pFile); // // Copy the data out // - - ImportEmbeddedTextures(asset); ImportMaterials(asset); From 990fe143a131f96cec74c841567e9b20230220a8 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Fri, 8 Sep 2017 15:54:03 -0400 Subject: [PATCH 57/90] =?UTF-8?q?Fix=20mesh=20primitive=E2=80=99s=20attrib?= =?UTF-8?q?utes=E2=80=99=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per spec TEXCOORD -> TEXCOORD_0 COLOR -> COLOR_0 JOINTS -> JOINTS_0 WEIGHTS -> WEIGHTS_0 Remove JOINTMATRIX since it’s not supported (and doesn’t seem to be output, anyway) TANGENT should be added at a later date --- code/glTF2AssetWriter.inl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index e62f2377e..ed599c23e 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -380,11 +380,10 @@ namespace glTF2 { { WriteAttrs(w, attrs, p.attributes.position, "POSITION"); WriteAttrs(w, attrs, p.attributes.normal, "NORMAL"); - WriteAttrs(w, attrs, p.attributes.texcoord, "TEXCOORD", true); - WriteAttrs(w, attrs, p.attributes.color, "COLOR"); - WriteAttrs(w, attrs, p.attributes.joint, "JOINT"); - WriteAttrs(w, attrs, p.attributes.jointmatrix, "JOINTMATRIX"); - WriteAttrs(w, attrs, p.attributes.weight, "WEIGHT"); + WriteAttrs(w, attrs, p.attributes.texcoord, "TEXCOORD_0", true); + WriteAttrs(w, attrs, p.attributes.color, "COLOR_0"); + WriteAttrs(w, attrs, p.attributes.joint, "JOINTS_0"); + WriteAttrs(w, attrs, p.attributes.weight, "WEIGHTS_0"); } prim.AddMember("attributes", attrs, w.mAl); } From b1a5ca451639dbaf4852580c6842b226f3ff860c Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Fri, 8 Sep 2017 15:58:09 -0400 Subject: [PATCH 58/90] Use `forceNumber` argument of `WriteAttrs` to write correct attribute names, instead --- code/glTF2AssetWriter.inl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index ed599c23e..c91313ab4 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -380,10 +380,10 @@ namespace glTF2 { { WriteAttrs(w, attrs, p.attributes.position, "POSITION"); WriteAttrs(w, attrs, p.attributes.normal, "NORMAL"); - WriteAttrs(w, attrs, p.attributes.texcoord, "TEXCOORD_0", true); - WriteAttrs(w, attrs, p.attributes.color, "COLOR_0"); - WriteAttrs(w, attrs, p.attributes.joint, "JOINTS_0"); - WriteAttrs(w, attrs, p.attributes.weight, "WEIGHTS_0"); + WriteAttrs(w, attrs, p.attributes.texcoord, "TEXCOORD", true); + WriteAttrs(w, attrs, p.attributes.color, "COLOR", true); + WriteAttrs(w, attrs, p.attributes.joint, "JOINTS", true); + WriteAttrs(w, attrs, p.attributes.weight, "WEIGHTS", true); } prim.AddMember("attributes", attrs, w.mAl); } From cde29c937c4fdefa0a2c02f2ec1a8bd49e4121fb Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Fri, 8 Sep 2017 16:32:00 -0400 Subject: [PATCH 59/90] Formatting --- code/glTF2Exporter.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index e8c42128e..e2b46b1f7 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -389,8 +389,6 @@ void glTF2Exporter::GetMatColor(const aiMaterial* mat, vec3& prop, const char* p void glTF2Exporter::ExportMaterials() { - bool& KHR_materials_pbrSpecularGlossiness = mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness; - aiString aiName; for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) { const aiMaterial* mat = mScene->mMaterials[i]; @@ -442,8 +440,8 @@ void glTF2Exporter::ExportMaterials() if (hasPbrSpecularGlossiness) { - if (!KHR_materials_pbrSpecularGlossiness) { - KHR_materials_pbrSpecularGlossiness = true; + if (!mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness) { + mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness = true; } PbrSpecularGlossiness pbrSG; From 86a8a58d126bbd58ff42edbcc71e79fb825f6922 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Sun, 10 Sep 2017 21:04:28 -0400 Subject: [PATCH 60/90] Exclude glTF2 Exporter test when ASSIMP_BUILD_NO_EXPORT --- test/unit/utglTF2ImportExport.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp index 09c43131d..fa69d648a 100644 --- a/test/unit/utglTF2ImportExport.cpp +++ b/test/unit/utglTF2ImportExport.cpp @@ -55,6 +55,7 @@ public: return nullptr != scene; } +#ifndef ASSIMP_BUILD_NO_EXPORT virtual bool exporterTest() { Assimp::Importer importer; Assimp::Exporter exporter; @@ -64,12 +65,16 @@ public: return true; } +#endif // ASSIMP_BUILD_NO_EXPORT + }; TEST_F( utglTF2ImportExport, importglTF2FromFileTest ) { EXPECT_TRUE( importerTest() ); } +#ifndef ASSIMP_BUILD_NO_EXPORT TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) { EXPECT_TRUE( exporterTest() ); } +#endif // ASSIMP_BUILD_NO_EXPORT From 4b01ecaf109ae1bbd3ae918e30abdc67d7448a5a Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Mon, 11 Sep 2017 16:31:40 -0400 Subject: [PATCH 61/90] Remove simple gltf2 export unit test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Segfaults on Linux for some reason. No other tests test exporting, so it’s fine --- test/unit/utglTF2ImportExport.cpp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp index fa69d648a..8e0fcbbcf 100644 --- a/test/unit/utglTF2ImportExport.cpp +++ b/test/unit/utglTF2ImportExport.cpp @@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AbstractImportExportBase.h" #include -#include using namespace Assimp; @@ -54,27 +53,8 @@ public: const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured.gltf", 0); return nullptr != scene; } - -#ifndef ASSIMP_BUILD_NO_EXPORT - virtual bool exporterTest() { - Assimp::Importer importer; - Assimp::Exporter exporter; - const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured.gltf", 0 ); - EXPECT_NE( nullptr, scene ); - EXPECT_EQ( aiReturn_SUCCESS, exporter.Export( scene, "gltf2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured_out.gltf" ) ); - - return true; - } -#endif // ASSIMP_BUILD_NO_EXPORT - }; TEST_F( utglTF2ImportExport, importglTF2FromFileTest ) { EXPECT_TRUE( importerTest() ); } - -#ifndef ASSIMP_BUILD_NO_EXPORT -TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) { - EXPECT_TRUE( exporterTest() ); -} -#endif // ASSIMP_BUILD_NO_EXPORT From 023cb27784e61ab92f915df49f18675c28a40df2 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Tue, 12 Sep 2017 09:57:58 -0400 Subject: [PATCH 62/90] Revert "Remove simple gltf2 export unit test" This reverts commit 4b01ecaf109ae1bbd3ae918e30abdc67d7448a5a. --- test/unit/utglTF2ImportExport.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp index 8e0fcbbcf..fa69d648a 100644 --- a/test/unit/utglTF2ImportExport.cpp +++ b/test/unit/utglTF2ImportExport.cpp @@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AbstractImportExportBase.h" #include +#include using namespace Assimp; @@ -53,8 +54,27 @@ public: const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured.gltf", 0); return nullptr != scene; } + +#ifndef ASSIMP_BUILD_NO_EXPORT + virtual bool exporterTest() { + Assimp::Importer importer; + Assimp::Exporter exporter; + const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured.gltf", 0 ); + EXPECT_NE( nullptr, scene ); + EXPECT_EQ( aiReturn_SUCCESS, exporter.Export( scene, "gltf2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured_out.gltf" ) ); + + return true; + } +#endif // ASSIMP_BUILD_NO_EXPORT + }; TEST_F( utglTF2ImportExport, importglTF2FromFileTest ) { EXPECT_TRUE( importerTest() ); } + +#ifndef ASSIMP_BUILD_NO_EXPORT +TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) { + EXPECT_TRUE( exporterTest() ); +} +#endif // ASSIMP_BUILD_NO_EXPORT From b0da0796c8191bc42e6cfecb765a9a4e11595a42 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Tue, 12 Sep 2017 10:07:15 -0400 Subject: [PATCH 63/90] Fix Segfault caused by losing pointer to std::string Keep std::string alive --- code/glTF2Asset.h | 14 +++++++------- code/glTF2Exporter.cpp | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index b093ec027..8604cd2a1 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -164,7 +164,7 @@ namespace glTF2 //! Magic number for GLB files #define AI_GLB_MAGIC_NUMBER "glTF" - #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0,0 + #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0 #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0 #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 0 #define AI_MATKEY_GLTF_ALPHAMODE "$mat.gltf.alphaMode", 0, 0 @@ -172,15 +172,15 @@ namespace glTF2 #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0 #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_DIFFUSE_FACTOR "$clr.diffuse", 0, 1 #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_SPECULAR_FACTOR "$clr.specular", 0, 1 - #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0,0 + #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0, 0 #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_DIFFUSE_TEXTURE aiTextureType_DIFFUSE, 1 #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_SPECULARGLOSSINESS_TEXTURE aiTextureType_UNKNOWN, 1 - #define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE (std::string(_AI_MATKEY_TEXTURE_BASE) + ".texCoord").c_str() - #define _AI_MATKEY_GLTF_MAPPINGNAME_BASE (std::string(_AI_MATKEY_MAPPING_BASE) + "name").c_str() - #define _AI_MATKEY_GLTF_MAPPINGID_BASE (std::string(_AI_MATKEY_MAPPING_BASE) + "id").c_str() - #define _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermag").c_str() - #define _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermin").c_str() + #define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord" + #define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname" + #define _AI_MATKEY_GLTF_MAPPINGID_BASE "$tex.mappingid" + #define _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE "$tex.mappingfiltermag" + #define _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE "$tex.mappingfiltermin" #define AI_MATKEY_GLTF_TEXTURE_TEXCOORD _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, type, N #define AI_MATKEY_GLTF_MAPPINGNAME(type, N) _AI_MATKEY_GLTF_MAPPINGNAME_BASE, type, N diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index e2b46b1f7..9a0e0cca1 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -276,16 +276,16 @@ void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref texture, a void glTF2Exporter::GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int slot) { - const char* key = (std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName).c_str(); + std::string textureKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName; - mat->Get(key, tt, slot, prop); + mat->Get(textureKey.c_str(), tt, slot, prop); } void glTF2Exporter::GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int slot) { - const char* key = (std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName).c_str(); + std::string textureKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName; - mat->Get(key, tt, slot, prop); + mat->Get(textureKey.c_str(), tt, slot, prop); } void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref& texture, aiTextureType tt, unsigned int slot = 0) From eca008d5ece5a8087a158b5f8d1651938e8fac7b Mon Sep 17 00:00:00 2001 From: John Senneker Date: Tue, 12 Sep 2017 11:55:22 -0400 Subject: [PATCH 64/90] Properly move string passed to JSON writer --- code/glTF2AssetWriter.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index c91313ab4..7c0b435f2 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -300,7 +300,7 @@ namespace glTF2 { } if (m.alphaMode != "OPAQUE") { - obj.AddMember("alphaMode", m.alphaMode, w.mAl); + obj.AddMember("alphaMode", Value(m.alphaMode, w.mAl).Move(), w.mAl); } if (m.doubleSided) { From 933bbb4f1c4752ee7bed77029a8604aa8f3e7bc6 Mon Sep 17 00:00:00 2001 From: John Senneker Date: Tue, 12 Sep 2017 11:55:52 -0400 Subject: [PATCH 65/90] Manually read alphaMode material property --- code/glTF2Exporter.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 9a0e0cca1..a3940e9ea 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -424,7 +424,20 @@ void glTF2Exporter::ExportMaterials() mat->Get(AI_MATKEY_TWOSIDED, m->doubleSided); mat->Get(AI_MATKEY_GLTF_ALPHACUTOFF, m->alphaCutoff); - if (mat->Get(AI_MATKEY_GLTF_ALPHAMODE, m->alphaMode) != AI_SUCCESS) { + bool foundAlphaMode = false; + for (size_t i = 0; i < mat->mNumProperties; ++i) { + aiMaterialProperty *prop = mat->mProperties[i]; + if (prop->mKey != aiString("$mat.gltf.alphaMode")) + continue; + + std::string alphaMode; + for (size_t c = 0; c < prop->mDataLength; ++c) + alphaMode += prop->mData[c]; + m->alphaMode = alphaMode; + foundAlphaMode = true; + } + + if (!foundAlphaMode) { float opacity; if (mat->Get(AI_MATKEY_OPACITY, opacity) == AI_SUCCESS) { @@ -435,7 +448,7 @@ void glTF2Exporter::ExportMaterials() } } - bool hasPbrSpecularGlossiness; + bool hasPbrSpecularGlossiness = false; mat->Get(AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS, hasPbrSpecularGlossiness); if (hasPbrSpecularGlossiness) { From 190f034e38bc130461df3f26b0f8fe1b650658aa Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Tue, 12 Sep 2017 18:57:44 +0300 Subject: [PATCH 66/90] Add AddressSanitizer option to CMake --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 690351e8b..260b78698 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,10 @@ OPTION ( ASSIMP_COVERALLS "Enable this to measure test coverage." OFF ) +OPTION ( ASSIMP_ASAN + "Enable AddressSanitizer." + OFF +) OPTION ( SYSTEM_IRRXML "Use system installed Irrlicht/IrrXML library." OFF @@ -212,6 +216,11 @@ if (ASSIMP_COVERALLS) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") endif() +if (ASSIMP_ASAN) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") +endif() + INCLUDE (FindPkgMacros) INCLUDE (PrecompiledHeader) From cbedc448c6b793d664f9357c5d4559a6da1a7c23 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 12 Sep 2017 18:59:38 +0200 Subject: [PATCH 67/90] closes https://github.com/assimp/assimp/issues/1426: add Defines.h to include folder for install. --- code/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 236e6d7ef..b9f07ce86 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -61,6 +61,7 @@ SET( PUBLIC_HEADERS ${HEADER_PATH}/color4.inl ${CMAKE_CURRENT_BINARY_DIR}/../include/assimp/config.h ${HEADER_PATH}/defs.h + ${HEADER_PATH}/Defines.h ${HEADER_PATH}/cfileio.h ${HEADER_PATH}/light.h ${HEADER_PATH}/material.h From e3163ec15eaf3df28bbe0956e9ba2687f7e42396 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 12 Sep 2017 19:07:17 +0200 Subject: [PATCH 68/90] FBX: fix some minor findings. --- code/FBXAnimation.cpp | 25 ++++++---------- code/FBXCompileConfig.h | 2 +- code/FBXConverter.cpp | 17 ++++------- code/FBXDocument.cpp | 60 ++++++++++++--------------------------- code/FBXDocument.h | 33 ++++----------------- code/FBXModel.cpp | 3 -- code/FBXNodeAttribute.cpp | 15 ++++------ code/FBXParser.cpp | 10 ++----- code/FBXParser.h | 19 ------------- 9 files changed, 47 insertions(+), 137 deletions(-) diff --git a/code/FBXAnimation.cpp b/code/FBXAnimation.cpp index e905b5bfc..6f9613f0d 100644 --- a/code/FBXAnimation.cpp +++ b/code/FBXAnimation.cpp @@ -87,17 +87,16 @@ AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::s } } - // ------------------------------------------------------------------------------------------------ AnimationCurve::~AnimationCurve() { - + // empty } - // ------------------------------------------------------------------------------------------------ -AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc, - const char* const * target_prop_whitelist /*= NULL*/, size_t whitelist_size /*= 0*/) +AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, + const Document& doc, const char* const * target_prop_whitelist /*= NULL*/, + size_t whitelist_size /*= 0*/) : Object(id, element, name) , target() , doc(doc) @@ -154,18 +153,16 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, cons props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false); } - // ------------------------------------------------------------------------------------------------ AnimationCurveNode::~AnimationCurveNode() { - + // empty } - // ------------------------------------------------------------------------------------------------ const AnimationCurveMap& AnimationCurveNode::Curves() const { - if(curves.empty()) { + if ( curves.empty() ) { // resolve attached animation curves const std::vector& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve"); @@ -195,7 +192,6 @@ const AnimationCurveMap& AnimationCurveNode::Curves() const return curves; } - // ------------------------------------------------------------------------------------------------ AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc) : Object(id, element, name) @@ -207,14 +203,12 @@ AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::s props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true); } - // ------------------------------------------------------------------------------------------------ AnimationLayer::~AnimationLayer() { - + // empty } - // ------------------------------------------------------------------------------------------------ AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/, size_t whitelist_size /*= 0*/) const @@ -298,14 +292,13 @@ AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::s } } - // ------------------------------------------------------------------------------------------------ AnimationStack::~AnimationStack() { - + // empty } } //!FBX } //!Assimp -#endif +#endif // ASSIMP_BUILD_NO_FBX_IMPORTER diff --git a/code/FBXCompileConfig.h b/code/FBXCompileConfig.h index d4d40b056..56aa1c787 100644 --- a/code/FBXCompileConfig.h +++ b/code/FBXCompileConfig.h @@ -66,4 +66,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # endif #endif -#endif +#endif // INCLUDED_AI_FBX_COMPILECONFIG_H diff --git a/code/FBXConverter.cpp b/code/FBXConverter.cpp index ebe7ac4e6..ff355100f 100644 --- a/code/FBXConverter.cpp +++ b/code/FBXConverter.cpp @@ -55,9 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "StringComparison.h" #include + #include #include - #include #include @@ -931,7 +931,7 @@ bool Converter::NeedsComplexTransformationChain( const Model& model ) const TransformationComp comp = static_cast< TransformationComp >( i ); if ( comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation || - comp == TransformationComp_GeometricScaling || comp == TransformationComp_GeometricRotation || comp == TransformationComp_GeometricTranslation ) { + comp == TransformationComp_GeometricScaling || comp == TransformationComp_GeometricRotation || comp == TransformationComp_GeometricTranslation ) { continue; } @@ -949,8 +949,7 @@ std::string Converter::NameTransformationChainNode( const std::string& name, Tra return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp ); } -void Converter::GenerateTransformationNodeChain( const Model& model, - std::vector& output_nodes ) +void Converter::GenerateTransformationNodeChain( const Model& model, std::vector& output_nodes ) { const PropertyTable& props = model.Props(); const Model::RotOrder rot = model.RotationOrder(); @@ -3119,7 +3118,6 @@ void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, c } } - void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs, const aiVector3D& def_value, double& maxTime, @@ -3140,7 +3138,6 @@ void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, con valOut[ i ].mTime = temp[ i ].mTime; - GetRotationMatrix( order, temp[ i ].mValue, m ); aiQuaternion quat = aiQuaternion( aiMatrix3x3( m ) ); @@ -3159,7 +3156,6 @@ void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, con } } - void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale, aiVectorKey* out_translation, const KeyFrameListList& scaling, @@ -3218,7 +3214,6 @@ void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey } } - aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order ) { aiMatrix4x4 m; @@ -3227,7 +3222,6 @@ aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrde return aiQuaternion( aiMatrix3x3( m ) ); } - void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector& nodes, const LayerMap& /*layers*/, int64_t start, int64_t stop, double& maxTime, @@ -3248,7 +3242,6 @@ void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vectormScalingKeys, keys, inputs, aiVector3D( 1.0f, 1.0f, 1.0f ), maxTime, minTime ); } - void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector& nodes, const LayerMap& /*layers*/, int64_t start, int64_t stop, @@ -3267,7 +3260,6 @@ void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vectormPositionKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime ); } - void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector& nodes, const LayerMap& /*layers*/, int64_t start, int64_t stop, @@ -3289,7 +3281,8 @@ void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vectormMeshes && !out->mNumMeshes ); + ai_assert( !out->mMeshes ); + ai_assert( !out->mNumMeshes ); // note: the trailing () ensures initialization with NULL - not // many C++ users seem to know this, so pointing it out to avoid diff --git a/code/FBXDocument.cpp b/code/FBXDocument.cpp index b19ce4cd0..9592bf31f 100644 --- a/code/FBXDocument.cpp +++ b/code/FBXDocument.cpp @@ -70,13 +70,13 @@ LazyObject::LazyObject(uint64_t id, const Element& element, const Document& doc) , id(id) , flags() { - + // empty } // ------------------------------------------------------------------------------------------------ LazyObject::~LazyObject() { - + // empty } // ------------------------------------------------------------------------------------------------ @@ -232,16 +232,15 @@ Object::Object(uint64_t id, const Element& element, const std::string& name) , name(name) , id(id) { - + // empty } // ------------------------------------------------------------------------------------------------ Object::~Object() { - + // empty } - // ------------------------------------------------------------------------------------------------ FileGlobalSettings::FileGlobalSettings(const Document& doc, std::shared_ptr props) : props(props) @@ -361,7 +360,6 @@ void Document::ReadGlobalSettings() globals.reset(new FileGlobalSettings(*this, props)); } - // ------------------------------------------------------------------------------------------------ void Document::ReadObjects() { @@ -387,7 +385,6 @@ void Document::ReadObjects() } const char* err; - const uint64_t id = ParseTokenAsID(*tok[0], err); if(err) { DOMError(err,el.second); @@ -469,8 +466,6 @@ void Document::ReadPropertyTemplates() } } - - // ------------------------------------------------------------------------------------------------ void Document::ReadConnections() { @@ -482,7 +477,6 @@ void Document::ReadConnections() } uint64_t insertionOrder = 0l; - const Scope& sconns = *econns->Compound(); const ElementCollection conns = sconns.GetCollection("C"); for(ElementMap::const_iterator it = conns.first; it != conns.second; ++it) { @@ -491,7 +485,9 @@ void Document::ReadConnections() // PP = property-property connection, ignored for now // (tokens: "PP", ID1, "Property1", ID2, "Property2") - if(type == "PP") continue; + if ( type == "PP" ) { + continue; + } const uint64_t src = ParseTokenAsID(GetRequiredToken(el,1)); const uint64_t dest = ParseTokenAsID(GetRequiredToken(el,2)); @@ -518,11 +514,10 @@ void Document::ReadConnections() } } - // ------------------------------------------------------------------------------------------------ const std::vector& Document::AnimationStacks() const { - if (!animationStacksResolved.empty() || !animationStacks.size()) { + if (!animationStacksResolved.empty() || animationStacks.empty()) { return animationStacksResolved; } @@ -540,7 +535,6 @@ const std::vector& Document::AnimationStacks() const return animationStacksResolved; } - // ------------------------------------------------------------------------------------------------ LazyObject* Document::GetObject(uint64_t id) const { @@ -551,8 +545,7 @@ LazyObject* Document::GetObject(uint64_t id) const #define MAX_CLASSNAMES 6 // ------------------------------------------------------------------------------------------------ -std::vector Document::GetConnectionsSequenced(uint64_t id, - const ConnectionMap& conns) const +std::vector Document::GetConnectionsSequenced(uint64_t id, const ConnectionMap& conns) const { std::vector temp; @@ -569,7 +562,6 @@ std::vector Document::GetConnectionsSequenced(uint64_t id, return temp; // NRVO should handle this } - // ------------------------------------------------------------------------------------------------ std::vector Document::GetConnectionsSequenced(uint64_t id, bool is_src, const ConnectionMap& conns, @@ -578,17 +570,17 @@ std::vector Document::GetConnectionsSequenced(uint64_t id, bo { ai_assert(classnames); - ai_assert(count != 0 && count <= MAX_CLASSNAMES); + ai_assert( count != 0 ); + ai_assert( count <= MAX_CLASSNAMES); size_t lenghts[MAX_CLASSNAMES]; const size_t c = count; for (size_t i = 0; i < c; ++i) { - lenghts[i] = strlen(classnames[i]); + lenghts[ i ] = strlen(classnames[i]); } std::vector temp; - const std::pair range = conns.equal_range(id); @@ -620,49 +612,40 @@ std::vector Document::GetConnectionsSequenced(uint64_t id, bo return temp; // NRVO should handle this } - // ------------------------------------------------------------------------------------------------ std::vector Document::GetConnectionsBySourceSequenced(uint64_t source) const { return GetConnectionsSequenced(source, ConnectionsBySource()); } - - // ------------------------------------------------------------------------------------------------ -std::vector Document::GetConnectionsBySourceSequenced(uint64_t dest, - const char* classname) const +std::vector Document::GetConnectionsBySourceSequenced(uint64_t dest, const char* classname) const { const char* arr[] = {classname}; return GetConnectionsBySourceSequenced(dest, arr,1); } - - // ------------------------------------------------------------------------------------------------ -std::vector Document::GetConnectionsBySourceSequenced(uint64_t source, - const char* const* classnames, size_t count) const +std::vector Document::GetConnectionsBySourceSequenced(uint64_t source, + const char* const* classnames, size_t count) const { return GetConnectionsSequenced(source, true, ConnectionsBySource(),classnames, count); } - // ------------------------------------------------------------------------------------------------ std::vector Document::GetConnectionsByDestinationSequenced(uint64_t dest, - const char* classname) const + const char* classname) const { const char* arr[] = {classname}; return GetConnectionsByDestinationSequenced(dest, arr,1); } - // ------------------------------------------------------------------------------------------------ std::vector Document::GetConnectionsByDestinationSequenced(uint64_t dest) const { return GetConnectionsSequenced(dest, ConnectionsByDestination()); } - // ------------------------------------------------------------------------------------------------ std::vector Document::GetConnectionsByDestinationSequenced(uint64_t dest, const char* const* classnames, size_t count) const @@ -671,10 +654,9 @@ std::vector Document::GetConnectionsByDestinationSequenced(ui return GetConnectionsSequenced(dest, false, ConnectionsByDestination(),classnames, count); } - // ------------------------------------------------------------------------------------------------ Connection::Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string& prop, - const Document& doc) + const Document& doc) : insertionOrder(insertionOrder) , prop(prop) @@ -687,14 +669,12 @@ Connection::Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, co ai_assert(!dest || doc.Objects().find(dest) != doc.Objects().end()); } - // ------------------------------------------------------------------------------------------------ Connection::~Connection() { - + // empty } - // ------------------------------------------------------------------------------------------------ LazyObject& Connection::LazySourceObject() const { @@ -703,7 +683,6 @@ LazyObject& Connection::LazySourceObject() const return *lazy; } - // ------------------------------------------------------------------------------------------------ LazyObject& Connection::LazyDestinationObject() const { @@ -712,7 +691,6 @@ LazyObject& Connection::LazyDestinationObject() const return *lazy; } - // ------------------------------------------------------------------------------------------------ const Object* Connection::SourceObject() const { @@ -721,7 +699,6 @@ const Object* Connection::SourceObject() const return lazy->Get(); } - // ------------------------------------------------------------------------------------------------ const Object* Connection::DestinationObject() const { @@ -734,4 +711,3 @@ const Object* Connection::DestinationObject() const } // !Assimp #endif - diff --git a/code/FBXDocument.h b/code/FBXDocument.h index 5c8bc610f..af89f53d5 100644 --- a/code/FBXDocument.h +++ b/code/FBXDocument.h @@ -338,12 +338,7 @@ public: class Model : public Object { public: - Model(uint64_t id, const Element& element, const Document& doc, const std::string& name); - virtual ~Model(); - -public: - enum RotOrder - { + enum RotOrder { RotOrder_EulerXYZ = 0, RotOrder_EulerXZY, RotOrder_EulerYZX, @@ -357,8 +352,7 @@ public: }; - enum TransformInheritance - { + enum TransformInheritance { TransformInheritance_RrSs = 0, TransformInheritance_RSrs, TransformInheritance_Rrs, @@ -366,7 +360,10 @@ public: TransformInheritance_MAX // end-of-enum sentinel }; -public: + Model(uint64_t id, const Element& element, const Document& doc, const std::string& name); + + virtual ~Model(); + fbx_simple_property(QuaternionInterpolate, int, 0) fbx_simple_property(RotationOffset, aiVector3D, aiVector3D()) @@ -443,7 +440,6 @@ public: fbx_simple_property(LODBox, bool, false) fbx_simple_property(Freeze, bool, false) -public: const std::string& Shading() const { return shading; } @@ -462,13 +458,11 @@ public: return materials; } - /** Get geometry links */ const std::vector& GetGeometry() const { return geometry; } - /** Get node attachments */ const std::vector& GetAttributes() const { return attributes; @@ -477,7 +471,6 @@ public: /** convenience method to check if the node has a Null node marker */ bool IsNull() const; - private: void ResolveLinks(const Element& element, const Document& doc); @@ -805,7 +798,6 @@ private: typedef std::vector AnimationCurveNodeList; - /** Represents a FBX animation layer (i.e. a list of node animations) */ class AnimationLayer : public Object { @@ -828,10 +820,8 @@ private: const Document& doc; }; - typedef std::vector AnimationLayerList; - /** Represents a FBX animation stack (i.e. a list of animation layers) */ class AnimationStack : public Object { @@ -839,7 +829,6 @@ public: AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc); virtual ~AnimationStack(); -public: fbx_simple_property(LocalStart, int64_t, 0L) fbx_simple_property(LocalStop, int64_t, 0L) fbx_simple_property(ReferenceStart, int64_t, 0L) @@ -879,7 +868,6 @@ private: typedef std::vector WeightArray; typedef std::vector WeightIndexArray; - /** DOM class for skin deformer clusters (aka subdeformers) */ class Cluster : public Deformer { @@ -924,8 +912,6 @@ private: const Model* node; }; - - /** DOM class for skin deformers */ class Skin : public Deformer { @@ -1009,10 +995,8 @@ public: typedef std::map ObjectMap; typedef std::fbx_unordered_map > PropertyTemplateMap; - typedef std::multimap ConnectionMap; - /** DOM class for global document settings, a single instance per document can * be accessed via Document.Globals(). */ class FileGlobalSettings @@ -1074,9 +1058,6 @@ private: const Document& doc; }; - - - /** DOM root for a FBX file */ class Document { @@ -1154,8 +1135,6 @@ private: const ConnectionMap&, const char* const* classnames, size_t count) const; - -private: void ReadHeader(); void ReadObjects(); void ReadPropertyTemplates(); diff --git a/code/FBXModel.cpp b/code/FBXModel.cpp index 90939c142..3d694d7d8 100644 --- a/code/FBXModel.cpp +++ b/code/FBXModel.cpp @@ -77,14 +77,12 @@ Model::Model(uint64_t id, const Element& element, const Document& doc, const std ResolveLinks(element,doc); } - // ------------------------------------------------------------------------------------------------ Model::~Model() { } - // ------------------------------------------------------------------------------------------------ void Model::ResolveLinks(const Element& element, const Document& doc) { @@ -132,7 +130,6 @@ void Model::ResolveLinks(const Element& element, const Document& doc) } } - // ------------------------------------------------------------------------------------------------ bool Model::IsNull() const { diff --git a/code/FBXNodeAttribute.cpp b/code/FBXNodeAttribute.cpp index bcf079c2e..545343c09 100644 --- a/code/FBXNodeAttribute.cpp +++ b/code/FBXNodeAttribute.cpp @@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { namespace FBX { - using namespace Util; +using namespace Util; // ------------------------------------------------------------------------------------------------ NodeAttribute::NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name) @@ -75,7 +75,7 @@ NodeAttribute::NodeAttribute(uint64_t id, const Element& element, const Document // ------------------------------------------------------------------------------------------------ NodeAttribute::~NodeAttribute() { - + // empty } @@ -101,33 +101,30 @@ CameraSwitcher::CameraSwitcher(uint64_t id, const Element& element, const Docume } } - // ------------------------------------------------------------------------------------------------ CameraSwitcher::~CameraSwitcher() { - + // empty } - // ------------------------------------------------------------------------------------------------ Camera::Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name) : NodeAttribute(id,element,doc,name) { - + // empty } - // ------------------------------------------------------------------------------------------------ Camera::~Camera() { + // empty } - // ------------------------------------------------------------------------------------------------ Light::Light(uint64_t id, const Element& element, const Document& doc, const std::string& name) : NodeAttribute(id,element,doc,name) { - + // empty } diff --git a/code/FBXParser.cpp b/code/FBXParser.cpp index 428c29a62..cf6930e22 100644 --- a/code/FBXParser.cpp +++ b/code/FBXParser.cpp @@ -224,41 +224,36 @@ Parser::Parser (const TokenList& tokens, bool is_binary) root.reset(new Scope(*this,true)); } - // ------------------------------------------------------------------------------------------------ Parser::~Parser() { + // empty } - // ------------------------------------------------------------------------------------------------ TokenPtr Parser::AdvanceToNextToken() { last = current; if (cursor == tokens.end()) { current = NULL; - } - else { + } else { current = *cursor++; } return current; } - // ------------------------------------------------------------------------------------------------ TokenPtr Parser::CurrentToken() const { return current; } - // ------------------------------------------------------------------------------------------------ TokenPtr Parser::LastToken() const { return last; } - // ------------------------------------------------------------------------------------------------ uint64_t ParseTokenAsID(const Token& t, const char*& err_out) { @@ -296,7 +291,6 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out) return id; } - // ------------------------------------------------------------------------------------------------ size_t ParseTokenAsDim(const Token& t, const char*& err_out) { diff --git a/code/FBXParser.h b/code/FBXParser.h index b0683ccd1..4d3766d70 100644 --- a/code/FBXParser.h +++ b/code/FBXParser.h @@ -85,12 +85,9 @@ typedef std::pair Element class Element { public: - Element(const Token& key_token, Parser& parser); ~Element(); -public: - const Scope* Compound() const { return compound.get(); } @@ -104,14 +101,11 @@ public: } private: - const Token& key_token; TokenList tokens; std::unique_ptr compound; }; - - /** FBX data entity that consists of a 'scope', a collection * of not necessarily unique #Element instances. * @@ -125,14 +119,10 @@ private: * @endverbatim */ class Scope { - public: - Scope(Parser& parser, bool topLevel = false); ~Scope(); -public: - const Element* operator[] (const std::string& index) const { ElementMap::const_iterator it = elements.find(index); return it == elements.end() ? NULL : (*it).second; @@ -158,28 +148,23 @@ public: } private: - ElementMap elements; }; - /** FBX parsing class, takes a list of input tokens and generates a hierarchy * of nested #Scope instances, representing the fbx DOM.*/ class Parser { public: - /** Parse given a token list. Does not take ownership of the tokens - * the objects must persist during the entire parser lifetime */ Parser (const TokenList& tokens,bool is_binary); ~Parser(); -public: const Scope& GetRootScope() const { return *root.get(); } - bool IsBinary() const { return is_binary; } @@ -233,8 +218,6 @@ void ParseVectorDataArray(std::vector& out, const Element& el); void ParseVectorDataArray(std::vector& out, const Element& e); void ParseVectorDataArray(std::vector& out, const Element& el); - - // extract a required element from a scope, abort if the element cannot be found const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element = NULL); @@ -243,8 +226,6 @@ const Scope& GetRequiredScope(const Element& el); // get token at a particular index const Token& GetRequiredToken(const Element& el, unsigned int index); - - // read a 4x4 matrix from an array of 16 floats aiMatrix4x4 ReadMatrix(const Element& element); From 6a3b030094481c3a901fbc8f570bf889246c9e09 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 12 Sep 2017 21:16:59 +0200 Subject: [PATCH 69/90] MDP: fix encoding issues. --- code/MMDPmdParser.h | 74 -------------------------- code/MMDPmxParser.cpp | 3 -- code/MMDPmxParser.h | 120 ------------------------------------------ code/MMDVmdParser.h | 32 ----------- 4 files changed, 229 deletions(-) diff --git a/code/MMDPmdParser.h b/code/MMDPmdParser.h index 5439b9043..586f20a5f 100644 --- a/code/MMDPmdParser.h +++ b/code/MMDPmdParser.h @@ -49,17 +49,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace pmd { - /// ヘッダ class PmdHeader { public: - /// モデル名 std::string name; - /// モデル名(英語) std::string name_english; - /// コメント std::string comment; - /// コメント(英語) std::string comment_english; bool Read(std::ifstream* stream) @@ -83,26 +78,19 @@ namespace pmd } }; - /// 頂点 class PmdVertex { public: - /// 位置 float position[3]; - /// 法線 float normal[3]; - /// UV座標 float uv[2]; - /// 関連ボーンインデックス uint16_t bone_index[2]; - /// ボーンウェイト uint8_t bone_weight; - /// エッジ不可視 bool edge_invisible; bool Read(std::ifstream* stream) @@ -117,27 +105,17 @@ namespace pmd } }; - /// 材質 class PmdMaterial { public: - /// 減衰色 float diffuse[4]; - /// 光沢度 float power; - /// 光沢色 float specular[3]; - /// 環境色 float ambient[3]; - /// トーンインデックス uint8_t toon_index; - /// エッジ uint8_t edge_flag; - /// インデックス数 uint32_t index_count; - /// テクスチャファイル名 std::string texture_filename; - /// スフィアファイル名 std::string sphere_filename; bool Read(std::ifstream* stream) @@ -180,23 +158,15 @@ namespace pmd RotationMovement }; - /// ボーン class PmdBone { public: - /// ボーン名 std::string name; - /// ボーン名(英語) std::string name_english; - /// 親ボーン番号 uint16_t parent_bone_index; - /// 末端ボーン番号 uint16_t tail_pos_bone_index; - /// ボーン種類 BoneType bone_type; - /// IKボーン番号 uint16_t ik_parent_bone_index; - /// ボーンのヘッドの位置 float bone_head_pos[3]; void Read(std::istream *stream) @@ -219,19 +189,13 @@ namespace pmd } }; - /// IK class PmdIk { public: - /// IKボーン番号 uint16_t ik_bone_index; - /// IKターゲットボーン番号 uint16_t target_bone_index; - /// 再帰回数 uint16_t interations; - /// 角度制限 float angle_limit; - /// 影響下ボーン番号 std::vector ik_child_bone_index; void Read(std::istream *stream) @@ -303,7 +267,6 @@ namespace pmd } }; - /// ボーン枠用の枠名 class PmdBoneDispName { public: @@ -338,59 +301,36 @@ namespace pmd } }; - /// 衝突形状 enum class RigidBodyShape : uint8_t { - /// 球 Sphere = 0, - /// 直方体 Box = 1, - /// カプセル Cpusel = 2 }; - /// 剛体タイプ enum class RigidBodyType : uint8_t { - /// ボーン追従 BoneConnected = 0, - /// 物理演算 Physics = 1, - /// 物理演算(Bone位置合せ) ConnectedPhysics = 2 }; - /// 剛体 class PmdRigidBody { public: - /// 名前 std::string name; - /// 関連ボーン番号 uint16_t related_bone_index; - /// グループ番号 uint8_t group_index; - /// マスク uint16_t mask; - /// 形状 RigidBodyShape shape; - /// 大きさ float size[3]; - /// 位置 float position[3]; - /// 回転 float orientation[3]; - /// 質量 float weight; - /// 移動ダンピング float linear_damping; - /// 回転ダンピング float anglar_damping; - /// 反発係数 float restitution; - /// 摩擦係数 float friction; - /// 演算方法 RigidBodyType rigid_type; void Read(std::istream *stream) @@ -414,31 +354,19 @@ namespace pmd } }; - /// 剛体の拘束 class PmdConstraint { public: - /// 名前 std::string name; - /// 剛体Aのインデックス uint32_t rigid_body_index_a; - /// 剛体Bのインデックス uint32_t rigid_body_index_b; - /// 位置 float position[3]; - /// 回転 float orientation[3]; - /// 最小移動制限 float linear_lower_limit[3]; - /// 最大移動制限 float linear_upper_limit[3]; - /// 最小回転制限 float angular_lower_limit[3]; - /// 最大回転制限 float angular_upper_limit[3]; - /// 移動に対する復元力 float linear_stiffness[3]; - /// 回転に対する復元力 float angular_stiffness[3]; void Read(std::istream *stream) @@ -459,7 +387,6 @@ namespace pmd } }; - /// PMDモデル class PmdModel { public: @@ -491,7 +418,6 @@ namespace pmd return result; } - /// ファイルからPmdModelを生成する static std::unique_ptr LoadFromStream(std::ifstream *stream) { auto result = mmd::make_unique(); diff --git a/code/MMDPmxParser.cpp b/code/MMDPmxParser.cpp index 6a76c2c7f..c38bdf49a 100644 --- a/code/MMDPmxParser.cpp +++ b/code/MMDPmxParser.cpp @@ -45,7 +45,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace pmx { - /// インデックス値を読み込む int ReadIndex(std::istream *stream, int size) { switch (size) @@ -79,7 +78,6 @@ namespace pmx } } - /// 文字列を読み込む std::string ReadString(std::istream *stream, uint8_t encoding) { int size; @@ -607,7 +605,6 @@ namespace pmx this->joints[i].Read(stream, &setting); } - //// ソフトボディ //if (this->version == 2.1f) //{ // stream->read((char*) &this->soft_body_count, sizeof(int)); diff --git a/code/MMDPmxParser.h b/code/MMDPmxParser.h index 4aff7f8eb..989cffed6 100644 --- a/code/MMDPmxParser.h +++ b/code/MMDPmxParser.h @@ -49,7 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace pmx { - /// インデックス設定 class PmxSetting { public: @@ -64,26 +63,17 @@ namespace pmx , rigidbody_index_size(0) {} - /// エンコード方式 uint8_t encoding; - /// 追加UV数 uint8_t uv; - /// 頂点インデックスサイズ uint8_t vertex_index_size; - /// テクスチャインデックスサイズ uint8_t texture_index_size; - /// マテリアルインデックスサイズ uint8_t material_index_size; - /// ボーンインデックスサイズ uint8_t bone_index_size; - /// モーフインデックスサイズ uint8_t morph_index_size; - /// 剛体インデックスサイズ uint8_t rigidbody_index_size; void Read(std::istream *stream); }; - /// 頂点スキニングタイプ enum class PmxVertexSkinningType : uint8_t { BDEF1 = 0, @@ -93,7 +83,6 @@ namespace pmx QDEF = 4, }; - /// 頂点スキニング class PmxVertexSkinning { public: @@ -200,7 +189,6 @@ namespace pmx void Read(std::istream *stresam, PmxSetting *setting); }; - /// 頂点 class PmxVertex { public: @@ -219,24 +207,16 @@ namespace pmx } } - /// 位置 float position[3]; - /// 法線 float normal[3]; - /// テクスチャ座標 float uv[2]; - /// 追加テクスチャ座標 float uva[4][4]; - /// スキニングタイプ PmxVertexSkinningType skinning_type; - /// スキニング std::unique_ptr skinning; - /// エッジ倍率 float edge; void Read(std::istream *stream, PmxSetting *setting); }; - /// マテリアル class PmxMaterial { public: @@ -261,42 +241,25 @@ namespace pmx } } - /// モデル名 std::string material_name; - /// モデル英名 std::string material_english_name; - /// 減衰色 float diffuse[4]; - /// 光沢色 float specular[3]; - /// 光沢度 float specularlity; - /// 環境色 float ambient[3]; - /// 描画フラグ uint8_t flag; - /// エッジ色 float edge_color[4]; - /// エッジサイズ float edge_size; - /// アルベドテクスチャインデックス int diffuse_texture_index; - /// スフィアテクスチャインデックス int sphere_texture_index; - /// スフィアテクスチャ演算モード uint8_t sphere_op_mode; - /// 共有トゥーンフラグ uint8_t common_toon_flag; - /// トゥーンテクスチャインデックス int toon_texture_index; - /// メモ std::string memo; - /// 頂点インデックス数 int index_count; void Read(std::istream *stream, PmxSetting *setting); }; - /// リンク class PmxIkLink { public: @@ -310,18 +273,13 @@ namespace pmx } } - /// リンクボーンインデックス int link_target; - /// 角度制限 uint8_t angle_lock; - /// 最大制限角度 float max_radian[3]; - /// 最小制限角度 float min_radian[3]; void Read(std::istream *stream, PmxSetting *settingn); }; - /// ボーン class PmxBone { public: @@ -347,43 +305,24 @@ namespace pmx } } - /// ボーン名 std::string bone_name; - /// ボーン英名 std::string bone_english_name; - /// 位置 float position[3]; - /// 親ボーンインデックス int parent_index; - /// 階層 int level; - /// ボーンフラグ uint16_t bone_flag; - /// 座標オフセット(has Target) float offset[3]; - /// 接続先ボーンインデックス(not has Target) int target_index; - /// 付与親ボーンインデックス int grant_parent_index; - /// 付与率 float grant_weight; - /// 固定軸の方向 float lock_axis_orientation[3]; - /// ローカル軸のX軸方向 float local_axis_x_orientation[3]; - /// ローカル軸のY軸方向 float local_axis_y_orientation[3]; - /// 外部親変形のkey値 int key; - /// IKターゲットボーン int ik_target_bone_index; - /// IKループ回数 int ik_loop; - /// IKループ計算時の角度制限(ラジアン) float ik_loop_angle_limit; - /// IKリンク数 int ik_link_count; - /// IKリンク std::unique_ptr ik_links; void Read(std::istream *stream, PmxSetting *setting); }; @@ -543,7 +482,6 @@ namespace pmx void Read(std::istream *stream, PmxSetting *setting); //override; }; - /// モーフ class PmxMorph { public: @@ -551,34 +489,21 @@ namespace pmx : offset_count(0) { } - /// モーフ名 std::string morph_name; - /// モーフ英名 std::string morph_english_name; - /// カテゴリ MorphCategory category; - /// モーフタイプ MorphType morph_type; - /// オフセット数 int offset_count; - /// 頂点モーフ配列 std::unique_ptr vertex_offsets; - /// UVモーフ配列 std::unique_ptr uv_offsets; - /// ボーンモーフ配列 std::unique_ptr bone_offsets; - /// マテリアルモーフ配列 std::unique_ptr material_offsets; - /// グループモーフ配列 std::unique_ptr group_offsets; - /// フリップモーフ配列 std::unique_ptr flip_offsets; - /// インパルスモーフ配列 std::unique_ptr implus_offsets; void Read(std::istream *stream, PmxSetting *setting); }; - /// 枠内要素 class PmxFrameElement { public: @@ -587,14 +512,11 @@ namespace pmx , index(0) { } - /// 要素対象 uint8_t element_target; - /// 要素対象インデックス int index; void Read(std::istream *stream, PmxSetting *setting); }; - /// 表示枠 class PmxFrame { public: @@ -603,15 +525,10 @@ namespace pmx , element_count(0) { } - /// 枠名 std::string frame_name; - /// 枠英名 std::string frame_english_name; - /// 特殊枠フラグ uint8_t frame_flag; - /// 枠内要素数 int element_count; - /// 枠内要素配列 std::unique_ptr elements; void Read(std::istream *stream, PmxSetting *setting); }; @@ -637,17 +554,11 @@ namespace pmx orientation[i] = 0.0f; } } - /// 剛体名 std::string girid_body_name; - /// 剛体英名 std::string girid_body_english_name; - /// 関連ボーンインデックス int target_bone; - /// グループ uint8_t group; - /// マスク uint16_t mask; - /// 形状 uint8_t shape; float size[3]; float position[3]; @@ -818,7 +729,6 @@ namespace pmx void Read(std::istream *stream, PmxSetting *setting); }; - /// PMXモデル class PmxModel { public: @@ -836,65 +746,35 @@ namespace pmx , soft_body_count(0) {} - /// バージョン float version; - /// 設定 PmxSetting setting; - /// モデル名 std::string model_name; - /// モデル英名 std::string model_english_name; - /// コメント std::string model_comment; - /// 英語コメント std::string model_english_comment; - /// 頂点数 int vertex_count; - /// 頂点配列 std::unique_ptr vertices; - /// インデックス数 int index_count; - /// インデックス配列 std::unique_ptr indices; - /// テクスチャ数 int texture_count; - /// テクスチャ配列 std::unique_ptr< std::string []> textures; - /// マテリアル数 int material_count; - /// マテリアル std::unique_ptr materials; - /// ボーン数 int bone_count; - /// ボーン配列 std::unique_ptr bones; - /// モーフ数 int morph_count; - /// モーフ配列 std::unique_ptr morphs; - /// 表示枠数 int frame_count; - /// 表示枠配列 std::unique_ptr frames; - /// 剛体数 int rigid_body_count; - /// 剛体配列 std::unique_ptr rigid_bodies; - /// ジョイント数 int joint_count; - /// ジョイント配列 std::unique_ptr joints; - /// ソフトボディ数 int soft_body_count; - /// ソフトボディ配列 std::unique_ptr soft_bodies; - /// モデル初期化 void Init(); - /// モデル読み込み void Read(std::istream *stream); - ///// ファイルからモデルの読み込み //static std::unique_ptr ReadFromFile(const char *filename); - ///// 入力ストリームからモデルの読み込み //static std::unique_ptr ReadFromStream(std::istream *stream); }; } diff --git a/code/MMDVmdParser.h b/code/MMDVmdParser.h index c5057ef47..778ee1161 100644 --- a/code/MMDVmdParser.h +++ b/code/MMDVmdParser.h @@ -50,19 +50,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace vmd { - /// ボーンフレーム class VmdBoneFrame { public: - /// ボーン名 std::string name; - /// フレーム番号 int frame; - /// 位置 float position[3]; - /// 回転 float orientation[4]; - /// 補間曲線 char interpolation[4][4][4]; void Read(std::istream* stream) @@ -86,15 +80,11 @@ namespace vmd } }; - /// 表情フレーム class VmdFaceFrame { public: - /// 表情名 std::string face_name; - /// 表情の重み float weight; - /// フレーム番号 uint32_t frame; void Read(std::istream* stream) @@ -114,23 +104,15 @@ namespace vmd } }; - /// カメラフレーム class VmdCameraFrame { public: - /// フレーム番号 int frame; - /// 距離 float distance; - /// 位置 float position[3]; - /// 回転 float orientation[3]; - /// 補間曲線 char interpolation[6][4]; - /// 視野角 float angle; - /// 不明データ char unknown[3]; void Read(std::istream *stream) @@ -156,15 +138,11 @@ namespace vmd } }; - /// ライトフレーム class VmdLightFrame { public: - /// フレーム番号 int frame; - /// 色 float color[3]; - /// 位置 float position[3]; void Read(std::istream* stream) @@ -182,7 +160,6 @@ namespace vmd } }; - /// IKの有効無効 class VmdIkEnable { public: @@ -190,7 +167,6 @@ namespace vmd bool enable; }; - /// IKフレーム class VmdIkFrame { public: @@ -229,23 +205,15 @@ namespace vmd } }; - /// VMDモーション class VmdMotion { public: - /// モデル名 std::string model_name; - /// バージョン int version; - /// ボーンフレーム std::vector bone_frames; - /// 表情フレーム std::vector face_frames; - /// カメラフレーム std::vector camera_frames; - /// ライトフレーム std::vector light_frames; - /// IKフレーム std::vector ik_frames; static std::unique_ptr LoadFromFile(char const *filename) From 2938a259b8c55e5f37ecacf0e2e0caed9c2d7010 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Tue, 12 Sep 2017 19:09:22 +0300 Subject: [PATCH 70/90] Enable AddressSanitizer for Linux clang build --- .travis.sh | 2 +- .travis.yml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.sh b/.travis.sh index 7161fd28d..64aafe922 100755 --- a/.travis.sh +++ b/.travis.sh @@ -1,6 +1,6 @@ function generate() { - cmake -G "Unix Makefiles" -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD -DASSIMP_COVERALLS=$ENABLE_COVERALLS + cmake -G "Unix Makefiles" -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD -DASSIMP_COVERALLS=$ENABLE_COVERALLS -DASSIMP_ASAN=$ASAN } if [ $ANDROID ]; then diff --git a/.travis.yml b/.travis.yml index 38849dae4..bb1820cc4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,13 +28,13 @@ env: - secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc=" - PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME} matrix: - - os: linux LINUX=1 TRAVIS_NO_EXPORT=YES ENABLE_COVERALLS=ON + - os: linux LINUX=1 TRAVIS_NO_EXPORT=YES ENABLE_COVERALLS=ON ASAN=OFF compiler: gcc - - os: linux LINUX=1 TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF + - os: linux LINUX=1 TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF ASAN=ON compiler: clang - - os: linux LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF + - os: linux LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF ASAN=OFF compiler: gcc - - os: linux LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF + - os: linux LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF ASAN=OFF compiler: clang - os: osx osx_image: xcode8.2 From b6f122ff2c20bbd7ada5f45bdcfb4c29b5370c42 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Tue, 12 Sep 2017 19:00:44 +0300 Subject: [PATCH 71/90] Fix delete / delete[] mismatch in glTFAsset --- code/glTFAsset.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/glTFAsset.inl b/code/glTFAsset.inl index 91d36c59b..0a0de2ce3 100644 --- a/code/glTFAsset.inl +++ b/code/glTFAsset.inl @@ -332,7 +332,7 @@ inline bool Buffer::LoadFromStream(IOStream& stream, size_t length, size_t baseO stream.Seek(baseOffset, aiOrigin_SET); } - mData.reset(new uint8_t[byteLength]); + mData.reset(new uint8_t[byteLength], std::default_delete()); if (stream.Read(mData.get(), byteLength, 1) != 1) { return false; From 2cc0a378ed156dbefec62dffdf994aa6901dc177 Mon Sep 17 00:00:00 2001 From: Daniel Hritzkiv Date: Wed, 13 Sep 2017 11:23:12 -0400 Subject: [PATCH 72/90] Update glTF in list of importers and exporters --- Readme.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Readme.md b/Readme.md index a5c31881a..1eaa6b8e1 100644 --- a/Readme.md +++ b/Readme.md @@ -52,7 +52,8 @@ __Importers__: - DXF - ENFF - FBX -- GLB/GLTF +- glTF 1.0 + GLB +- glTF 2.0 - HMB - IFC-STEP - IRR / IRRMESH @@ -106,8 +107,8 @@ __Exporters__: - JSON (for WebGl, via https://github.com/acgessler/assimp2json) - ASSBIN - STEP -- glTF (partial) -- glTF2.0 +- glTF 1.0 (partial) +- glTF 2.0 (partial) ### Building ### Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do. From afd6c4d57ddfa8428c42afb63a953f76621c3718 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 13 Sep 2017 21:40:44 +0200 Subject: [PATCH 73/90] Revert "Asan" --- .travis.sh | 2 +- .travis.yml | 8 ++++---- CMakeLists.txt | 9 --------- code/glTFAsset.inl | 2 +- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/.travis.sh b/.travis.sh index 64aafe922..7161fd28d 100755 --- a/.travis.sh +++ b/.travis.sh @@ -1,6 +1,6 @@ function generate() { - cmake -G "Unix Makefiles" -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD -DASSIMP_COVERALLS=$ENABLE_COVERALLS -DASSIMP_ASAN=$ASAN + cmake -G "Unix Makefiles" -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD -DASSIMP_COVERALLS=$ENABLE_COVERALLS } if [ $ANDROID ]; then diff --git a/.travis.yml b/.travis.yml index bb1820cc4..38849dae4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,13 +28,13 @@ env: - secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc=" - PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME} matrix: - - os: linux LINUX=1 TRAVIS_NO_EXPORT=YES ENABLE_COVERALLS=ON ASAN=OFF + - os: linux LINUX=1 TRAVIS_NO_EXPORT=YES ENABLE_COVERALLS=ON compiler: gcc - - os: linux LINUX=1 TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF ASAN=ON + - os: linux LINUX=1 TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF compiler: clang - - os: linux LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF ASAN=OFF + - os: linux LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF compiler: gcc - - os: linux LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF ASAN=OFF + - os: linux LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF compiler: clang - os: osx osx_image: xcode8.2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 260b78698..690351e8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,10 +78,6 @@ OPTION ( ASSIMP_COVERALLS "Enable this to measure test coverage." OFF ) -OPTION ( ASSIMP_ASAN - "Enable AddressSanitizer." - OFF -) OPTION ( SYSTEM_IRRXML "Use system installed Irrlicht/IrrXML library." OFF @@ -216,11 +212,6 @@ if (ASSIMP_COVERALLS) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") endif() -if (ASSIMP_ASAN) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") -endif() - INCLUDE (FindPkgMacros) INCLUDE (PrecompiledHeader) diff --git a/code/glTFAsset.inl b/code/glTFAsset.inl index 61afebfb4..9284ccb02 100644 --- a/code/glTFAsset.inl +++ b/code/glTFAsset.inl @@ -341,7 +341,7 @@ inline bool Buffer::LoadFromStream(IOStream& stream, size_t length, size_t baseO stream.Seek(baseOffset, aiOrigin_SET); } - mData.reset(new uint8_t[byteLength], std::default_delete()); + mData.reset(new uint8_t[byteLength]); if (stream.Read(mData.get(), byteLength, 1) != 1) { return false; From 58213804ff82c5cd7deccd9478d4b0d5770c7992 Mon Sep 17 00:00:00 2001 From: vkovalev123 Date: Thu, 14 Sep 2017 14:55:02 +0300 Subject: [PATCH 74/90] Update 3DSLoader.cpp Fixed reading of CHINK_RGBF. If reading performs on x32 platform then reading will execute right, but on x64 it`s wrong because it will read 8 bytes instead 4. --- code/3DSLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/3DSLoader.cpp b/code/3DSLoader.cpp index 522bec307..704884a57 100644 --- a/code/3DSLoader.cpp +++ b/code/3DSLoader.cpp @@ -1381,7 +1381,7 @@ void Discreet3DSImporter::ParseColorChunk( aiColor3D* out, bool acceptPercent ) bGamma = true; case Discreet3DS::CHUNK_RGBF: - if (sizeof(ai_real) * 3 > diff) { + if (sizeof(float) * 3 > diff) { *out = clrError; return; } From 94a6fc78f423e18404e13ef271cc3fdbe77472ac Mon Sep 17 00:00:00 2001 From: Jared Mulconry Date: Fri, 15 Sep 2017 18:27:59 +1000 Subject: [PATCH 75/90] Addressed last remaining warning under MSVC caused by use of 'deprecated' fopen. --- contrib/irrXML/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contrib/irrXML/CMakeLists.txt b/contrib/irrXML/CMakeLists.txt index 980bd99a4..48941970a 100644 --- a/contrib/irrXML/CMakeLists.txt +++ b/contrib/irrXML/CMakeLists.txt @@ -8,6 +8,11 @@ set( IrrXML_SRCS irrXML.h ) +if ( MSVC ) + ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS ) + ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS ) +endif ( MSVC ) + add_library(IrrXML STATIC ${IrrXML_SRCS}) set(IRRXML_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "IrrXML_Include" ) set(IRRXML_LIBRARY "IrrXML" CACHE INTERNAL "IrrXML" ) From f2e2f74d730e19ab2a705d6f96bc56816e667f16 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 14 Sep 2017 10:54:02 +0300 Subject: [PATCH 76/90] Add CMake flag to treat warnings as errors --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 690351e8b..b404e6916 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,10 @@ OPTION ( ASSIMP_COVERALLS "Enable this to measure test coverage." OFF ) +OPTION ( ASSIMP_WERRRO + "Treat warnings as errors." + OFF +) OPTION ( SYSTEM_IRRXML "Use system installed Irrlicht/IrrXML library." OFF @@ -212,6 +216,11 @@ if (ASSIMP_COVERALLS) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") endif() +if (ASSIMP_WERROR) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") +endif() + INCLUDE (FindPkgMacros) INCLUDE (PrecompiledHeader) From 0b140db0a40fb7563964029af927785fe81cd5b2 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 14 Sep 2017 11:18:02 +0300 Subject: [PATCH 77/90] glTFExporter: Silence uninitialized variable warning This is a false positive, idx_srcdata_begin is only used if comp_allow is true and in that case it's also initialized. --- code/glTFExporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/glTFExporter.cpp b/code/glTFExporter.cpp index 8967a7aa7..7215a98c3 100644 --- a/code/glTFExporter.cpp +++ b/code/glTFExporter.cpp @@ -507,7 +507,7 @@ void glTFExporter::ExportMeshes() // Variables needed for compression. BEGIN. // Indices, not pointers - because pointer to buffer is changing while writing to it. - size_t idx_srcdata_begin;// Index of buffer before writing mesh data. Also, index of begin of coordinates array in buffer. + size_t idx_srcdata_begin = 0; // Index of buffer before writing mesh data. Also, index of begin of coordinates array in buffer. size_t idx_srcdata_normal = SIZE_MAX;// Index of begin of normals array in buffer. SIZE_MAX - mean that mesh has no normals. std::vector idx_srcdata_tc;// Array of indices. Every index point to begin of texture coordinates array in buffer. size_t idx_srcdata_ind;// Index of begin of coordinates indices array in buffer. From b9efc234d0cbc08f0d09135d4cca56298cf8adfd Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 14 Sep 2017 11:22:32 +0300 Subject: [PATCH 78/90] DefaultLogger: Whitespace cleanup to fix GCC misleading indentation warning --- code/DefaultLogger.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/DefaultLogger.cpp b/code/DefaultLogger.cpp index 5a6f19544..b69e18ea9 100644 --- a/code/DefaultLogger.cpp +++ b/code/DefaultLogger.cpp @@ -253,8 +253,8 @@ void DefaultLogger::kill() // Debug message void DefaultLogger::OnDebug( const char* message ) { - if ( m_Severity == Logger::NORMAL ) - return; + if ( m_Severity == Logger::NORMAL ) + return; static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16; char msg[Size]; From f4a0ab81b1d711c1151bee390e0ed5189d2f5560 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 14 Sep 2017 11:25:19 +0300 Subject: [PATCH 79/90] AssbinExporter: Add Write specialization for aiColor3D --- code/AssbinExporter.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 4ea261718..bd2ed0b95 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -139,6 +139,17 @@ inline size_t Write(IOStream * stream, const aiVector3D& v) return t; } +// ----------------------------------------------------------------------------------- +// Serialize a color value +template <> +inline size_t Write(IOStream * stream, const aiColor3D& v) +{ + size_t t = Write(stream,v.r); + t += Write(stream,v.g); + t += Write(stream,v.b); + return t; +} + // ----------------------------------------------------------------------------------- // Serialize a color value template <> From 046c229e486369ee52ec45db37e18a022cc511d3 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Fri, 15 Sep 2017 12:41:40 +0300 Subject: [PATCH 80/90] AssbinExporter: Fix strict aliasing violation --- code/AssbinExporter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index bd2ed0b95..a6fbcd8f7 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -650,9 +650,9 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size) Write(&chunk,l->mAttenuationQuadratic); } - Write(&chunk,(const aiVector3D&)l->mColorDiffuse); - Write(&chunk,(const aiVector3D&)l->mColorSpecular); - Write(&chunk,(const aiVector3D&)l->mColorAmbient); + Write(&chunk,l->mColorDiffuse); + Write(&chunk,l->mColorSpecular); + Write(&chunk,l->mColorAmbient); if (l->mType == aiLightSource_SPOT) { Write(&chunk,l->mAngleInnerCone); From f1998d52dce46b33e669f671a0672ba4dde752fc Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Thu, 14 Sep 2017 12:19:03 +0300 Subject: [PATCH 81/90] Importer: Whitespace cleanup to fix GCC misleading indentation warning --- code/Importer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index eb0119693..379daab02 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -831,8 +831,8 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) pimpl->mProgressHandler->UpdatePostProcess( static_cast(pimpl->mPostProcessingSteps.size()), static_cast(pimpl->mPostProcessingSteps.size()) ); // update private scene flags - if( pimpl->mScene ) - ScenePriv(pimpl->mScene)->mPPStepsApplied |= pFlags; + if( pimpl->mScene ) + ScenePriv(pimpl->mScene)->mPPStepsApplied |= pFlags; // clear any data allocated by post-process steps pimpl->mPPShared->Clean(); From 01c50394ce1e870e744ec2537c271562276f474a Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Fri, 15 Sep 2017 12:31:52 +0300 Subject: [PATCH 82/90] FBXParser: Silence uninitialized variable warnings --- code/FBXParser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/FBXParser.cpp b/code/FBXParser.cpp index cf6930e22..b5661caf8 100644 --- a/code/FBXParser.cpp +++ b/code/FBXParser.cpp @@ -281,7 +281,7 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out) unsigned int length = static_cast(t.end() - t.begin()); ai_assert(length > 0); - const char* out; + const char* out = nullptr; const uint64_t id = strtoul10_64(t.begin(),&out,&length); if (out > t.end()) { err_out = "failed to parse ID (text)"; @@ -327,7 +327,7 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out) return 0; } - const char* out; + const char* out = nullptr; const size_t id = static_cast(strtoul10_64(t.begin() + 1,&out,&length)); if (out > t.end()) { err_out = "failed to parse ID"; @@ -440,7 +440,7 @@ int64_t ParseTokenAsInt64(const Token& t, const char*& err_out) unsigned int length = static_cast(t.end() - t.begin()); ai_assert(length > 0); - const char* out; + const char* out = nullptr; const int64_t id = strtol10_64(t.begin(), &out, &length); if (out > t.end()) { err_out = "failed to parse Int64 (text)"; From 234ffc0ad6a22c590209216f4d727252e75cb0b9 Mon Sep 17 00:00:00 2001 From: Richard Mitton Date: Fri, 15 Sep 2017 12:39:58 -0700 Subject: [PATCH 83/90] Fixed truncated material names The previous Unicode library change accidentally trimmed off the last character of SIB material names. --- code/SIBImporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/SIBImporter.cpp b/code/SIBImporter.cpp index 6cd398f48..3fa66bd77 100644 --- a/code/SIBImporter.cpp +++ b/code/SIBImporter.cpp @@ -201,7 +201,7 @@ static aiString ReadString(StreamReaderLE* stream, uint32_t numWChars) //ConvertUTF16toUTF8(&start, end, &dest, limit, lenientConversion); //*dest = '\0'; - str[str.size()-1] = '\0'; + str[str.size()] = '\0'; // Return the final string. aiString result = aiString((const char *)&str[0]); //delete[] str; From f602055da5e63675913bf3747b1b754dae31e0cd Mon Sep 17 00:00:00 2001 From: Richard Mitton Date: Fri, 15 Sep 2017 12:40:38 -0700 Subject: [PATCH 84/90] Added Silo 2.5 support Silo 2.5 bumps the version number of SIB files for no apparent reason. Doesn't appear to be any other changes to the file format. --- code/SIBImporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/SIBImporter.cpp b/code/SIBImporter.cpp index 3fa66bd77..4ae2ab7d4 100644 --- a/code/SIBImporter.cpp +++ b/code/SIBImporter.cpp @@ -827,7 +827,7 @@ static void ReadInstance(SIB* sib, StreamReaderLE* stream) static void CheckVersion(StreamReaderLE* stream) { uint32_t version = stream->GetU4(); - if ( version != 1 ) { + if ( version < 1 || version > 2 ) { throw DeadlyImportError( "SIB: Unsupported file version." ); } } From 5478d4d4c758f4f652399bb0597e5f3bc96a53c9 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 16 Sep 2017 15:22:37 +0300 Subject: [PATCH 85/90] travis: Move os declarations earlier --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 38849dae4..c02be9e06 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,10 @@ branches: only: - master +os: + - linux + - osx + osx_image: xcode8.3 env: @@ -50,9 +54,6 @@ script: - export COVERALLS_SERVICE_NAME=travis-ci - export COVERALLS_REPO_TOKEN=abc12345 - . ./.travis.sh -os: - - linux - - osx after_success: - if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && lcov --directory . --capture --output-file coverage.info && lcov --remove coverage.info '/usr/*' 'contrib/*' 'test/*' --output-file coverage.info && lcov --list coverage.info && coveralls-lcov --source-encoding=ISO-8859-1 --repo-token=${COVERALLS_TOKEN} coverage.info ; fi From 167fb7e250a813e1f96bb7903d212a2fd490ae4b Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 16 Sep 2017 15:34:32 +0300 Subject: [PATCH 86/90] travis: Correctly minimize build matrix --- .travis.yml | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index c02be9e06..ddb3fedd9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,17 +31,29 @@ env: # COVERITY_SCAN_TOKEN - secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc=" - PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME} - matrix: - - os: linux LINUX=1 TRAVIS_NO_EXPORT=YES ENABLE_COVERALLS=ON + +matrix: + exclude: + - os: linux + env: + + include: + - os: linux compiler: gcc - - os: linux LINUX=1 TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF - compiler: clang - - os: linux LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF + env: LINUX=1 TRAVIS_NO_EXPORT=YES ENABLE_COVERALLS=ON + - os: linux compiler: gcc - - os: linux LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF - compiler: clang + env: LINUX=1 TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF + - os: linux + compiler: gcc + env: LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF + - os: linux + compiler: gcc + env: LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF - os: osx + compiler: clang osx_image: xcode8.2 + env: install: - if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi From 798d2d063ced4a922bd41b3eb9f7630830e022e8 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 16 Sep 2017 15:52:18 +0300 Subject: [PATCH 87/90] travis: Only build with xcode 8.3 --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index ddb3fedd9..6c29561e3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,8 +24,6 @@ os: - linux - osx -osx_image: xcode8.3 - env: global: # COVERITY_SCAN_TOKEN @@ -52,7 +50,7 @@ matrix: env: LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF - os: osx compiler: clang - osx_image: xcode8.2 + osx_image: xcode8.3 env: install: From cf8453a21a5661e4a486c82dcc87fb5a64670d68 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 16 Sep 2017 15:53:02 +0300 Subject: [PATCH 88/90] travis: Enable ccache --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6c29561e3..a75c5e94b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,8 @@ sudo: required language: cpp +cache: ccache + before_install: - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq && sudo apt-get install cmake && sudo apt-get install cmake python3 && sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- ; fi - 'if [ "$TRAVIS_OS_NAME" = "osx" ]; then From 69f8dc9b31550594c719ebc0358b73fa76e0cc17 Mon Sep 17 00:00:00 2001 From: Turo Lamminen Date: Sat, 16 Sep 2017 17:59:47 +0300 Subject: [PATCH 89/90] Travis: Disable OS X build since it doesn't do anything currently --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index a75c5e94b..cf0988517 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,6 @@ branches: os: - linux - - osx env: global: @@ -50,10 +49,6 @@ matrix: - os: linux compiler: gcc env: LINUX=1 SHARED_BUILD=ON TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF - - os: osx - compiler: clang - osx_image: xcode8.3 - env: install: - if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi From c207e745349a18da5366286d2e8a18a21e2ce41c Mon Sep 17 00:00:00 2001 From: Jeremy Cowles Date: Sun, 17 Sep 2017 10:06:57 -0700 Subject: [PATCH 90/90] Fix glTF 2.0 multi-primitive support Previously, only one primitive was supported, in fact memory was corrupted when more than one primitive was found per glTF mesh. In this change, each primitive is unrolled as a new Assimp Mesh, resulting in multiple Assimp meshes per node when multiple primitives exist per glTF mesh. This is required in the general case, since glTF primitives can have different material bindings and primitive modes. --- code/glTF2Importer.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 34f12b5af..6de482981 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -518,13 +518,22 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector& } if (node.mesh) { - ainode->mNumMeshes = 1; - ainode->mMeshes = new unsigned int[1]; - int k = 0; int idx = node.mesh.GetIndex(); - for (unsigned int j = meshOffsets[idx]; j < meshOffsets[idx + 1]; ++j, ++k) { + ai_assert(idx >= 0 && idx < meshOffsets.size()); + + unsigned int offBegin = meshOffsets[idx]; + unsigned int offEnd = meshOffsets[idx + 1]; + int k = 0; + + ai_assert(offEnd >= offBegin); + + ainode->mNumMeshes = offEnd - offBegin; + ainode->mMeshes = new unsigned int[ainode->mNumMeshes]; + + for (unsigned int j = offBegin; j < offEnd; ++j, ++k) { + ai_assert(k < ainode->mNumMeshes); ainode->mMeshes[k] = j; } }