def __init__(self, objects: List[Hittable], time0: float, time1: float): axis = random_int(0, 2) key_func: Callable[[Hittable], float] = self.key_func(axis) length = len(objects) if length == 1: self.left = self.right = objects[0] elif length == 2: if key_func(objects[0]) < key_func(objects[1]): self.left = objects[0] self.right = objects[1] else: self.left = objects[1] self.right = objects[0] else: sorted_objects = sorted(objects, key=key_func) mid = int(length / 2) self.left = BVHNode(sorted_objects[0:mid], time0, time1) self.right = BVHNode(sorted_objects[mid:length], time0, time1) box_left = self.left.bounding_box(time0, time1) box_right = self.right.bounding_box(time0, time1) if box_left is None or box_right is None: print("No bounding box in bvh_node constructor.") raise ValueError self.box = AABB.surrounding_box(box_left, box_right)
def __init__(self, obj: Hittable, angle: float) -> None: radians = degrees_to_radians(angle) self.sin_theta = np.sin(radians) self.cos_theta = np.cos(radians) self.obj = obj self.bbox = obj.bounding_box(0, 1) if self.bbox is None: raise ValueError point_min = Point3(np.inf, np.inf, np.inf) point_max = Point3(-np.inf, -np.inf, -np.inf) for i in range(2): for j in range(2): for k in range(2): x = i * self.bbox.max().x() + (1 - i) * self.bbox.min().x() y = j * self.bbox.max().y() + (1 - j) * self.bbox.min().y() z = k * self.bbox.max().z() + (1 - k) * self.bbox.min().z() newx = self.cos_theta * x + self.sin_theta * z newz = -self.sin_theta * x + self.cos_theta * z new = Vec3(newx, y, newz) for c in range(3): point_min[c] = np.minimum(point_min[c], new[c]) point_max[c] = np.maximum(point_max[c], new[c]) self.bbox = AABB(point_min, point_max)
def bounding_box(self, t0: float, t1: float) -> Optional[AABB]: box = self.obj.bounding_box(t0, t1) if box is None: return None output_box = AABB(box.min() + self.offset, box.max() + self.offset) return output_box
def bounding_box(self, t0: float, t1: float) -> Optional[AABB]: if not self.objects: return None output_box = None for obj in self.objects: temp_box = obj.bounding_box(t0, t1) if temp_box is None: return None if output_box is None: output_box = temp_box else: output_box = AABB.surrounding_box(output_box, temp_box) return output_box
def bounding_box(self, t0: float, t1: float) -> Optional[AABB]: return AABB(self.box_min, self.box_max)
def bounding_box(self, t0: float, t1: float) -> Optional[AABB]: output_box = AABB( Point3(self.k-0.0001, self.y0, self.z0), Point3(self.k+0.0001, self.y1, self.z1) ) return output_box
def bounding_box(self, t0: float, t1: float) -> Optional[AABB]: radius_vec = Vec3(*[self.radius] * 3) box0 = AABB(self.center(t0) - radius_vec, self.center(t0) + radius_vec) box1 = AABB(self.center(t1) - radius_vec, self.center(t1) + radius_vec) return AABB.surrounding_box(box0, box1)
def bounding_box(self, t0: float, t1: float) -> Optional[AABB]: radius_vec = Vec3(*[self.radius] * 3) return AABB(self.center - radius_vec, self.center + radius_vec)