Beispiel #1
0
    def get_tmatrix(self):
        c = self.get_center()
        tmatrix = Matrix44.identity()
        # tmatrix = Matrix44.z_rotation(math.radians(self.rotation))
        tmatrix.translate += Vector3(-c.x, -c.y, 0)
        tmatrix.translate += Vector3(self.world_pos.x, self.world_pos.y, 0)

        # z_rotation_matrix = Matrix44.z_rotation(math.radians(self.rotation))
        # z_rotation_matrix.invert()
        # tmatrix *= z_rotation_matrix
        # Can't get rotation working :(

        # Working:
        # tmatrix = Matrix44.translation(self.world_pos.x, self.world_pos.y, 0)
        return tmatrix
Beispiel #2
0
 def world_to_screen(self, pos):
     """Convert world coordinates (Vector2) to screen coordinates (Vector2)"""
     vec2to3 = Vector3(pos.x, pos.y, 0)
     transformed = self.get_tmatrix().get_inverse().transform(
         vec2to3)  # World to screen
     return Vector2(transformed[0] + self.position.x,
                    transformed[1] + self.position.y)
Beispiel #3
0
    def move(self, forward=None, right=None, up=None):
        """Changes the translation according to a direction vector.
        To move in opposite directions (i.e back, left and down), first
        negate the vector
        
        forward -- Vector or tuple to move in the 'forward' direction
        right -- Vector or tuple to move in the 'right' direction
        up -- Vector or tuple to move in the 'up' direction
        
        """

        if forward is not None:
            self.translate = Vector3(self.translate) + forward
        if right is not None:
            self.right = Vector3(self.right) + right
        if up is not None:
            self.up = Vector3(self.up) + up
    def transform_vec3(self, v):
        """Transforms a vector and returns the result as a Vector3.

        v -- Vector to transform

        """

        m = self._m
        x, y, z = v
        return Vector3.from_floats( x * m[0] + y * m[4] + z * m[8]  + m[12],
                                    x * m[1] + y * m[5] + z * m[9]  + m[13],
                                    x * m[2] + y * m[6] + z * m[10] + m[14] )
    def transform_sequence_vec3(self, points):

        m_0,  m_1,  m_2,  m_3, \
        m_4,  m_5,  m_6,  m_7, \
        m_8,  m_9,  m_10, m_11, \
        m_12, m_13, m_14, m_15 = self._m

        return [ Vector3.from_floats
                 ( x * m_0 + y * m_4 + z * m_8  + m_12,
                   x * m_1 + y * m_5 + z * m_9  + m_13,
                   x * m_2 + y * m_6 + z * m_10 + m_14 )
                   for x,y,z in points ]
Beispiel #6
0
    def transform_vec3(self, v):
        """Transforms a vector and returns the result as a Vector3.

        v -- Vector to transform

        """

        m = self._m
        x, y, z = v
        return Vector3.from_floats(x * m[0] + y * m[4] + z * m[8] + m[12],
                                   x * m[1] + y * m[5] + z * m[9] + m[13],
                                   x * m[2] + y * m[6] + z * m[10] + m[14])
Beispiel #7
0
    def transform_sequence_vec3(self, points):

        m_0, m_1, m_2, m_3, \
        m_4, m_5, m_6, m_7, \
        m_8, m_9, m_10, m_11, \
        m_12, m_13, m_14, m_15 = self._m

        return [Vector3.from_floats
                (x * m_0 + y * m_4 + z * m_8 + m_12,
                 x * m_1 + y * m_5 + z * m_9 + m_13,
                 x * m_2 + y * m_6 + z * m_10 + m_14)
                for x, y, z in points]
    def rotate_vec3(self, v):
        """Rotates a Vector3 and returns the result.
        The translation part of the Matrix44 is ignored.

        v -- Vector to rotate

        """

        m = self._m
        x, y, z = v
        return Vector3.from_floats( x * m[0] + y * m[4] + z * m[8],
                                    x * m[1] + y * m[5] + z * m[9],
                                    x * m[2] + y * m[6] + z * m[10] )
