Exemple #1
0
    def intersection(self, O, D):
        D_hat = vl.vdot(self.normal, self.vertices[:, :1] - O)

        num = D_hat
        den = vl.vdot(self.normal, D)

        normal_to_d = vl.vdot(self.normal, D)

        # Check if parallel
        is_parallel = (abs(normal_to_d) < global_config.PARALLEL_EPSILON)
        non_parallel_indices = np.where(np.logical_not(is_parallel))

        # Check Back Facing
        back_facing = normal_to_d > 0.
        t_hat = np.zeros([1, den.shape[1]])
        if O.shape[1] > 1:
            num = num[non_parallel_indices]
        t_hat[non_parallel_indices] = num / den[non_parallel_indices]

        P = O + D * t_hat
        iot = self.inside_out_test(P)

        visible_mask = iot & (t_hat > 0.) & (np.logical_not(is_parallel)) & (
            np.logical_not(back_facing * self.single_sided))

        t = t_hat * visible_mask + global_config.MAX_DISTANCE * np.logical_not(
            visible_mask)
        t_out = t
        N_out = np.zeros_like(t) + self.normal
        M_out = O + t * D
        return t_out, M_out, N_out
Exemple #2
0
    def intersection(self, O, D):
        O_hat = vl.inverse_transform(self.T, O)
        D_hat = D
        t = vl.vdot(self.normal, -O_hat) / (vl.vdot(self.normal, D_hat))
        pred = (t > 0.)
        t_out = np.where(pred, t, global_config.MAX_DISTANCE)

        M = (O_hat + D_hat * t_out)
        M_out = vl.transform(self.T, M)
        N_out = np.ones_like(M_out) * self.normal

        return t_out, M_out, N_out
Exemple #3
0
    def refract(self, s, V, N, inside):
        n1 = np.where(inside, s.material.finish.ior, 1.)  # TODO don't hardcode air as n1
        n2 = np.where(inside, 1., s.material.finish.ior)
        n = n1 / n2
        cos_i = -vl.vdot(N, V)
        sin_t2 = n * n * (1.0 - cos_i * cos_i)

        cos_t = np.sqrt(1. - sin_t2)

        return vl.vnorm(V * n + N * (n * cos_i - cos_t))
Exemple #4
0
 def color_specular(self, s, N, to_L, to_O, intensity):
     if s.material.finish.specular == 0.:
         return 0.
     else:
         R = self.reflect(to_L, N)
         specular_intensity = np.maximum(vl.vdot(to_O, R), 0.)
         specular_color = np.power(specular_intensity, 1./s.material.finish.roughness) * intensity * s.material.finish.specular
         if s.material.metallic == True:
             specular_color = specular_color * vl.vnorm(s.material.surface_color)
         return specular_color
Exemple #5
0
    def light(self, s, O, V, t, M, N, bounces):
        to_O = vl.vnorm(O - M)

        inside = (vl.vdot(V, N) > 0.)

        N_hat = np.where(inside, -N, N)

        ambient_color = self.color_ambient(s)
        diffuse_specular_color = self.color_diffuse_specular(s, O, M, N_hat, V)
        reflected_refracted_color = self.color_reflected_refracted(s, O, M, N_hat, V, inside, bounces)

        return ambient_color + diffuse_specular_color + reflected_refracted_color
