public void GetAllNodesTest(int svoNum) { SVO svo = svos[svoNum]; int svoSize = 0; string expectedOutput = "SVO Output for sample type FlatGround, size 0: [Node, Position (-1.0000, -1.0000, -1.0000), Size: 2, Leaf: False, Level: 1], [Node, Position (-1.0000, -1.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-1.0000, -0.5000, -1.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-1.0000, -0.5000, -0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-0.5000, -0.5000, -1.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-0.5000, -0.5000, -0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-1.0000, -1.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-1.0000, -0.5000, 0.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-1.0000, -0.5000, 0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-0.5000, -0.5000, 0.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-0.5000, -0.5000, 0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, -1.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, -0.5000, -1.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, -0.5000, -0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.5000, -0.5000, -1.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.5000, -0.5000, -0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, -1.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, -0.5000, 0.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, -0.5000, 0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.5000, -0.5000, 0.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.5000, -0.5000, 0.5000), Size: 0.5, Leaf: True, Level: 2] |||||| SVO Output for sample type Sphere, size 1: [Node, Position (-1.0000, -1.0000, -1.0000), Size: 2, Leaf: False, Level: 1], [Node, Position (-1.0000, -1.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-1.0000, -1.0000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.7500, -0.7500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, -0.7500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, -0.5000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.7500, -0.5000, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, -0.2500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, -0.5000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-1.0000, -0.5000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, -0.2500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, -0.2500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, -0.5000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -1.0000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, -0.7500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -0.7500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -1.0000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, -1.0000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -0.7500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -1.0000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -1.0000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -0.5000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, -0.5000, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -0.2500, -1.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -0.5000, -1.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -0.2500, -1.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, -1.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-1.0000, -1.0000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.7500, -0.7500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, -0.7500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, -0.5000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-1.0000, -0.5000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, -0.2500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, -0.2500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, -0.5000, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, -0.5000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.7500, -0.5000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, -0.2500, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -1.0000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, -1.0000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -0.7500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -1.0000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -1.0000, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -1.0000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, -0.7500, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -0.7500, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -0.5000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, -0.5000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -0.2500, 0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -0.5000, 0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -0.2500, 0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, 0.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-1.0000, 0.0000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.7500, 0.0000, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, 0.2500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, 0.0000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-1.0000, 0.0000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, 0.0000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, 0.2500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, 0.2500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, 0.5000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.7500, 0.5000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, 0.5000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.0000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, 0.0000, -1.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.2500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.0000, -1.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.2500, -1.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.5000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, 0.5000, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.5000, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.5000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, 0.5000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.7500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.7500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.7500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, 0.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-1.0000, 0.0000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-1.0000, 0.0000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, 0.0000, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, 0.2500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, 0.2500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, 0.0000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.7500, 0.0000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, 0.2500, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, 0.5000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.7500, 0.5000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, 0.5000, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.0000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, 0.0000, 0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.2500, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.0000, 0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.2500, 0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.5000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, 0.5000, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.7500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.7500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.7500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.5000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, 0.5000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.5000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -1.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, -1.0000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, -0.7500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.7500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -1.0000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, -1.0000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -1.0000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -1.0000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.7500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -0.5000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, -0.5000, -1.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -0.2500, -1.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.5000, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.2500, -1.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -1.0000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, -0.7500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -0.7500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -0.5000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, -0.5000, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -0.2500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -0.5000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, -0.5000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.7500, -0.5000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.7500, -0.2500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.7500, -0.2500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -1.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, -1.0000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, -1.0000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -1.0000, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -1.0000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.7500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -1.0000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, -0.7500, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.7500, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -0.5000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, -0.5000, 0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -0.2500, 0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.5000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.2500, 0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -1.0000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, -0.7500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -0.7500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -0.5000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, -0.5000, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.7500, -0.5000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.7500, -0.2500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.7500, -0.2500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -0.5000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, -0.5000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -0.2500, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, 0.0000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, 0.0000, -1.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.2500, -1.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.0000, -1.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.2500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.5000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, 0.5000, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.5000, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.5000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, 0.7500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.7500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.5000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.7500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.0000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, 0.0000, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.2500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.0000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, 0.2500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.7500, 0.0000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.7500, 0.0000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.7500, 0.2500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.5000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, 0.5000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.5000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, 0.0000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, 0.0000, 0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.2500, 0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.0000, 0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.2500, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.5000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, 0.7500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.7500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.5000, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.7500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.5000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, 0.5000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.5000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.0000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, 0.2500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.7500, 0.0000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.7500, 0.0000, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.7500, 0.2500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.0000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, 0.0000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.2500, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.5000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, 0.5000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.5000, 0.2500), Size: 0.25, Leaf: True, Level: 3] |||||| SVO Output for sample type Simplex, size 0: [Node, Position (-1.0000, -1.0000, -1.0000), Size: 2, Leaf: False, Level: 1], [Node, Position (-1.0000, -1.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-1.0000, -0.5000, -1.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-0.5000, -1.0000, -0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-1.0000, -1.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-1.0000, -0.5000, 0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-0.5000, -1.0000, 0.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-0.5000, -0.5000, 0.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-0.5000, -0.5000, 0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-1.0000, 0.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-1.0000, 0.0000, -1.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-1.0000, 0.0000, -0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-1.0000, 0.5000, -0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-1.0000, 0.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-1.0000, 0.0000, 0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-1.0000, 0.5000, 0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (-0.5000, 0.5000, 0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, -1.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, -1.0000, -1.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, -0.5000, -1.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, -0.5000, -0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, -1.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, -1.0000, 0.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, -0.5000, 0.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.5000, -1.0000, 0.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.5000, -1.0000, 0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.5000, -0.5000, 0.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.5000, -0.5000, 0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, 0.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, 0.0000, -1.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, 0.0000, -0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, 0.5000, -1.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, 0.5000, -0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.5000, 0.5000, -1.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, 0.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, 0.0000, 0.0000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, 0.0000, 0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.0000, 0.5000, 0.5000), Size: 0.5, Leaf: True, Level: 2], [Node, Position (0.5000, 0.0000, 0.5000), Size: 0.5, Leaf: True, Level: 2] |||||| SVO Output for sample type RotatedCuboid, size 1: [Node, Position (-1.0000, -1.0000, -1.0000), Size: 2, Leaf: False, Level: 1], [Node, Position (-1.0000, -1.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-1.0000, -1.0000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.7500, -0.7500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, -0.5000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.7500, -0.5000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, -0.2500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -1.0000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, -0.7500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -0.7500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -0.5000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, -0.5000, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -0.2500, -1.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -0.2500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -0.5000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, -0.5000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -0.2500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -0.5000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, -1.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-1.0000, -0.5000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.7500, -0.5000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, -0.2500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -1.0000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, -0.7500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -0.7500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -0.5000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, -0.5000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -0.2500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, -0.5000, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, -0.5000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.2500, -0.2500, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, 0.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-0.5000, 0.0000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.2500, 0.0000, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.2500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.0000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, 0.0000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.0000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.2500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.2500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.5000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, 0.5000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.5000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.5000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.5000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-1.0000, 0.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (-1.0000, 0.0000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.7500, 0.0000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, 0.0000, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, 0.2500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.7500, 0.2500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.0000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, 0.2500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.2500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.2500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.2500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.5000, 0.0000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (-0.5000, 0.0000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (-0.2500, 0.0000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -1.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, -0.5000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, -0.2500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.2500, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -0.5000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, -0.5000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -0.5000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.5000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.5000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -0.5000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, -0.5000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -0.5000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -0.2500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, -0.2500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -1.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, -1.0000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, -0.7500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -0.7500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.7500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.7500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -0.5000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.2500, -0.5000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.5000, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.2500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, -0.2500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -0.5000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, -0.5000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, -0.2500, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.0000, -1.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, 0.0000, -1.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, 0.0000, -0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.0000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, 0.2500, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.0000, -0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.2500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.5000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, 0.5000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.5000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.0000, -0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, 0.0000, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.2500, -0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.0000, 0.0000), Size: 1, Leaf: False, Level: 1], [Node, Position (0.0000, 0.0000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, 0.2500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.0000, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.2500, 0.2500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.0000, 0.5000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, 0.0000, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.0000, 0.7500), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.2500, 0.5000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.0000, 0.5000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.0000, 0.5000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.2500, 0.5000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.0000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, 0.0000, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.2500, 0.0000), Size: 0.25, Leaf: True, Level: 3], [Node, Position (0.5000, 0.5000, 0.0000), Size: 0.5, Leaf: False, Level: 2], [Node, Position (0.5000, 0.5000, 0.0000), Size: 0.25, Leaf: True, Level: 3] |||||| "; string output = ""; UtilFuncs.Sampler[] samplers = new UtilFuncs.Sampler[] { SampleFunctions.functions[(int)SampleFunctions.Type.FlatGround], SampleFunctions.functions[(int)SampleFunctions.Type.Sphere], SampleFunctions.functions[(int)SampleFunctions.Type.RotatedCuboid], SampleFunctions.functions[(int)SampleFunctions.Type.Simplex], }; foreach (SampleFunctions.Type type in SampleFunctions.Type.GetValues(typeof(SampleFunctions.Type))) { UtilFuncs.Sampler sample = SampleFunctions.functions[(int)type]; if (sample != null) { svo.Create(sample, svoSize + 3); string svoOutput = "SVO Output for sample type " + type.ToString() + ", size " + svoSize + ": " + string.Join(", ", svo.GetAllNodes()) + " |||||| "; output += svoOutput; svoSize = (svoSize + 1) % 2; } } Assert.That(output, Is.EqualTo(expectedOutput).NoClip); }
void TestTransvoxel(int sF) { int resolution = 12; int res1 = resolution + 1; MCMesh m = new MCMesh(); List <Vector3> vertices = new List <Vector3>(); List <int> triangles = new List <int>(); int sampleFn = 1; byte lod = 63; UtilFuncs.Sampler fn = (float x, float y, float z) => sampleFunctions[sampleFn](x, y, z, 16); SE.Transvoxel.Transvoxel.GenerateChunk(new Vector3(0, 0, 0), vertices, triangles, resolution, fn, lod); Debug.Log("0 tris"); if (triangles.Count > 0) { m.Triangles = triangles.ToArray(); m.Vertices = vertices; Mesh(m); } }
public static void Run(int resolution, UtilFuncs.Sampler samp, Chunks.Chunk chunk) { resolution += 1; chunk.State = Chunks.ChunkState.Meshing; Resolution = resolution; System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); //List<Vector3> lod1vertices = new List<Vector3>(); //List<Vector3> lod1normals = new List<Vector3>(); List <int> indices = new List <int>(); CellInfo[,,] drawInfos = GenVertices(resolution, samp); long genVertsTime = sw.ElapsedMilliseconds; sw.Restart(); //GenVerticesLOD1(resolution, drawInfos, samp); //long genVertsLod1Time = sw.ElapsedMilliseconds; sw.Restart(); GenIndices(drawInfos, indices, vertices, normals); long genIndicesTime = sw.ElapsedMilliseconds; chunk.Vertices = vertices; chunk.Triangles = indices.ToArray(); chunk.Normals = normals; //chunk.LOD1Vertices = lod1vertices; //chunk.LOD1Normals = lod1normals; chunk.State = Chunks.ChunkState.Blank; sw.Stop(); //Debug.Log("Uniform dual contouring time for " + resolution + "^3 mesh: " + (genVertsTime + genVertsLod1Time + genIndicesTime) + "ms" + "(GenVerts: " + genVertsTime + ", GenVertsLOD1: " + genVertsLod1Time + ", GenIndices: " + genIndicesTime + ")"); }
public void Create(UtilFuncs.Sampler sample, int maxLevel) { this.maxLevel = maxLevel; this.sample = sample; BuildSVO(); }
public static MCMesh PolyganizeNode(Node node, float worldSize, int resolution) { float mul = node.Size; UtilFuncs.Sampler sample = (float x, float y, float z) => UtilFuncs.Sample( (((x * node.Size) / resolution) + node.Position.x) * worldSize, (((y * node.Size) / resolution) + node.Position.y) * worldSize, (((z * node.Size) / resolution) + node.Position.z) * worldSize); /*Node[] neighbors = FindNeighbors(root, node); * * int currentSide = 1; * * for(int i = 0; i < 6; i++) { * if(neighbors[i] != null && neighbors[i].Depth < node.Depth) { * lod |= (byte)currentSide; * } * currentSide = currentSide << (byte)1; * }*/ //node.LODSides = 0; sbyte[][][][] data = GenerateChunkData(resolution, sample); MCMesh m = SE.MarchingCubes.PolygonizeArea(new Vector3(0, 0, 0), node.LODSides, resolution, data); //Mesh m2 = new Mesh(); //m2.SetVertices(m.Vertices); //m2.SetNormals(m.Normals); //m2.triangles = m.Triangles; return(m); }
public CompactSVO(UtilFuncs.Sampler sample, int maxLevel, CompactSVOCreator creator, CompactSVOTracer tracer) { this.creator = creator; this.tracer = tracer; Create(sample, maxLevel); }
public CompactSVO(UtilFuncs.Sampler sample, int maxLevel) { this.creator = new NaiveCreator(); this.tracer = new NVIDIAIterativeNaiveTracer(); Create(sample, maxLevel); }
public static bool PolygonizeArea(int resolution, UtilFuncs.Sampler samp, Chunks.Chunk chunk) { int res2 = resolution + 2; float[] data = new float[res2 * res2 * res2]; return(PolygonizeArea(resolution, samp, chunk, data)); }
public static Vector3 CalculateSurfaceNormal(Vector3 p, UtilFuncs.Sampler sample) { const float H = 0.001f; float dx = sample(p.x + H, p.y, p.z) - sample(p.x - H, p.y, p.z); float dy = sample(p.x, p.y + H, p.z) - sample(p.x, p.y - H, p.z); float dz = sample(p.x, p.y, p.z + H) - sample(p.x, p.y, p.z - H); return(new Vector3(dx, dy, dz).normalized); }
public Node GenerateQuadtree(UtilFuncs.Sampler sample, int maxDepth) { Node root = new Node(); root.Min = new Vector3(-1, -1, -1); root.Size = 2f; root.Depth = 0; ConstructNode(root, maxDepth, sample); return(root); }
public static bool FillData(int resolution, Vector3Int start, int stepSize, UtilFuncs.Sampler samp, float[] data) { int currentIndex = 0; stepSize /= resolution; int endX = resolution * stepSize + start.x; int endY = resolution * stepSize + start.y; int endZ = resolution * stepSize + start.z; float f = 0.001f; bool negExists = false; bool posExists = false; for (int x = start.x; x < endX; x += stepSize) { for (int y = start.y; y < endY; y += stepSize) { for (int z = start.z; z < endZ; z += stepSize) { float density = samp(x, y, z); if (density >= 0) { posExists = true; } else { negExists = true; } float dx = density - samp(x - f, y, z); float dy = density - samp(x, y - f, z); float dz = density - samp(x, y, z - f); float total = (dx * dx) + (dy * dy) + (dz * dz); total = Mathf.Sqrt(total); dx /= total; dy /= total; dz /= total; data[currentIndex] = density; data[currentIndex + 1] = dx; data[currentIndex + 2] = dy; data[currentIndex + 3] = dz; currentIndex += 4; } } } return(negExists && posExists); }
// Given that node resides inside the surface, detects if it's an edge voxel (has air next to it) private bool IsEdge(Node node, UtilFuncs.Sampler sample) { foreach (Vector3 direction in Constants.vdirections) { Vector3 pos = node.GetCenter() + direction * (float)(node.size); float s = sample(pos.x, pos.y, pos.z); if (s > 0) { return(true); } } return(false); }
public void ConstructNode(Node node, int maxDepth, UtilFuncs.Sampler sample) { node.Color = UtilFuncs.SinColor(node.Depth); node.Color.a = 0.8f; if (node.Depth == maxDepth) { node.IsLeaf = true; Vector3 center = node.Min + (Vector3.one * node.Size) / 2f; node.ContainsSurface = sample(center.x, center.y, 0) < 0 ? true : false; node.CompletelyFilled = node.ContainsSurface; } else { node.IsLeaf = false; node.Children = new Node[4]; node.CompletelyFilled = true; for (int i = 0; i < 4; i++) { //Debug.Log("Created child with depth " + (node.Depth + 1)); node.Children[i] = new Node(); node.Children[i].Parent = node; node.Children[i].Size = node.Size / 2f; node.Children[i].Min = node.Min + Constants.qoffsets[i] * (node.Size / 2f); node.Children[i].Depth = node.Depth + 1; ConstructNode(node.Children[i], maxDepth, sample); node.ContainsSurface |= node.Children[i].ContainsSurface; if (!node.Children[i].CompletelyFilled) { node.CompletelyFilled = false; } } if (!node.ContainsSurface) { node.Children = null; node.IsLeaf = true; } if (node.CompletelyFilled) // All children have surface { node.Children = null; node.IsLeaf = true; } } }
public SVOData Create(UtilFuncs.Sampler sample, int maxLevel) { SVOData result = new SVOData(); Node root = new Node(new Vector3(1, 1, 1), 1, 1, false); BuildTree(root, 1, sample, maxLevel); List <int> nodes = new List <int>(); List <uint> attachments = new List <uint>(); CompressSVO(root, nodes, attachments); result.childDescriptors = nodes; result.attachments = attachments; return(result); }
public static sbyte[][][][] GenerateChunkData(int resolution, UtilFuncs.Sampler sample) { int res1 = resolution + 1; sbyte[][][][] data = new sbyte[res1][][][]; float f = 0.01f; float nx, ny, nz; for (int x = 0; x < res1; x++) { data[x] = new sbyte[res1][][]; for (int y = 0; y < res1; y++) { data[x][y] = new sbyte[res1][]; for (int z = 0; z < res1; z++) { data[x][y][z] = new sbyte[4]; nx = (float)x; //- ((float)res1)/2f; ny = (float)y; //- ((float)res1)/2f; nz = (float)z; //- ((float)res1)/2f; data[x][y][z][0] = (sbyte)(Mathf.Clamp(-8f * sample(nx, ny, nz), -127, 127)); float dx = sample(nx + f, ny, nz) - sample(nx - f, ny, nz); float dy = sample(nx, ny + f, nz) - sample(nx, ny - f, nz); float dz = sample(nx, ny, nz + f) - sample(nx, ny, nz - f); float total = (dx * dx) + (dy * dy) + (dz * dz); total = Mathf.Sqrt(total); dx /= total; dx *= 127; dy /= total; dy *= 127; dz /= total; dz *= 127; data[x][y][z][1] = (sbyte)dx; data[x][y][z][2] = (sbyte)dy; data[x][y][z][3] = (sbyte)dz; } } } return(data); }
public static Vector3 ApproximateZeroCrossingPosition(Vector3 p0, Vector3 p1, UtilFuncs.Sampler sample) { // approximate the zero crossing by finding the min value along the edge float minValue = 100000; float t = 0; float currentT = 0; const int steps = 8; const float increment = 1f / (float)steps; while (currentT <= 1f) { Vector3 p = p0 + ((p1 - p0) * currentT); float density = Mathf.Abs(sample(p.x, p.y, p.z)); if (density < minValue) { minValue = density; t = currentT; } currentT += increment; } return(p0 + ((p1 - p0) * t)); }
public static BenchmarkResult PolygonizeAreaBenchmarked(int resolution, UtilFuncs.Sampler samp, Chunks.Chunk chunk, float[] data) { BenchmarkResult result = new BenchmarkResult(); double fillDataMs, createVerticesMs, triangulateMs, transitionCellMs = 0; int res1 = resolution + 1; System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); FillData(resolution, chunk, data); sw.Stop(); fillDataMs = sw.Elapsed.TotalMilliseconds; sw.Restart(); int resm1 = resolution - 1; int resm2 = resolution - 2; List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <int> triangles = new List <int>(); ushort[] edges = new ushort[res1 * res1 * res1 * 3]; Vector3Int begin = new Vector3Int(0, 0, 0); Vector3Int end = new Vector3Int(res1, res1, res1); byte lod = (byte)chunk.LODCode; if ((lod & 1) == 1) { begin.x += 1; } if ((lod & 2) == 2) { end.x -= 1; } if ((lod & 4) == 4) { begin.y += 1; } if ((lod & 8) == 8) { end.y -= 1; } if ((lod & 16) == 16) { begin.z += 1; } if ((lod & 32) == 32) { end.z -= 1; } CreateVertices(edges, begin, end, vertices, normals, res1, data); sw.Stop(); createVerticesMs = sw.Elapsed.TotalMilliseconds; sw.Restart(); end -= Vector3Int.one; Triangulate(edges, begin, end, triangles, resolution, data); sw.Stop(); triangulateMs = sw.Elapsed.TotalMilliseconds; sw.Restart(); //Debug.Log("Phase 1 of surface extraction took " + sw.ElapsedMilliseconds + " ms."); if (lod != 0) { GenerateTransitionCells(vertices, normals, triangles, resolution, data, lod); } sw.Stop(); transitionCellMs = sw.Elapsed.TotalMilliseconds; sw.Restart(); //Debug.Log("Phase 2 of surface extraction took " + sw.ElapsedMilliseconds + " ms."); //MCVT(vertices, triangles, normals, resolution, lod, data); result.createVerticesMs = createVerticesMs; result.fillDataMs = fillDataMs; result.transitionCellMs = transitionCellMs; result.triangulateMs = triangulateMs; chunk.Vertices = vertices; chunk.Triangles = triangles.ToArray(); chunk.Normals = normals; return(result); }
// "level" is the number of jumps needed to get to root // Level 0 is 1x1x1 (1 bool) // Level 1 is 2x2x2 (16 bools) // Level 2 is 4x4x4 (64 bools), etc. // a slice bool returns true if the cube contains a surface public static bool[][,,] GetSlices(UtilFuncs.Sampler sample, int maxLevel) { // generate deepest level first. then downsample // i.e. if maxLevel = 2, then max resolution is 2^2 = 4 int maxResolution = (int)Mathf.Pow(2, maxLevel); bool[][,,] slices = new bool[maxLevel + 1][, , ]; for (int i = maxLevel, res = maxResolution; i >= 0; res >>= 1, i--) { slices[i] = new bool[res, res, res]; } float factor = 1f / (float)maxResolution; bool[] containsVoxel = new bool[maxLevel + 1]; int[,] directions = { { 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 }, { 0, 0, -1 }, { 0, -1, 0 }, { -1, 0, 0 } }; int[,] offsets = { { 0, 0, 0 }, { 0, 0, 1 }, { 0, 1, 0 }, { 0, 1, 1 }, { 1, 0, 0 }, { 1, 0, 1 }, { 1, 1, 0 }, { 1, 1, 1 } }; for (int i = 0; i < maxResolution * maxResolution * maxResolution; i++) { int x = 0, y = 0, z = 0; MortonUtil.MortonDecode((ulong)i, ref x, ref y, ref z); float density = sample((float)x * factor, (float)y * factor, (float)z * factor); bool hasAirAsNeighbor = false; for (int j = 0; j < 6 && !hasAirAsNeighbor; j++) { float density2 = sample((float)(x + directions[j, 0]) * factor, (float)(y + directions[j, 1]) * factor, (float)(z + directions[j, 2]) * factor); hasAirAsNeighbor = density2 < 0; } slices[maxLevel][x, y, z] = (density > 0) && hasAirAsNeighbor; } for (int level = maxLevel - 1; level >= 0; level--) { int res = (int)Mathf.Pow(2, level); for (int x = 0; x < res; x++) { for (int y = 0; y < res; y++) { for (int z = 0; z < res; z++) { bool containsSurface = false; for (int i = 0; i < 8 && !containsSurface; i++) { int x2 = x * 2 + offsets[i, 0]; int y2 = y * 2 + offsets[i, 1]; int z2 = z * 2 + offsets[i, 2]; containsSurface = slices[level + 1][x2, y2, z2]; } slices[level][x, y, z] = containsSurface; } } } } return(slices); }
public static CellInfo[,,] GenVertices(int resolution, UtilFuncs.Sampler samp) { CellInfo[,,] cellInfos = new CellInfo[resolution, resolution, resolution]; for (int x = 0; x < resolution; x++) { for (int y = 0; y < resolution; y++) { for (int z = 0; z < resolution; z++) { //Vector3 p = new Vector3(x, y, z); byte caseCode = 0; sbyte[] densities = new sbyte[8]; for (int i = 0; i < 8; i++) { Vector3 pos = new Vector3(x, y, z) + DCC.vfoffsets[i]; densities[i] = (sbyte)Mathf.Clamp((samp(pos.x, pos.y, pos.z) * 127f), -127f, 127f); //data[index + inArray[i]]; if (densities[i] < 0) { caseCode |= (byte)(1 << i); } } Vector3[] cpositions = new Vector3[4]; Vector3[] cnormals = new Vector3[4]; int edgeCount = 0; for (int i = 0; i < 12 && edgeCount < 4; i++) { byte c1 = (byte)DCC.edgevmap[i][0]; byte c2 = (byte)DCC.edgevmap[i][1]; Vector3 p1 = new Vector3(x, y, z) + DCC.vfoffsets[c1]; Vector3 p2 = new Vector3(x, y, z) + DCC.vfoffsets[c2]; bool m1 = ((caseCode >> c1) & 1) == 1; bool m2 = ((caseCode >> c2) & 1) == 1; if (m1 != m2) { cpositions[edgeCount] = ApproximateZeroCrossingPosition(p1, p2, samp); cnormals[edgeCount] = CalculateSurfaceNormal(cpositions[edgeCount], samp); edgeCount++; } } if (edgeCount == 0) { continue; } CellInfo cellInfo = new CellInfo(); QEF.QEFSolver qef = new QEF.QEFSolver(); for (int i = 0; i < edgeCount; i++) { qef.Add(cpositions[i], cnormals[i]); } cellInfo.Position = qef.Solve(0.0001f, 4, 0.0001f); //drawInfo.index = vertices.Count; Vector3 max = new Vector3(x, y, z) + Vector3.one; if (cellInfo.Position.x < x || cellInfo.Position.x > max.x || cellInfo.Position.y < y || cellInfo.Position.y > max.y || cellInfo.Position.z < z || cellInfo.Position.z > max.z) { cellInfo.Position = qef.MassPoint; } //vertices.Add(drawInfo.position); for (int i = 0; i < edgeCount; i++) { cellInfo.Normal += cnormals[i]; } cellInfo.Normal = Vector3.Normalize(cellInfo.Normal); //CalculateSurfaceNormal(drawInfo.position, samp); //normals.Add(drawInfo.averageNormal); cellInfo.Corners = caseCode; cellInfos[x, y, z] = cellInfo; } } } return(cellInfos); }
public static TransitionCellResult ProcessTransitionCell(byte lod, Vector3 min, Vector3 size, UtilFuncs.Sampler Sample) { TransitionCellResult result = new TransitionCellResult(); int numLODFaces = 0; for (int i = 0; i < 6; i++) { if (((lod >> i) & 1) == 1) { numLODFaces++; } } result.numLODFaces = numLODFaces; if (numLODFaces > 0 && numLODFaces < 4) { int numGridCells = LODOffsets[numLODFaces - 1].Length; GridCell[] cells = new GridCell[numGridCells]; Quaternion rotation = LODRotations[lod]; for (int i = 0; i < numGridCells; i++) { cells[i] = new GridCell(); cells[i].points = new Point[8]; for (int j = 0; j < 8; j++) { Vector3 rotatedOffset = (rotation * LODOffsets[numLODFaces - 1][i][j]) + new Vector3(1f, 1f, 1f); cells[i].points[j].position = new Vector3(min.x + size.x * rotatedOffset.x, min.y + size.y * rotatedOffset.y, min.z + size.z * rotatedOffset.z); cells[i].points[j].density = Sample(cells[i].points[j].position.x, cells[i].points[j].position.y, cells[i].points[j].position.z); } } result.cells = cells; return(result); } return(null); }
public NaiveSVO(UtilFuncs.Sampler sample, int maxLevel) { Create(sample, maxLevel); }
public static void GenerateChunk(Vector3 min, List <Vector3> vertices, List <int> triangles, int resolution, UtilFuncs.Sampler sample, byte lod) { sbyte[][][][] data = GenerateChunkData(min, resolution, sample); GenerateChunkExterior(vertices, triangles, data, lod, resolution); GenerateChunkInterior(vertices, triangles, data, resolution); //GenerateTestTransitionCells(vertices, triangles, data, resolution); }
/* * Tree building methods * * Constructs subtree from node. * Will return null if node does not contain surface. * Will return node if node contains surface. */ private Node BuildTree(Node node, int level, UtilFuncs.Sampler sample, int maxLevel) { // Node is leaf. Determine if within surface. If so, return node. if (node.leaf) { Vector3 p = node.position + Vector3.one * (float)node.size / 2; if (sample(p.x, p.y, p.z) <= 0 && IsEdge(node, sample)) { // Node is on an edge, calculate normal and color Vector3 normal = Vector3.zero; float h = 0.001f; normal.x = sample(p.x - h, p.y, p.z) - sample(p.x, p.y, p.z); normal.y = sample(p.x, p.y - h, p.z) - sample(p.x, p.y, p.z); normal.z = sample(p.x, p.y, p.z - h) - sample(p.x, p.y, p.z); normal = -Vector3.Normalize(normal); node.normal = normal; // node.Color = new Color(-Mathf.Clamp(normal.x, -1, 0), -Mathf.Clamp(normal.y, -1, 0), -Mathf.Clamp(normal.z, -1, 0), 1.0f); node.color = new Color(node.position.x - 1, node.position.y - 1, node.position.z - 1, 1.0f); int encoded = encodeRawNormal16(normal); //Vector3 decoded = Vector3.Normalize(decodeRawNormal16(encoded)); //node.Color = new Color(Mathf.Abs(decoded.x), Mathf.Abs(decoded.y), Mathf.Abs(decoded.z), 1.0f); return(node); } } // Node is not leaf. Construct 8 children. If any of them intersect surface, return node. else { bool childExists = false; int numLeaves = 0; node.children = new Node[8]; float half = node.size / 2; for (int i = 0; i < 8; i++) { Node child = new Node(node.position + Constants.vfoffsets[i] * (float)(half), half, level + 1, level + 1 == maxLevel); node.children[i] = BuildTree(child, level + 1, sample, maxLevel); if (node.children[i] != null) { childExists = true; if (node.children[i].leaf) { numLeaves++; } } } if (childExists) { // Compute average color and normal int numChildren = 0; Vector3 color = Vector3.zero; Vector3 normal = Vector3.zero; for (int i = 0; i < 8; i++) { if (node.children[i] != null) { numChildren++; color.x += node.children[i].color.r; normal += node.children[i].normal; } } color = color * (1f / (float)numChildren); node.color = new Color(color.x, color.y, color.z); node.normal = Vector3.Normalize(normal); return(node); } } return(null); }