Beispiel #9
0
    def get_row_vec3(self, row_no):
        """Returns a Vector3 for a given row.

        row_no -- The row index

        """

        try:
            r = row_no * 4
            x, y, z = self._m[r:r + 3]
            return Vector3.from_floats(x, y, z)
        except IndexError:
            raise IndexError("Row and Column should be 0, 1, 2 or 3")
    def get_row_vec3(self, row_no):
        """Returns a Vector3 for a given row.

        row_no -- The row index

        """

        try:
            r = row_no*4
            x, y, z = self._m[r:r+3]
            return Vector3.from_floats(x, y, z)
        except IndexError:
            raise IndexError( "Row and Column should be 0, 1, 2 or 3" )
Beispiel #11
0
    def rotate_vec3(self, v):
        """Rotates a Vector3 and returns the result.
        The translation part of the Matrix44 is ignored.

        v -- Vector to rotate

        """

        m = self._m
        x, y, z = v
        return Vector3.from_floats(x * m[0] + y * m[4] + z * m[8],
                                   x * m[1] + y * m[5] + z * m[9],
                                   x * m[2] + y * m[6] + z * m[10])
Beispiel #12
0
    def iter_transform_vec3(self, points):
        """Transforms a sequence of points, and yields the result as Vector3s

        points -- A sequence of vectors

        """

        m_0, m_1, m_2, m_3, \
        m_4, m_5, m_6, m_7, \
        m_8, m_9, m_10, m_11, \
        m_12, m_13, m_14, m_15 = self._m

        for x, y, z in points:
            yield Vector3.from_floats(x * m_0 + y * m_4 + z * m_8 + m_12,
                                      x * m_1 + y * m_5 + z * m_9 + m_13,
                                      x * m_2 + y * m_6 + z * m_10 + m_14)
Beispiel #13
0
def test():

    m = Matrix44.xyz_rotation(radians(45), radians(20), radians(0))

    print(m)

    print("--Transpose")

    print(m.get_transpose())

    print("--")

    print(m.get_row(2))

    m.transpose()
    print(m)

    print

    #print (10, 20, 30) + Vector3(1,2,3)

    m.translate = (m.translate) + Vector3(10, 20, 30)

    print(m)

    print

    v = (1., 2., 3.)
    print(v)
    vt = m.transform(v)
    print(vt)

    vit = m.get_inverse().transform(vt)

    print(vit)

    print(m.inverse_transform(vt))
    m[1, 2] = 3.

    print

    print(m.x_axis)
    print(m.translate)
    m.translate = (1, 2, 3)

    print(m)
    def iter_transform_vec3(self, points):

        """Transforms a sequence of points, and yields the result as Vector3s

        points -- A sequence of vectors

        """

        m_0,  m_1,  m_2,  m_3, \
        m_4,  m_5,  m_6,  m_7, \
        m_8,  m_9,  m_10, m_11, \
        m_12, m_13, m_14, m_15 = self._m

        for x, y, z in points:

            yield Vector3.from_floats( x * m_0 + y * m_4 + z * m_8  + m_12,
                                       x * m_1 + y * m_5 + z * m_9  + m_13,
                                       x * m_2 + y * m_6 + z * m_10 + m_14 )
Beispiel #15
0
 def as_vec3(self):
     """Shorthand for converting to a vector3."""
     return Vector3._from_float_sequence(self)
Beispiel #16
0
def test():
    m = Matrix44.xyz_rotation(radians(45), radians(20), radians(0))

    # m.translate += (1, 2, 3)
    print(m.right)
    print(m.right.as_vec3())

    n = m.copy()

    r = Matrix44.z_rotation(radians(32))
    m *= r
    print(m)
    n.fast_mul(r)

    print(n)

    print("--Transpose")

    print(m.get_transpose())

    print("--")

    print(m.get_row(2))

    m.transpose()
    print(m)

    print()

    # print (10, 20, 30) + Vector3(1,2,3)

    m.translate = (m.translate[:3]) + Vector3(10, 20, 30)

    print(m)

    print()

    v = (1., 2., 3.)
    print(v)
    vt = m.transform(v)
    print(vt)

    vit = m.get_inverse().transform(vt)

    print(vit)

    print(m.inverse_transform(vt))
    m[1, 2] = 3.

    print()

    print(m.x_axis)
    print(m.translate)

    m.translate = (1, 2, 3)

    print(m)

    identity = Matrix44()
    # identity.set_row(0, (1, 2, 3, 4))
    print(identity)

    identity[3, 1] = 456
    # identity *= Matrix44.scale(20.32, 764.2323, -23)

    print(identity)
    print(eval(repr(identity)))

    print(m)

    print(m.translate + Vector3(1, 2, 3))

    print(m)

    m.translate = (0, 0, 0)
