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
enum SamplerMagFilter
enum class SamplerMagFilter: unsigned int
{
UNSET = 0,
SamplerMagFilter_Nearest = 9728,
SamplerMagFilter_Linear = 9729
};
//! Values for the Sampler::minFilter field
enum SamplerMinFilter
enum class SamplerMinFilter: unsigned int
{
UNSET = 0,
SamplerMinFilter_Nearest = 9728,
SamplerMinFilter_Linear = 9729,
SamplerMinFilter_Nearest_Mipmap_Nearest = 9984,
@ -260,11 +262,12 @@ namespace glTF2
};
//! Values for the Sampler::wrapS and Sampler::wrapT field
enum SamplerWrap
enum class SamplerWrap: unsigned int
{
SamplerWrap_Clamp_To_Edge = 33071,
SamplerWrap_Mirrored_Repeat = 33648,
SamplerWrap_Repeat = 10497
UNSET = 0,
Clamp_To_Edge = 33071,
Mirrored_Repeat = 33648,
Repeat = 10497
};
//! Values for the Texture::format and Texture::internalFormat fields
@ -795,10 +798,10 @@ namespace glTF2
struct Sampler : public Object
{
SamplerMagFilter magFilter; //!< The texture magnification filter. (required)
SamplerMinFilter minFilter; //!< The texture minification filter. (required)
SamplerWrap wrapS; //!< The texture wrapping in the S direction. (required)
SamplerWrap wrapT; //!< The texture wrapping in the T direction. (required)
SamplerMagFilter magFilter; //!< The texture magnification filter.
SamplerMinFilter minFilter; //!< The texture minification filter.
SamplerWrap wrapS; //!< The texture wrapping in the S direction.
SamplerWrap wrapT; //!< The texture wrapping in the T direction.
Sampler() { SetDefaults(); }
void Read(Value& obj, Asset& r);
@ -955,6 +958,8 @@ namespace glTF2
Ref<T> Get(unsigned int i);
Ref<T> Get(const char* id);
bool Has(const char* id);
Ref<T> Create(const char* id);
Ref<T> Create(const std::string& id)
{ 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);
}
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>
@ -697,6 +707,7 @@ inline void Sampler::Read(Value& obj, Asset& r)
{
SetDefaults();
ReadMember(obj, "name", name);
ReadMember(obj, "magFilter", magFilter);
ReadMember(obj, "minFilter", minFilter);
ReadMember(obj, "wrapS", wrapS);
@ -705,10 +716,11 @@ inline void Sampler::Read(Value& obj, Asset& r)
inline void Sampler::SetDefaults()
{
magFilter = SamplerMagFilter_Linear;
minFilter = SamplerMinFilter_Linear;
wrapS = SamplerWrap_Repeat;
wrapT = SamplerWrap_Repeat;
//only wrapping modes have defaults
wrapS = SamplerWrap::Repeat;
wrapT = SamplerWrap::Repeat;
magFilter = SamplerMagFilter::UNSET;
minFilter = SamplerMinFilter::UNSET;
}
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,
// 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;
Mesh::AccessorList* vec = 0;
if (GetAttribVector(prim, attr, vec, undPos)) {
@ -943,7 +954,6 @@ inline void Node::Read(Value& obj, Asset& r)
}
}
if (Value* matrix = FindArray(obj, "matrix")) {
ReadValue(*matrix, this->matrix);
}
@ -978,7 +988,6 @@ inline void Scene::Read(Value& obj, Asset& r)
}
}
inline void AssetMetadata::Read(Document& doc)
{
// read the version, etc.
@ -1013,8 +1022,6 @@ inline void AssetMetadata::Read(Document& doc)
}
}
//
// Asset methods implementation
//
@ -1142,7 +1149,6 @@ inline void Asset::SetAsBinary()
}
}
inline void Asset::ReadExtensionsUsed(Document& doc)
{
Value* extsUsed = FindArray(doc, "extensionsUsed");

View File

@ -467,17 +467,24 @@ namespace glTF2 {
inline void Write(Value& obj, Sampler& b, AssetWriter& w)
{
if (b.wrapS) {
obj.AddMember("wrapS", b.wrapS, w.mAl);
if (!b.name.empty()) {
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;
}
void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref<Texture> texture)
inline void SetSamplerWrap(SamplerWrap& wrap, aiTextureMapMode map)
{
std::string samplerId = mAsset->FindUniqueID("", "sampler");
texture->sampler = mAsset->samplers.Create(samplerId);
switch (map) {
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;
aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0),(int*)&mapU);
aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0),(int*)&mapV);
SamplerMagFilter filterMag;
SamplerMinFilter filterMin;
switch (mapU) {
case aiTextureMapMode_Wrap:
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;
};
if (aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_U(tt, slot), (int*)&mapU) == AI_SUCCESS) {
SetSamplerWrap(texture->sampler->wrapS, mapU);
}
switch (mapV) {
case aiTextureMapMode_Wrap:
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;
};
if (aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_V(tt, slot), (int*)&mapV) == AI_SUCCESS) {
SetSamplerWrap(texture->sampler->wrapT, mapV);
}
// Hard coded Texture filtering options because I do not know where to find them in the aiMaterial.
texture->sampler->magFilter = SamplerMagFilter_Linear;
texture->sampler->minFilter = SamplerMinFilter_Linear_Mipmap_Linear;
if (aiGetMaterialInteger(mat, (std::string(_AI_MATKEY_MAPPING_BASE) + "filtermag").c_str(), tt, slot, (int*)&filterMag) == AI_SUCCESS) {
texture->sampler->magFilter = filterMag;
}
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)
@ -324,7 +337,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTe
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) {
const aiMaterial* mat = mScene->mMaterials[i];
std::string id = "material_" + std::to_string(i);
Ref<Material> m = mAsset->materials.Create(id);
std::string name;
if (mat->Get(AI_MATKEY_NAME, aiName) == AI_SUCCESS) {
name = aiName.C_Str();
}
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.metallicRoughnessTexture, aiTextureType_UNKNOWN, 0);//get unknown slot
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->occlusionTexture, aiTextureType_LIGHTMAP);
@ -409,8 +428,6 @@ void glTF2Exporter::ExportMaterials()
mat->Get(AI_MATKEY_TWOSIDED, m->doubleSided);
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);
bool hasPbrSpecularGlossiness;

View File

@ -108,7 +108,7 @@ namespace Assimp
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, 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);

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();
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);
}
}
}
}