Merge pull request #2626 from muxanickms/crash_in_ai_mesh_desctuctor

A crash in the aiMesh destructor
pull/2643/head^2
Kim Kulling 2019-09-07 09:31:47 +02:00 committed by GitHub
commit c1d4549d19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 330 additions and 3 deletions

View File

@ -253,7 +253,7 @@ ELSEIF(MSVC)
IF(MSVC12)
ADD_COMPILE_OPTIONS(/wd4351)
ENDIF()
SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob2")
SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob2 /DEBUG:FULL /Zi")
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
IF(NOT HUNTER_ENABLED)
SET(CMAKE_CXX_FLAGS "-fPIC -std=c++11 ${CMAKE_CXX_FLAGS}")

View File

@ -1091,6 +1091,35 @@ void SceneCombiner::Copy( aiMesh** _dest, const aiMesh* src ) {
aiFace& f = dest->mFaces[i];
GetArrayCopy(f.mIndices,f.mNumIndices);
}
// make a deep copy of all blend shapes
CopyPtrArray(dest->mAnimMeshes, dest->mAnimMeshes, dest->mNumAnimMeshes);
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy(aiAnimMesh** _dest, const aiAnimMesh* src) {
if (nullptr == _dest || nullptr == src) {
return;
}
aiAnimMesh* dest = *_dest = new aiAnimMesh();
// get a flat copy
::memcpy(dest, src, sizeof(aiAnimMesh));
// and reallocate all arrays
GetArrayCopy(dest->mVertices, dest->mNumVertices);
GetArrayCopy(dest->mNormals, dest->mNumVertices);
GetArrayCopy(dest->mTangents, dest->mNumVertices);
GetArrayCopy(dest->mBitangents, dest->mNumVertices);
unsigned int n = 0;
while (dest->HasTextureCoords(n))
GetArrayCopy(dest->mTextureCoords[n++], dest->mNumVertices);
n = 0;
while (dest->HasVertexColors(n))
GetArrayCopy(dest->mColors[n++], dest->mNumVertices);
}
// ------------------------------------------------------------------------------------------------

View File

@ -1041,7 +1041,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
delete[] values;
} else if (node.rotation.isPresent) {
anim->mNumRotationKeys = 1;
anim->mRotationKeys = new aiQuatKey();
anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys];
anim->mRotationKeys->mTime = 0.f;
anim->mRotationKeys->mValue.x = node.rotation.value[0];
anim->mRotationKeys->mValue.y = node.rotation.value[1];
@ -1064,7 +1064,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
delete[] values;
} else if (node.scale.isPresent) {
anim->mNumScalingKeys = 1;
anim->mScalingKeys = new aiVectorKey();
anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys];
anim->mScalingKeys->mTime = 0.f;
anim->mScalingKeys->mValue.x = node.scale.value[0];
anim->mScalingKeys->mValue.y = node.scale.value[1];
@ -1130,6 +1130,7 @@ void glTF2Importer::ImportAnimations(glTF2::Asset& r)
// Use the latest keyframe for the duration of the animation
double maxDuration = 0;
unsigned int maxNumberOfKeys = 0;
for (unsigned int j = 0; j < ai_anim->mNumChannels; ++j) {
auto chan = ai_anim->mChannels[j];
if (chan->mNumPositionKeys) {
@ -1137,21 +1138,25 @@ void glTF2Importer::ImportAnimations(glTF2::Asset& r)
if (lastPosKey.mTime > maxDuration) {
maxDuration = lastPosKey.mTime;
}
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumPositionKeys);
}
if (chan->mNumRotationKeys) {
auto lastRotKey = chan->mRotationKeys[chan->mNumRotationKeys - 1];
if (lastRotKey.mTime > maxDuration) {
maxDuration = lastRotKey.mTime;
}
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumRotationKeys);
}
if (chan->mNumScalingKeys) {
auto lastScaleKey = chan->mScalingKeys[chan->mNumScalingKeys - 1];
if (lastScaleKey.mTime > maxDuration) {
maxDuration = lastScaleKey.mTime;
}
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumScalingKeys);
}
}
ai_anim->mDuration = maxDuration;
ai_anim->mTicksPerSecond = (maxNumberOfKeys > 0 && maxDuration > 0) ? (maxNumberOfKeys / (maxDuration/1000)) : 30;
mScene->mAnimations[i] = ai_anim;
}

