def project(self, window, translate, fov):
        # distance from camera
        d = math.tan(math.radians(fov / 2.0))
        v = self.v + translate
        self.projected = Vector3(0.0, 0.0, 0.0)
        self.projected.y = v.y / (d * v.z)
        self.projected.x = v.x / (window.aspect_ratio * d * v.z)
        self.projected.z = v.z

        self.projected.x = (self.projected.x * window.width /
                            2.0) + (window.width / 2.0)
        self.projected.y = -(self.projected.y * window.height / 2.0) + (
            window.height / 2.0)

        # compute lambert
        light_direction = (Vector3(0.0, 10.0, -3) - self.v).normalized
        self.lambert = max(light_direction.dot(self.n), 0)
    def draw(self, window, fov):
        self.a.project(window, Vector3(0, -1.5, 5), fov)
        self.b.project(window, Vector3(0, -1.5, 5), fov)
        self.c.project(window, Vector3(0, -1.5, 5), fov)

        p1 = self.a
        p2 = self.b
        p3 = self.c

        if p1.projected.y > p2.projected.y:
            tmp = p2
            p2 = p1
            p1 = tmp

        if p2.projected.y > p3.projected.y:
            tmp = p2
            p2 = p3
            p3 = tmp

        if p1.projected.y > p2.projected.y:
            tmp = p2
            p2 = p1
            p1 = tmp

        p1p2 = (p2.projected.x - p1.projected.x) / (p2.projected.y -
                                                    p1.projected.y)
        p1p3 = (p3.projected.x - p1.projected.x) / (p3.projected.y -
                                                    p1.projected.y)

        for y in range(int(p1.projected.y), int(p3.projected.y) + 1):
            if p1p3 > p1p2:
                if y < p2.projected.y:
                    self.scanline(window, y, p1, p2, p1, p3)
                else:
                    self.scanline(window, y, p2, p3, p1, p3)
            else:
                if y < p2.projected.y:
                    self.scanline(window, y, p1, p3, p1, p2)
                else:
                    self.scanline(window, y, p1, p3, p2, p3)
    def __init__(self, obj):
        self.triangles = []
        for index in range(0, len(obj.vertices), 9):

            v = Vector3(obj.vertices[index], obj.vertices[index + 1],
                        obj.vertices[index + 2] * -1)
            n = Vector3(obj.normals[index], obj.normals[index + 1],
                        obj.normals[index + 2] * -1)
            a = Vertex(v, n, None)

            v = Vector3(obj.vertices[index + 3], obj.vertices[index + 4],
                        obj.vertices[index + 5] * -1)
            n = Vector3(obj.normals[index + 3], obj.normals[index + 4],
                        obj.normals[index + 5] * -1)
            b = Vertex(v, n, None)

            v = Vector3(obj.vertices[index + 6], obj.vertices[index + 7],
                        obj.vertices[index + 8] * -1)
            n = Vector3(obj.normals[index + 6], obj.normals[index + 7],
                        obj.normals[index + 8] * -1)
            c = Vertex(v, n, None)

            triangle = Triangle(a, b, c)
            self.triangles.append(triangle)
        print(len(self.triangles))
 def test_sum_with_vector3(self):
     v0 = Vector3(17, 30, 22)
     v1 = Vector3(22, 17, 30)
     v_sum = v0 + v1
     self.assertEqual(v_sum, Vector3(39, 47, 52))
 def test_vector3_rotation(self):
     v = Vector3(17, 30, 22)
     self.assertEqual(Quaternion.euler(0, 0, 0) * v, Vector3(17, 30, 22))
     self.assertEqual(Quaternion.euler(0, 0, 180) * v, Vector3(17, -30, 22))
 def test_cross(self):
     v0 = Vector3(1, 0, 0)
     v1 = Vector3(0, 1, 0)
     v_cross = v0.cross(v1)
     self.assertEqual(v_cross, Vector3(0, 0, 1))
 def test_normalized(self):
     v0 = Vector3(1, 0, 0)
     self.assertEqual(v0.normalized, Vector3(1, 0, 0))
     v1 = Vector3(2, 0, 0)
     self.assertEqual(v1.normalized, Vector3(1, 0, 0))
 def test_indexing(self):
     v = Vector3(17, 30, 22)
     self.assertEqual(v[0], 17)
     self.assertEqual(v[1], 30)
     self.assertEqual(v[2], 22)
 def test_mul_with_num(self):
     v0 = Vector3(17, 30, 22)
     v_mul = v0 * 1
     self.assertEqual(v_mul, Vector3(17, 30, 22))
     self.assertEqual(v_mul * Vector3(2, 2, 2), Vector3(34, 60, 44))
 def test_sum_with_num(self):
     v0 = Vector3(17, 30, 22)
     v_sum = v0 + 5
     self.assertEqual(v_sum, Vector3(22, 35, 27))
 def test_sub_with_vector3(self):
     v0 = Vector3(17, 30, 22)
     v1 = Vector3(5, 5, 5)
     v_sub = v0 - v1
     self.assertEqual(v_sub, Vector3(12, 25, 17))
    def __init__(self, filename):

        tmp_vertices = []
        tmp_normals = []
        tmp_uvs = []

        self._vertices = []
        self._normals = []
        self._uvs = []

        with open(filename) as f:
            while True:
                line = f.readline()
                if line == '':
                    break

                if line.startswith('v '):
                    items = line.split(' ')
                    v0 = float(items[1])
                    v1 = float(items[2])
                    v2 = float(items[3])
                    tmp_vertices.append(Vector3(v0, v1, v2))

                if line.startswith('vt '):
                    items = line.split(' ')
                    uv0 = float(items[1])
                    uv1 = float(items[2])
                    tmp_uvs.append(Vector2(uv0, uv1))

                if line.startswith('vn '):
                    items = line.split(' ')
                    n0 = float(items[1])
                    n1 = float(items[2])
                    n2 = float(items[3])
                    tmp_normals.append(Vector3(n0, n1, n2))

                if line.startswith('f '):
                    items = line.split(' ')
                    f0 = items[1]
                    f1 = items[2]
                    f2 = items[3]

                    f0_items = f0.split('/')
                    idx0 = int(f0_items[0]) - 1
                    idx1 = int(f0_items[1]) - 1
                    idx2 = int(f0_items[2]) - 1
                    self._vertices += tmp_vertices[idx0].tuple
                    self._uvs += tmp_uvs[idx1].tuple
                    self._normals += tmp_normals[idx2].tuple

                    f1_items = f1.split('/')
                    idx0 = int(f1_items[0]) - 1
                    idx1 = int(f1_items[1]) - 1
                    idx2 = int(f1_items[2]) - 1
                    self._vertices += tmp_vertices[idx0].tuple
                    self._uvs += tmp_uvs[idx1].tuple
                    self._normals += tmp_normals[idx2].tuple

                    f2_items = f2.split('/')
                    idx0 = int(f2_items[0]) - 1
                    idx1 = int(f2_items[1]) - 1
                    idx2 = int(f2_items[2]) - 1
                    self._vertices += tmp_vertices[idx0].tuple
                    self._uvs += tmp_uvs[idx1].tuple
                    self._normals += tmp_normals[idx2].tuple

        self.vertices = numpy.array(self._vertices, dtype=numpy.float32)
        self.normals = numpy.array(self._normals, dtype=numpy.float32)
        self.uvs = numpy.array(self._uvs, dtype=numpy.float32)