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
pull/1423/head
Daniel Hritzkiv 2017-09-03 22:09:48 -04:00
parent 7245cceead
commit a9c4fa84b5
No known key found for this signature in database
GPG Key ID: D1D19875679D5CBF
6 changed files with 123 additions and 67 deletions

View File

@ -242,15 +242,17 @@ namespace glTF2
}; };
//! Values for the Sampler::magFilter field //! Values for the Sampler::magFilter field
enum SamplerMagFilter enum class SamplerMagFilter: unsigned int
{ {
UNSET = 0,
SamplerMagFilter_Nearest = 9728, SamplerMagFilter_Nearest = 9728,
SamplerMagFilter_Linear = 9729 SamplerMagFilter_Linear = 9729
}; };
//! Values for the Sampler::minFilter field //! Values for the Sampler::minFilter field
enum SamplerMinFilter enum class SamplerMinFilter: unsigned int
{ {
UNSET = 0,
SamplerMinFilter_Nearest = 9728, SamplerMinFilter_Nearest = 9728,
SamplerMinFilter_Linear = 9729, SamplerMinFilter_Linear = 9729,
SamplerMinFilter_Nearest_Mipmap_Nearest = 9984, SamplerMinFilter_Nearest_Mipmap_Nearest = 9984,
@ -260,11 +262,12 @@ namespace glTF2
}; };
//! Values for the Sampler::wrapS and Sampler::wrapT field //! Values for the Sampler::wrapS and Sampler::wrapT field
enum SamplerWrap enum class SamplerWrap: unsigned int
{ {
SamplerWrap_Clamp_To_Edge = 33071, UNSET = 0,
SamplerWrap_Mirrored_Repeat = 33648, Clamp_To_Edge = 33071,
SamplerWrap_Repeat = 10497 Mirrored_Repeat = 33648,
Repeat = 10497
}; };
//! Values for the Texture::format and Texture::internalFormat fields //! Values for the Texture::format and Texture::internalFormat fields
@ -795,10 +798,10 @@ namespace glTF2
struct Sampler : public Object struct Sampler : public Object
{ {
SamplerMagFilter magFilter; //!< The texture magnification filter. (required) SamplerMagFilter magFilter; //!< The texture magnification filter.
SamplerMinFilter minFilter; //!< The texture minification filter. (required) SamplerMinFilter minFilter; //!< The texture minification filter.
SamplerWrap wrapS; //!< The texture wrapping in the S direction. (required) SamplerWrap wrapS; //!< The texture wrapping in the S direction.
SamplerWrap wrapT; //!< The texture wrapping in the T direction. (required) SamplerWrap wrapT; //!< The texture wrapping in the T direction.
Sampler() { SetDefaults(); } Sampler() { SetDefaults(); }
void Read(Value& obj, Asset& r); void Read(Value& obj, Asset& r);
@ -955,6 +958,8 @@ namespace glTF2
Ref<T> Get(unsigned int i); Ref<T> Get(unsigned int i);
Ref<T> Get(const char* id); Ref<T> Get(const char* id);
bool Has(const char* id);
Ref<T> Create(const char* id); Ref<T> Create(const char* id);
Ref<T> Create(const std::string& id) Ref<T> Create(const std::string& id)
{ return Create(id.c_str()); } { return Create(id.c_str()); }

View File

@ -244,7 +244,17 @@ Ref<T> LazyDict<T>::Get(const char* id)
return Ref<T>(mObjs, it->second); return Ref<T>(mObjs, it->second);
} }
throw std::out_of_range("id \"" + std::string(id) + "\" Doesn't exist"); return Create(id);
}
template<class T>
bool LazyDict<T>::Has(const char* id)
{
id = T::TranslateId(mAsset, id);
typename IdDict::iterator it = mObjsById.find(id);
return it != mObjsById.end();
} }
template<class T> template<class T>
@ -697,6 +707,7 @@ inline void Sampler::Read(Value& obj, Asset& r)
{ {
SetDefaults(); SetDefaults();
ReadMember(obj, "name", name);
ReadMember(obj, "magFilter", magFilter); ReadMember(obj, "magFilter", magFilter);
ReadMember(obj, "minFilter", minFilter); ReadMember(obj, "minFilter", minFilter);
ReadMember(obj, "wrapS", wrapS); ReadMember(obj, "wrapS", wrapS);
@ -705,10 +716,11 @@ inline void Sampler::Read(Value& obj, Asset& r)
inline void Sampler::SetDefaults() inline void Sampler::SetDefaults()
{ {
magFilter = SamplerMagFilter_Linear; //only wrapping modes have defaults
minFilter = SamplerMinFilter_Linear; wrapS = SamplerWrap::Repeat;
wrapS = SamplerWrap_Repeat; wrapT = SamplerWrap::Repeat;
wrapT = SamplerWrap_Repeat; magFilter = SamplerMagFilter::UNSET;
minFilter = SamplerMinFilter::UNSET;
} }
inline void Texture::Read(Value& obj, Asset& r) 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, // 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. // 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; int undPos = 0;
Mesh::AccessorList* vec = 0; Mesh::AccessorList* vec = 0;
if (GetAttribVector(prim, attr, vec, undPos)) { if (GetAttribVector(prim, attr, vec, undPos)) {
@ -943,7 +954,6 @@ inline void Node::Read(Value& obj, Asset& r)
} }
} }
if (Value* matrix = FindArray(obj, "matrix")) { if (Value* matrix = FindArray(obj, "matrix")) {
ReadValue(*matrix, this->matrix); ReadValue(*matrix, this->matrix);
} }
@ -978,7 +988,6 @@ inline void Scene::Read(Value& obj, Asset& r)
} }
} }
inline void AssetMetadata::Read(Document& doc) inline void AssetMetadata::Read(Document& doc)
{ {
// read the version, etc. // read the version, etc.
@ -1013,8 +1022,6 @@ inline void AssetMetadata::Read(Document& doc)
} }
} }
// //
// Asset methods implementation // Asset methods implementation
// //
@ -1142,7 +1149,6 @@ inline void Asset::SetAsBinary()
} }
} }
inline void Asset::ReadExtensionsUsed(Document& doc) inline void Asset::ReadExtensionsUsed(Document& doc)
{ {
Value* extsUsed = FindArray(doc, "extensionsUsed"); Value* extsUsed = FindArray(doc, "extensionsUsed");

View File

@ -467,17 +467,24 @@ namespace glTF2 {
inline void Write(Value& obj, Sampler& b, AssetWriter& w) inline void Write(Value& obj, Sampler& b, AssetWriter& w)
{ {
if (b.wrapS) { if (!b.name.empty()) {
obj.AddMember("wrapS", b.wrapS, w.mAl); 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<unsigned int>(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<unsigned int>(b.wrapT), w.mAl);
} }
if (b.minFilter) {
obj.AddMember("minFilter", b.minFilter, w.mAl); if (b.magFilter != SamplerMagFilter::UNSET) {
obj.AddMember("magFilter", static_cast<unsigned int>(b.magFilter), w.mAl);
}
if (b.minFilter != SamplerMinFilter::UNSET) {
obj.AddMember("minFilter", static_cast<unsigned int>(b.minFilter), w.mAl);
} }
} }

View File

@ -223,50 +223,63 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
return acc; return acc;
} }
void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref<Texture> texture) inline void SetSamplerWrap(SamplerWrap& wrap, aiTextureMapMode map)
{ {
std::string samplerId = mAsset->FindUniqueID("", "sampler"); switch (map) {
texture->sampler = mAsset->samplers.Create(samplerId); case aiTextureMapMode_Clamp:
wrap = SamplerWrap::Clamp_To_Edge;
break;
case aiTextureMapMode_Mirror:
wrap = SamplerWrap::Mirrored_Repeat;
break;
case aiTextureMapMode_Wrap:
case aiTextureMapMode_Decal:
default:
wrap = SamplerWrap::Repeat;
break;
};
}
void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref<Texture> 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; aiTextureMapMode mapU, mapV;
aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0),(int*)&mapU); SamplerMagFilter filterMag;
aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0),(int*)&mapV); SamplerMinFilter filterMin;
switch (mapU) { if (aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_U(tt, slot), (int*)&mapU) == AI_SUCCESS) {
case aiTextureMapMode_Wrap: SetSamplerWrap(texture->sampler->wrapS, mapU);
texture->sampler->wrapS = SamplerWrap_Repeat; }
break;
case aiTextureMapMode_Clamp:
texture->sampler->wrapS = SamplerWrap_Clamp_To_Edge;
break;
case aiTextureMapMode_Mirror:
texture->sampler->wrapS = SamplerWrap_Mirrored_Repeat;
break;
case aiTextureMapMode_Decal:
default:
texture->sampler->wrapS = SamplerWrap_Repeat;
break;
};
switch (mapV) { if (aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_V(tt, slot), (int*)&mapV) == AI_SUCCESS) {
case aiTextureMapMode_Wrap: SetSamplerWrap(texture->sampler->wrapT, mapV);
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;
break;
};
// Hard coded Texture filtering options because I do not know where to find them in the aiMaterial. if (aiGetMaterialInteger(mat, (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermag").c_str(), tt, slot, (int*)&filterMag) == AI_SUCCESS) {
texture->sampler->magFilter = SamplerMagFilter_Linear; texture->sampler->magFilter = filterMag;
texture->sampler->minFilter = SamplerMinFilter_Linear_Mipmap_Linear; }
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) 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>& texture, aiTe
texture->source->uri = path; 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) { for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
const aiMaterial* mat = mScene->mMaterials[i]; const aiMaterial* mat = mScene->mMaterials[i];
std::string id = "material_" + std::to_string(i);
Ref<Material> m = mAsset->materials.Create(id);
std::string name; std::string name;
if (mat->Get(AI_MATKEY_NAME, aiName) == AI_SUCCESS) { if (mat->Get(AI_MATKEY_NAME, aiName) == AI_SUCCESS) {
name = aiName.C_Str(); name = aiName.C_Str();
} }
name = mAsset->FindUniqueID(name, "material"); name = mAsset->FindUniqueID(name, "material");
Ref<Material> m = mAsset->materials.Create(name); m->name = name;
GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_DIFFUSE); GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_DIFFUSE);
GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, aiTextureType_UNKNOWN, 0);//get unknown slot GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, aiTextureType_UNKNOWN, 0);//get unknown slot
GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE); 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->normalTexture, aiTextureType_NORMALS);
GetMatTex(mat, m->occlusionTexture, aiTextureType_LIGHTMAP); GetMatTex(mat, m->occlusionTexture, aiTextureType_LIGHTMAP);
@ -409,8 +428,6 @@ void glTF2Exporter::ExportMaterials()
mat->Get(AI_MATKEY_TWOSIDED, m->doubleSided); mat->Get(AI_MATKEY_TWOSIDED, m->doubleSided);
mat->Get("$mat.gltf.alphaCutoff", 0, 0, m->alphaCutoff); 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); mat->Get("$mat.gltf.alphaMode", 0, 0, m->alphaMode);
bool hasPbrSpecularGlossiness; bool hasPbrSpecularGlossiness;

View File

@ -108,7 +108,7 @@ namespace Assimp
void WriteBinaryData(IOStream* outfile, std::size_t sceneLength); void WriteBinaryData(IOStream* outfile, std::size_t sceneLength);
void GetTexSampler(const aiMaterial* mat, glTF2::Ref<glTF2::Texture> texture); void GetTexSampler(const aiMaterial* mat, glTF2::Ref<glTF2::Texture> 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, 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 GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int idx);
void GetMatTex(const aiMaterial* mat, glTF2::Ref<glTF2::Texture>& texture, aiTextureType tt, unsigned int slot); void GetMatTex(const aiMaterial* mat, glTF2::Ref<glTF2::Texture>& texture, aiTextureType tt, unsigned int slot);

View File

@ -194,6 +194,27 @@ inline void SetMaterialTextureProperty(std::vector<int>& embeddedTexIdxs, Asset&
const char *texCoordName = (std::string(_AI_MATKEY_TEXTURE_BASE) + ".texCoord").c_str(); 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, texCoordName, texType, texSlot);
if (prop.texture->sampler) {
Ref<Sampler> 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);
}
}
} }
} }