示例#1
0
    def compute_uvw(self):
        # w
        self.w = self.eye - self.focal
        self.w = Normalize(self.w)
        # u
        self.u = Cross(self.up, self.w)
        self.u = Normalize(self.u)
        # v
        self.v = Cross(self.w, self.u)
        self.v = Normalize(self.v)

        # check for singularity. if conditions met, camera orientations are hardcoded
        # camera looking straight down
        if (self.eye.x == self.focal.x and self.eye.z == self.focal.z
                and self.focal.y < self.eye.y):
            self.u = Vector3D(0.0, 0.0, 1.0)
            self.v = Vector3D(1.0, 0.0, 0.0)
            self.w = Vector3D(0.0, 1.0, 0.0)

        # camera looking straight up
        if (self.eye.x == self.focal.x and self.eye.z == self.focal.z
                and self.focal.y > self.eye.y):
            self.u = Vector3D(1.0, 0.0, 0.0)
            self.v = Vector3D(0.0, 0.0, 1.0)
            self.w = Vector3D(0.0, -1.0, 0.0)
示例#2
0
    def intersect(self, ray):

        r = Normalize(ray.d)
        # Checando se o triangulo e o raio são paralelos
        if Dot(r, self.normal) == 0.0:
            # Raio nao intersecta o triangulo
            hit = False
            distance = 0.0
            hit_point = Vector3D(0.0, 0.0, 0.0)

            return (hit, distance, hit_point, self.normal)

        ray_dir = Normalize(ray.d)
        # Calculando o ponto que pode está no plano do triangulo
        t = Dot(self.normal, (self.A - ray.o)) / Dot(ray_dir, self.normal)
        hit_point = ray.get_hitpoint(t)

        if t < 0.0001:
            # Raio nao intersecta o triangulo
            hit = False
            distance = 0.0
            hit_point = Vector3D(0.0, 0.0, 0.0)

            return (hit, distance, hit_point, self.normal)

        # Checando se o Ponto está dentro do triangulo
        # Inside-OutSide Test
        vectorAB = self.B - self.A;
        vectorBC = self.C - self.B;
        vectorCA = self.A - self.C;

        C0 = hit_point - self.A
        C1 = hit_point - self.B
        C2 = hit_point - self.C

        if (Dot(self.normal, Cross(vectorAB, C0)) > 0
                and Dot(self.normal, Cross(vectorBC, C1)) > 0
                and Dot(self.normal, Cross(vectorCA, C2))) > 0:
            #print("Acertou: " + str (vectorAB))
            hit = True
            distance = t
            hit_point = ray.get_hitpoint(t)
            return (hit, distance, hit_point, self.normal)  # tuple

        if (Dot(self.normal, Cross(vectorAB, C0)) < 0
                and Dot(self.normal, Cross(vectorBC, C1)) < 0
                and Dot(self.normal, Cross(vectorCA, C2))) < 0:
            #print("Acertou")
            hit = True
            distance = t
            hit_point = ray.get_hitpoint(t)
            return (hit, distance, hit_point, self.normal)  # tuple

        # Didn't hit the triangule
        hit = False
        distance = 0.0
        hit_point = Vector3D(0.0, 0.0, 0.0)

        return (hit, distance, hit_point, self.normal)
    def trace_ray(self, ray, depth):
        difuso = BLACK
        especular = BLACK

        # Checando interseções com cada objeto
        dist = 100
        hit = False
        objeto = 1
        hit_point = Vector3D(0.0, 0.0, 0.0)
        normal = Vector3D(0.0, 0.0, 0.0)

        for obj in self.obj_list:
            inter = obj.intersect(ray)
            tmp_hit = inter[0]
            distance = inter[1]

            if tmp_hit and distance < dist:
                dist = distance
                objeto = obj
                hit = tmp_hit
                hit_point = inter[2]
                normal = inter[3]

        if hit: ## Se o raio bateu no objeto calculamos a cor do ponto
            if isinstance(objeto, Light):
                return objeto.color
            else:
                result = local_color(objeto, normal, ray, self.ambient)
        else:
            return self.background


        # Calculando os Raios Secúndarios
        ktot = obj.kd + obj.ks + obj.kt
        aleatorio = random.random()*ktot


        if depth > 0:
            if aleatorio < obj.kd:                            ## Raio Difuso
                x = random.random()
                y = random.random()
                dir = random_direction(x, y, normal)

                new_ray = Ray(hit_point, Normalize(dir))
                difuso = self.trace_ray(new_ray, depth - 1)
            elif aleatorio < obj.kd + obj.ks:        #         ## Raio especular
                L = Normalize(flip_direction(ray.d))
                N = objeto.normal
                R = (N * (Dot(N, L)) - L) * 2.0

                new_ray = Ray(hit_point, Normalize(R))
                especular = self.trace_ray(new_ray, depth - 1)
            else:                                               ## Raio Transmitido
                pass

        return result + difuso*objeto.trans_difusa + especular*objeto.trans_especular
示例#4
0
 def get_direction(self, x, y):
     direction = (self.u * x) + (self.v * y) - (self.w * self.view_dist)
     return Normalize(direction)