Beispiel #17
0
 def screen_to_world(self, pos):
     """Convert screen coordinates (Vector2) to world coordinates (Vector2)"""
     pos = Vector2(pos)
     pos -= self.position
     transformed = self.get_tmatrix().transform(Vector3(pos.x, pos.y, 0))
     return Vector2(transformed[0], transformed[1])
def run():
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE, 0)

    default_font = pygame.font.get_default_font()
    font = pygame.font.SysFont(default_font, 24)

    ball = pygame.image.load("ball.png").convert_alpha()

    # The 3D points
    points = []

    fov = 90.  # Field of view
    viewing_distance = calculate_viewing_distance(radians(fov), SCREEN_SIZE[0])

    # Create a list of points along the edge of a cube
    for x in range(0, CUBE_SIZE + 1, 20):
        edge_x = x == 0 or x == CUBE_SIZE

        for y in range(0, CUBE_SIZE + 1, 20):
            edge_y = y == 0 or y == CUBE_SIZE

            for z in range(0, CUBE_SIZE + 1, 20):
                edge_z = z == 0 or z == CUBE_SIZE

                if sum((edge_x, edge_y, edge_z)) >= 2:
                    point_x = float(x) - CUBE_SIZE / 2
                    point_y = float(y) - CUBE_SIZE / 2
                    point_z = float(z) - CUBE_SIZE / 2

                    points.append(Vector3(point_x, point_y, point_z))

    # Sort points in z order
    def point_z(point):
        return point.z

    points.sort(key=point_z, reverse=True)

    center_x, center_y = SCREEN_SIZE
    center_x /= 2
    center_y /= 2

    ball_w, ball_h = ball.get_size()
    ball_center_x = ball_w / 2
    ball_center_y = ball_h / 2

    camera_position = Vector3(0.0, 0.0, -700.)
    camera_speed = Vector3(300.0, 300.0, 300.0)

    clock = pygame.time.Clock()

    while True:

        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                quit()

        screen.fill((0, 0, 0))

        pressed_keys = pygame.key.get_pressed()

        time_passed = clock.tick()
        time_passed_seconds = time_passed / 1000.

        direction = Vector3()
        if pressed_keys[K_LEFT]:
            direction.x = -1.0
        elif pressed_keys[K_RIGHT]:
            direction.x = +1.0

        if pressed_keys[K_UP]:
            direction.y = +1.0
        elif pressed_keys[K_DOWN]:
            direction.y = -1.0

        if pressed_keys[K_q]:
            direction.z = +1.0
        elif pressed_keys[K_a]:
            direction.z = -1.0

        if pressed_keys[K_w]:
            fov = min(179., fov + 1.)
            w = SCREEN_SIZE[0]
            viewing_distance = calculate_viewing_distance(radians(fov), w)
        elif pressed_keys[K_s]:
            fov = max(1., fov - 1.)
            w = SCREEN_SIZE[0]
            viewing_distance = calculate_viewing_distance(radians(fov), w)

        camera_position += direction * camera_speed * time_passed_seconds

        # Draw the 3D points
        for point in points:

            x, y, z = point - camera_position

            if z > 0:
                x = x * viewing_distance / z
                y = -y * viewing_distance / z
                x += center_x
                y += center_y
                screen.blit(ball, (x - ball_center_x, y - ball_center_y))

        # Draw the field of view diagram
        diagram_width = SCREEN_SIZE[0] / 4
        col = (50, 255, 50)
        diagram_points = []
        diagram_points.append((diagram_width / 2, 100 + viewing_distance / 4))
        diagram_points.append((0, 100))
        diagram_points.append((diagram_width, 100))
        diagram_points.append((diagram_width / 2, 100 + viewing_distance / 4))
        diagram_points.append((diagram_width / 2, 100))
        pygame.draw.lines(screen, col, False, diagram_points, 2)

        # Draw the text
        white = (255, 255, 255)
        cam_text = font.render("camera = " + str(camera_position), True, white)
        screen.blit(cam_text, (5, 5))
        fov_text = font.render("field of view = %i" % int(fov), True, white)
        screen.blit(fov_text, (5, 35))
        txt = "viewing distance = %.3f" % viewing_distance
        d_text = font.render(txt, True, white)
        screen.blit(d_text, (5, 65))

        pygame.display.update()
 def as_vec3(self):
     """Shorthand for converting to a vector3."""
     return Vector3._from_float_sequence(self)
