| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- import pytest
- from collisions import *
- from panda3d.core import PNMImage
- def test_sphere_into_heightfield():
- # Setup PNMImage
- img = PNMImage(512, 512, 1)
- img.set_gray_val(1, 1, 255)
- # Make CollisionHeightfield
- max_height = 10
- num_subdivisions = 1
- heightfield = CollisionHeightfield(img, max_height, num_subdivisions)
- # The coordinate (1, 1) on our heightfield image
- # maps to the coordinate (1, 510, Z) in 3D space
- sphere = CollisionSphere((1, 510, 11), 1)
- entry, np_from, np_into = make_collision(sphere, heightfield)
- assert entry.get_surface_point(np_from) == (1, 510, 10)
- assert entry.get_surface_normal(np_from) == (0, 0, 1)
- # Set the sphere higher so it is not colliding anymore
- sphere.set_center((1, 510, 11.1))
- entry = make_collision(sphere, heightfield)[0]
- assert entry is None
- # Set the max_height to re-collide with the sphere
- max_height = 10.1
- heightfield.set_max_height(max_height)
- entry, np_from, np_into = make_collision(sphere, heightfield)
- assert entry.get_surface_point(np_from) == (1, 510, 10.1)
- with pytest.raises(AssertionError) as err:
- assert heightfield.set_num_subdivisions(-1) == err
- assert heightfield.set_num_subdivisions(11) == err
- # Use a greater number of subdivisions, should still work
- num_subdivisions = 10
- heightfield.set_num_subdivisions(num_subdivisions)
- entry, np_from, np_into = make_collision(sphere, heightfield)
- assert entry.get_surface_point(np_from) == (1, 510, 10.1)
- # Using 10 subdivisions is overkill for such a small heightfield,
- # CollisionHeightfield should've automatically decreased it
- assert heightfield.get_num_subdivisions() < num_subdivisions
- # Zero subdivisions should work too
- num_subdivisions = 0
- heightfield.set_num_subdivisions(num_subdivisions)
- entry, np_from, np_into = make_collision(sphere, heightfield)
- assert entry.get_surface_point(np_from) == (1, 510, 10.1)
- # Modify the heightfield, no longer colliding
- img.set_gray_val(1, 1, 254)
- heightfield.set_heightfield(img)
- entry = make_collision(sphere, heightfield)[0]
- assert entry is None
- def test_ray_into_heightfield():
- # Setup heightfield
- img = PNMImage(127, 127, 1)
- img.fill_val(0)
- max_height = 10
- num_subdivisions = 1
- heightfield = CollisionHeightfield(img, max_height, num_subdivisions)
- # Make ray
- ray = CollisionRay((100, 100, 100), (-1, -1, -1))
- entry = make_collision(ray, heightfield)[0]
- assert entry is not None
- # Ray with only a z component in its direction
- ray.set_direction((0, 0, -5))
- entry, np_from, np_into = make_collision(ray, heightfield)
- assert entry.get_surface_point(np_from) == (100, 100, 0)
- # Set coordinate (54, 38) on heightfield to gray value of 255
- # Note that coordinate (54, 38) on the heightfield
- # maps to (54, 88, Z) in 3D space
- img.set_gray_val(54, 38, 255)
- heightfield.set_heightfield(img)
- ray.set_origin((54, 88, 10))
- entry, np_from, np_into = make_collision(ray, heightfield)
- assert entry.get_surface_point(np_from) == (54, 88, 10)
- def test_box_into_heightfield():
- # Try using a large non-square heightfield image
- img = PNMImage(5023, 5130, 1)
- img.set_gray_val(1, 1, 255)
- # Make CollisionHeightfield
- max_height = 10
- num_subdivisions = 5
- heightfield = CollisionHeightfield(img, max_height, num_subdivisions)
- # Make box
- box = CollisionBox((1, 5128, 10), 1, 1, 1)
- entry = make_collision(box, heightfield)
- assert entry is not None
|