Exemple #6
0
    def intersection(self, O, D):
        v0 = self.v0
        v0v1 = self.v0v1
        v0v2 = self.v0v2

        p_vec = np.cross(D, v0v2, axis=0)
        det = vl.vdot(v0v1, p_vec)

        # Check Parallel
        is_parallel = abs(det) < global_config.PARALLEL_EPSILON
        non_parallel_indices = np.where(np.logical_not(is_parallel))

        inv_det = np.ones_like(det) * global_config.MAX_DISTANCE
        inv_det[non_parallel_indices] = 1. / det[non_parallel_indices]

        # Check Backfacing
        backfacing = self.single_sided * (det > 0.)

        t_vec = (O - v0)
        u = vl.vdot(t_vec, p_vec) * inv_det
        u_mask = ((u < 0.) | (u > 1.))

        q_vec = np.cross(t_vec, v0v1, axis=0)
        v = vl.vdot(D, q_vec) * inv_det
        w_mask = (v < 0.) | ((u + v) > 1.)

        t = vl.vdot(v0v2, q_vec) * inv_det

        visible_mask = (np.logical_not(u_mask | w_mask)) & (t > 0.) & (
            np.logical_not(is_parallel)) & (np.logical_not(backfacing))

        t_out = t * visible_mask + global_config.MAX_DISTANCE * np.logical_not(
            visible_mask)
        N_out = np.zeros_like(t) + self.normal
        M_out = O + t * D
        if not self.single_sided:
            normal_flip = -1. * (vl.vdot(D * visible_mask, self.normal) > 0.)
            N_out = N_out * normal_flip
        return t_out, M_out, N_out
Exemple #7
0
    def reflectance(self, s, N, V, inside):
        n1 = np.where(inside, s.material.finish.ior, 1.)  # TODO don't hardcode air as n1
        n2 = np.where(inside, 1., s.material.finish.ior)
        n = n1 / n2
        cos_i = -vl.vdot(N, V)
        sin_t2 = n * n * (1.0 - cos_i * cos_i)

        cos_t = np.sqrt(1. - sin_t2)

        r_s = (n1 * cos_i - n2 * cos_t) / (n1 * cos_i + n2 * cos_t)
        r_p = (n2 * cos_i - n1 * cos_t) / (n2 * cos_i + n1 * cos_t)

        return np.where(sin_t2 > 1., 1., (r_s * r_s + r_p * r_p) / 2.0)
Exemple #8
0
    def intersection(self, O, D):
        O_hat = vl.inverse_transform(
            self.S,
            vl.inverse_transform(self.R, vl.inverse_transform(self.T, O)))
        D_hat = vl.inverse_transform(self.S, vl.inverse_transform(self.R, D))
        a = vl.vdot(D_hat, D_hat)
        b = 2 * vl.vdot(O_hat, D_hat)
        c = vl.vdot(O_hat, O_hat) - 1
        disc = (b**2) - (4 * a * c)

        t0 = (-b - np.sqrt(np.maximum(disc, 0.))) / (2 * a)
        t1 = (-b + np.sqrt(np.maximum(disc, 0.))) / (2 * a)
        t = np.where((t0 > 0) & (t0 < t1), t0, t1)

        pred = (disc > 0.) & (t > 0.)
        t_out = np.where(pred, t, global_config.MAX_DISTANCE)
        M = (O_hat + D_hat * t_out)
        M_out = vl.transform(self.T,
                             vl.transform(self.R, vl.transform(self.S, M)))
        N_out = vl.vnorm(vl.transform(self.R, vl.inverse_transform(self.S, M)))

        return t_out, M_out, N_out
Exemple #9
0
    def inside_out_test(self, P):
        P_min_V = P[:, None, :] - self.vertices[:, :, None]
        N = self.normal

        edges = [
            self.vertices[:, i:i + 1] - self.vertices[:, i - 1:i]
            for i in range(1, self.vertices.shape[1])
        ]
        edges.append(self.vertices[:, 0:1] - self.vertices[:, -1:])
        edges = np.concatenate(edges, axis=1)
        W = np.cross(edges[:, :, None], P_min_V, axis=0)
        K = vl.vdot(N[:, :, None], W)
        inside = np.prod((K <= 0.), axis=1)
        return inside