Beispiel #20
0
def run():
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE, 0)
    font = pygame.font.SysFont("courier new", 16, True)
    ball = pygame.image.load("ball.png").convert_alpha()

    # os pontos 3D
    points = []

    fov = 75.  # campo de visao
    viewing_distance = calculate_viewing_distance(radians(fov), SCREEN_SIZE[0])

    # cria uma lista de pontos ao longo da borda de um cubo
    for x in range(0, CUBE_SIZE + 1, 10):
        edge_x = x == 0 or x == CUBE_SIZE

        for y in range(0, CUBE_SIZE + 1, 10):
            edge_y = y == 0 or y == CUBE_SIZE

            for z in range(0, CUBE_SIZE + 1, 10):
                edge_z = z == 0 or z == CUBE_SIZE

                if sum((edge_x, edge_y, edge_z)) >= 2:
                    point_x = float(x) - CUBE_SIZE / 2
                    point_y = float(y) - CUBE_SIZE / 2
                    point_z = float(z) - CUBE_SIZE / 2
                    points.append(Vector3(point_x, point_y, point_z))

    def point_z(point):
        return point[2]

    center_x, center_y = SCREEN_SIZE
    center_x /= 2
    center_y /= 2

    ball_w, ball_h = ball.get_size()
    ball_center_x = ball_w / 2
    ball_center_y = ball_h / 2

    camera_position = Vector3(0.0, 0.0, 600.)

    rotation = Vector3()
    rotation_speed = Vector3(radians(20), radians(20), radians(20))
    clock = pygame.time.Clock()

    # Algumas cores para desenhar
    red = (255, 0, 0)
    green = (0, 255, 0)
    blue = (0, 0, 255)
    white = (255, 255, 255)

    # Nomes para os eixos
    x_surface = font.render("X", True, white)
    y_surface = font.render("Y", True, white)
    z_surface = font.render("Z", True, white)

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                quit()

        screen.fill((0, 0, 0))

        time_passed = clock.tick()
        time_passed_seconds = time_passed / 1000.

        rotation_direction = Vector3()

        # Ajusta a direcao da rotacao de acordo com as teclas pressionadas
        pressed_keys = pygame.key.get_pressed()

        if pressed_keys[K_q]:
            rotation_direction.x = +1.0
        elif pressed_keys[K_a]:
            rotation_direction.x = -1.0

        if pressed_keys[K_w]:
            rotation_direction.y = +1.0
        elif pressed_keys[K_s]:
            rotation_direction.y = -1.0

        if pressed_keys[K_e]:
            rotation_direction.z = +1.0
        elif pressed_keys[K_d]:
            rotation_direction.z = -1.0

        # Aplica um movimento baseado em tempo à rotação
        rotation += rotation_direction * rotation_speed * time_passed_seconds

        # Cria a matriz de rotação
        rotation_matrix = Matrix.x_rotation(rotation.x)
        rotation_matrix *= Matrix.y_rotation(rotation.y)
        rotation_matrix *= Matrix.z_rotation(rotation.z)

        transformed_points = []

        # Transforma todos os pontos e ajusta conforme a posição da câmera
        for point in points:
            p = rotation_matrix.transform_vec3(point) - camera_position
            transformed_points.append(p)

        transformed_points.sort(key=point_z)

        # Faz a projeção de perspectiva e o blit de todos os pontos
        for x, y, z in transformed_points:
            if z < 0:
                x = center_x + x * -viewing_distance / z
                y = center_y + -y * -viewing_distance / z
                screen.blit(ball, (x - ball_center_x, y - ball_center_y))

        # funacao para desenhar um unico eixo
        def draw_axis(color, axis, label):
            axis = rotation_matrix.transform_vec3(axis * 150.)
            SCREEN_SIZE = (640, 480)
            center_x = SCREEN_SIZE[0] / 2.0
            center_y = SCREEN_SIZE[1] / 2.0
            x, y, z = axis - camera_position

            x = center_x + x * -viewing_distance / z
            y = center_y + -y * -viewing_distance / z

            pygame.draw.line(screen, color, (center_x, center_y), (x, y), 2)

            w, h = label.get_size()
            screen.blit(label, (x - w / 2, y - h / 2))

        # desenha os eixos x, y, z
        x_axis = Vector3(1, 0, 0)
        y_axis = Vector3(0, 1, 0)
        z_axis = Vector3(0, 0, 1)

        draw_axis(red, x_axis, x_surface)
        draw_axis(green, y_axis, y_surface)
        draw_axis(blue, z_axis, z_surface)

        # exibe informacoes de rotacao na tela
        degrees_txt = tuple(degrees(r) for r in rotation)
        rotation_txt = "Rotacao: Q/A %.3f, W/S %.3f, E/D %.3f" % degrees_txt
        txt_surface = font.render(rotation_txt, True, white)
        screen.blit(txt_surface, (5, 5))

        # exibe a matriz de rotacao na tela
        matrix_txt = str(rotation_matrix)
        txt_y = 25
        for line in matrix_txt.split('\n'):
            txt_surface = font.render(line, True, white)
            screen.blit(txt_surface, (5, txt_y))
            txt_y += 20

        pygame.display.update()
