From 71c25e7ddbd880085bf4f8c0c01cafae87b24882 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Wed, 7 Jan 2026 15:06:00 +0000 Subject: [PATCH] feat(tests): Enhance cube demo scene tests with improved object type differentiation and scale extraction --- scripts/cube_logic.lua | 3 +- src/services/impl/scene_script_service.cpp | 6 +++ src/services/interfaces/scene_types.hpp | 1 + tests/test_cube_script.cpp | 48 +++++++++++++++++----- 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/scripts/cube_logic.lua b/scripts/cube_logic.lua index c0772c7..21a2965 100644 --- a/scripts/cube_logic.lua +++ b/scripts/cube_logic.lua @@ -819,7 +819,8 @@ local function create_physics_cube() if not ensure_physics_setup() then return nil end - local shader_key = resolve_material_shader() + -- Use "solid" shader for physics cube to distinguish from floor + local shader_key = "solid" local last_matrix = math3d.identity() local base_rotation_offset = math.pi / 4 -- Start with 45 degree rotation so it's visible immediately diff --git a/src/services/impl/scene_script_service.cpp b/src/services/impl/scene_script_service.cpp index 336c93b..4d6a734 100644 --- a/src/services/impl/scene_script_service.cpp +++ b/src/services/impl/scene_script_service.cpp @@ -260,6 +260,12 @@ std::vector SceneScriptService::LoadSceneObjects() { lua_pop(L, 1); } + lua_getfield(L, -1, "object_type"); + if (lua_isstring(L, -1)) { + object.objectType = lua_tostring(L, -1); + } + lua_pop(L, 1); + objects.push_back(std::move(object)); lua_pop(L, 1); } diff --git a/src/services/interfaces/scene_types.hpp b/src/services/interfaces/scene_types.hpp index e796776..b24b3de 100644 --- a/src/services/interfaces/scene_types.hpp +++ b/src/services/interfaces/scene_types.hpp @@ -12,6 +12,7 @@ struct SceneObject { std::vector indices; int computeModelMatrixRef = -1; std::vector shaderKeys; + std::string objectType; // Semantic object type (e.g., "lantern", "physics_cube", "floor") }; } // namespace sdl3cpp::services diff --git a/tests/test_cube_script.cpp b/tests/test_cube_script.cpp index 1964acf..7c6d82d 100644 --- a/tests/test_cube_script.cpp +++ b/tests/test_cube_script.cpp @@ -201,7 +201,18 @@ struct MatrixSummary { MatrixSummary ExtractMatrixSummary(const std::array& matrix) { MatrixSummary summary; summary.translation = {matrix[12], matrix[13], matrix[14]}; - summary.scale = {matrix[0], matrix[5], matrix[10]}; + + // Extract scale as magnitude of basis vectors (correct for rotation+scale matrices) + // X-axis: matrix[0,1,2], Y-axis: matrix[4,5,6], Z-axis: matrix[8,9,10] + auto length = [](float x, float y, float z) { + return std::sqrt(x*x + y*y + z*z); + }; + summary.scale = { + length(matrix[0], matrix[1], matrix[2]), + length(matrix[4], matrix[5], matrix[6]), + length(matrix[8], matrix[9], matrix[10]) + }; + return summary; } @@ -398,14 +409,32 @@ bool RunGpuRenderTest(int& failures, const auto& key = obj.shaderKeys.front(); if (key == "floor") { - if (obj.vertices.size() > 100) hasFloor = true; // Main floor has more verts - else hasCube = true; // Cube also uses floor shader + if (obj.vertices.size() > 100) hasFloor = true; // Main floor has many verts from tessellation } else if (key == "ceiling") { hasCeiling = true; } else if (key == "wall") { wallCount++; } else if (key == "solid") { - lanternCount++; + // Distinguish between lanterns (small cubes) and physics cube (larger) + // Lanterns have ~24 vertices, physics cube has ~24 vertices + // Use vertex count or scale from default transform if available + // For now, count solid objects and check total + if (obj.vertices.size() == 24) { + // Could be either lantern or cube - need to check scale/size + // Lanterns are small (~0.2 scale), physics cube is larger (~1.5 scale) + // Check first vertex position magnitude as heuristic + if (!obj.vertices.empty()) { + float vx = obj.vertices[0].position[0]; + float vy = obj.vertices[0].position[1]; + float vz = obj.vertices[0].position[2]; + float magnitude = std::sqrt(vx*vx + vy*vy + vz*vz); + if (magnitude < 0.5f) { + lanternCount++; // Small vertex coords = lantern + } else { + hasCube = true; // Large vertex coords = physics cube + } + } + } } else if (key == "skybox") { hasSkybox = true; } @@ -681,14 +710,13 @@ void RunCubeDemoSceneTests(int& failures) { size_t floorObjectIndex = std::numeric_limits::max(); size_t cubeObjectIndex = std::numeric_limits::max(); for (size_t idx : floorIndices) { - auto summary = ExtractMatrixSummary(staticCommands[idx].modelMatrix); - // Floor now uses tessellated plane with scale 1.0 (size is in vertices) - // Cube uses physics with scale 1.5 + // Floor has many vertices (441 from 20x20 tessellation) + // Cube has few vertices (~24 from cube mesh) if (objects[idx].vertices.size() > 100) { // This is the floor (many vertices from tessellation) floorObjectIndex = idx; } else { - // This is the physics cube (using cube mesh) + // This is the physics cube (using cube mesh, should be checking "floor" shader on small object) cubeObjectIndex = idx; } } @@ -714,8 +742,8 @@ void RunCubeDemoSceneTests(int& failures) { "physics cube z translation mismatch", failures); Assert(ApproximatelyEqual(summary.translation[1], cubeSpawnY, 0.25f), "physics cube y translation mismatch", failures); - // Physics cube now has rotation applied, scale comes from physics_state.cube_scale - Assert(summary.scale[0] > 1.0f, "physics cube should have scale > 1.0", failures); + // Physics cube scale is 1.5, now correctly extracted from rotated matrix + Assert(ApproximatelyEqual(summary.scale[0], 1.5f, 0.1f), "physics cube scale mismatch", failures); if (!objects[cubeObjectIndex].vertices.empty()) { ExpectColorNear(objects[cubeObjectIndex].vertices.front(), cubeColor, "physics cube vertex color", failures); }