Fixed GLTF bugs, and added a few test models

This commit is contained in:
Otger
2016-05-10 16:25:15 +02:00
parent a55e31bc72
commit 159af06524
18 changed files with 1343 additions and 15 deletions
+7 -1
View File
@@ -355,6 +355,10 @@ namespace glTF
{ return false; }
virtual ~Object() {}
//! Maps special IDs to another ID, where needed. Subclasses may override it (statically)
static const char* TranslateId(Asset& r, const char* id)
{ return id; }
};
@@ -484,6 +488,8 @@ namespace glTF
bool IsSpecial() const
{ return mIsSpecial; }
static const char* TranslateId(Asset& r, const char* id);
};
@@ -766,7 +772,7 @@ namespace glTF
//! (Implemented in glTFAssetWriter.h)
template<class T>
void WriteLazyDict(LazyDict<T>& d, AssetWriter& w);
//! Manages lazy loading of the glTF top-level objects, and keeps a reference to them by ID
//! It is the owner the loaded objects, so when it is destroyed it also deletes them
+28 -9
View File
@@ -184,6 +184,8 @@ Ref<T> LazyDict<T>::Get(unsigned int i)
template<class T>
Ref<T> LazyDict<T>::Get(const char* id)
{
id = T::TranslateId(mAsset, id);
typename Dict::iterator it = mObjsById.find(id);
if (it != mObjsById.end()) { // already created?
return Ref<T>(mObjs, it->second);
@@ -191,7 +193,7 @@ Ref<T> LazyDict<T>::Get(const char* id)
// read it from the JSON object
if (!mDict) {
return Ref<T>(); // section is missing
throw DeadlyImportError("GLTF: Missing section \"" + std::string(mDictId) + "\"");
}
Value::MemberIterator obj = mDict->FindMember(id);
@@ -242,6 +244,15 @@ inline Buffer::Buffer()
: byteLength(0), type(Type_arraybuffer), mIsSpecial(false)
{ }
inline const char* Buffer::TranslateId(Asset& r, const char* id)
{
// Compatibility with old spec
if (r.extensionsUsed.KHR_binary_glTF && strcmp(id, "KHR_binary_glTF") == 0) {
return "binary_glTF";
}
return id;
}
inline void Buffer::Read(Value& obj, Asset& r)
{
@@ -266,10 +277,16 @@ inline void Buffer::Read(Value& obj, Asset& r)
this->mData.reset(data);
if (statedLength > 0 && this->byteLength != statedLength) {
throw DeadlyImportError("GLTF: buffer length mismatch");
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + std::to_string(statedLength) +
" bytes, but found " + std::to_string(dataURI.dataLength));
}
}
else { // assume raw data
if (statedLength != dataURI.dataLength) {
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + std::to_string(statedLength) +
" bytes, but found " + std::to_string(dataURI.dataLength));
}
this->mData.reset(new uint8_t[dataURI.dataLength]);
memcmp(dataURI.data, this->mData.get(), dataURI.dataLength);
}
@@ -589,14 +606,16 @@ inline void Material::Read(Value& material, Asset& r)
else if (strcmp(t, "CONSTANT") == 0) technique = Technique_CONSTANT;
}
ReadMaterialProperty(r, *ext, "ambient", this->ambient);
ReadMaterialProperty(r, *ext, "diffuse", this->diffuse);
ReadMaterialProperty(r, *ext, "specular", this->specular);
if (Value* values = FindObject(*ext, "values")) {
ReadMaterialProperty(r, *values, "ambient", this->ambient);
ReadMaterialProperty(r, *values, "diffuse", this->diffuse);
ReadMaterialProperty(r, *values, "specular", this->specular);
ReadMember(*ext, "doubleSided", doubleSided);
ReadMember(*ext, "transparent", transparent);
ReadMember(*ext, "transparency", transparency);
ReadMember(*ext, "shininess", shininess);
ReadMember(*values, "doubleSided", doubleSided);
ReadMember(*values, "transparent", transparent);
ReadMember(*values, "transparency", transparency);
ReadMember(*values, "shininess", shininess);
}
}
}
}
+23 -5
View File
@@ -214,14 +214,14 @@ void glTFImporter::ImportMaterials(glTF::Asset& r)
}
inline void SetFace(aiFace& face, int a)
static inline void SetFace(aiFace& face, int a)
{
face.mNumIndices = 1;
face.mIndices = new unsigned int[1];
face.mIndices[0] = a;
}
inline void SetFace(aiFace& face, int a, int b)
static inline void SetFace(aiFace& face, int a, int b)
{
face.mNumIndices = 2;
face.mIndices = new unsigned int[2];
@@ -229,7 +229,7 @@ inline void SetFace(aiFace& face, int a, int b)
face.mIndices[1] = b;
}
inline void SetFace(aiFace& face, int a, int b, int c)
static inline void SetFace(aiFace& face, int a, int b, int c)
{
face.mNumIndices = 3;
face.mIndices = new unsigned int[3];
@@ -238,6 +238,18 @@ inline void SetFace(aiFace& face, int a, int b, int c)
face.mIndices[2] = c;
}
static inline bool CheckValidFacesIndices(aiFace* faces, unsigned nFaces, unsigned nVerts)
{
for (unsigned i = 0; i < nFaces; ++i) {
for (unsigned j = 0; j < faces[i].mNumIndices; ++j) {
unsigned idx = faces[i].mIndices[j];
if (idx >= nVerts)
return false;
}
}
return true;
}
void glTFImporter::ImportMeshes(glTF::Asset& r)
{
std::vector<aiMesh*> meshes;
@@ -294,6 +306,11 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
for (size_t tc = 0; tc < attr.texcoord.size() && tc <= AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
aiVector3D* values = aim->mTextureCoords[tc];
for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
values[i].y = 1 - values[i].y; // Flip Y coords
}
}
@@ -304,7 +321,7 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
unsigned int count = prim.indices->count;
Accessor::Indexer data = prim.indices->GetIndexer();
assert(data.IsValid());
ai_assert(data.IsValid());
switch (prim.mode) {
case PrimitiveMode_POINTS: {
@@ -369,6 +386,7 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
if (faces) {
aim->mFaces = faces;
aim->mNumFaces = nFaces;
ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
}
}
@@ -466,7 +484,7 @@ aiNode* ImportNode(aiScene* pScene, glTF::Asset& r, std::vector<unsigned int>& m
}
}
aiMatrix4x4 matrix = ainode->mTransformation;
aiMatrix4x4& matrix = ainode->mTransformation;
if (node.matrix.isPresent) {
CopyValue(node.matrix.value, matrix);
}