def test_extend(unit_box, big_triangle): assert (unit_box.span == ONES).all() assert (unit_box.min == ZEROS).all() assert (unit_box.max == ONES).all() unit_box.extend(big_triangle) assert (unit_box.span == point(5, 5, 1)).all() assert (unit_box.min == ZEROS).all() assert (unit_box.max == point(5, 5, 1)).all()
def test_contains_point(unit_box, ray_inside_box, x_axis, y_axis, z_axis): assert unit_box.contains_point(ray_inside_box.origin) assert unit_box.contains_point(x_axis) assert unit_box.contains_point(y_axis) assert unit_box.contains_point(z_axis) assert not unit_box.contains_point(-1 * x_axis) assert not unit_box.contains_point(-1 * y_axis) assert not unit_box.contains_point(-1 * z_axis) assert not unit_box.contains_point(point(10, 2, 4))
def load_obj(path, material=Material.DIFFUSE.value): obj = objloader.Obj.open(path) logger.info('model %s has %d vertices and %d faces', path, len(obj.vert), len(obj.face)/3) if obj.norm: logger.info('model %s specifies normal vectors', path) if obj.text: logger.info('model %s is texture-mapped', path) packed_model = obj.pack() # build the vertices and triangles vertices = numba.typed.List() for vertex in obj.vert: vertices.append(point(*vertex)) triangles = numba.typed.List() for (v0, _, _), (v1, _, _), (v2, _, _) in zip(*[iter(obj.face)]*3): triangles.append(Triangle(vertices[v0 - 1], vertices[v1 - 1], vertices[v2 - 1], material=material)) return triangles
def load_obj(path, material=Material.DIFFUSE.value): obj = objloader.Obj.open(path) logger.info('model %s has %d vertices and %d faces', path, len(obj.vert), len(obj.face) / 3) if obj.norm: logger.info('model %s specifies normal vectors', path) if obj.text: logger.info('model %s is texture-mapped', path) # build the vertices and triangles verts = [point(*vert) for vert in obj.vert] triangles = [ Triangle(verts[v0 - 1], verts[v1 - 1], verts[v2 - 1], material=material) for (v0, _, _), (v1, _, _), (v2, _, _) in zip(*[iter(obj.face)] * 3) ] return triangles
def __init__(self, center=point(0, 0, 0), direction=vec(1, 0, 0), phys_width=1.0, phys_height=1.0, pixel_width=1280, pixel_height=720): self.center = center self.direction = direction self.phys_width = phys_width self.phys_height = phys_height self.focal_dist = (phys_width / 2.) / np.tan(H_FOV / 2.0) self.focal_point = self.center + self.focal_dist * direction self.pixel_width = pixel_width self.pixel_height = pixel_height self.samples = 0 self.sample_counts = np.zeros((MAX_BOUNCES + 2, MAX_BOUNCES + 2), dtype=np.int64) if abs(self.direction[0]) < FLOAT_TOLERANCE: self.dx = UNIT_X if direction[2] > 0 else UNIT_X * -1 else: self.dx = unit(np.cross(direction * (UNIT_X + UNIT_Z), UNIT_Y * -1)) if abs(self.direction[1]) < FLOAT_TOLERANCE: self.dy = UNIT_Y else: self.dy = unit(np.cross(direction, self.dx)) self.dx_dp = self.dx * self.phys_width / self.pixel_width self.dy_dp = self.dy * self.phys_height / self.pixel_height self.origin = center - self.dx * phys_width / 2 - self.dy * phys_height / 2 self.image = np.zeros((pixel_height, pixel_width, 3), dtype=np.float64) self.images = np.zeros( (MAX_BOUNCES + 2, MAX_BOUNCES + 2, pixel_height, pixel_width, 3), dtype=np.float64)
from primitives import point, Box from utils import timed from datetime import datetime from bvh import BoundingVolumeHierarchy, triangles_for_box from load import load_obj from bidirectional import bidirectional_screen_sample from unidirectional import unidirectional_screen_sample from constants import Material from collections import ChainMap WINDOW_WIDTH = 160 WINDOW_HEIGHT = 90 SAMPLE_COUNT = 40 default_config = { 'cam_center': point(0, 2, 6), 'cam_direction': point(0, 0, -1), 'window_width': 160, 'window_height': 90, 'sample_count': 10, 'primitives': triangles_for_box(Box(point(-10, -3, -10), point(10, 17, 10))), 'bvh_constructor': BoundingVolumeHierarchy, 'sample_function': unidirectional_screen_sample, 'postprocess_function': lambda x: tone_map(x.image), } bidirectional_config = ChainMap( { 'sample_function': bidirectional_screen_sample, 'postprocess_function': composite_image,
def ray_inside_box(): return Ray(point(0.5, 0.5, 0.5), UNIT_Z)
def ray_that_hits(): # hits object in center return Ray(point(0.2, 0.2, 5), -1 * UNIT_Z)