Working read, import, export, and write of gltf2 (pbr) material

pull/1423/head
Daniel Hritzkiv 2017-08-30 17:25:11 -04:00
parent 6b4286abf6
commit 11cb9ac139
No known key found for this signature in database
GPG Key ID: D1D19875679D5CBF
6 changed files with 329 additions and 135 deletions

View File

@ -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> 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> 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<Texture> baseColorTexture;
Ref<Texture> metallicRoughnessTexture;
vec4 baseColorFactor;
TextureInfo baseColorTexture;
TextureInfo metallicRoughnessTexture;
float metallicFactor;
float roughnessFactor;
//other basic material properties
Ref<Texture> normalTexture;
Ref<Texture> occlusionTexture;
Ref<Texture> 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<Texture> normal;
Ref<Texture> normal;*/
Technique technique;

View File

@ -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<T> LazyDict<T>::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)

View File

@ -72,6 +72,12 @@ namespace glTF2 {
return val;
}
inline Value& MakeValue(Value& val, float r, MemoryPoolAllocator<>& al) {
val.SetDouble(r);
return val;
}
template<class T>
inline void AddRefsVector(Value& obj, const char* fieldId, std::vector< Ref<T> >& v, MemoryPoolAllocator<>& al) {
if (v.empty()) return;
@ -196,51 +202,148 @@ namespace glTF2 {
}
namespace {
inline void WriteTex(Value& obj, Ref<Texture> 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<size_t N>
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<size_t N>
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())

View File

@ -234,12 +234,6 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& 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> texture)
{
std::string samplerId = mAsset->FindUniqueID("", "sampler");
@ -286,11 +280,11 @@ void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref<Texture> texture)
texture->sampler->minFilter = SamplerMinFilter_Linear_Mipmap_Linear;
}
void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTextureType tt)
void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& 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>& 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<Material> 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<Mesh> 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 ********************/

View File

@ -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<glTF2::Texture> texture);
void GetMatTex(const aiMaterial* mat, glTF2::Ref<glTF2::Texture>& 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<glTF2::Texture>& 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();

View File

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