summaryrefslogtreecommitdiff
path: root/test/test_bvh.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_bvh.py')
-rw-r--r--test/test_bvh.py159
1 files changed, 159 insertions, 0 deletions
diff --git a/test/test_bvh.py b/test/test_bvh.py
new file mode 100644
index 0000000..5372f6e
--- /dev/null
+++ b/test/test_bvh.py
@@ -0,0 +1,159 @@
+import unittest
+from chroma.bvh import BVH, BVHLayerSlice, WorldCoords, uint4, \
+ OutOfRangeError, unpack_nodes
+import numpy as np
+from numpy.testing import assert_array_max_ulp, assert_array_equal, \
+ assert_approx_equal
+
+def lslice(layer_bounds, layer_number):
+ '''Returns a slice object for retrieving a particular layer in an
+ array of nodes.'''
+ return slice(layer_bounds[layer_number], layer_bounds[layer_number+1])
+
+class TestWorldCoords(unittest.TestCase):
+ def setUp(self):
+ self.coords = WorldCoords([-1,-1,-1], 0.1)
+
+ def test_fixed_to_world(self):
+ f = [0, 1, 100]
+ assert_array_max_ulp(self.coords.fixed_to_world(f),
+ [-1.0, -0.9, 9.0], dtype=np.float32)
+
+ def test_world_to_fixed(self):
+ w = [-1.0, -0.9, 9.0]
+ assert_array_equal(self.coords.world_to_fixed(w),
+ [0, 1, 100])
+
+
+ def test_fixed_array_to_world(self):
+ f = [[0, 1, 100],
+ [20, 40, 60],
+ [210, 310, 410]]
+
+ assert_array_max_ulp(self.coords.fixed_to_world(f),
+ [[-1.0, -0.9, 9.0],
+ [1.0, 3.0, 5.0],
+ [20.0, 30.0, 40.0]],
+ dtype=np.float32)
+
+ def test_world_array_to_fixed(self):
+ w = [[-1.0, -0.9, 9.0],
+ [1.0, 3.0, 5.0],
+ [20.0, 30.0, 40.0]]
+ assert_array_equal(self.coords.world_to_fixed(w),
+ [[0, 1, 100],
+ [20, 40, 60],
+ [210, 310, 410]])
+
+ def test_out_of_range(self):
+ with self.assertRaises(OutOfRangeError):
+ self.coords.world_to_fixed([-2.0, 0.0, 0.0])
+ with self.assertRaises(OutOfRangeError):
+ self.coords.world_to_fixed([0.0, 1e9, 0.0])
+
+def create_bvh():
+ # 3 layer binary tree
+ degree = 2
+ world_coords = WorldCoords(np.array([-1.0,-1.0,-1.0]), 0.1)
+ layer_bounds = [0, 1, 3, 7]
+ nodes = np.empty(shape=layer_bounds[-1], dtype=uint4)
+
+ # bottom layer
+ layer = lslice(layer_bounds, 2)
+ nodes['x'][layer] = [ 0x00010000, 0x00020001,
+ 0x00010000, 0x00010000]
+ nodes['y'][layer] = [ 0x00010000, 0x00010000,
+ 0x00020001, 0x00010000]
+ nodes['z'][layer] = [ 0x00010000, 0x00010000,
+ 0x00010000, 0x00020001]
+ nodes['w'][layer] = 0x80000000 # leaf nodes
+
+ # middle layer
+ layer = lslice(layer_bounds, 1)
+ nodes['x'][layer] = [ 0x00020000, 0x00010000 ]
+ nodes['y'][layer] = [ 0x00010000, 0x00020000 ]
+ nodes['z'][layer] = [ 0x00010000, 0x00020000 ]
+ nodes['w'][layer] = [ 0x00000003, 0x00000005 ]
+
+ # top layer
+ layer = lslice(layer_bounds, 0)
+ nodes['x'][layer] = [ 0x00020000 ]
+ nodes['y'][layer] = [ 0x00020000 ]
+ nodes['z'][layer] = [ 0x00020000 ]
+ nodes['w'][layer] = [ 0x00000001 ]
+
+ layer_offsets = list(layer_bounds[:-1]) # trim last entry
+ bvh = BVH(degree=degree, world_coords=world_coords,
+ nodes=nodes, layer_offsets=layer_offsets)
+
+ return bvh
+
+def test_unpack_nodes():
+ bvh = create_bvh()
+
+ layer = bvh.get_layer(2)
+ unpack = unpack_nodes(layer.nodes)
+ assert_array_equal(unpack['xlo'], [0, 1, 0, 0])
+ assert_array_equal(unpack['xhi'], [1, 2, 1, 1])
+ assert_array_equal(unpack['ylo'], [0, 0, 1, 0])
+ assert_array_equal(unpack['yhi'], [1, 1, 2, 1])
+ assert_array_equal(unpack['zlo'], [0, 0, 0, 1])
+ assert_array_equal(unpack['zhi'], [1, 1, 1, 2])
+ assert unpack['leaf'].all()
+
+ layer = bvh.get_layer(1)
+ unpack = unpack_nodes(layer.nodes)
+ assert_array_equal(unpack['xlo'], [0, 0])
+ assert_array_equal(unpack['xhi'], [2, 1])
+ assert_array_equal(unpack['ylo'], [0, 0])
+ assert_array_equal(unpack['yhi'], [1, 2])
+ assert_array_equal(unpack['zlo'], [0, 0])
+ assert_array_equal(unpack['zhi'], [1, 2])
+ assert_array_equal(unpack['child'], [3, 5])
+ assert not unpack['leaf'].any()
+
+ layer = bvh.get_layer(0)
+ unpack = unpack_nodes(layer.nodes)
+ assert_array_equal(unpack['xlo'], [0])
+ assert_array_equal(unpack['xhi'], [2])
+ assert_array_equal(unpack['ylo'], [0])
+ assert_array_equal(unpack['yhi'], [2])
+ assert_array_equal(unpack['zlo'], [0])
+ assert_array_equal(unpack['zhi'], [2])
+ assert_array_equal(unpack['child'], [1])
+ assert not unpack['leaf'].any()
+
+
+class TestBVH(unittest.TestCase):
+ def setUp(self):
+ self.bvh = create_bvh()
+
+ def test_len(self):
+ self.assertEqual(len(self.bvh), 7)
+
+ def test_layer_count(self):
+ self.assertEqual(self.bvh.layer_count(), 3)
+
+ def test_get_layer(self):
+ layer = self.bvh.get_layer(0)
+ self.assertEqual(len(layer), 1)
+
+ layer = self.bvh.get_layer(1)
+ self.assertEqual(len(layer), 2)
+
+ layer = self.bvh.get_layer(2)
+ self.assertEqual(len(layer), 4)
+
+class TestBVHLayer(unittest.TestCase):
+ def setUp(self):
+ self.bvh = create_bvh()
+
+ def test_area(self):
+ layer = self.bvh.get_layer(2)
+ assert_approx_equal(layer.area(), 4*6*0.1**2)
+
+ layer = self.bvh.get_layer(1)
+ assert_approx_equal(layer.area(), (4*2+2 + 4*2+2*4)*0.1**2)
+
+ layer = self.bvh.get_layer(0)
+ assert_approx_equal(layer.area(), (6*2*2)*0.1**2)