diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index cece307d9..4aa56e9ef 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -181,13 +181,17 @@ namespace glTF2 #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_SCALE_BASE "$tex.scale" + #define _AI_MATKEY_GLTF_STRENGTH_BASE "$tex.strength" #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 - + #define AI_MATKEY_GLTF_TEXTURE_SCALE(type, N) _AI_MATKEY_GLTF_SCALE_BASE, type, N + #define AI_MATKEY_GLTF_TEXTURE_STRENGTH(type, N) _AI_MATKEY_GLTF_STRENGTH_BASE, type, N + #ifdef ASSIMP_API #include "./../include/assimp/Compiler/pushpack1.h" #endif diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 94e5ca3f1..40917f441 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -99,14 +99,14 @@ const aiImporterDesc* glTF2Importer::GetInfo() const return &desc; } -bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const +bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool /* checkSig */) const { const std::string &extension = GetExtension(pFile); if (extension != "gltf" && extension != "glb") return false; - if (checkSig && pIOHandler) { + if (pIOHandler) { glTF2::Asset asset(pIOHandler); try { asset.Load(pFile, extension == "glb"); @@ -211,63 +211,90 @@ inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& } } +inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::NormalTextureInfo& prop, aiMaterial* mat, aiTextureType texType, unsigned int texSlot = 0) +{ + SetMaterialTextureProperty( embeddedTexIdxs, r, (glTF2::TextureInfo) prop, mat, texType, texSlot ); + + if (prop.texture && prop.texture->source) { + mat->AddProperty(&prop.scale, 1, AI_MATKEY_GLTF_TEXTURE_SCALE(texType, texSlot)); + } +} + +inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::OcclusionTextureInfo& prop, aiMaterial* mat, aiTextureType texType, unsigned int texSlot = 0) +{ + SetMaterialTextureProperty( embeddedTexIdxs, r, (glTF2::TextureInfo) prop, mat, texType, texSlot ); + + if (prop.texture && prop.texture->source) { + mat->AddProperty(&prop.strength, 1, AI_MATKEY_GLTF_TEXTURE_STRENGTH(texType, texSlot)); + } +} + +static aiMaterial* ImportMaterial(std::vector& embeddedTexIdxs, Asset& r, Material& mat) +{ + aiMaterial* aimat = new aiMaterial(); + + if (!mat.name.empty()) { + aiString str(mat.name); + + aimat->AddProperty(&str, AI_MATKEY_NAME); + } + + SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); + SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR); + + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE); + + 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); + + float roughnessAsShininess = (1 - mat.pbrMetallicRoughness.roughnessFactor) * 1000; + aimat->AddProperty(&roughnessAsShininess, 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); + + aiString alphaMode(mat.alphaMode); + aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE); + aimat->AddProperty(&mat.alphaCutoff, 1, AI_MATKEY_GLTF_ALPHACUTOFF); + + //pbrSpecularGlossiness + if (mat.pbrSpecularGlossiness.isPresent) { + PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value; + + aimat->AddProperty(&mat.pbrSpecularGlossiness.isPresent, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS); + SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); + SetMaterialColorProperty(r, pbrSG.specularFactor, aimat, AI_MATKEY_COLOR_SPECULAR); + + float glossinessAsShininess = pbrSG.glossinessFactor * 1000.0f; + aimat->AddProperty(&glossinessAsShininess, 1, AI_MATKEY_SHININESS); + aimat->AddProperty(&pbrSG.glossinessFactor, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR); + + SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.diffuseTexture, aimat, aiTextureType_DIFFUSE); + + SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.specularGlossinessTexture, aimat, aiTextureType_SPECULAR); + } + + return aimat; +} + void glTF2Importer::ImportMaterials(glTF2::Asset& r) { - mScene->mNumMaterials = unsigned(r.materials.Size()); + const unsigned int numImportedMaterials = unsigned(r.materials.Size()); + Material defaultMaterial; + + mScene->mNumMaterials = numImportedMaterials + 1; mScene->mMaterials = new aiMaterial*[mScene->mNumMaterials]; + mScene->mMaterials[numImportedMaterials] = ImportMaterial(embeddedTexIdxs, r, defaultMaterial); - 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.name); - - aimat->AddProperty(&str, AI_MATKEY_NAME); - } - - SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); - SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR); - - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE); - - 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); - - float roughnessAsShininess = (1 - mat.pbrMetallicRoughness.roughnessFactor) * 1000; - aimat->AddProperty(&roughnessAsShininess, 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); - - aiString alphaMode(mat.alphaMode); - aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE); - aimat->AddProperty(&mat.alphaCutoff, 1, AI_MATKEY_GLTF_ALPHACUTOFF); - - //pbrSpecularGlossiness - if (mat.pbrSpecularGlossiness.isPresent) { - PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value; - - aimat->AddProperty(&mat.pbrSpecularGlossiness.isPresent, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS); - SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); - SetMaterialColorProperty(r, pbrSG.specularFactor, aimat, AI_MATKEY_COLOR_SPECULAR); - - float glossinessAsShininess = pbrSG.glossinessFactor * 1000.0f; - aimat->AddProperty(&glossinessAsShininess, 1, AI_MATKEY_SHININESS); - aimat->AddProperty(&pbrSG.glossinessFactor, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR); - - SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.diffuseTexture, aimat, aiTextureType_DIFFUSE); - - SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.specularGlossinessTexture, aimat, aiTextureType_SPECULAR); - } + for (unsigned int i = 0; i < numImportedMaterials; ++i) { + mScene->mMaterials[i] = ImportMaterial(embeddedTexIdxs, r, r.materials[i]); } } @@ -479,6 +506,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r) if (prim.material) { aim->mMaterialIndex = prim.material.GetIndex(); } + else { + aim->mMaterialIndex = mScene->mNumMaterials - 1; + } + } } @@ -499,6 +530,9 @@ void glTF2Importer::ImportCameras(glTF2::Asset& r) aiCamera* aicam = mScene->mCameras[i] = new aiCamera(); + // cameras point in -Z by default, rest is specified in node transform + aicam->mLookAt = aiVector3D(0.f,0.f,-1.f); + if (cam.type == Camera::Perspective) { aicam->mAspect = cam.cameraProperties.perspective.aspectRatio; diff --git a/code/glTFImporter.cpp b/code/glTFImporter.cpp index 381e459fd..e5a1ae883 100644 --- a/code/glTFImporter.cpp +++ b/code/glTFImporter.cpp @@ -98,14 +98,14 @@ const aiImporterDesc* glTFImporter::GetInfo() const return &desc; } -bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const +bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool /* checkSig */) const { const std::string &extension = GetExtension(pFile); if (extension != "gltf" && extension != "glb") return false; - if (checkSig && pIOHandler) { + if (pIOHandler) { glTF::Asset asset(pIOHandler); try { asset.Load(pFile, extension == "glb"); diff --git a/doc/dox.h b/doc/dox.h index 2672adcb5..afd6e487a 100644 --- a/doc/dox.h +++ b/doc/dox.h @@ -533,8 +533,9 @@ assimp::Importer::ReadFile(), aiImportFile() or aiImportFileEx() - see the @link for further information on how to use the library. By default, all 3D data is provided in a right-handed coordinate system such as OpenGL uses. In -this coordinate system, +X points to the right, -Z points away from the viewer into the screen and -+Y points upwards. Several modeling packages such as 3D Studio Max use this coordinate system as well (or a rotated variant of it). +this coordinate system, +X points to the right, +Y points upwards and +Z points out of the screen +towards the viewer. Several modeling packages such as 3D Studio Max use this coordinate system as well +(or a rotated variant of it). By contrast, some other environments use left-handed coordinate systems, a prominent example being DirectX. If you need the imported data to be in a left-handed coordinate system, supply the #aiProcess_MakeLeftHanded flag to the ReadFile() function call. @@ -552,7 +553,7 @@ although our built-in triangulation (#aiProcess_Triangulate postprocessing step) The output UV coordinate system has its origin in the lower-left corner: @code -0y|1y ---------- 1x|1y +0x|1y ---------- 1x|1y | | | | | | @@ -568,8 +569,7 @@ X2 Y2 Z2 T2 X3 Y3 Z3 T3 0 0 0 1 @endcode - -... with (X1, X2, X3) being the X base vector, (Y1, Y2, Y3) being the Y base vector, (Z1, Z2, Z3) +with (X1, X2, X3) being the X base vector, (Y1, Y2, Y3) being the Y base vector, (Z1, Z2, Z3) being the Z base vector and (T1, T2, T3) being the translation part. If you want to use these matrices in DirectX functions, you have to transpose them. @@ -664,7 +664,7 @@ See the @link materials Material System Page. @endlink @section bones Bones -A mesh may have a set of bones in the form of aiBone structures.. Bones are a means to deform a mesh +A mesh may have a set of bones in the form of aiBone objects. Bones are a means to deform a mesh according to the movement of a skeleton. Each bone has a name and a set of vertices on which it has influence. Its offset matrix declares the transformation needed to transform from mesh space to the local space of this bone.