Beispiel #21
0
def rotate_vector2(vec2, degrees):
    rotation_matrix = Matrix44.z_rotation(math.radians(degrees))
    transformed = rotation_matrix.transform_vec3(Vector3(vec2.x, vec2.y, 0))
    return Vector2(transformed.x, transformed.y)
Beispiel #22
0
    def move(self, forward=None, right=None, up=None):
        """Changes the translation according to a direction vector.
        To move in opposite directions (i.e back, left and down), first
        negate the vector.

        forward -- Units to move in the 'forward' direction
        right -- Units to move in the 'right' direction
        up -- Units to move in the 'up' direction

        """

        if forward is not None:
            self.translate = Vector3(self.translate) + \
                             Vector3(self.forward) * forward

        if right is not None:
            self.translate = Vector3(self.translate) + \
                             Vector3(self.right) * right

        if up is not None:
            self.translate = Vector3(self.translate) + \
                             Vector3(self.up) * up


# def test():
#     m = Matrix44.xyz_rotation(radians(45), radians(20), radians(0))
#
#     # m.translate += (1, 2, 3)
#     print(m.right)
#     print(m.right.as_vec3())
#
#     n = m.copy()
#
#     r = Matrix44.z_rotation(radians(32))
#     m *= r
#     print(m)
#     n.fast_mul(r)
#
#     print(n)
#
#     print("--Transpose")
#
#     print(m.get_transpose())
#
#     print("--")
#
#     print(m.get_row(2))
#
#     m.transpose()
#     print(m)
#
#     print()
#
#     # print (10, 20, 30) + Vector3(1,2,3)
#
#     m.translate = (m.translate[:3]) + Vector3(10, 20, 30)
#
#     print(m)
#
#     print()
#
#     v = (1., 2., 3.)
#     print(v)
#     vt = m.transform(v)
#     print(vt)
#
#     vit = m.get_inverse().transform(vt)
#
#     print(vit)
#
#     print(m.inverse_transform(vt))
#     m[1, 2] = 3.
#
#     print()
#
#     print(m.x_axis)
#     print(m.translate)
#     m.translate = (1, 2, 3)
#
#     print(m)
#
#     identity = Matrix44()
#     # identity.set_row(0, (1, 2, 3, 4))
#     print(identity)
#
#     identity[3, 1] = 456
#     # identity *= Matrix44.scale(20.32, 764.2323, -23)
#
#     print(identity)
#     print(eval(repr(identity)))
#
#     print(m)
#
#     print(m.translate + Vector3(1, 2, 3))
#
#     print(m)
#
#     m.translate = (0, 0, 0)
#
#
# if __name__ == "__main__":
#     test()
Beispiel #23
0
def run():
    
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE, 0)
        
    font = pygame.font.SysFont("courier new", 16, True)
    
    ball = pygame.image.load("map.png").convert_alpha()
    
    points = []
    
    fov = 75. # Field of view
    viewing_distance = calculate_viewing_distance(radians(fov), SCREEN_SIZE[0])
    
    # Create a list of points along the edge of a cube
    for x in xrange(0, CUBE_SIZE+1, 10):
        edge_x = x == 0 or x == CUBE_SIZE
        
        for y in xrange(0, CUBE_SIZE+1, 10):
            edge_y = y == 0 or y == CUBE_SIZE
            
            for z in xrange(0, CUBE_SIZE+1, 10):
                edge_z = z == 0 or z == CUBE_SIZE
                
                if sum((edge_x, edge_y, edge_z)) >= 2:
                    
                    point_x = float(x) - CUBE_SIZE/2
                    point_y = float(y) - CUBE_SIZE/2
                    point_z = float(z) - CUBE_SIZE/2
                    
                    points.append(Vector3(point_x, point_y, point_z))
        
    def point_z(point):
        return point[2]
    
    center_x, center_y = SCREEN_SIZE
    center_x /= 2
    center_y /= 2
    
    ball_w, ball_h = ball.get_size()
    ball_center_x = ball_w / 2
    ball_center_y = ball_h / 2
    
    camera_position = Vector3(0.0, 0.0, 600.)
        
    rotation = Vector3()
    rotation_speed = Vector3(radians(20), radians(20), radians(20))
    
    clock = pygame.time.Clock()
    
    # Some colors for drawing
    red = (255, 0, 0)
    green = (0, 255, 0)
    blue = (0, 0, 255)    
    white = (255, 255, 255)
    
    # Labels for the axes
    x_surface = font.render("X", True, white)
    y_surface = font.render("Y", True, white)
    z_surface = font.render("Z", True, white)
        
    while True:
        
        for event in pygame.event.get():
            if event.type == QUIT:
                return            
        
        screen.fill((0, 0, 0))        
        
        time_passed = clock.tick()
        time_passed_seconds = time_passed / 1000.                
        
        rotation_direction = Vector3()
        
        #Adjust the rotation direction depending on key presses
        pressed_keys = pygame.key.get_pressed()
        
        if pressed_keys[K_q]:
            rotation_direction.x = +1.0
        elif pressed_keys[K_a]:
            rotation_direction.x = -1.0
                        
        if pressed_keys[K_w]:
            rotation_direction.y = +1.0
        elif pressed_keys[K_s]:
            rotation_direction.y = -1.0
        
        if pressed_keys[K_e]:
            rotation_direction.z = +1.0
        elif pressed_keys[K_d]:
            rotation_direction.z = -1.0
        
        # Apply time based movement to rotation
        rotation += rotation_direction * rotation_speed * time_passed_seconds
        
        # Build the rotation matrix
        rotation_matrix = Matrix.x_rotation(rotation.x)
        rotation_matrix *= Matrix.y_rotation(rotation.y)
        rotation_matrix *= Matrix.z_rotation(rotation.z)        
        
        transformed_points = []

        # Transform all the points and adjust for camera position
        for point in points:
            
            p = rotation_matrix.transform_vec3(point) - camera_position            
            
            transformed_points.append(p)
        
        transformed_points.sort(key=point_z)
        
        # Perspective project and blit all the points
        for x, y, z in transformed_points:            
            
            if z < 0:
                x = center_x + x * -viewing_distance / z
                y = center_y + -y * -viewing_distance / z
            
                screen.blit(ball, (x-ball_center_x, y-ball_center_y))
                
        
        # Function to draw a single axes, see below
        def draw_axis(color, axis, label):
            
            axis = rotation_matrix.transform_vec3(axis * 150.)
            SCREEN_SIZE =  (640, 480)
            center_x = SCREEN_SIZE[0] / 2.0
            center_y = SCREEN_SIZE[1] / 2.0
            x, y, z = axis - camera_position
                
            x = center_x + x * -viewing_distance / z
            y = center_y + -y * -viewing_distance / z
            
            pygame.draw.line(screen, color, (center_x, center_y), (x, y), 2)
            
            w, h = label.get_size()
            screen.blit(label, (x-w/2, y-h/2))
        
        # Draw the x, y and z axes
        x_axis = Vector3(1, 0, 0)
        y_axis = Vector3(0, 1, 0)
        z_axis = Vector3(0, 0, 1)        
        
        draw_axis(red, x_axis, x_surface)
        draw_axis(green, y_axis, y_surface)
        draw_axis(blue, z_axis, z_surface)
            
        # Display rotation information on screen
        degrees_txt = tuple(degrees(r) for r in rotation)
        rotation_txt = "Rotation: Q/A %.3f, W/S %.3f, E/D %.3f" % degrees_txt
        txt_surface = font.render(rotation_txt, True, white)
        screen.blit(txt_surface, (5, 5))
        
        # Displat the rotation matrix on screen
        matrix_txt = str(rotation_matrix)
        txt_y = 25
        for line in matrix_txt.split('\n'):
            txt_surface = font.render(line, True, white)
            screen.blit(txt_surface, (5, txt_y))
            txt_y += 20
            
        pygame.display.update()
