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] = '-';