Working read, import, export, and write of gltf2 (pbr) material
parent
6b4286abf6
commit
11cb9ac139
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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 ********************/
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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] = '-';
|
||||
|
|
Loading…
Reference in New Issue