Merge branch 'master' into search-invalid-textures-missing-texture-types

pull/3000/head
Kim Kulling 2020-02-14 18:04:30 +01:00 committed by GitHub
commit bdd5e52176
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 125 additions and 65 deletions

View File

@ -448,15 +448,14 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
std::vector<T> tempData; std::vector<T> tempData;
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName)); ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
if (tempData.size() != vertex_count) { if (tempData.size() != mapping_offsets.size()) {
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByVertice mapping: ") FBXImporter::LogError(Formatter::format("length of input data unexpected for ByVertice mapping: ")
<< tempData.size() << ", expected " << vertex_count); << tempData.size() << ", expected " << mapping_offsets.size());
return; return;
} }
data_out.resize(vertex_count); data_out.resize(vertex_count);
for (size_t i = 0, e = tempData.size(); i < e; ++i) { for (size_t i = 0, e = tempData.size(); i < e; ++i) {
const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i]; const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i];
for (unsigned int j = istart; j < iend; ++j) { for (unsigned int j = istart; j < iend; ++j) {
data_out[mappings[j]] = tempData[i]; data_out[mappings[j]] = tempData[i];

View File

@ -367,8 +367,12 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
// first - next in the fbx token stream comes ',', // first - next in the fbx token stream comes ',',
// which fast_atof could interpret as decimal point. // which fast_atof could interpret as decimal point.
#define MAX_FLOAT_LENGTH 31 #define MAX_FLOAT_LENGTH 31
char temp[MAX_FLOAT_LENGTH + 1];
const size_t length = static_cast<size_t>(t.end()-t.begin()); const size_t length = static_cast<size_t>(t.end()-t.begin());
if (length > MAX_FLOAT_LENGTH) {
return 0.f;
}
char temp[MAX_FLOAT_LENGTH + 1];
std::copy(t.begin(), t.end(), temp); std::copy(t.begin(), t.end(), temp);
temp[std::min(static_cast<size_t>(MAX_FLOAT_LENGTH),length)] = '\0'; temp[std::min(static_cast<size_t>(MAX_FLOAT_LENGTH),length)] = '\0';

View File

@ -109,7 +109,9 @@ using namespace std;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Default constructor // Default constructor
M3DImporter::M3DImporter() : M3DImporter::M3DImporter() :
mScene(nullptr) {} mScene(nullptr) {
// empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns true, if file is a binary or ASCII Model 3D file. // Returns true, if file is a binary or ASCII Model 3D file.
@ -225,7 +227,7 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// convert materials. properties are converted using a static table in M3DMaterials.h // convert materials. properties are converted using a static table in M3DMaterials.h
void M3DImporter::importMaterials(const M3DWrapper &m3d_wrap) { void M3DImporter::importMaterials(const M3DWrapper &m3d) {
unsigned int i, j, k, l, n; unsigned int i, j, k, l, n;
m3dm_t *m; m3dm_t *m;
aiString name = aiString(AI_DEFAULT_MATERIAL_NAME); aiString name = aiString(AI_DEFAULT_MATERIAL_NAME);
@ -233,9 +235,9 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d_wrap) {
ai_real f; ai_real f;
ai_assert(mScene != nullptr); ai_assert(mScene != nullptr);
ai_assert(m3d_wrap); ai_assert(m3d);
mScene->mNumMaterials = m3d_wrap->nummaterial + 1; mScene->mNumMaterials = m3d->nummaterial + 1;
mScene->mMaterials = new aiMaterial *[mScene->mNumMaterials]; mScene->mMaterials = new aiMaterial *[mScene->mNumMaterials];
ASSIMP_LOG_DEBUG_F("M3D: importMaterials ", mScene->mNumMaterials); ASSIMP_LOG_DEBUG_F("M3D: importMaterials ", mScene->mNumMaterials);
@ -248,8 +250,12 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d_wrap) {
mat->AddProperty(&c, 1, AI_MATKEY_COLOR_DIFFUSE); mat->AddProperty(&c, 1, AI_MATKEY_COLOR_DIFFUSE);
mScene->mMaterials[0] = mat; mScene->mMaterials[0] = mat;
for (i = 0; i < m3d_wrap->nummaterial; i++) { if (!m3d->nummaterial || !m3d->material) {
m = &m3d_wrap->material[i]; return;
}
for (i = 0; i < m3d->nummaterial; i++) {
m = &m3d->material[i];
aiMaterial *mat = new aiMaterial; aiMaterial *mat = new aiMaterial;
name.Set(std::string(m->name)); name.Set(std::string(m->name));
mat->AddProperty(&name, AI_MATKEY_NAME); mat->AddProperty(&name, AI_MATKEY_NAME);
@ -294,9 +300,9 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d_wrap) {
// texture map properties // texture map properties
if (m->prop[j].type >= 128 && aiTxProps[k].pKey && if (m->prop[j].type >= 128 && aiTxProps[k].pKey &&
// extra check, should never happen, do we have the refered texture? // extra check, should never happen, do we have the refered texture?
m->prop[j].value.textureid < m3d_wrap->numtexture && m->prop[j].value.textureid < m3d->numtexture &&
m3d_wrap->texture[m->prop[j].value.textureid].name) { m3d->texture[m->prop[j].value.textureid].name) {
name.Set(std::string(std::string(m3d_wrap->texture[m->prop[j].value.textureid].name) + ".png")); name.Set(std::string(std::string(m3d->texture[m->prop[j].value.textureid].name) + ".png"));
mat->AddProperty(&name, aiTxProps[k].pKey, aiTxProps[k].type, aiTxProps[k].index); mat->AddProperty(&name, aiTxProps[k].pKey, aiTxProps[k].type, aiTxProps[k].index);
n = 0; n = 0;
mat->AddProperty(&n, 1, _AI_MATKEY_UVWSRC_BASE, aiProps[k].type, aiProps[k].index); mat->AddProperty(&n, 1, _AI_MATKEY_UVWSRC_BASE, aiProps[k].type, aiProps[k].index);
@ -310,7 +316,12 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d_wrap) {
// import textures, this is the simplest of all // import textures, this is the simplest of all
void M3DImporter::importTextures(const M3DWrapper &m3d) { void M3DImporter::importTextures(const M3DWrapper &m3d) {
unsigned int i; unsigned int i;
const char *formatHint[] = { "rgba0800", "rgba0808", "rgba8880", "rgba8888" }; const char *formatHint[] = {
"rgba0800",
"rgba0808",
"rgba8880",
"rgba8888"
};
m3dtx_t *t; m3dtx_t *t;
ai_assert(mScene != nullptr); ai_assert(mScene != nullptr);
@ -319,8 +330,9 @@ void M3DImporter::importTextures(const M3DWrapper &m3d) {
mScene->mNumTextures = m3d->numtexture; mScene->mNumTextures = m3d->numtexture;
ASSIMP_LOG_DEBUG_F("M3D: importTextures ", mScene->mNumTextures); ASSIMP_LOG_DEBUG_F("M3D: importTextures ", mScene->mNumTextures);
if (!m3d->numtexture) if (!m3d->numtexture || !m3d->texture) {
return; return;
}
mScene->mTextures = new aiTexture *[m3d->numtexture]; mScene->mTextures = new aiTexture *[m3d->numtexture];
for (i = 0; i < m3d->numtexture; i++) { for (i = 0; i < m3d->numtexture; i++) {
@ -371,6 +383,12 @@ void M3DImporter::importTextures(const M3DWrapper &m3d) {
// individually. In assimp there're per mesh vertex and UV lists, and they must be // individually. In assimp there're per mesh vertex and UV lists, and they must be
// indexed simultaneously. // indexed simultaneously.
void M3DImporter::importMeshes(const M3DWrapper &m3d) { void M3DImporter::importMeshes(const M3DWrapper &m3d) {
ASSIMP_LOG_DEBUG_F("M3D: importMeshes ", m3d->numface);
if (!m3d->numface || !m3d->face || !m3d->numvertex || !m3d->vertex) {
return;
}
unsigned int i, j, k, l, numpoly = 3, lastMat = M3D_INDEXMAX; unsigned int i, j, k, l, numpoly = 3, lastMat = M3D_INDEXMAX;
std::vector<aiMesh *> *meshes = new std::vector<aiMesh *>(); std::vector<aiMesh *> *meshes = new std::vector<aiMesh *>();
std::vector<aiFace> *faces = nullptr; std::vector<aiFace> *faces = nullptr;
@ -385,7 +403,6 @@ void M3DImporter::importMeshes(const M3DWrapper &m3d) {
ai_assert(m3d); ai_assert(m3d);
ai_assert(mScene->mRootNode != nullptr); ai_assert(mScene->mRootNode != nullptr);
ASSIMP_LOG_DEBUG_F("M3D: importMeshes ", m3d->numface);
for (i = 0; i < m3d->numface; i++) { for (i = 0; i < m3d->numface; i++) {
// we must switch mesh if material changes // we must switch mesh if material changes
@ -420,6 +437,7 @@ void M3DImporter::importMeshes(const M3DWrapper &m3d) {
k = static_cast<unsigned int>(vertices->size()); k = static_cast<unsigned int>(vertices->size());
pFace->mIndices[j] = k; pFace->mIndices[j] = k;
l = m3d->face[i].vertex[j]; l = m3d->face[i].vertex[j];
if(l >= m3d->numvertex) continue;
pos.x = m3d->vertex[l].x; pos.x = m3d->vertex[l].x;
pos.y = m3d->vertex[l].y; pos.y = m3d->vertex[l].y;
pos.z = m3d->vertex[l].z; pos.z = m3d->vertex[l].z;
@ -432,14 +450,14 @@ void M3DImporter::importMeshes(const M3DWrapper &m3d) {
vertexids->push_back(l); vertexids->push_back(l);
} }
l = m3d->face[i].texcoord[j]; l = m3d->face[i].texcoord[j];
if (l != M3D_UNDEF) { if (l != M3D_UNDEF && l < m3d->numtmap) {
uv.x = m3d->tmap[l].u; uv.x = m3d->tmap[l].u;
uv.y = m3d->tmap[l].v; uv.y = m3d->tmap[l].v;
uv.z = 0.0; uv.z = 0.0;
texcoords->push_back(uv); texcoords->push_back(uv);
} }
l = m3d->face[i].normal[j]; l = m3d->face[i].normal[j];
if (l != M3D_UNDEF) { if (l != M3D_UNDEF && l < m3d->numvertex) {
norm.x = m3d->vertex[l].x; norm.x = m3d->vertex[l].x;
norm.y = m3d->vertex[l].y; norm.y = m3d->vertex[l].y;
norm.z = m3d->vertex[l].z; norm.z = m3d->vertex[l].z;
@ -487,8 +505,15 @@ void M3DImporter::importBones(const M3DWrapper &m3d, unsigned int parentid, aiNo
ASSIMP_LOG_DEBUG_F("M3D: importBones ", m3d->numbone, " parentid ", (int)parentid); ASSIMP_LOG_DEBUG_F("M3D: importBones ", m3d->numbone, " parentid ", (int)parentid);
for (n = 0, i = parentid + 1; i < m3d->numbone; i++) if (!m3d->numbone || !m3d->bone) {
if (m3d->bone[i].parent == parentid) n++; return;
}
for (n = 0, i = parentid + 1; i < m3d->numbone; i++) {
if (m3d->bone[i].parent == parentid) {
n++;
}
}
pParent->mChildren = new aiNode *[n]; pParent->mChildren = new aiNode *[n];
for (i = parentid + 1; i < m3d->numbone; i++) { for (i = parentid + 1; i < m3d->numbone; i++) {
@ -521,8 +546,9 @@ void M3DImporter::importAnimations(const M3DWrapper &m3d) {
ASSIMP_LOG_DEBUG_F("M3D: importAnimations ", mScene->mNumAnimations); ASSIMP_LOG_DEBUG_F("M3D: importAnimations ", mScene->mNumAnimations);
if (!m3d->numaction || !m3d->numbone) if (!m3d->numaction || !m3d->action || !m3d->numbone || !m3d->bone || !m3d->vertex) {
return; return;
}
mScene->mAnimations = new aiAnimation *[m3d->numaction]; mScene->mAnimations = new aiAnimation *[m3d->numaction];
for (i = 0; i < m3d->numaction; i++) { for (i = 0; i < m3d->numaction; i++) {
@ -552,6 +578,7 @@ void M3DImporter::importAnimations(const M3DWrapper &m3d) {
ori = a->frame[j].transform[k].ori; ori = a->frame[j].transform[k].ori;
} }
} }
if(pos >= m3d->numvertex || ori >= m3d->numvertex) continue;
m3dv_t *v = &m3d->vertex[pos]; m3dv_t *v = &m3d->vertex[pos];
m3dv_t *q = &m3d->vertex[ori]; m3dv_t *q = &m3d->vertex[ori];
pAnim->mChannels[l]->mPositionKeys[j].mTime = t; pAnim->mChannels[l]->mPositionKeys[j].mTime = t;
@ -587,6 +614,8 @@ void M3DImporter::convertPose(const M3DWrapper &m3d, aiMatrix4x4 *m, unsigned in
ai_assert(m3d); ai_assert(m3d);
ai_assert(posid != M3D_UNDEF && posid < m3d->numvertex); ai_assert(posid != M3D_UNDEF && posid < m3d->numvertex);
ai_assert(orientid != M3D_UNDEF && orientid < m3d->numvertex); ai_assert(orientid != M3D_UNDEF && orientid < m3d->numvertex);
if (!m3d->numvertex || !m3d->vertex)
return;
m3dv_t *p = &m3d->vertex[posid]; m3dv_t *p = &m3d->vertex[posid];
m3dv_t *q = &m3d->vertex[orientid]; m3dv_t *q = &m3d->vertex[orientid];
@ -629,16 +658,18 @@ void M3DImporter::convertPose(const M3DWrapper &m3d, aiMatrix4x4 *m, unsigned in
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// find a node by name // find a node by name
aiNode *M3DImporter::findNode(aiNode *pNode, aiString name) { aiNode *M3DImporter::findNode(aiNode *pNode, aiString name) {
unsigned int i;
ai_assert(pNode != nullptr); ai_assert(pNode != nullptr);
ai_assert(mScene != nullptr); ai_assert(mScene != nullptr);
if (pNode->mName == name) if (pNode->mName == name) {
return pNode; return pNode;
for (i = 0; i < pNode->mNumChildren; i++) { }
for (unsigned int i = 0; i < pNode->mNumChildren; i++) {
aiNode *pChild = findNode(pNode->mChildren[i], name); aiNode *pChild = findNode(pNode->mChildren[i], name);
if (pChild) return pChild; if (pChild) {
return pChild;
}
} }
return nullptr; return nullptr;
} }
@ -700,8 +731,8 @@ void M3DImporter::populateMesh(const M3DWrapper &m3d, aiMesh *pMesh, std::vector
// this is complicated, because M3D stores a list of bone id / weight pairs per // this is complicated, because M3D stores a list of bone id / weight pairs per
// vertex but assimp uses lists of local vertex id/weight pairs per local bone list // vertex but assimp uses lists of local vertex id/weight pairs per local bone list
pMesh->mNumBones = m3d->numbone; pMesh->mNumBones = m3d->numbone;
/* we need aiBone with mOffsetMatrix for bones without weights as well */ // we need aiBone with mOffsetMatrix for bones without weights as well
if (pMesh->mNumBones) { if (pMesh->mNumBones && m3d->numbone && m3d->bone) {
pMesh->mBones = new aiBone *[pMesh->mNumBones]; pMesh->mBones = new aiBone *[pMesh->mNumBones];
for (unsigned int i = 0; i < m3d->numbone; i++) { for (unsigned int i = 0; i < m3d->numbone; i++) {
aiNode *pNode; aiNode *pNode;
@ -715,10 +746,13 @@ void M3DImporter::populateMesh(const M3DWrapper &m3d, aiMesh *pMesh, std::vector
} else } else
pMesh->mBones[i]->mOffsetMatrix = aiMatrix4x4(); pMesh->mBones[i]->mOffsetMatrix = aiMatrix4x4();
} }
if (vertexids->size()) { if (vertexids->size() && m3d->numvertex && m3d->vertex && m3d->numskin && m3d->skin) {
unsigned int i, j; unsigned int i, j;
// first count how many vertices we have per bone // first count how many vertices we have per bone
for (i = 0; i < vertexids->size(); i++) { for (i = 0; i < vertexids->size(); i++) {
if(vertexids->at(i) >= m3d->numvertex) {
continue;
}
unsigned int s = m3d->vertex[vertexids->at(i)].skinid; unsigned int s = m3d->vertex[vertexids->at(i)].skinid;
if (s != M3D_UNDEF && s != M3D_INDEXMAX) { if (s != M3D_UNDEF && s != M3D_INDEXMAX) {
for (unsigned int k = 0; k < M3D_NUMBONE && m3d->skin[s].weight[k] > 0.0; k++) { for (unsigned int k = 0; k < M3D_NUMBONE && m3d->skin[s].weight[k] > 0.0; k++) {
@ -742,9 +776,11 @@ void M3DImporter::populateMesh(const M3DWrapper &m3d, aiMesh *pMesh, std::vector
} }
// fill up with data // fill up with data
for (i = 0; i < vertexids->size(); i++) { for (i = 0; i < vertexids->size(); i++) {
if(vertexids->at(i) >= m3d->numvertex) continue;
unsigned int s = m3d->vertex[vertexids->at(i)].skinid; unsigned int s = m3d->vertex[vertexids->at(i)].skinid;
if (s != M3D_UNDEF && s != M3D_INDEXMAX) { if (s != M3D_UNDEF && s != M3D_INDEXMAX && s < m3d->numskin) {
for (unsigned int k = 0; k < M3D_NUMBONE && m3d->skin[s].weight[k] > 0.0; k++) { for (unsigned int k = 0; k < M3D_NUMBONE && m3d->skin[s].weight[k] > 0.0; k++) {
if(m3d->skin[s].boneid[k] >= m3d->numbone) continue;
aiString name = aiString(std::string(m3d->bone[m3d->skin[s].boneid[k]].name)); aiString name = aiString(std::string(m3d->bone[m3d->skin[s].boneid[k]].name));
for (j = 0; j < pMesh->mNumBones; j++) { for (j = 0; j < pMesh->mNumBones; j++) {
if (pMesh->mBones[j]->mName == name) { if (pMesh->mBones[j]->mName == name) {

View File

@ -191,6 +191,7 @@ namespace glTF
//! Values for the BufferView::target field //! Values for the BufferView::target field
enum BufferViewTarget enum BufferViewTarget
{ {
BufferViewTarget_NONE = 0,
BufferViewTarget_ARRAY_BUFFER = 34962, BufferViewTarget_ARRAY_BUFFER = 34962,
BufferViewTarget_ELEMENT_ARRAY_BUFFER = 34963 BufferViewTarget_ELEMENT_ARRAY_BUFFER = 34963
}; };

View File

@ -203,8 +203,10 @@ namespace glTF {
obj.AddMember("buffer", Value(bv.buffer->id, w.mAl).Move(), w.mAl); obj.AddMember("buffer", Value(bv.buffer->id, w.mAl).Move(), w.mAl);
obj.AddMember("byteOffset", static_cast<uint64_t>(bv.byteOffset), w.mAl); obj.AddMember("byteOffset", static_cast<uint64_t>(bv.byteOffset), w.mAl);
obj.AddMember("byteLength", static_cast<uint64_t>(bv.byteLength), w.mAl); obj.AddMember("byteLength", static_cast<uint64_t>(bv.byteLength), w.mAl);
if (bv.target != BufferViewTarget_NONE) {
obj.AddMember("target", int(bv.target), w.mAl); obj.AddMember("target", int(bv.target), w.mAl);
} }
}
inline void Write(Value& /*obj*/, Camera& /*c*/, AssetWriter& /*w*/) inline void Write(Value& /*obj*/, Camera& /*c*/, AssetWriter& /*w*/)
{ {

View File

@ -160,10 +160,7 @@ static void CopyValue(const aiMatrix4x4& v, glTF::mat4& o)
static void CopyValue(const aiMatrix4x4& v, aiMatrix4x4& o) static void CopyValue(const aiMatrix4x4& v, aiMatrix4x4& o)
{ {
o.a1 = v.a1; o.a2 = v.a2; o.a3 = v.a3; o.a4 = v.a4; memcpy(&o, &v, sizeof(aiMatrix4x4));
o.b1 = v.b1; o.b2 = v.b2; o.b3 = v.b3; o.b4 = v.b4;
o.c1 = v.c1; o.c2 = v.c2; o.c3 = v.c3; o.c4 = v.c4;
o.d1 = v.d1; o.d2 = v.d2; o.d3 = v.d3; o.d4 = v.d4;
} }
static void IdentityMatrix4(glTF::mat4& o) static void IdentityMatrix4(glTF::mat4& o)
@ -231,8 +228,7 @@ inline void SetAccessorRange(ComponentType compType, Ref<Accessor> acc, void* da
} }
inline Ref<Accessor> ExportData(Asset &a, std::string &meshName, Ref<Buffer> &buffer, inline Ref<Accessor> ExportData(Asset &a, std::string &meshName, Ref<Buffer> &buffer,
unsigned int count, void* data, AttribType::Value typeIn, AttribType::Value typeOut, ComponentType compType, bool isIndices = false) unsigned int count, void *data, AttribType::Value typeIn, AttribType::Value typeOut, ComponentType compType, BufferViewTarget target = BufferViewTarget_NONE) {
{
if (!count || !data) return Ref<Accessor>(); if (!count || !data) return Ref<Accessor>();
unsigned int numCompsIn = AttribType::GetNumComponents(typeIn); unsigned int numCompsIn = AttribType::GetNumComponents(typeIn);
@ -251,7 +247,7 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
bv->buffer = buffer; bv->buffer = buffer;
bv->byteOffset = unsigned(offset); bv->byteOffset = unsigned(offset);
bv->byteLength = length; //! The target that the WebGL buffer should be bound to. bv->byteLength = length; //! The target that the WebGL buffer should be bound to.
bv->target = isIndices ? BufferViewTarget_ELEMENT_ARRAY_BUFFER : BufferViewTarget_ARRAY_BUFFER; bv->target = target;
// accessor // accessor
Ref<Accessor> acc = a.accessors.Create(a.FindUniqueID(meshName, "accessor")); Ref<Accessor> acc = a.accessors.Create(a.FindUniqueID(meshName, "accessor"));
@ -616,13 +612,13 @@ void glTFExporter::ExportMeshes()
// If compression is used then you need parameters of uncompressed region: begin and size. At this step "begin" is stored. // If compression is used then you need parameters of uncompressed region: begin and size. At this step "begin" is stored.
if(comp_allow) idx_srcdata_begin = b->byteLength; if(comp_allow) idx_srcdata_begin = b->byteLength;
Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
if (v) p.attributes.position.push_back(v); if (v) p.attributes.position.push_back(v);
/******************** Normals ********************/ /******************** Normals ********************/
if(comp_allow && (aim->mNormals != 0)) idx_srcdata_normal = b->byteLength;// Store index of normals array. if(comp_allow && (aim->mNormals != 0)) idx_srcdata_normal = b->byteLength;// Store index of normals array.
Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
if (n) p.attributes.normal.push_back(n); if (n) p.attributes.normal.push_back(n);
/************** Texture coordinates **************/ /************** Texture coordinates **************/
@ -639,7 +635,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, false); Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
if (tc) p.attributes.texcoord.push_back(tc); if (tc) p.attributes.texcoord.push_back(tc);
} }
} }
@ -657,7 +653,7 @@ void glTFExporter::ExportMeshes()
} }
} }
p.indices = ExportData(*mAsset, meshId, b, unsigned(indices.size()), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_SHORT, true); p.indices = ExportData(*mAsset, meshId, b, unsigned(indices.size()), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_SHORT, BufferViewTarget_ELEMENT_ARRAY_BUFFER);
} }
switch (aim->mPrimitiveTypes) { switch (aim->mPrimitiveTypes) {

View File

@ -198,6 +198,7 @@ namespace glTF2
//! Values for the BufferView::target field //! Values for the BufferView::target field
enum BufferViewTarget enum BufferViewTarget
{ {
BufferViewTarget_NONE = 0,
BufferViewTarget_ARRAY_BUFFER = 34962, BufferViewTarget_ARRAY_BUFFER = 34962,
BufferViewTarget_ELEMENT_ARRAY_BUFFER = 34963 BufferViewTarget_ELEMENT_ARRAY_BUFFER = 34963
}; };

View File

@ -176,13 +176,13 @@ namespace glTF2 {
valSampler.AddMember("input", s.input->index, w.mAl); valSampler.AddMember("input", s.input->index, w.mAl);
switch (s.interpolation) { switch (s.interpolation) {
case Interpolation_LINEAR: case Interpolation_LINEAR:
valSampler.AddMember("path", "LINEAR", w.mAl); valSampler.AddMember("interpolation", "LINEAR", w.mAl);
break; break;
case Interpolation_STEP: case Interpolation_STEP:
valSampler.AddMember("path", "STEP", w.mAl); valSampler.AddMember("interpolation", "STEP", w.mAl);
break; break;
case Interpolation_CUBICSPLINE: case Interpolation_CUBICSPLINE:
valSampler.AddMember("path", "CUBICSPLINE", w.mAl); valSampler.AddMember("interpolation", "CUBICSPLINE", w.mAl);
break; break;
} }
valSampler.AddMember("output", s.output->index, w.mAl); valSampler.AddMember("output", s.output->index, w.mAl);
@ -209,7 +209,7 @@ namespace glTF2 {
if (bv.byteStride != 0) { if (bv.byteStride != 0) {
obj.AddMember("byteStride", bv.byteStride, w.mAl); obj.AddMember("byteStride", bv.byteStride, w.mAl);
} }
if (bv.target != 0) { if (bv.target != BufferViewTarget_NONE) {
obj.AddMember("target", int(bv.target), w.mAl); obj.AddMember("target", int(bv.target), w.mAl);
} }
} }

View File

@ -141,10 +141,7 @@ static void CopyValue(const aiMatrix4x4& v, mat4& o) {
} }
static void CopyValue(const aiMatrix4x4& v, aiMatrix4x4& o) { static void CopyValue(const aiMatrix4x4& v, aiMatrix4x4& o) {
o.a1 = v.a1; o.a2 = v.a2; o.a3 = v.a3; o.a4 = v.a4; memcpy(&o, &v, sizeof(aiMatrix4x4));
o.b1 = v.b1; o.b2 = v.b2; o.b3 = v.b3; o.b4 = v.b4;
o.c1 = v.c1; o.c2 = v.c2; o.c3 = v.c3; o.c4 = v.c4;
o.d1 = v.d1; o.d2 = v.d2; o.d3 = v.d3; o.d4 = v.d4;
} }
static void IdentityMatrix4(mat4& o) { static void IdentityMatrix4(mat4& o) {
@ -211,7 +208,7 @@ inline void SetAccessorRange(ComponentType compType, Ref<Accessor> acc, void* da
} }
inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& buffer, inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& buffer,
size_t count, void* data, AttribType::Value typeIn, AttribType::Value typeOut, ComponentType compType, bool isIndices = false) size_t count, void* data, AttribType::Value typeIn, AttribType::Value typeOut, ComponentType compType, BufferViewTarget target = BufferViewTarget_NONE)
{ {
if (!count || !data) { if (!count || !data) {
return Ref<Accessor>(); return Ref<Accessor>();
@ -234,7 +231,7 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
bv->byteOffset = offset; bv->byteOffset = offset;
bv->byteLength = length; //! The target that the WebGL buffer should be bound to. bv->byteLength = length; //! The target that the WebGL buffer should be bound to.
bv->byteStride = 0; bv->byteStride = 0;
bv->target = isIndices ? BufferViewTarget_ELEMENT_ARRAY_BUFFER : BufferViewTarget_ARRAY_BUFFER; bv->target = target;
// accessor // accessor
Ref<Accessor> acc = a.accessors.Create(a.FindUniqueID(meshName, "accessor")); Ref<Accessor> acc = a.accessors.Create(a.FindUniqueID(meshName, "accessor"));
@ -747,7 +744,7 @@ void glTF2Exporter::ExportMeshes()
p.material = mAsset->materials.Get(aim->mMaterialIndex); p.material = mAsset->materials.Get(aim->mMaterialIndex);
/******************* Vertices ********************/ /******************* Vertices ********************/
Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
if (v) p.attributes.position.push_back(v); if (v) p.attributes.position.push_back(v);
/******************** Normals ********************/ /******************** Normals ********************/
@ -758,7 +755,7 @@ void glTF2Exporter::ExportMeshes()
} }
} }
Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
if (n) p.attributes.normal.push_back(n); if (n) p.attributes.normal.push_back(n);
/************** Texture coordinates **************/ /************** Texture coordinates **************/
@ -776,14 +773,14 @@ void glTF2Exporter::ExportMeshes()
if (aim->mNumUVComponents[i] > 0) { if (aim->mNumUVComponents[i] > 0) {
AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3; AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3;
Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, false); Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
if (tc) p.attributes.texcoord.push_back(tc); if (tc) p.attributes.texcoord.push_back(tc);
} }
} }
/*************** Vertex colors ****************/ /*************** Vertex colors ****************/
for (unsigned int indexColorChannel = 0; indexColorChannel < aim->GetNumColorChannels(); ++indexColorChannel) { for (unsigned int indexColorChannel = 0; indexColorChannel < aim->GetNumColorChannels(); ++indexColorChannel) {
Ref<Accessor> c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel], AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, false); Ref<Accessor> c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel], AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
if (c) if (c)
p.attributes.color.push_back(c); p.attributes.color.push_back(c);
} }
@ -799,7 +796,7 @@ void glTF2Exporter::ExportMeshes()
} }
} }
p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_INT, true); p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_INT, BufferViewTarget_ELEMENT_ARRAY_BUFFER);
} }
switch (aim->mPrimitiveTypes) { switch (aim->mPrimitiveTypes) {
@ -956,9 +953,28 @@ unsigned int glTF2Exporter::ExportNode(const aiNode* n, Ref<Node>& parent)
node->name = name; node->name = name;
if (!n->mTransformation.IsIdentity()) { if (!n->mTransformation.IsIdentity()) {
if (mScene->mNumAnimations > 0) {
aiQuaternion quaternion;
n->mTransformation.Decompose(*reinterpret_cast<aiVector3D *>(&node->scale.value), quaternion, *reinterpret_cast<aiVector3D *>(&node->translation.value));
aiVector3D vector(static_cast<ai_real>(1.0f), static_cast<ai_real>(1.0f), static_cast<ai_real>(1.0f));
if (!reinterpret_cast<aiVector3D *>(&node->scale.value)->Equal(vector)) {
node->scale.isPresent = true;
}
if (!reinterpret_cast<aiVector3D *>(&node->translation.value)->Equal(vector)) {
node->translation.isPresent = true;
}
node->rotation.isPresent = true;
node->rotation.value[0] = quaternion.x;
node->rotation.value[1] = quaternion.y;
node->rotation.value[2] = quaternion.z;
node->rotation.value[3] = quaternion.w;
node->matrix.isPresent = false;
} else {
node->matrix.isPresent = true; node->matrix.isPresent = true;
CopyValue(n->mTransformation, node->matrix.value); CopyValue(n->mTransformation, node->matrix.value);
} }
}
for (unsigned int i = 0; i < n->mNumMeshes; ++i) { for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i])); node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i]));

View File

@ -925,6 +925,11 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
if (node.camera) { if (node.camera) {
pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName; pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName;
if (node.translation.isPresent) {
aiVector3D trans;
CopyValue(node.translation.value, trans);
pScene->mCameras[node.camera.GetIndex()]->mPosition = trans;
}
} }
if (node.light) { if (node.light) {