View File

@ -65,6 +65,7 @@ struct aiLight;
struct aiMetadata;
struct aiBone;
struct aiMesh;
struct aiAnimMesh;
struct aiAnimation;
struct aiNodeAnim;
@ -363,6 +364,7 @@ public:
static void Copy (aiMesh** dest, const aiMesh* src);
// similar to Copy():
static void Copy (aiAnimMesh** dest, const aiAnimMesh* src);
static void Copy (aiMaterial** dest, const aiMaterial* src);
static void Copy (aiTexture** dest, const aiTexture* src);
static void Copy (aiAnimation** dest, const aiAnimation* src);

View File

@ -0,0 +1,282 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 24,
"type": "VEC3"
},
{
"bufferView": 1,
"componentType": 5126,
"count": 24,
"type": "VEC4"
},
{
"bufferView": 2,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"max": [
0.0100000035,
0.0100000035,
0.01
],
"min": [
-0.0100000044,
-0.0100000054,
-0.01
]
},
{
"bufferView": 3,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"name": "thin"
},
{
"bufferView": 4,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"max": [
0.0,
0.01893253,
0.0
],
"min": [
0.0,
0.0,
0.0
],
"name": "thin"
},
{
"bufferView": 5,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"name": "thin"
},
{
"bufferView": 6,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"name": "angle"
},
{
"bufferView": 7,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"max": [
0.0,
0.0198908355,
0.0
],
"min": [
0.0,
0.0,
0.0
],
"name": "angle"
},
{
"bufferView": 8,
"componentType": 5126,
"count": 24,
"type": "VEC3",
"name": "angle"
},
{
"bufferView": 9,
"componentType": 5123,
"count": 36,
"type": "SCALAR"
},
{
"bufferView": 10,
"componentType": 5126,
"count": 127,
"type": "SCALAR",
"max": [
4.19999743
],
"min": [
0.0
]
},
{
"bufferView": 11,
"componentType": 5126,
"count": 254,
"type": "SCALAR"
}
],
"animations": [
{
"channels": [
{
"sampler": 0,
"target": {
"node": 0,
"path": "weights"
}
}
],
"samplers": [
{
"input": 10,
"interpolation": "LINEAR",
"output": 11
}
],
"name": "Square"
}
],
"asset": {
"generator": "glTF Tools for Unity",
"version": "2.0"
},
"bufferViews": [
{
"buffer": 0,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 288,
"byteLength": 384
},
{
"buffer": 0,
"byteOffset": 672,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 960,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 1248,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 1536,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 1824,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 2112,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 2400,
"byteLength": 288
},
{
"buffer": 0,
"byteOffset": 2688,
"byteLength": 72
},
{
"buffer": 0,
"byteOffset": 2760,
"byteLength": 508
},
{
"buffer": 0,
"byteOffset": 3268,
"byteLength": 1016
}
],
"buffers": [
{
"uri": "AnimatedMorphCube.bin",
"byteLength": 4284
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"NORMAL": 0,
"TANGENT": 1,
"POSITION": 2
},
"indices": 9,
"material": 0,
"targets": [
{
"NORMAL": 3,
"POSITION": 4,
"TANGENT": 5
},
{
"NORMAL": 6,
"POSITION": 7,
"TANGENT": 8
}
]
}
],
"weights": [
0.0,
0.0
],
"name": "Cube"
}
],
"materials": [
{
"pbrMetallicRoughness": {
"baseColorFactor": [
0.6038274,
0.6038274,
0.6038274,
1.0
],
"metallicFactor": 0.0,
"roughnessFactor": 0.5
},
"name": "Material"
}
],
"nodes": [
{
"mesh": 0,
"rotation": [
0.0,
0.7071067,
-0.7071068,
0.0
],
"scale": [
100.0,
100.0,
100.0
],
"name": "AnimatedMorphCube"
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -380,4 +380,13 @@ TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) {
EXPECT_TRUE( exporterTest() );
}
TEST_F( utglTF2ImportExport, crash_in_anim_mesh_destructor ) {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube.gltf",
aiProcess_ValidateDataStructure);
ASSERT_NE( nullptr, scene );
Assimp::Exporter exporter;
ASSERT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Sample-Models/AnimatedMorphCube-glTF/AnimatedMorphCube_out.glTF"));
}
#endif // ASSIMP_BUILD_NO_EXPORT