(a) ) )
- mOutput << startstr << "" << endstr;
+ mOutput << startstr << "" << endstr;
}
mOutput << startstr << "";
@@ -1113,18 +1141,18 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
{
mOutput << startstr << "" << endstr;
PushTag();
- mOutput << startstr << "" << endstr;
+ mOutput << startstr << "" << endstr;
if( mesh->HasNormals() )
- mOutput << startstr << "" << endstr;
+ mOutput << startstr << "" << endstr;
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
{
if( mesh->HasTextureCoords(static_cast(a)) )
- mOutput << startstr << "" << endstr;
+ mOutput << startstr << "" << endstr;
}
for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
{
if( mesh->HasVertexColors(static_cast(a) ) )
- mOutput << startstr << "" << endstr;
+ mOutput << startstr << "" << endstr;
}
mOutput << startstr << "";
@@ -1173,13 +1201,13 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
return;
}
- std::string arrayId = pIdString + "-array";
+ std::string arrayId = XMLIDEncode(pIdString) + "-array";
- mOutput << startstr << "" << endstr;
+ mOutput << startstr << "" << endstr;
PushTag();
// source array
- mOutput << startstr << " ";
+ mOutput << startstr << " ";
PushTag();
if( pType == FloatType_TexCoord2 )
@@ -1265,11 +1293,12 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
// Writes the scene library
void ColladaExporter::WriteSceneLibrary()
{
- const std::string scene_name_escaped = XMLEscape(mScene->mRootNode->mName.C_Str());
+ const std::string sceneName = XMLEscape(mScene->mRootNode->mName.C_Str());
+ const std::string sceneId = XMLIDEncode(mScene->mRootNode->mName.C_Str());
mOutput << startstr << "" << endstr;
PushTag();
- mOutput << startstr << "" << endstr;
+ mOutput << startstr << "" << endstr;
PushTag();
// start recursive write at the root node
@@ -1300,7 +1329,7 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
idstr = idstr + ending;
}
- const std::string idstrEscaped = XMLEscape(idstr);
+ const std::string idstrEscaped = XMLIDEncode(idstr);
mOutput << startstr << "" << endstr;
PushTag();
@@ -1372,13 +1401,13 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
}
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-interpolation");
- std::string arrayId = node_idstr + "-array";
+ std::string arrayId = XMLIDEncode(node_idstr) + "-array";
- mOutput << startstr << "" << endstr;
+ mOutput << startstr << "" << endstr;
PushTag();
// source array
- mOutput << startstr << " ";
+ mOutput << startstr << " ";
for( size_t a = 0; a < names.size(); ++a ) {
mOutput << names[a] << " ";
}
@@ -1387,7 +1416,7 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
mOutput << startstr << "" << endstr;
PushTag();
- mOutput << startstr << "" << endstr;
+ mOutput << startstr << "" << endstr;
PushTag();
mOutput << startstr << "" << endstr;
@@ -1409,12 +1438,12 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
{
// samplers
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-sampler");
- mOutput << startstr << "" << endstr;
+ mOutput << startstr << "" << endstr;
PushTag();
- mOutput << startstr << "mNodeName.data + std::string("_matrix-input") ) << "\"/>" << endstr;
- mOutput << startstr << "mNodeName.data + std::string("_matrix-output") ) << "\"/>" << endstr;
- mOutput << startstr << "mNodeName.data + std::string("_matrix-interpolation") ) << "\"/>" << endstr;
+ mOutput << startstr << "mNodeName.data + std::string("_matrix-input") ) << "\"/>" << endstr;
+ mOutput << startstr << "mNodeName.data + std::string("_matrix-output") ) << "\"/>" << endstr;
+ mOutput << startstr << "mNodeName.data + std::string("_matrix-interpolation") ) << "\"/>" << endstr;
PopTag();
mOutput << startstr << "" << endstr;
@@ -1426,7 +1455,7 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
{
// channels
- mOutput << startstr << "mNodeName.data + std::string("_matrix-sampler") ) << "\" target=\"" << XMLEscape(nodeAnim->mNodeName.data) << "/matrix\"/>" << endstr;
+ mOutput << startstr << "mNodeName.data + std::string("_matrix-sampler") ) << "\" target=\"" << XMLIDEncode(nodeAnim->mNodeName.data) << "/matrix\"/>" << endstr;
}
}
@@ -1437,8 +1466,6 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
// ------------------------------------------------------------------------------------------------
void ColladaExporter::WriteAnimationsLibrary()
{
- const std::string scene_name_escaped = XMLEscape(mScene->mRootNode->mName.C_Str());
-
if ( mScene->mNumAnimations > 0 ) {
mOutput << startstr << "" << endstr;
PushTag();
@@ -1546,16 +1573,17 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
}
}
- const std::string node_name_escaped = XMLEscape(pNode->mName.data);
+ const std::string node_id = XMLIDEncode(pNode->mName.data);
+ const std::string node_name = XMLEscape(pNode->mName.data);
mOutput << startstr << "" << endstr;
PushTag();
@@ -1594,14 +1622,14 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
//check if it is a camera node
for(size_t i=0; imNumCameras; i++){
if(mScene->mCameras[i]->mName == pNode->mName){
- mOutput << startstr <<"" << endstr;
+ mOutput << startstr <<"" << endstr;
break;
}
}
//check if it is a light node
for(size_t i=0; imNumLights; i++){
if(mScene->mLights[i]->mName == pNode->mName){
- mOutput << startstr <<"" << endstr;
+ mOutput << startstr <<"" << endstr;
break;
}
}
@@ -1615,15 +1643,17 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
continue;
+ const std::string meshName = mesh->mName.length == 0 ? GetMeshId(pNode->mMeshes[a]) : mesh->mName.C_Str();
+
if( mesh->mNumBones == 0 )
{
- mOutput << startstr << "mMeshes[a])) << "\">" << endstr;
+ mOutput << startstr << "" << endstr;
PushTag();
}
else
{
mOutput << startstr
- << "mMeshes[a])) << "-skin\">"
+ << ""
<< endstr;
PushTag();
@@ -1631,7 +1661,7 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
// use the first bone to find skeleton root
const aiNode * skeletonRootBoneNode = findSkeletonRootNode( pScene, mesh );
if ( skeletonRootBoneNode ) {
- mFoundSkeletonRootNodeID = XMLEscape( skeletonRootBoneNode->mName.C_Str() );
+ mFoundSkeletonRootNodeID = XMLIDEncode( skeletonRootBoneNode->mName.C_Str() );
}
mOutput << startstr << "#" << mFoundSkeletonRootNodeID << "" << endstr;
}
@@ -1639,7 +1669,7 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
PushTag();
mOutput << startstr << "" << endstr;
PushTag();
- mOutput << startstr << "mMaterialIndex].name) << "\">" << endstr;
+ mOutput << startstr << "mMaterialIndex].name) << "\">" << endstr;
PushTag();
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
{
diff --git a/code/Common/BaseImporter.cpp b/code/Common/BaseImporter.cpp
index b77bbfe23c..5c1e605549 100644
--- a/code/Common/BaseImporter.cpp
+++ b/code/Common/BaseImporter.cpp
@@ -67,7 +67,20 @@ using namespace Assimp;
// Constructor to be privately used by Importer
BaseImporter::BaseImporter() AI_NO_EXCEPT
: m_progress() {
- // nothing to do here
+ /**
+ * Assimp Importer
+ * unit conversions available
+ * if you need another measurment unit add it below.
+ * it's currently defined in assimp that we prefer meters.
+ *
+ * NOTE: Initialised here rather than in the header file
+ * to workaround a VS2013 bug with brace initialisers
+ * */
+ importerUnits[ImporterUnits::M] = 1.0;
+ importerUnits[ImporterUnits::CM] = 0.01;
+ importerUnits[ImporterUnits::MM] = 0.001;
+ importerUnits[ImporterUnits::INCHES] = 0.0254;
+ importerUnits[ImporterUnits::FEET] = 0.3048;
}
// ------------------------------------------------------------------------------------------------
diff --git a/code/glTF/glTFImporter.cpp b/code/glTF/glTFImporter.cpp
index 9ecd742f60..9ec13ea696 100644
--- a/code/glTF/glTFImporter.cpp
+++ b/code/glTF/glTFImporter.cpp
@@ -170,6 +170,8 @@ void glTFImporter::ImportMaterials(glTF::Asset& r) {
if (mScene->mNumMaterials == 0) {
mScene->mNumMaterials = 1;
+ // Delete the array of length zero created above.
+ delete[] mScene->mMaterials;
mScene->mMaterials = new aiMaterial*[1];
mScene->mMaterials[0] = new aiMaterial();
}
@@ -330,6 +332,10 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
case PrimitiveMode_LINES: {
nFaces = count / 2;
+ if (nFaces * 2 != count) {
+ ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
+ count = nFaces * 2;
+ }
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFace(faces[i / 2], data.GetUInt(i), data.GetUInt(i + 1));
@@ -353,6 +359,10 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
case PrimitiveMode_TRIANGLES: {
nFaces = count / 3;
+ if (nFaces * 3 != count) {
+ ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
+ count = nFaces * 3;
+ }
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFace(faces[i / 3], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
@@ -395,6 +405,10 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
case PrimitiveMode_LINES: {
nFaces = count / 2;
+ if (nFaces * 2 != count) {
+ ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
+ count = nFaces * 2;
+ }
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFace(faces[i / 2], i, i + 1);
@@ -418,6 +432,10 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
case PrimitiveMode_TRIANGLES: {
nFaces = count / 3;
+ if (nFaces * 3 != count) {
+ ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
+ count = nFaces * 3;
+ }
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFace(faces[i / 3], i, i + 1, i + 2);
diff --git a/code/glTF2/glTF2Importer.cpp b/code/glTF2/glTF2Importer.cpp
index c2106e26ff..b3141fd960 100644
--- a/code/glTF2/glTF2Importer.cpp
+++ b/code/glTF2/glTF2Importer.cpp
@@ -530,6 +530,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
case PrimitiveMode_LINES: {
nFaces = count / 2;
+ if (nFaces * 2 != count) {
+ ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
+ count = nFaces * 2;
+ }
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFace(faces[i / 2], data.GetUInt(i), data.GetUInt(i + 1));
@@ -553,6 +557,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
case PrimitiveMode_TRIANGLES: {
nFaces = count / 3;
+ if (nFaces * 3 != count) {
+ ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
+ count = nFaces * 3;
+ }
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFace(faces[i / 3], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
@@ -604,6 +612,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
case PrimitiveMode_LINES: {
nFaces = count / 2;
+ if (nFaces * 2 != count) {
+ ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
+ count = nFaces * 2;
+ }
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFace(faces[i / 2], i, i + 1);
@@ -627,6 +639,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
case PrimitiveMode_TRIANGLES: {
nFaces = count / 3;
+ if (nFaces * 3 != count) {
+ ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
+ count = nFaces * 3;
+ }
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFace(faces[i / 3], i, i + 1, i + 2);
diff --git a/include/assimp/BaseImporter.h b/include/assimp/BaseImporter.h
index bd0451be32..ad8a3dafd8 100644
--- a/include/assimp/BaseImporter.h
+++ b/include/assimp/BaseImporter.h
@@ -196,16 +196,13 @@ class ASSIMP_API BaseImporter {
/**
* Assimp Importer
* unit conversions available
- * if you need another measurment unit add it below.
- * it's currently defined in assimp that we prefer meters.
+ * NOTE: Valid options are initialised in the
+ * constructor in the implementation file to
+ * work around a VS2013 compiler bug if support
+ * for that compiler is dropped in the future
+ * initialisation can be moved back here
* */
- std::map importerUnits = {
- {ImporterUnits::M, 1},
- {ImporterUnits::CM, 0.01},
- {ImporterUnits::MM, 0.001},
- {ImporterUnits::INCHES, 0.0254},
- {ImporterUnits::FEET, 0.3048}
- };
+ std::map importerUnits;
virtual void SetApplicationUnits( const ImporterUnits& unit )
{
diff --git a/test/models/glTF/IncorrectVertexArrays/Cube.bin b/test/models/glTF/IncorrectVertexArrays/Cube.bin
new file mode 100644
index 0000000000..fa55b363a3
Binary files /dev/null and b/test/models/glTF/IncorrectVertexArrays/Cube.bin differ
diff --git a/test/models/glTF/IncorrectVertexArrays/Cube_v1.gltf b/test/models/glTF/IncorrectVertexArrays/Cube_v1.gltf
new file mode 100644
index 0000000000..c076c5bcb1
--- /dev/null
+++ b/test/models/glTF/IncorrectVertexArrays/Cube_v1.gltf
@@ -0,0 +1,283 @@
+{
+ "accessors" : {
+ "accessor_0" : {
+ "bufferView" : "bufferView_0",
+ "byteOffset" : 0,
+ "componentType" : 5123,
+ "count" : 36,
+ "max" : [
+ 35
+ ],
+ "min" : [
+ 0
+ ],
+ "type" : "SCALAR"
+ },
+ "accessor_1" : {
+ "bufferView" : "bufferView_1",
+ "byteOffset" : 0,
+ "componentType" : 5126,
+ "count" : 36,
+ "max" : [
+ 1.000000,
+ 1.000000,
+ 1.000001
+ ],
+ "min" : [
+ -1.000000,
+ -1.000000,
+ -1.000000
+ ],
+ "type" : "VEC3"
+ },
+ "accessor_2" : {
+ "bufferView" : "bufferView_2",
+ "byteOffset" : 0,
+ "componentType" : 5126,
+ "count" : 36,
+ "max" : [
+ 1.000000,
+ 1.000000,
+ 1.000000
+ ],
+ "min" : [
+ -1.000000,
+ -1.000000,
+ -1.000000
+ ],
+ "type" : "VEC3"
+ },
+ "accessor_3" : {
+ "bufferView" : "bufferView_3",
+ "byteOffset" : 0,
+ "componentType" : 5126,
+ "count" : 36,
+ "max" : [
+ 1.000000,
+ -0.000000,
+ -0.000000,
+ 1.000000
+ ],
+ "min" : [
+ 0.000000,
+ -0.000000,
+ -1.000000,
+ -1.000000
+ ],
+ "type" : "VEC4"
+ },
+ "accessor_4" : {
+ "bufferView" : "bufferView_4",
+ "byteOffset" : 0,
+ "componentType" : 5126,
+ "count" : 36,
+ "max" : [
+ 1.000000,
+ 1.000000
+ ],
+ "min" : [
+ -1.000000,
+ -1.000000
+ ],
+ "type" : "VEC2"
+ },
+ "accessor_5" : {
+ "bufferView" : "bufferView_1",
+ "byteOffset" : 0,
+ "componentType" : 5126,
+ "count" : 36,
+ "type" : "VEC3"
+ },
+ "accessor_6" : {
+ "bufferView" : "bufferView_1",
+ "byteOffset" : 0,
+ "componentType" : 5126,
+ "count" : 35,
+ "type" : "VEC3"
+ },
+ "accessor_7" : {
+ "bufferView" : "bufferView_0",
+ "byteOffset" : 0,
+ "componentType" : 5123,
+ "count" : 35,
+ "max" : [
+ 35
+ ],
+ "min" : [
+ 0
+ ],
+ "type" : "SCALAR"
+ }
+ },
+ "asset" : {
+ "generator" : "VKTS glTF 2.0 exporter",
+ "version" : "1.0"
+ },
+ "bufferViews" : {
+ "bufferView_0" : {
+ "buffer" : "buffer_0",
+ "byteLength" : 72,
+ "byteOffset" : 0,
+ "target" : 34963
+ },
+ "bufferView_1" : {
+ "buffer" : "buffer_0",
+ "byteLength" : 432,
+ "byteOffset" : 72,
+ "target" : 34962
+ },
+ "bufferView_2" : {
+ "buffer" : "buffer_0",
+ "byteLength" : 432,
+ "byteOffset" : 504,
+ "target" : 34962
+ },
+ "bufferView_3" : {
+ "buffer" : "buffer_0",
+ "byteLength" : 576,
+ "byteOffset" : 936,
+ "target" : 34962
+ },
+ "bufferView_4" : {
+ "buffer" : "buffer_0",
+ "byteLength" : 288,
+ "byteOffset" : 1512,
+ "target" : 34962
+ }
+ },
+ "buffers" : {
+ "buffer_0" : {
+ "byteLength" : 514,
+ "uri" : "Cube.bin"
+ }
+ },
+ "meshes" : {
+ "mesh_0" : {
+ "name" : "Cube",
+ "primitives" : [
+ {
+ "attributes" : {
+ "POSITION" : "accessor_1"
+ },
+ "mode" : 4
+ }
+ ]
+ },
+ "mesh_1" : {
+ "name" : "TruncatedCube",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : "accessor_6"
+ },
+ "mode" : 4
+ } ]
+ },
+ "mesh_2" : {
+ "name" : "Lines",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : "accessor_5"
+ },
+ "mode" : 1
+ } ]
+ },
+ "mesh_3" : {
+ "name" : "TruncatedLines",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : "accessor_6"
+ },
+ "mode" : 1
+ } ]
+ },
+ "mesh_4" : {
+ "name" : "IndexedCube",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : "accessor_1"
+ },
+ "mode" : 4,
+ "indices" : "accessor_0"
+ } ]
+ },
+ "mesh_5" : {
+ "name" : "TruncatedIndexedCube",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : "accessor_6"
+ },
+ "mode" : 4,
+ "indices" : "accessor_7"
+ } ]
+ },
+ "mesh_6" : {
+ "name" : "IndexedLines",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : "accessor_5"
+ },
+ "mode" : 1,
+ "indices" : "accessor_0"
+ } ]
+ },
+ "mesh_7" : {
+ "name" : "TruncatedIndexedLines",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : "accessor_6"
+ },
+ "mode" : 1,
+ "indices" : "accessor_7"
+ } ]
+ }
+ },
+ "nodes" : {
+ "node_0" : {
+ "meshes" : [ "mesh_0" ],
+ "name" : "Cube"
+ },
+ "node_1" : {
+ "meshes" : [ "mesh_1" ],
+ "name" : "TruncatedCube",
+ "translation": [ 2.5, 0.0, 2.5 ]
+ },
+ "node_2" : {
+ "meshes" : [ "mesh_2" ],
+ "name" : "Lines",
+ "translation": [ 2.5, 0.0, 0.0 ]
+ },
+ "node_3" : {
+ "meshes" : [ "mesh_3" ],
+ "name" : "TruncatedLines",
+ "translation": [ 2.5, 0.0, -2.5 ]
+ },
+ "node_4" : {
+ "meshes" : [ "mesh_4" ],
+ "name" : "IndexedCube",
+ "translation": [ -2.5, 0.0, 2.5 ]
+ },
+ "node_5" : {
+ "meshes" : [ "mesh_5" ],
+ "name" : "TruncatedIndexedCube",
+ "translation": [ -2.5, 0.0, 0.0 ]
+ },
+ "node_6" : {
+ "meshes" : [ "mesh_6" ],
+ "name" : "IndexedLines",
+ "translation": [ -2.5, 0.0, -2.5 ]
+ },
+ "node_7" : {
+ "meshes" : [ "mesh_7" ],
+ "name" : "TruncatedIndexedLines",
+ "translation": [ 0.0, 0.0, -2.5 ]
+ }
+ },
+ "scene" : "defaultScene",
+ "scenes" : {
+ "defaultScene" : {
+ "nodes" : [
+ "node_0", "node_1", "node_2", "node_3", "node_4", "node_5", "node_6", "node_7"
+ ]
+ }
+ }
+}
diff --git a/test/models/glTF2/IncorrectVertexArrays/Cube.bin b/test/models/glTF2/IncorrectVertexArrays/Cube.bin
new file mode 100644
index 0000000000..fa55b363a3
Binary files /dev/null and b/test/models/glTF2/IncorrectVertexArrays/Cube.bin differ
diff --git a/test/models/glTF2/IncorrectVertexArrays/Cube.gltf b/test/models/glTF2/IncorrectVertexArrays/Cube.gltf
new file mode 100644
index 0000000000..0ca17e1e53
--- /dev/null
+++ b/test/models/glTF2/IncorrectVertexArrays/Cube.gltf
@@ -0,0 +1,286 @@
+{
+ "accessors" : [
+ {
+ "bufferView" : 0,
+ "byteOffset" : 0,
+ "componentType" : 5123,
+ "count" : 36,
+ "max" : [
+ 35
+ ],
+ "min" : [
+ 0
+ ],
+ "type" : "SCALAR"
+ },
+ {
+ "bufferView" : 1,
+ "byteOffset" : 0,
+ "componentType" : 5126,
+ "count" : 36,
+ "max" : [
+ 1.000000,
+ 1.000000,
+ 1.000001
+ ],
+ "min" : [
+ -1.000000,
+ -1.000000,
+ -1.000000
+ ],
+ "type" : "VEC3"
+ },
+ {
+ "bufferView" : 2,
+ "byteOffset" : 0,
+ "componentType" : 5126,
+ "count" : 36,
+ "max" : [
+ 1.000000,
+ 1.000000,
+ 1.000000
+ ],
+ "min" : [
+ -1.000000,
+ -1.000000,
+ -1.000000
+ ],
+ "type" : "VEC3"
+ },
+ {
+ "bufferView" : 3,
+ "byteOffset" : 0,
+ "componentType" : 5126,
+ "count" : 36,
+ "max" : [
+ 1.000000,
+ -0.000000,
+ -0.000000,
+ 1.000000
+ ],
+ "min" : [
+ 0.000000,
+ -0.000000,
+ -1.000000,
+ -1.000000
+ ],
+ "type" : "VEC4"
+ },
+ {
+ "bufferView" : 4,
+ "byteOffset" : 0,
+ "componentType" : 5126,
+ "count" : 36,
+ "max" : [
+ 1.000000,
+ 1.000000
+ ],
+ "min" : [
+ -1.000000,
+ -1.000000
+ ],
+ "type" : "VEC2"
+ },
+ {
+ "bufferView" : 1,
+ "byteOffset" : 0,
+ "componentType" : 5126,
+ "count" : 36,
+ "type" : "VEC3"
+ },
+ {
+ "bufferView" : 1,
+ "byteOffset" : 0,
+ "componentType" : 5126,
+ "count" : 35,
+ "type" : "VEC3"
+ },
+ {
+ "bufferView" : 0,
+ "byteOffset" : 0,
+ "componentType" : 5123,
+ "count" : 35,
+ "max" : [
+ 35
+ ],
+ "min" : [
+ 0
+ ],
+ "type" : "SCALAR"
+ }
+ ],
+ "asset" : {
+ "generator" : "VKTS glTF 2.0 exporter",
+ "version" : "2.0"
+ },
+ "bufferViews" : [
+ {
+ "buffer" : 0,
+ "byteLength" : 72,
+ "byteOffset" : 0,
+ "target" : 34963
+ },
+ {
+ "buffer" : 0,
+ "byteLength" : 432,
+ "byteOffset" : 72,
+ "target" : 34962
+ },
+ {
+ "buffer" : 0,
+ "byteLength" : 432,
+ "byteOffset" : 504,
+ "target" : 34962
+ },
+ {
+ "buffer" : 0,
+ "byteLength" : 576,
+ "byteOffset" : 936,
+ "target" : 34962
+ },
+ {
+ "buffer" : 0,
+ "byteLength" : 288,
+ "byteOffset" : 1512,
+ "target" : 34962
+ }
+ ],
+ "buffers" : [
+ {
+ "byteLength" : 514,
+ "uri" : "Cube.bin"
+ }
+ ],
+ "meshes" : [
+ {
+ "name" : "Cube",
+ "primitives" : [
+ {
+ "attributes" : {
+ "POSITION" : 1
+ },
+ "mode" : 4
+ }
+ ]
+ },
+ {
+ "name" : "TruncatedCube",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : 6
+ },
+ "mode" : 4
+ } ]
+ },
+ {
+ "name" : "Lines",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : 5
+ },
+ "mode" : 1
+ } ]
+ },
+ {
+ "name" : "TruncatedLines",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : 6
+ },
+ "mode" : 1
+ } ]
+ },
+ {
+ "name" : "IndexedCube",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : 1
+ },
+ "mode" : 4,
+ "indices" : 0
+ } ]
+ },
+ {
+ "name" : "TruncatedIndexedCube",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : 6
+ },
+ "mode" : 4,
+ "indices" : 7
+ } ]
+ },
+ {
+ "name" : "IndexedLines",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : 5
+ },
+ "mode" : 1,
+ "indices" : 0
+ } ]
+ },
+ {
+ "name" : "TruncatedIndexedLines",
+ "primitives" : [ {
+ "attributes" : {
+ "POSITION" : 6
+ },
+ "mode" : 1,
+ "indices" : 7
+ } ]
+ }
+ ],
+ "nodes" : [
+ {
+ "mesh" : 0,
+ "name" : "Cube"
+ },
+ {
+ "mesh" : 1,
+ "name" : "TruncatedCube",
+ "translation": [ 2.5, 0.0, 2.5 ]
+ },
+ {
+ "mesh" : 2,
+ "name" : "Lines",
+ "translation": [ 2.5, 0.0, 0.0 ]
+ },
+ {
+ "mesh" : 3,
+ "name" : "TruncatedLines",
+ "translation": [ 2.5, 0.0, -2.5 ]
+ },
+ {
+ "mesh" : 4,
+ "name" : "IndexedCube",
+ "translation": [ -2.5, 0.0, 2.5 ]
+ },
+ {
+ "mesh" : 5,
+ "name" : "TruncatedIndexedCube",
+ "translation": [ -2.5, 0.0, 0.0 ]
+ },
+ {
+ "mesh" : 6,
+ "name" : "IndexedLines",
+ "translation": [ -2.5, 0.0, -2.5 ]
+ },
+ {
+ "mesh" : 7,
+ "name" : "TruncatedIndexedLines",
+ "translation": [ 0.0, 0.0, -2.5 ]
+ }
+ ],
+ "samplers" : [
+ {}
+ ],
+ "scene" : 0,
+ "scenes" : [
+ {
+ "nodes" : [
+ 0, 1, 2, 3, 4, 5, 6, 7
+ ]
+ }
+ ]
+}
diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp
index 829d314518..6925098b94 100644
--- a/test/unit/utglTF2ImportExport.cpp
+++ b/test/unit/utglTF2ImportExport.cpp
@@ -382,6 +382,29 @@ TEST_F(utglTF2ImportExport, import_cameras) {
EXPECT_NE(nullptr, scene);
}
+TEST_F(utglTF2ImportExport, incorrect_vertex_arrays) {
+ Assimp::Importer importer;
+ const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/IncorrectVertexArrays/Cube.gltf",
+ aiProcess_ValidateDataStructure);
+ EXPECT_NE(nullptr, scene);
+ EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 36u);
+ EXPECT_EQ(scene->mMeshes[0]->mNumFaces, 12u);
+ EXPECT_EQ(scene->mMeshes[1]->mNumVertices, 35u);
+ EXPECT_EQ(scene->mMeshes[1]->mNumFaces, 11u);
+ EXPECT_EQ(scene->mMeshes[2]->mNumVertices, 36u);
+ EXPECT_EQ(scene->mMeshes[2]->mNumFaces, 18u);
+ EXPECT_EQ(scene->mMeshes[3]->mNumVertices, 35u);
+ EXPECT_EQ(scene->mMeshes[3]->mNumFaces, 17u);
+ EXPECT_EQ(scene->mMeshes[4]->mNumVertices, 36u);
+ EXPECT_EQ(scene->mMeshes[4]->mNumFaces, 12u);
+ EXPECT_EQ(scene->mMeshes[5]->mNumVertices, 35u);
+ EXPECT_EQ(scene->mMeshes[5]->mNumFaces, 11u);
+ EXPECT_EQ(scene->mMeshes[6]->mNumVertices, 36u);
+ EXPECT_EQ(scene->mMeshes[6]->mNumFaces, 18u);
+ EXPECT_EQ(scene->mMeshes[7]->mNumVertices, 35u);
+ EXPECT_EQ(scene->mMeshes[7]->mNumFaces, 17u);
+}
+
#ifndef ASSIMP_BUILD_NO_EXPORT
TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) {
EXPECT_TRUE( exporterTest() );
diff --git a/test/unit/utglTFImportExport.cpp b/test/unit/utglTFImportExport.cpp
index 562cb05b96..90f0758bb0 100644
--- a/test/unit/utglTFImportExport.cpp
+++ b/test/unit/utglTFImportExport.cpp
@@ -46,6 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include
#include
+#include
+
using namespace Assimp;
class utglTFImportExport : public AbstractImportExportBase {
@@ -60,3 +62,26 @@ class utglTFImportExport : public AbstractImportExportBase {
TEST_F( utglTFImportExport, importglTFFromFileTest ) {
EXPECT_TRUE( importerTest() );
}
+
+TEST_F(utglTFImportExport, incorrect_vertex_arrays) {
+ Assimp::Importer importer;
+ const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF/IncorrectVertexArrays/Cube_v1.gltf",
+ aiProcess_ValidateDataStructure);
+ EXPECT_NE(nullptr, scene);
+ EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 36u);
+ EXPECT_EQ(scene->mMeshes[0]->mNumFaces, 12u);
+ EXPECT_EQ(scene->mMeshes[1]->mNumVertices, 35u);
+ EXPECT_EQ(scene->mMeshes[1]->mNumFaces, 11u);
+ EXPECT_EQ(scene->mMeshes[2]->mNumVertices, 36u);
+ EXPECT_EQ(scene->mMeshes[2]->mNumFaces, 18u);
+ EXPECT_EQ(scene->mMeshes[3]->mNumVertices, 35u);
+ EXPECT_EQ(scene->mMeshes[3]->mNumFaces, 17u);
+ EXPECT_EQ(scene->mMeshes[4]->mNumVertices, 36u);
+ EXPECT_EQ(scene->mMeshes[4]->mNumFaces, 12u);
+ EXPECT_EQ(scene->mMeshes[5]->mNumVertices, 35u);
+ EXPECT_EQ(scene->mMeshes[5]->mNumFaces, 11u);
+ EXPECT_EQ(scene->mMeshes[6]->mNumVertices, 36u);
+ EXPECT_EQ(scene->mMeshes[6]->mNumFaces, 18u);
+ EXPECT_EQ(scene->mMeshes[7]->mNumVertices, 35u);
+ EXPECT_EQ(scene->mMeshes[7]->mNumFaces, 17u);
+}