Merge pull request #1015 from ascandal/feature/fix-glTF-validator-errors
Fix glTF validator errorspull/1019/head
commit
f94b7287fc
16
CHANGES
16
CHANGES
|
@ -2,6 +2,22 @@
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
3.2.1 (2016-10-01)
|
||||||
|
|
||||||
|
FEATURES:
|
||||||
|
- Updated glTF exporter to meet 1.0 specification.
|
||||||
|
|
||||||
|
FIXES/HOUSEKEEPING:
|
||||||
|
- Fixed glTF Validator errors for exported glTF format.
|
||||||
|
|
||||||
|
ISSUES:
|
||||||
|
- Hard coded sampler setting for
|
||||||
|
- magFilter
|
||||||
|
- minFilter
|
||||||
|
- void* in ExportData for accessor max and min.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
3.2.0 (2015-11-03)
|
3.2.0 (2015-11-03)
|
||||||
|
|
||||||
FEATURES:
|
FEATURES:
|
||||||
|
|
|
@ -236,6 +236,32 @@ namespace glTF
|
||||||
BufferViewTarget_ELEMENT_ARRAY_BUFFER = 34963
|
BufferViewTarget_ELEMENT_ARRAY_BUFFER = 34963
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! Values for the Sampler::magFilter field
|
||||||
|
enum SamplerMagFilter
|
||||||
|
{
|
||||||
|
SamplerMagFilter_Nearest = 9728,
|
||||||
|
SamplerMagFilter_Linear = 9729
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Values for the Sampler::minFilter field
|
||||||
|
enum SamplerMinFilter
|
||||||
|
{
|
||||||
|
SamplerMinFilter_Nearest = 9728,
|
||||||
|
SamplerMinFilter_Linear = 9729,
|
||||||
|
SamplerMinFilter_Nearest_Mipmap_Nearest = 9984,
|
||||||
|
SamplerMinFilter_Linear_Mipmap_Nearest = 9985,
|
||||||
|
SamplerMinFilter_Nearest_Mipmap_Linear = 9986,
|
||||||
|
SamplerMinFilter_Linear_Mipmap_Linear = 9987
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Values for the Sampler::wrapS and Sampler::wrapT field
|
||||||
|
enum SamplerWrap
|
||||||
|
{
|
||||||
|
SamplerWrap_Clamp_To_Edge = 33071,
|
||||||
|
SamplerWrap_Mirrored_Repeat = 33648,
|
||||||
|
SamplerWrap_Repeat = 10497
|
||||||
|
};
|
||||||
|
|
||||||
//! Values for the Texture::format and Texture::internalFormat fields
|
//! Values for the Texture::format and Texture::internalFormat fields
|
||||||
enum TextureFormat
|
enum TextureFormat
|
||||||
{
|
{
|
||||||
|
@ -377,8 +403,8 @@ namespace glTF
|
||||||
ComponentType componentType; //!< The datatype of components in the attribute. (required)
|
ComponentType componentType; //!< The datatype of components in the attribute. (required)
|
||||||
unsigned int count; //!< The number of attributes referenced by this accessor. (required)
|
unsigned int count; //!< The number of attributes referenced by this accessor. (required)
|
||||||
AttribType::Value type; //!< Specifies if the attribute is a scalar, vector, or matrix. (required)
|
AttribType::Value type; //!< Specifies if the attribute is a scalar, vector, or matrix. (required)
|
||||||
//std::vector<float> max; //!< Maximum value of each component in this attribute.
|
std::vector<float> max; //!< Maximum value of each component in this attribute.
|
||||||
//std::vector<float> min; //!< Minimum value of each component in this attribute.
|
std::vector<float> min; //!< Minimum value of each component in this attribute.
|
||||||
|
|
||||||
unsigned int GetNumComponents();
|
unsigned int GetNumComponents();
|
||||||
unsigned int GetBytesPerComponent();
|
unsigned int GetBytesPerComponent();
|
||||||
|
@ -812,8 +838,14 @@ namespace glTF
|
||||||
|
|
||||||
struct Sampler : public Object
|
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)
|
||||||
|
|
||||||
Sampler() {}
|
Sampler() {}
|
||||||
void Read(Value& obj, Asset& r);
|
void Read(Value& obj, Asset& r);
|
||||||
|
void SetDefaults();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Scene : public Object
|
struct Scene : public Object
|
||||||
|
@ -860,7 +892,7 @@ namespace glTF
|
||||||
//! A texture and its sampler.
|
//! A texture and its sampler.
|
||||||
struct Texture : public Object
|
struct Texture : public Object
|
||||||
{
|
{
|
||||||
//Ref<Sampler> source; //!< The ID of the sampler used by this texture. (required)
|
Ref<Sampler> sampler; //!< The ID of the sampler used by this texture. (required)
|
||||||
Ref<Image> source; //!< The ID of the image used by this texture. (required)
|
Ref<Image> source; //!< The ID of the image used by this texture. (required)
|
||||||
|
|
||||||
//TextureFormat format; //!< The texture's format. (default: TextureFormat_RGBA)
|
//TextureFormat format; //!< The texture's format. (default: TextureFormat_RGBA)
|
||||||
|
@ -1049,7 +1081,7 @@ namespace glTF
|
||||||
LazyDict<Mesh> meshes;
|
LazyDict<Mesh> meshes;
|
||||||
LazyDict<Node> nodes;
|
LazyDict<Node> nodes;
|
||||||
//LazyDict<Program> programs;
|
//LazyDict<Program> programs;
|
||||||
//LazyDict<Sampler> samplers;
|
LazyDict<Sampler> samplers;
|
||||||
LazyDict<Scene> scenes;
|
LazyDict<Scene> scenes;
|
||||||
//LazyDict<Shader> shaders;
|
//LazyDict<Shader> shaders;
|
||||||
//LazyDict<Skin> skins;
|
//LazyDict<Skin> skins;
|
||||||
|
@ -1074,7 +1106,7 @@ namespace glTF
|
||||||
, meshes (*this, "meshes")
|
, meshes (*this, "meshes")
|
||||||
, nodes (*this, "nodes")
|
, nodes (*this, "nodes")
|
||||||
//, programs (*this, "programs")
|
//, programs (*this, "programs")
|
||||||
//, samplers (*this, "samplers")
|
, samplers (*this, "samplers")
|
||||||
, scenes (*this, "scenes")
|
, scenes (*this, "scenes")
|
||||||
//, shaders (*this, "shaders")
|
//, shaders (*this, "shaders")
|
||||||
//, skins (*this, "skins")
|
//, skins (*this, "skins")
|
||||||
|
|
|
@ -665,12 +665,35 @@ inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Sampler::Read(Value& obj, Asset& r)
|
||||||
|
{
|
||||||
|
SetDefaults();
|
||||||
|
|
||||||
|
ReadMember(obj, "magFilter", magFilter);
|
||||||
|
ReadMember(obj, "minFilter", minFilter);
|
||||||
|
ReadMember(obj, "wrapS", wrapS);
|
||||||
|
ReadMember(obj, "wrapT", wrapT);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Sampler::SetDefaults()
|
||||||
|
{
|
||||||
|
magFilter = SamplerMagFilter_Linear;
|
||||||
|
minFilter = SamplerMinFilter_Linear;
|
||||||
|
wrapS = SamplerWrap_Repeat;
|
||||||
|
wrapT = SamplerWrap_Repeat;
|
||||||
|
}
|
||||||
|
|
||||||
inline void Texture::Read(Value& obj, Asset& r)
|
inline void Texture::Read(Value& obj, Asset& r)
|
||||||
{
|
{
|
||||||
const char* sourcestr;
|
const char* sourcestr;
|
||||||
if (ReadMember(obj, "source", sourcestr)) {
|
if (ReadMember(obj, "source", sourcestr)) {
|
||||||
source = r.images.Get(sourcestr);
|
source = r.images.Get(sourcestr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* samplerstr;
|
||||||
|
if (ReadMember(obj, "sampler", samplerstr)) {
|
||||||
|
sampler = r.samplers.Get(samplerstr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -62,6 +62,15 @@ namespace glTF {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Value& MakeValue(Value& val, const std::vector<float> & r, MemoryPoolAllocator<>& al) {
|
||||||
|
val.SetArray();
|
||||||
|
val.Reserve(r.size(), al);
|
||||||
|
for (int i = 0; i < r.size(); ++i) {
|
||||||
|
val.PushBack(r[i], al);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void AddRefsVector(Value& obj, const char* fieldId, std::vector< Ref<T> >& v, MemoryPoolAllocator<>& al) {
|
inline void AddRefsVector(Value& obj, const char* fieldId, std::vector< Ref<T> >& v, MemoryPoolAllocator<>& al) {
|
||||||
if (v.empty()) return;
|
if (v.empty()) return;
|
||||||
|
@ -85,6 +94,10 @@ namespace glTF {
|
||||||
obj.AddMember("componentType", int(a.componentType), w.mAl);
|
obj.AddMember("componentType", int(a.componentType), w.mAl);
|
||||||
obj.AddMember("count", a.count, w.mAl);
|
obj.AddMember("count", a.count, w.mAl);
|
||||||
obj.AddMember("type", StringRef(AttribType::ToString(a.type)), w.mAl);
|
obj.AddMember("type", StringRef(AttribType::ToString(a.type)), w.mAl);
|
||||||
|
|
||||||
|
Value vTmpMax, vTmpMin;
|
||||||
|
obj.AddMember("max", MakeValue(vTmpMax, a.max, w.mAl), w.mAl);
|
||||||
|
obj.AddMember("min", MakeValue(vTmpMin, a.min, w.mAl), w.mAl);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Write(Value& obj, Animation& a, AssetWriter& w)
|
inline void Write(Value& obj, Animation& a, AssetWriter& w)
|
||||||
|
@ -323,7 +336,18 @@ namespace glTF {
|
||||||
|
|
||||||
inline void Write(Value& obj, Sampler& b, AssetWriter& w)
|
inline void Write(Value& obj, Sampler& b, AssetWriter& w)
|
||||||
{
|
{
|
||||||
|
if (b.wrapS) {
|
||||||
|
obj.AddMember("wrapS", b.wrapS, w.mAl);
|
||||||
|
}
|
||||||
|
if (b.wrapT) {
|
||||||
|
obj.AddMember("wrapT", b.wrapT, w.mAl);
|
||||||
|
}
|
||||||
|
if (b.magFilter) {
|
||||||
|
obj.AddMember("magFilter", b.magFilter, w.mAl);
|
||||||
|
}
|
||||||
|
if (b.minFilter) {
|
||||||
|
obj.AddMember("minFilter", b.minFilter, w.mAl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Write(Value& scene, Scene& s, AssetWriter& w)
|
inline void Write(Value& scene, Scene& s, AssetWriter& w)
|
||||||
|
@ -351,6 +375,9 @@ namespace glTF {
|
||||||
if (tex.source) {
|
if (tex.source) {
|
||||||
obj.AddMember("source", Value(tex.source->id, w.mAl).Move(), w.mAl);
|
obj.AddMember("source", Value(tex.source->id, w.mAl).Move(), w.mAl);
|
||||||
}
|
}
|
||||||
|
if (tex.sampler) {
|
||||||
|
obj.AddMember("sampler", Value(tex.sampler->id, w.mAl).Move(), w.mAl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Write(Value& obj, Light& b, AssetWriter& w)
|
inline void Write(Value& obj, Light& b, AssetWriter& w)
|
||||||
|
@ -493,7 +520,9 @@ namespace glTF {
|
||||||
Value asset;
|
Value asset;
|
||||||
asset.SetObject();
|
asset.SetObject();
|
||||||
{
|
{
|
||||||
asset.AddMember("version", mAsset.asset.version, mAl);
|
char versionChar[10];
|
||||||
|
ai_snprintf(versionChar, sizeof(versionChar), "%d", mAsset.asset.version);
|
||||||
|
asset.AddMember("version", Value(versionChar, mAl).Move(), mAl);
|
||||||
|
|
||||||
asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl);
|
asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,6 +193,36 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
|
||||||
acc->count = count;
|
acc->count = count;
|
||||||
acc->type = typeOut;
|
acc->type = typeOut;
|
||||||
|
|
||||||
|
// calculate min and max values
|
||||||
|
{
|
||||||
|
// Allocate and initialize with large values.
|
||||||
|
float float_MAX = 10000000000000;
|
||||||
|
for (int i = 0 ; i < numCompsOut ; i++) {
|
||||||
|
acc->min.push_back( float_MAX);
|
||||||
|
acc->max.push_back(-float_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search and set extreme values.
|
||||||
|
float valueTmp;
|
||||||
|
for (int i = 0 ; i < count ; i++) {
|
||||||
|
for (int j = 0 ; j < numCompsOut ; j++) {
|
||||||
|
|
||||||
|
if (numCompsOut == 1) {
|
||||||
|
valueTmp = static_cast<unsigned short*>(data)[i];
|
||||||
|
} else {
|
||||||
|
valueTmp = static_cast<aiVector3D*>(data)[i][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueTmp < acc->min[j]) {
|
||||||
|
acc->min[j] = valueTmp;
|
||||||
|
}
|
||||||
|
if (valueTmp > acc->max[j]) {
|
||||||
|
acc->max[j] = valueTmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// copy the data
|
// copy the data
|
||||||
acc->WriteData(count, data, numCompsIn*bytesPerComp);
|
acc->WriteData(count, data, numCompsIn*bytesPerComp);
|
||||||
|
|
||||||
|
@ -205,6 +235,52 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void glTFExporter::GetTexSampler(const aiMaterial* mat, glTF::TexProperty& prop)
|
||||||
|
{
|
||||||
|
std::string samplerId = mAsset->FindUniqueID("", "sampler");
|
||||||
|
prop.texture->sampler = mAsset->samplers.Create(samplerId);
|
||||||
|
|
||||||
|
aiTextureMapMode mapU, mapV;
|
||||||
|
aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0),(int*)&mapU);
|
||||||
|
aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0),(int*)&mapV);
|
||||||
|
|
||||||
|
switch (mapU) {
|
||||||
|
case aiTextureMapMode_Wrap:
|
||||||
|
prop.texture->sampler->wrapS = SamplerWrap_Repeat;
|
||||||
|
break;
|
||||||
|
case aiTextureMapMode_Clamp:
|
||||||
|
prop.texture->sampler->wrapS = SamplerWrap_Clamp_To_Edge;
|
||||||
|
break;
|
||||||
|
case aiTextureMapMode_Mirror:
|
||||||
|
prop.texture->sampler->wrapS = SamplerWrap_Mirrored_Repeat;
|
||||||
|
break;
|
||||||
|
case aiTextureMapMode_Decal:
|
||||||
|
default:
|
||||||
|
prop.texture->sampler->wrapS = SamplerWrap_Repeat;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (mapV) {
|
||||||
|
case aiTextureMapMode_Wrap:
|
||||||
|
prop.texture->sampler->wrapT = SamplerWrap_Repeat;
|
||||||
|
break;
|
||||||
|
case aiTextureMapMode_Clamp:
|
||||||
|
prop.texture->sampler->wrapT = SamplerWrap_Clamp_To_Edge;
|
||||||
|
break;
|
||||||
|
case aiTextureMapMode_Mirror:
|
||||||
|
prop.texture->sampler->wrapT = SamplerWrap_Mirrored_Repeat;
|
||||||
|
break;
|
||||||
|
case aiTextureMapMode_Decal:
|
||||||
|
default:
|
||||||
|
prop.texture->sampler->wrapT = SamplerWrap_Repeat;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hard coded Texture filtering options because I do not know where to find them in the aiMaterial.
|
||||||
|
prop.texture->sampler->magFilter = SamplerMagFilter_Linear;
|
||||||
|
prop.texture->sampler->minFilter = SamplerMinFilter_Linear;
|
||||||
|
}
|
||||||
|
|
||||||
void glTFExporter::GetMatColorOrTex(const aiMaterial* mat, glTF::TexProperty& prop, const char* propName, int type, int idx, aiTextureType tt)
|
void glTFExporter::GetMatColorOrTex(const aiMaterial* mat, glTF::TexProperty& prop, const char* propName, int type, int idx, aiTextureType tt)
|
||||||
{
|
{
|
||||||
aiString tex;
|
aiString tex;
|
||||||
|
@ -244,6 +320,8 @@ void glTFExporter::GetMatColorOrTex(const aiMaterial* mat, glTF::TexProperty& pr
|
||||||
else {
|
else {
|
||||||
prop.texture->source->uri = path;
|
prop.texture->source->uri = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetTexSampler(mat, prop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,6 +332,7 @@ void glTFExporter::GetMatColorOrTex(const aiMaterial* mat, glTF::TexProperty& pr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void glTFExporter::ExportMaterials()
|
void glTFExporter::ExportMaterials()
|
||||||
{
|
{
|
||||||
aiString aiName;
|
aiString aiName;
|
||||||
|
@ -369,7 +448,7 @@ void glTFExporter::ExportMeshes()
|
||||||
|
|
||||||
if(comp_allow) idx_srcdata_tc.push_back(b->byteLength);// Store index of texture coordinates array.
|
if(comp_allow) idx_srcdata_tc.push_back(b->byteLength);// Store index of texture coordinates array.
|
||||||
|
|
||||||
Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, true);
|
Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, false);
|
||||||
if (tc) p.attributes.texcoord.push_back(tc);
|
if (tc) p.attributes.texcoord.push_back(tc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,7 @@ namespace Assimp
|
||||||
|
|
||||||
void WriteBinaryData(IOStream* outfile, std::size_t sceneLength);
|
void WriteBinaryData(IOStream* outfile, std::size_t sceneLength);
|
||||||
|
|
||||||
|
void GetTexSampler(const aiMaterial* mat, glTF::TexProperty& prop);
|
||||||
void GetMatColorOrTex(const aiMaterial* mat, glTF::TexProperty& prop, const char* propName, int type, int idx, aiTextureType tt);
|
void GetMatColorOrTex(const aiMaterial* mat, glTF::TexProperty& prop, const char* propName, int type, int idx, aiTextureType tt);
|
||||||
void ExportMetadata();
|
void ExportMetadata();
|
||||||
void ExportMaterials();
|
void ExportMaterials();
|
||||||
|
|
Loading…
Reference in New Issue