From 1aeb5095ac9b0ed1fececbea1412a5436f00f3ac Mon Sep 17 00:00:00 2001 From: codereader Date: Sun, 30 May 2021 21:22:38 +0200 Subject: [PATCH] #5628: Add another test case (and corresponding fix) with an ASE containing a *GEOMOBJECT without *MATERIAL_REF. The game engine falls back to the first material if not specified otherwise, DR now does the same. (This obviously was produced by an older Blender ASE exporter.) --- radiantcore/model/import/AseModel.cpp | 7 +- test/Models.cpp | 17 ++ .../ase/testcube_without_material_ref.ase | 174 ++++++++++++++++++ 3 files changed, 195 insertions(+), 3 deletions(-) create mode 100644 test/resources/tdm/models/ase/testcube_without_material_ref.ase diff --git a/radiantcore/model/import/AseModel.cpp b/radiantcore/model/import/AseModel.cpp index 640c37aa18..8b14499deb 100644 --- a/radiantcore/model/import/AseModel.cpp +++ b/radiantcore/model/import/AseModel.cpp @@ -526,7 +526,8 @@ void AseModel::parseGeomObject(parser::StringTokeniser& tokeniser) { Mesh mesh; Matrix4 nodeMatrix = Matrix4::getIdentity(); - int materialIndex = -1; + // even if no *MATERIAL_REF is found in the object, we use material 0 by default + std::size_t materialIndex = 0; int blockLevel = 0; @@ -553,7 +554,7 @@ void AseModel::parseGeomObject(parser::StringTokeniser& tokeniser) // normals of the mesh. parseNodeMatrix(nodeMatrix, tokeniser); } - /* mesh material reference. this usually comes at the end of + /* Optional: mesh material reference. This usually comes at the end of * geomobjects after the mesh blocks. we must assume that the * new mesh was already created so all we can do here is assign * the material reference id (shader index) now. */ @@ -563,7 +564,7 @@ void AseModel::parseGeomObject(parser::StringTokeniser& tokeniser) if (index >= _materials.size()) throw parser::ParseException("MATERIAL_REF index out of bounds >= MATERIAL_COUNT"); - materialIndex = static_cast(index); + materialIndex = index; } } diff --git a/test/Models.cpp b/test/Models.cpp index 1688b89a5b..fef6497907 100644 --- a/test/Models.cpp +++ b/test/Models.cpp @@ -420,4 +420,21 @@ TEST_F(AseImportTest, ParseMeshFaceWithoutABBCCA) } } +TEST_F(AseImportTest, ParseGeomObjectWithoutMaterialRef) +{ + // This model contains a *GEOMOBJECT without any *MATERIAL_REF the parser needs to be able to deal with that + auto model = GlobalModelCache().getModel("models/ase/testcube_without_material_ref.ase"); + + // Model should be loaded successfully + EXPECT_TRUE(model); + + if (model) + { + EXPECT_EQ(model->getSurfaceCount(), 1); + EXPECT_EQ(model->getSurface(0).getDefaultMaterial(), "textures/darkmod/stone/flat/tiles_rough_grey"); + EXPECT_EQ(model->getSurface(0).getNumVertices(), 24); + EXPECT_EQ(model->getSurface(0).getNumTriangles(), 12); + } +} + } diff --git a/test/resources/tdm/models/ase/testcube_without_material_ref.ase b/test/resources/tdm/models/ase/testcube_without_material_ref.ase new file mode 100644 index 0000000000..b327ef6f5f --- /dev/null +++ b/test/resources/tdm/models/ase/testcube_without_material_ref.ase @@ -0,0 +1,174 @@ +*3DSMAX_ASCIIEXPORT 200 +*COMMENT "Ascii Scene Exporter v2.52" +*SCENE { + *SCENE_FILENAME "cube.blend" + *SCENE_FIRSTFRAME 0 + *SCENE_LASTFRAME 100 + *SCENE_FRAMESPEED 30 + *SCENE_TICKSPERFRAME 160 + *SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000 + *SCENE_AMBIENT_STATIC 0.0000 0.0000 0.0000 +} +*MATERIAL_LIST { + *MATERIAL_COUNT 1 + *MATERIAL 0 { + *MATERIAL_NAME "material" + *MATERIAL_CLASS "Standard" + *MATERIAL_AMBIENT 0.0000 0.0000 0.0000 + *MATERIAL_DIFFUSE 0.9071 0.9071 0.9071 1.0000 + *MATERIAL_SPECULAR 1.0000 1.0000 1.0000 + *MATERIAL_SHINE 2.5000 + *MATERIAL_SHINESTRENGTH 0.5000 + *MATERIAL_TRANSPARENCY 0.0000 + *MATERIAL_WIRESIZE 1.0000 + *MATERIAL_SHADING Blinn + *MATERIAL_XP_FALLOFF 0.0000 + *MATERIAL_SELFILLUM 0.0000 + *MATERIAL_FALLOFF In + *MATERIAL_XP_TYPE Filter + *MAP_DIFFUSE { + *MAP_NAME "material" + *MAP_CLASS "Bitmap" + *MAP_SUBNO 1 + *MAP_AMOUNT 1.0000 + *BITMAP "//base/textures/darkmod/stone/flat/tiles_rough_grey" + *MAP_TYPE Screen + *UVW_U_OFFSET 0.0000 + *UVW_V_OFFSET 0.0000 + *UVW_U_TILING 1.0000 + *UVW_V_TILING 1.0000 + *UVW_ANGLE 0.0000 + *UVW_BLUR 1.0000 + *UVW_BLUR_OFFSET 0.0000 + *UVW_NOISE_AMT 1.0000 + *UVW_NOISE_SIZE 1.0000 + *UVW_NOISE_LEVEL 1 + *UVW_NOISE_PHASE 0.0000 + *BITMAP_FILTER Pyramidal + } + } +} +*GEOMOBJECT { + *NODE_NAME "Cube" + *NODE_TM { + *NODE_NAME "Cube" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0000 0.0000 0.0000 + *TM_ROW1 0.0000 1.0000 0.0000 + *TM_ROW2 0.0000 0.0000 1.0000 + *TM_ROW3 0.0000 0.0000 0.0000 + *TM_POS 0.0000 0.0000 0.0000 + *TM_ROTAXIS 0.0000 0.0000 0.0000 + *TM_ROTANGLE 0.0000 + *TM_SCALE 1.0000 1.0000 1.0000 + *TM_SCALEAXIS 0.0000 0.0000 0.0000 + *TM_SCALEAXISANG 0.0000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 8 + *MESH_NUMFACES 12 + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 -16.0000 -16.0000 -16.0000 + *MESH_VERTEX 1 -16.0000 -16.0000 16.0000 + *MESH_VERTEX 2 -16.0000 16.0000 -16.0000 + *MESH_VERTEX 3 -16.0000 16.0000 16.0000 + *MESH_VERTEX 4 16.0000 -16.0000 -16.0000 + *MESH_VERTEX 5 16.0000 -16.0000 16.0000 + *MESH_VERTEX 6 16.0000 16.0000 -16.0000 + *MESH_VERTEX 7 16.0000 16.0000 16.0000 + } + *MESH_FACE_LIST { + *MESH_FACE 0: A: 1 B: 2 C: 0 AB: 0 BC: 0 CA: 0 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1: A: 3 B: 6 C: 2 AB: 0 BC: 0 CA: 0 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 2: A: 7 B: 4 C: 6 AB: 0 BC: 0 CA: 0 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 3: A: 5 B: 0 C: 4 AB: 0 BC: 0 CA: 0 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 4: A: 6 B: 0 C: 2 AB: 0 BC: 0 CA: 0 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 5: A: 3 B: 5 C: 7 AB: 0 BC: 0 CA: 0 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 6: A: 1 B: 3 C: 2 AB: 0 BC: 0 CA: 0 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 7: A: 3 B: 7 C: 6 AB: 0 BC: 0 CA: 0 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 8: A: 7 B: 5 C: 4 AB: 0 BC: 0 CA: 0 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 9: A: 5 B: 1 C: 0 AB: 0 BC: 0 CA: 0 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 10: A: 6 B: 4 C: 0 AB: 0 BC: 0 CA: 0 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 11: A: 3 B: 1 C: 5 AB: 0 BC: 0 CA: 0 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 1.0000 0.0000 0.0000 + *MESH_TVERT 1 0.0000 1.0000 0.0000 + *MESH_TVERT 2 0.0000 0.0000 0.0000 + *MESH_TVERT 3 1.0000 1.0000 0.0000 + } + *MESH_NUMTVFACES 12 + *MESH_TFACELIST { + *MESH_TFACE 0 0 1 2 + *MESH_TFACE 1 0 1 2 + *MESH_TFACE 2 0 1 2 + *MESH_TFACE 3 0 1 2 + *MESH_TFACE 4 0 1 2 + *MESH_TFACE 5 0 1 2 + *MESH_TFACE 6 0 3 1 + *MESH_TFACE 7 0 3 1 + *MESH_TFACE 8 0 3 1 + *MESH_TFACE 9 0 3 1 + *MESH_TFACE 10 0 3 1 + *MESH_TFACE 11 0 3 1 + } + *MESH_NUMCVERTEX 0 + *MESH_NORMALS { + *MESH_FACENORMAL 0 -1.0000 0.0000 0.0000 + *MESH_VERTEXNORMAL 1 -1.0000 0.0000 0.0000 + *MESH_VERTEXNORMAL 2 -1.0000 0.0000 0.0000 + *MESH_VERTEXNORMAL 0 -1.0000 0.0000 0.0000 + *MESH_FACENORMAL 1 0.0000 1.0000 -0.0000 + *MESH_VERTEXNORMAL 3 0.0000 1.0000 0.0000 + *MESH_VERTEXNORMAL 6 0.0000 1.0000 0.0000 + *MESH_VERTEXNORMAL 2 0.0000 1.0000 0.0000 + *MESH_FACENORMAL 2 1.0000 0.0000 -0.0000 + *MESH_VERTEXNORMAL 7 1.0000 0.0000 0.0000 + *MESH_VERTEXNORMAL 4 1.0000 0.0000 0.0000 + *MESH_VERTEXNORMAL 6 1.0000 0.0000 0.0000 + *MESH_FACENORMAL 3 0.0000 -1.0000 0.0000 + *MESH_VERTEXNORMAL 5 0.0000 -1.0000 0.0000 + *MESH_VERTEXNORMAL 0 0.0000 -1.0000 0.0000 + *MESH_VERTEXNORMAL 4 0.0000 -1.0000 0.0000 + *MESH_FACENORMAL 4 0.0000 0.0000 -1.0000 + *MESH_VERTEXNORMAL 6 0.0000 0.0000 -1.0000 + *MESH_VERTEXNORMAL 0 0.0000 0.0000 -1.0000 + *MESH_VERTEXNORMAL 2 0.0000 0.0000 -1.0000 + *MESH_FACENORMAL 5 0.0000 0.0000 1.0000 + *MESH_VERTEXNORMAL 3 0.0000 0.0000 1.0000 + *MESH_VERTEXNORMAL 5 0.0000 0.0000 1.0000 + *MESH_VERTEXNORMAL 7 0.0000 0.0000 1.0000 + *MESH_FACENORMAL 6 -1.0000 0.0000 0.0000 + *MESH_VERTEXNORMAL 1 -1.0000 0.0000 0.0000 + *MESH_VERTEXNORMAL 3 -1.0000 0.0000 0.0000 + *MESH_VERTEXNORMAL 2 -1.0000 0.0000 0.0000 + *MESH_FACENORMAL 7 0.0000 1.0000 -0.0000 + *MESH_VERTEXNORMAL 3 0.0000 1.0000 0.0000 + *MESH_VERTEXNORMAL 7 0.0000 1.0000 0.0000 + *MESH_VERTEXNORMAL 6 0.0000 1.0000 0.0000 + *MESH_FACENORMAL 8 1.0000 0.0000 0.0000 + *MESH_VERTEXNORMAL 7 1.0000 0.0000 0.0000 + *MESH_VERTEXNORMAL 5 1.0000 0.0000 0.0000 + *MESH_VERTEXNORMAL 4 1.0000 0.0000 0.0000 + *MESH_FACENORMAL 9 0.0000 -1.0000 0.0000 + *MESH_VERTEXNORMAL 5 0.0000 -1.0000 0.0000 + *MESH_VERTEXNORMAL 1 0.0000 -1.0000 0.0000 + *MESH_VERTEXNORMAL 0 0.0000 -1.0000 0.0000 + *MESH_FACENORMAL 10 0.0000 0.0000 -1.0000 + *MESH_VERTEXNORMAL 6 0.0000 0.0000 -1.0000 + *MESH_VERTEXNORMAL 4 0.0000 0.0000 -1.0000 + *MESH_VERTEXNORMAL 0 0.0000 0.0000 -1.0000 + *MESH_FACENORMAL 11 0.0000 -0.0000 1.0000 + *MESH_VERTEXNORMAL 3 0.0000 0.0000 1.0000 + *MESH_VERTEXNORMAL 1 0.0000 0.0000 1.0000 + *MESH_VERTEXNORMAL 5 0.0000 0.0000 1.0000 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 +} \ No newline at end of file