Exemple #10
0
    def intersection(self, O, D):
        O_hat = vl.inverse_transform(
            self.S,
            vl.inverse_transform(self.R, vl.inverse_transform(self.T, O)))
        D_hat = vl.inverse_transform(self.S, vl.inverse_transform(self.R, D))

        xy_mask = np.array([1., 1., 0.]).reshape(-1, 1)
        O_xy = O_hat * xy_mask
        D_xy = D_hat * xy_mask

        a = vl.vdot(D_xy, D_xy)
        b = 2 * vl.vdot(D_xy, O_xy)
        c = vl.vdot(O_xy, O_xy) - 1

        disc = (b**2) - (4 * a * c)
        t0 = (-b - np.sqrt(np.maximum(disc, 0.))) / (2 * a)
        t1 = (-b + np.sqrt(np.maximum(disc, 0.))) / (2 * a)

        zo = O_hat[2:3]
        zd = D_hat[2:3]
        z0 = (zo + zd * t0)
        z1 = (zo + zd * t1)

        z0_mask = (t0 > 0) & (z0 <= self.z_max) & (z0 >= self.z_min) & (disc >
                                                                        0.)
        z1_mask = (t1 > 0) & (z1 <= self.z_max) & (z1 >= self.z_min) & (disc >
                                                                        0.)

        # # Compute Cylinder Intersections
        t_cand0 = np.where(z0_mask, t0, global_config.MAX_DISTANCE)
        t_cand1 = np.where(z1_mask, t1, global_config.MAX_DISTANCE)
        t_cand_cyl = np.min(np.array([t_cand0, t_cand1]), axis=0)

        # # Compute Endcap Cylinder Intersections
        if self.closed is True:
            t3 = (self.z_min - zo) / zd
            t4 = (self.z_max - zo) / zd

            P_front = (O_xy + D_xy * t3)
            P_back = (O_xy + D_xy * t4)

            front_cap_hit_mask = (vl.vdot(P_front, P_front) <= 1.)
            back_cap_hit_mask = (vl.vdot(P_back, P_back) <= 1.)

            hit_mask = (z0_mask | z1_mask)

            t_front_cap = front_cap_hit_mask * t3
            t_back_cap = back_cap_hit_mask * t4
            t_side = t_cand_cyl

            t_front_cap[t_front_cap <= 0.] = global_config.MAX_DISTANCE
            t_back_cap[t_back_cap <= 0.] = global_config.MAX_DISTANCE
            t_side[t_side <= 0.] = global_config.MAX_DISTANCE

            t_out = np.min([t_side, t_front_cap, t_back_cap], axis=0)
            t_arg_out = np.argmin([t_side, t_front_cap, t_back_cap], axis=0)

            M_out = O_hat + D_hat * t_out

            normal_cyl = hit_mask * (M_out * xy_mask)
            normal_front_cap = front_cap_hit_mask * np.array(
                [0, 0, -1]).reshape(-1, 1)
            normal_back_cap = back_cap_hit_mask * np.array([0, 0, 1]).reshape(
                -1, 1)
            normals = np.sum([
                normal_cyl * (t_arg_out == 0), normal_front_cap *
                (t_arg_out == 1), normal_back_cap * (t_arg_out == 2)
            ],
                             axis=0)

            M_out = vl.transform(
                self.T, vl.transform(self.R, vl.transform(self.S, M_out)))
            N_out = vl.vnorm(
                vl.transform(self.R, vl.inverse_transform(self.S, normals)))
            return t_out, M_out, N_out

        else:
            t_out = t_cand_cyl
            M = (O_hat + D_hat * t_out)
            M_out = vl.transform(self.T,
                                 vl.transform(self.R, vl.transform(self.S, M)))
            N_out = vl.vnorm(
                vl.transform(self.R, vl.inverse_transform(self.S,
                                                          M * xy_mask)))

            return t_out, M_out, N_out
Exemple #11
0
 def reflect(self, V, N):
     return vl.vnorm(N * 2 * vl.vdot(V, N) - V)
