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 writtenpull/1423/head
parent
7245cceead
commit
a9c4fa84b5
|
@ -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()); }
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue