예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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
예제 #4
0
    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
예제 #5
0
 def bounding_box(self, t0: float, t1: float) -> Optional[AABB]:
     return AABB(self.box_min, self.box_max)
예제 #6
0
 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
예제 #7
0
 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)
예제 #8
0
 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)