def get_projection_matrix(self):
        """Retrieves the projection matrix of this camera.
        This function sets up the proj_matrix attribute as well.

        Returns:
            Matrix4 - Projection matrix of this camera
        """
        self.proj_matrix = Matrix4.zeros()
        if self.ortho:
            self.proj_matrix[0, 0] = self.res_x * 0.5
            self.proj_matrix[1, 1] = self.res_y * 0.5
            self.proj_matrix[3, 0] = 0
            self.proj_matrix[3, 1] = 0
            self.proj_matrix[3, 3] = 1
        else:
            t = math.tan(self.fov * 0.5)
            a = self.res_y / self.res_x
            self.proj_matrix[0, 0] = 0.5 * self.res_x / t
            self.proj_matrix[1, 1] = 0.5 * self.res_y / (a * t)
            self.proj_matrix[2, 3] = 1
            self.proj_matrix[2, 2] = self.far_plane / (self.far_plane -
                                                       self.near_plane)
            self.proj_matrix[3, 2] = self.proj_matrix[2, 2] * self.near_plane

        return self.proj_matrix
    def __init__(self, ortho, res_x, res_y):
        """
        Arguments:
            ortho {bool} - True if this is an ortographic camera, false otherwise.

            res_x {int} - Horizontal resolution of the window. This will be the size of the window
            in ortographic view

            res_y {int} - Vertical resolution of the window. This will be the size of the window in
            ortographic view
        """
        super().__init__(self)

        self.ortho = ortho
        """{bool} True if this is an ortographic camera, false otherwise"""
        self.res_x = res_x
        """{int} Horizontal resolution of the window. This will be the size of the window in
        ortographic view"""
        self.res_y = res_y
        """{int} Vertical resolution of the window. This will be the size of the window in
        ortographic view"""
        self.near_plane = 1
        """{number} Distance from the camera to the near plane. Defaults to 1"""
        self.far_plane = 100
        """{number} Distance from the camera to the far plane. Defaults to 100"""
        self.fov = math.radians(60)
        """{number} Field of view angle (in radians) of the camera (if in perspective mode)"""
        self.proj_matrix = Matrix4.identity()
        """{Matrix4} Projection matrix. This is only set after get_projection_matrix is called
Exemple #3
0
 def test_type(self):
     v1 = Vector4(3,4,5,1)
     v2 = Vector4(6,7,8,9)
     m = Matrix4([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])
     self.assertTrue(isinstance(v1*10.0, Vector4))
     self.assertTrue(isinstance(v1/10.0, Vector4))
     self.assertTrue(isinstance(v1+v2, Vector4))
     self.assertTrue(isinstance(v1-v2, Vector4))
     self.assertTrue(isinstance(m(v2), Vector4))
     self.assertTrue(isinstance(v1.dot(v2), float))
    def get_camera_matrix(self):
        """Retrieves the view matrix of this camera. This is basically the same as a PRS matrix
        without scalling, and with the position and rotation negated.

        Returns:
            Matrix4 - View matrix of this camera
        """
        trans = Matrix4.identity()
        trans[3, 0] = -self.position.x
        trans[3, 1] = -self.position.y
        trans[3, 2] = -self.position.z

        rotation_matrix = self.rotation.inverted().as_rotation_matrix()

        return trans * rotation_matrix
    def draw_triangles(self,
                       triangles,
                       colour=(255, 255, 255),
                       fill=True,
                       shaded=True):
        """Draw triangle formed by v1, v2, v3"""

        # Initialise screen space transform matrix
        matrix = Matrix4.init_screen_space_transform(
            float(self.renderer.width) / 2.0,
            float(self.renderer.height) / 2.0)

        for tri in triangles:

            # Apply screen space transform to vertices
            min_y_vert = tri[0].transform(matrix).perspective_divide()
            mid_y_vert = tri[1].transform(matrix).perspective_divide()
            max_y_vert = tri[2].transform(matrix).perspective_divide()

            # Experimental shading
            normal = tri[0].triangle_normal(tri[1], tri[2])

            # Backface culling
            # if (not self.draw_backfaces) and min_y_vert.triangle_area(max_y_vert, mid_y_vert) >= 0:
            #     return

            # Calculate shading
            if shaded:
                shading = np.dot(normal,
                                 np.array([-0.57735, -0.57735, 0.57735]))

                if shading < 0:
                    shading = 0

                shading = np.array([shading, 0.2]).max()
            else:
                shading = 1

            c = (colour[0] * shading, colour[1] * shading, colour[2] * shading)

            # Swap vertices to reorder
            if min_y_vert.y > max_y_vert.y:
                temp = max_y_vert
                max_y_vert = min_y_vert
                min_y_vert = temp

            if min_y_vert.y > mid_y_vert.y:
                temp = mid_y_vert
                mid_y_vert = min_y_vert
                min_y_vert = temp

            if mid_y_vert.y > max_y_vert.y:
                temp = max_y_vert
                max_y_vert = mid_y_vert
                mid_y_vert = temp

            # Use triangle area to determine handedness
            area = min_y_vert.triangle_area(max_y_vert, min_y_vert)
            handedness = area >= 0

            # Write triangles to scan buffer and then draw triangles
            self.scan_triangle(min_y_vert, mid_y_vert, max_y_vert, handedness,
                               c, fill)