Beispiel #24
0
def main():
    pygame.init()
    screen = pygame.display.set_mode(screensize,0,32)
    defaultfont = pygame.font.get_default_font()
    sysfont = pygame.font.SysFont(defaultfont,24)
    ballsurf = pygame.image.load('ball.png').convert_alpha()

    # the 3D points
    points = []

    fov = 90  # Field of view
    viewdistance = calculateViewingDistance(radians(fov), screenwidth)
    # create a list of points along the edge of a cube
    for x in range(0, cubesize+1, 20):
        isEdgeX  =  (x==0) or (x==cubesize)
        for y in range(0,cubesize+1,20):
            isEdgeY  =  (y==0) or (y==cubesize)
            for z in range(0,cubesize+1,20):
                isEdgeZ  =  (z==0) or (z==cubesize)
                if sum( [isEdgeX, isEdgeY, isEdgeZ] ) >= 2:
                    pointX = x - cubesize/2.0
                    pointY = y - cubesize/2.0
                    pointZ = z - cubesize/2.0
                    points.append( Vector3(pointX,pointY,pointZ) )
    # sort points in z order
    def getPointZ(point):
        return point.z
    points.sort(key=getPointZ, reverse=True)

    centerX,centerY = screenwidth/2, screenheight/2
    ballwidth,ballheight = ballsurf.get_size()
    ballcenterX,ballcenterY = ballwidth/2, ballheight/2
    cameraposition = Vector3(0.0, 0.0, -700.0)
    cameraspeed = Vector3(300.0, 300.0, 300.0)

    clock = pygame.time.Clock()

    while True:
        for e in pygame.event.get():
            if e.type == QUIT: pygame.quit(); exit()
        screen.fill(black)
        pressedkeys = pygame.key.get_pressed()
        timepassed = clock.tick(fps)/1000.0

        direction = Vector3()
        if pressedkeys[K_LEFT]:        direction.x = -1.0
        elif pressedkeys[K_RIGHT]:     direction.x = +1.0
        elif pressedkeys[K_UP]:        direction.y = -1.0
        elif pressedkeys[K_DOWN]:      direction.y = +1.0
        elif pressedkeys[K_a]:         direction.z = -1.0
        elif pressedkeys[K_q]:         direction.z = +1.0

        if pressedkeys[K_w]:
            fov = min(179.0, fov+1.0)
            viewdistance = calculateViewingDistance( radians(fov), screenwidth)
        elif pressedkeys[K_s]:
            fov = max(1.0, fov-1.0)
            viewdistance = calculateViewingDistance( radians(fov), screenwidth)
        cameraposition += timepassed * cameraspeed * direction
        # draw the 3D points
        for point in points:
            x,y,z = point - cameraposition
            if z > 0:
                x =  x * viewdistance/z
                y = -y * viewdistance/z
                x += centerX
                y += centerY
                screen.blit(ballsurf, (x-ballcenterX,y-ballcenterY) )
        # draw the field of view diagram
        diagramwidth = screenwidth/4
        color = 50,255,50
        diagrampoints = []
        diagrampoints.append( (diagramwidth/2, 100+viewdistance/4) )
        diagrampoints.append( (0,100))
        diagrampoints.append( (diagramwidth,100))
        diagrampoints.append( (diagramwidth/2,100+viewdistance/4))
        diagrampoints.append( (diagramwidth/2,100) )
        pygame.draw.lines(screen,color,False,diagrampoints,2)
        # draw the text
        cam_textsurf = sysfont.render('Camera = %s' %str(cameraposition), True,white)
        fov_textsurf = sysfont.render('field of view = %i' %int(fov), True,white)
        txt = 'viewing distance  = %.3f' % viewdistance
        dist_textsurf = sysfont.render(txt,True,white)
        screen.blit(cam_textsurf, (5,5) )
        screen.blit(fov_textsurf, (5,35) )
        screen.blit(dist_textsurf, (5,65) )
        pygame.display.update()