Exemple #12
0
 def color_diffuse(self, s, N, to_L, intensity):
     lambert_color = np.maximum(vl.vdot(N, to_L), 0.) * s.material.surface_color
     return lambert_color * intensity * s.material.finish.diffuse
Exemple #13
0
    def intersection(self, O, D):
        O_hat = vl.inverse_transform(
            self.S,
            vl.inverse_transform(self.R, vl.inverse_transform(self.T, O)))
        D_hat = vl.inverse_transform(self.S, vl.inverse_transform(self.R, D))

        xy_mask = np.array([1., 1., 0.]).reshape(-1, 1)
        z_mask = np.array([0., 0., 1.]).reshape(-1, 1)
        O_xy = O_hat * xy_mask
        O_z = O_hat * z_mask
        D_xy = D_hat * xy_mask
        D_z = D_hat * z_mask

        a = vl.vdot(D_xy, D_xy) - vl.vdot(D_z, D_z)
        b = (2 * vl.vdot(D_xy, O_xy)) - (2 * vl.vdot(D_z, O_z))
        c = vl.vdot(O_xy, O_xy) - vl.vdot(O_z, O_z)

        disc = (b**2) - (4 * a * c)
        t0 = (-b - np.sqrt(np.maximum(disc, 0.))) / (2 * a)
        t1 = (-b + np.sqrt(np.maximum(disc, 0.))) / (2 * a)

        zo = O_hat[2:3]
        zd = D_hat[2:3]
        z0 = (zo + zd * t0)
        z1 = (zo + zd * t1)
        z0_mask = (t0 > 0) & (z0 <= self.z_max) & (z0 >= self.z_min) & (disc >
                                                                        0.)
        z1_mask = (t1 > 0) & (z1 <= self.z_max) & (z1 >= self.z_min) & (disc >
                                                                        0.)

        # Compute Cone Intersections
        t_cand0 = np.where(z0_mask, t0, global_config.MAX_DISTANCE)
        t_cand1 = np.where(z1_mask, t1, global_config.MAX_DISTANCE)

        t_cand_cone = np.min(np.array([t_cand0, t_cand1]), axis=0)

        # Compute Endcap Cone Intersections
        if self.closed is True:
            t4 = (self.z_max - zo) / zd
            P_back = (O_xy + D_xy * t4)

            back_cap_hit_mask = (vl.vdot(P_back, P_back) <= 1.)
            hit_mask = (z0_mask | z1_mask)

            t_side = t_cand_cone
            t_back_cap = back_cap_hit_mask * t4

            t_back_cap[t_back_cap <= 0.] = global_config.MAX_DISTANCE
            t_side[t_side <= 0.] = global_config.MAX_DISTANCE

            t_out = np.min([t_side, t_back_cap], axis=0)
            t_arg_out = np.argmin([t_side, t_back_cap], axis=0)
            M_out = O_hat + D_hat * t_out

            M_norm = (M_out * xy_mask)
            M_norm[2, :] = -1.
            normal_cone = M_norm
            normal_back_cap = back_cap_hit_mask * np.array([0, 0, 1]).reshape(
                -1, 1)
            normals = np.sum([
                normal_cone * (t_arg_out == 0), normal_back_cap *
                (t_arg_out == 1)
            ],
                             axis=0)

            M_out = vl.transform(
                self.T, vl.transform(self.R, vl.transform(self.S, M_out)))
            N_out = vl.vnorm(
                vl.transform(self.R, vl.inverse_transform(self.S, normals)))
            return t_out, M_out, N_out

        else:
            t_out = t_cand_cone
            M = (O_hat + D_hat * t_out)
            M_norm = M * xy_mask
            M_norm[2, :] = -1.

            M_out = vl.transform(self.T,
                                 vl.transform(self.R, vl.transform(self.S, M)))
            N_out = vl.vnorm(
                vl.transform(self.R, vl.inverse_transform(self.S, M_norm)))
            return t_out, M_out, N_out