3D / voxel unit tests
This commit is contained in:
parent
e12e80e511
commit
71cd2b9b41
22 changed files with 4705 additions and 0 deletions
182
tests/unit/mesh_instance_test.py
Normal file
182
tests/unit/mesh_instance_test.py
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
# 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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue