McRogueFace/tests/unit/mesh_instance_test.py
2026-02-06 16:15:07 -05:00

182 lines
6 KiB
Python

# mesh_instance_test.py - Unit test for MeshLayer mesh instances and Viewport3D mesh APIs
import mcrfpy
import sys
def test_viewport3d_add_mesh():
"""Test adding meshes to Viewport3D layers"""
vp = mcrfpy.Viewport3D()
# Add a mesh layer first
vp.add_layer("ground", z_index=0)
# Create a model to place (simple cube primitive)
model = mcrfpy.Model3D()
# Add mesh instance at position
result = vp.add_mesh("ground", model, pos=(5.0, 0.0, 5.0))
# Should return the index of the added mesh
assert result is not None, "Expected add_mesh to return something"
assert isinstance(result, int), f"Expected int index, got {type(result)}"
assert result == 0, f"Expected first mesh index 0, got {result}"
print("[PASS] test_viewport3d_add_mesh")
def test_viewport3d_add_mesh_with_transform():
"""Test adding meshes with rotation and scale"""
vp = mcrfpy.Viewport3D()
vp.add_layer("buildings", z_index=0)
model = mcrfpy.Model3D()
# Add with rotation (in degrees as per API)
idx1 = vp.add_mesh("buildings", model, pos=(10.0, 0.0, 10.0), rotation=90)
assert idx1 == 0, f"Expected first mesh index 0, got {idx1}"
# Add with scale
idx2 = vp.add_mesh("buildings", model, pos=(15.0, 0.0, 15.0), scale=2.0)
assert idx2 == 1, f"Expected second mesh index 1, got {idx2}"
# Add with both rotation and scale
idx3 = vp.add_mesh("buildings", model, pos=(5.0, 0.0, 5.0), rotation=45, scale=0.5)
assert idx3 == 2, f"Expected third mesh index 2, got {idx3}"
print("[PASS] test_viewport3d_add_mesh_with_transform")
def test_viewport3d_clear_meshes():
"""Test clearing meshes from a layer"""
vp = mcrfpy.Viewport3D()
vp.add_layer("objects", z_index=0)
model = mcrfpy.Model3D()
# Add several meshes
vp.add_mesh("objects", model, pos=(1.0, 0.0, 1.0))
vp.add_mesh("objects", model, pos=(2.0, 0.0, 2.0))
vp.add_mesh("objects", model, pos=(3.0, 0.0, 3.0))
# Clear meshes from layer
vp.clear_meshes("objects")
# Add a new mesh - should get index 0 since list was cleared
idx = vp.add_mesh("objects", model, pos=(0.0, 0.0, 0.0))
assert idx == 0, f"Expected index 0 after clear, got {idx}"
print("[PASS] test_viewport3d_clear_meshes")
def test_viewport3d_place_blocking():
"""Test placing blocking information on the navigation grid"""
vp = mcrfpy.Viewport3D()
# Initialize navigation grid first
vp.set_grid_size(width=16, depth=16)
# Place blocking cell (unwalkable, non-transparent)
vp.place_blocking(grid_pos=(5, 5), footprint=(1, 1))
# Place larger blocking footprint
vp.place_blocking(grid_pos=(10, 10), footprint=(2, 2))
# Place blocking with custom walkability
vp.place_blocking(grid_pos=(0, 0), footprint=(3, 3), walkable=False, transparent=True)
# Verify the cells were marked (check via VoxelPoint)
cell = vp.at(5, 5)
assert cell.walkable == False, f"Expected cell (5,5) unwalkable, got walkable={cell.walkable}"
cell_transparent = vp.at(0, 0)
assert cell_transparent.transparent == True, f"Expected cell (0,0) transparent"
print("[PASS] test_viewport3d_place_blocking")
def test_viewport3d_mesh_layer_operations():
"""Test various mesh layer operations"""
vp = mcrfpy.Viewport3D()
# Create multiple layers
vp.add_layer("floor", z_index=0)
vp.add_layer("walls", z_index=1)
vp.add_layer("props", z_index=2)
model = mcrfpy.Model3D()
# Add meshes to different layers
vp.add_mesh("floor", model, pos=(0.0, 0.0, 0.0))
vp.add_mesh("walls", model, pos=(1.0, 1.0, 0.0), rotation=0, scale=1.5)
vp.add_mesh("props", model, pos=(2.0, 0.0, 2.0), scale=0.25)
# Clear only one layer
vp.clear_meshes("walls")
# Other layers should be unaffected
# (Can verify by adding to them and checking indices)
idx_floor = vp.add_mesh("floor", model, pos=(5.0, 0.0, 5.0))
assert idx_floor == 1, f"Expected floor mesh index 1, got {idx_floor}"
idx_walls = vp.add_mesh("walls", model, pos=(5.0, 0.0, 5.0))
assert idx_walls == 0, f"Expected walls mesh index 0 after clear, got {idx_walls}"
print("[PASS] test_viewport3d_mesh_layer_operations")
def test_auto_layer_creation():
"""Test that add_mesh auto-creates layers if they don't exist"""
vp = mcrfpy.Viewport3D()
model = mcrfpy.Model3D()
# Add mesh to a layer that doesn't exist yet - should auto-create it
idx = vp.add_mesh("auto_created", model, pos=(0.0, 0.0, 0.0))
assert idx == 0, f"Expected index 0 for auto-created layer, got {idx}"
# Verify the layer was created
layer = vp.get_layer("auto_created")
assert layer is not None, "Expected auto_created layer to exist"
print("[PASS] test_auto_layer_creation")
def test_invalid_layer_clear():
"""Test error handling for clearing non-existent layers"""
vp = mcrfpy.Viewport3D()
# Try to clear meshes from non-existent layer
try:
vp.clear_meshes("nonexistent")
# If it doesn't raise, it might just silently succeed (which is fine too)
print("[PASS] test_invalid_layer_clear (no exception)")
return
except (ValueError, KeyError, RuntimeError):
print("[PASS] test_invalid_layer_clear (exception raised)")
return
def run_all_tests():
"""Run all mesh instance tests"""
tests = [
test_viewport3d_add_mesh,
test_viewport3d_add_mesh_with_transform,
test_viewport3d_clear_meshes,
test_viewport3d_place_blocking,
test_viewport3d_mesh_layer_operations,
test_auto_layer_creation,
test_invalid_layer_clear,
]
passed = 0
failed = 0
for test in tests:
try:
test()
passed += 1
except AssertionError as e:
print(f"[FAIL] {test.__name__}: {e}")
failed += 1
except Exception as e:
print(f"[ERROR] {test.__name__}: {e}")
failed += 1
print(f"\n=== Results: {passed} passed, {failed} failed ===")
return failed == 0
if __name__ == "__main__":
success = run_all_tests()
sys.exit(0 if success else 1)