Skip to content

Commit f11fa04

Browse files
authored
Add w3d model loading test (#784)
1 parent d43ab3d commit f11fa04

File tree

4 files changed

+129
-3
lines changed

4 files changed

+129
-3
lines changed

src/tools/wdump/wdump.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3959,7 +3959,7 @@ LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
39593959
TreeView_SetItemState(g_treewnd, TreeView_GetSelection(g_treewnd), 0, TVIS_SELECTED);
39603960
TreeView_DeleteAllItems(g_treewnd);
39613961
BufferedFileClass file(fname);
3962-
file.Open(1);
3962+
file.Open(FM_READ);
39633963
ChunkLoadClass cload(&file);
39643964

39653965
if (g_main) {
@@ -4030,7 +4030,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
40304030

40314031
if (__argc > 1) {
40324032
BufferedFileClass file(__argv[1]);
4033-
file.Open(1);
4033+
file.Open(FM_READ);
40344034
ChunkLoadClass cload(&file);
40354035
g_main = new ChunkData;
40364036
ParseSubchunks(cload, g_main);

tests/CMakeLists.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,16 @@ FetchContent_Declare(
66

77
FetchContent_MakeAvailable(googletest)
88

9-
add_executable(thyme_tests globals.cpp test_audiofilecache.cpp test_crc.cpp test_filesystem.cpp test_w3d_math.cpp)
9+
set(TEST_SRCS
10+
globals.cpp
11+
test_audiofilecache.cpp
12+
test_crc.cpp
13+
test_filesystem.cpp
14+
test_w3d_load.cpp
15+
test_w3d_math.cpp
16+
)
17+
18+
add_executable(thyme_tests ${TEST_SRCS})
1019
target_link_libraries(thyme_tests gtest gtest_main)
1120
target_compile_definitions(thyme_tests PRIVATE -DTESTDATA_PATH="${CMAKE_CURRENT_SOURCE_DIR}/data")
1221

tests/data/models/cube.w3d

1.67 KB
Binary file not shown.

tests/test_w3d_load.cpp

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/**
2+
* @file
3+
*
4+
* @author feliwir
5+
*
6+
* @brief Set of tests to test w3d model loading
7+
*
8+
* @copyright Thyme is free software: you can redistribute it and/or
9+
* modify it under the terms of the GNU General Public License
10+
* as published by the Free Software Foundation, either version
11+
* 2 of the License, or (at your option) any later version.
12+
* A full copy of the GNU General Public License can be found in
13+
* LICENSE
14+
*/
15+
#include <captainslog.h>
16+
#include <gtest/gtest.h>
17+
18+
#include "always.h"
19+
#include "asciistring.h"
20+
#include "assetmgr.h"
21+
#include "bufffileclass.h"
22+
#include "chunkio.h"
23+
#include "meshmdl.h"
24+
#include "w3d_file.h"
25+
26+
struct Chunk
27+
{
28+
int type;
29+
int size;
30+
std::vector<Chunk> subchunks;
31+
};
32+
33+
// clang-format off
34+
Chunk cubemodel = { -1, -1,
35+
{ { W3D_CHUNK_MESH, 1701,
36+
{ { W3D_CHUNK_MESH_HEADER3, 116 },
37+
{ W3D_CHUNK_VERTICES, 432 },
38+
{ W3D_CHUNK_VERTEX_NORMALS, 432 },
39+
{ W3D_CHUNK_TRIANGLES, 384 },
40+
{ W3D_CHUNK_VERTEX_SHADE_INDICES, 144 },
41+
{ W3D_CHUNK_MATERIAL_INFO, 16 },
42+
{ W3D_CHUNK_VERTEX_MATERIALS, 65,
43+
{ { W3D_CHUNK_VERTEX_MATERIAL, 57,
44+
{ { W3D_CHUNK_VERTEX_MATERIAL_NAME, 9 },
45+
{ W3D_CHUNK_VERTEX_MATERIAL_INFO, 32 },
46+
} },
47+
} },
48+
{ W3D_CHUNK_SHADERS, 16 },
49+
{ W3D_CHUNK_MATERIAL_PASS, 24,
50+
{ { W3D_CHUNK_VERTEX_MATERIAL_IDS, 4},
51+
{ W3D_CHUNK_SHADER_IDS, 4},
52+
} },
53+
} },
54+
}
55+
};
56+
// clang-format on
57+
58+
void validate_chunk(ChunkLoadClass &cload, const Chunk &chunk, int depth = 1)
59+
{
60+
int idx = 0;
61+
while (cload.Open_Chunk()) {
62+
if (chunk.subchunks.size() <= idx) {
63+
ASSERT_TRUE(chunk.subchunks.size() > idx) << "Missing chunk: " << cload.Cur_Chunk_ID();
64+
cload.Close_Chunk();
65+
}
66+
67+
const auto &ref = chunk.subchunks[idx];
68+
EXPECT_EQ(cload.Cur_Chunk_ID(), ref.type);
69+
EXPECT_EQ(cload.Cur_Chunk_Depth(), depth);
70+
EXPECT_EQ(cload.Cur_Chunk_Length(), ref.size);
71+
72+
// Read the data and check we get all bytes
73+
std::vector<uint8_t> data;
74+
data.resize(cload.Cur_Chunk_Length());
75+
EXPECT_EQ(cload.Read(data.data(), data.size()), ref.size);
76+
77+
if (cload.Contains_Chunks()) {
78+
validate_chunk(cload, ref, depth + 1);
79+
}
80+
81+
cload.Close_Chunk();
82+
idx++;
83+
}
84+
}
85+
86+
TEST(w3d_model, validate_chunk_loader)
87+
{
88+
auto filepath = Utf8String(TESTDATA_PATH) + "/models/cube.w3d";
89+
90+
BufferedFileClass file(filepath.Str());
91+
ASSERT_TRUE(file.Open(FM_READ));
92+
ChunkLoadClass cload(&file);
93+
94+
// Traverse through the model to validate chunks
95+
validate_chunk(cload, cubemodel);
96+
}
97+
98+
TEST(w3d_model, load_model)
99+
{
100+
// We need to have an instance of this
101+
W3DAssetManager assetmngr;
102+
auto filepath = Utf8String(TESTDATA_PATH) + "/models/cube.w3d";
103+
104+
BufferedFileClass file(filepath.Str());
105+
ASSERT_TRUE(file.Open(FM_READ));
106+
ChunkLoadClass cload(&file);
107+
EXPECT_TRUE(cload.Open_Chunk());
108+
EXPECT_EQ(cload.Cur_Chunk_ID(), W3D_CHUNK_MESH);
109+
110+
MeshModelClass mesh;
111+
EXPECT_EQ(mesh.Load_W3D(cload), W3D_ERROR_OK);
112+
EXPECT_EQ(mesh.Get_Polygon_Count(), 12);
113+
EXPECT_EQ(mesh.Get_Vertex_Count(), 36);
114+
EXPECT_STREQ(mesh.Get_Name(), "cube");
115+
116+
cload.Close_Chunk();
117+
}

0 commit comments

Comments
 (0)