Ejemplo n.º 1
0
def create_cube_points():
    points = []
    # 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))
    return points
Ejemplo n.º 2
0
def get_direction(pressed_keys):
    direction = Vector3()
    if pressed_keys[pygame.K_LEFT]:
        direction.x = -1.0
    elif pressed_keys[pygame.K_RIGHT]:
        direction.x = +1.0

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

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

    return direction
Ejemplo n.º 3
0
    def render(self):
        # Set the cube color, applies to all vertices till next call
        glColor(self.color)

        # Adjust all the vertices so that the cube is at self.position
        vertices = []
        for v in self.vertices:
            vertices.append( tuple(Vector3(v) + self.position))

        # Draw all 6 faces of the cube
        glBegin(GL_QUADS)
        for face_no in range(self.num_faces):
            glNormal3dv(self.normals[face_no])
            v1, v2, v3, v4 = self.vertex_indices[face_no]
            glVertex(vertices[v1])
            glVertex(vertices[v2])
            glVertex(vertices[v3])
            glVertex(vertices[v4])

        glEnd()
Ejemplo n.º 4
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
Ejemplo n.º 5
0
def start():
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE, pygame.HWSURFACE|pygame.OPENGL|pygame.DOUBLEBUF)
    resize(*SCREEN_SIZE)
    init()

    clock = pygame.time.Clock()

    # This object renders the 'map'
    map = Map()

    # Camera transform matrix
    cam_matrix = Matrix44()
    cam_matrix.translate = (10.0, 0.6, 10.0)

    # Initialize speeds and directions
    rotation_direction = Vector3()
    rotation_speed = radians(90.0)
    movement_direction = Vector3()
    movement_speed = 5.0

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE:
                pygame.quit()
                quit()
        # Clear the screen, and z-buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

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

        pressed_keys = pygame.key.get_pressed()

        # Reset rotation and movement directions
        rotation_direction.set(0.0, 0.0, 0.0)
        movement_direction.set(0.0, 0.0, 0.0)

        # Modify direction vectors for key presses
        if pressed_keys[pygame.K_LEFT]:
            rotation_direction.y = +1.0
        elif pressed_keys[pygame.K_RIGHT]:
            rotation_direction.y = -1.0
        if pressed_keys[pygame.K_UP]:
            rotation_direction.x = -1.0
        elif pressed_keys[pygame.K_DOWN]:
            rotation_direction.x = +1.0
        if pressed_keys[pygame.K_z]:
            rotation_direction.z = -1.0
        elif pressed_keys[pygame.K_x]:
            rotation_direction.z = +1.0
        if pressed_keys[pygame.K_q]:
            movement_direction.z = -1.0
        elif pressed_keys[pygame.K_a]:
            movement_direction.z = +1.0

        # Calculate rotation matrix and multiply by camera matrix
        rotation = rotation_direction * rotation_speed * time_passed_seconds
        rotation_matrix = Matrix44.xyz_rotation(*rotation)
        cam_matrix *= rotation_matrix

        # Calcluate movment and add it to camera matrix translate
        heading = Vector3(cam_matrix.forward)
        movement = heading * movement_direction.z * movement_speed
        cam_matrix.translate += movement * time_passed_seconds

        # Upload the inverse camera matrix to OpenGL
        glLoadMatrixd(cam_matrix.get_inverse().to_opengl())

        # Light must be transformed as well
        glLight(GL_LIGHT0, GL_POSITION, (0, 1.5, 1, 0))

        map.render()

        pygame.display.flip()
Ejemplo n.º 6
0
def start():
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
    ball = pygame.image.load("images/ball.png").convert_alpha()

    points = create_cube_points()
    fov = 90.0  #degrees
    viewing_distance = calculate_view_distance(fov, SCREEN_W)

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

    center_x, center_y = SCREEN_W / 2, SCREEN_H / 2
    ball_w, ball_h = ball.get_size()
    ball_center_x, ball_center_y = ball_w / 2, ball_h / 2

    camera_position = Vector3(0.0, 0.0, -700.0)
    camera_speed = Vector3(300.0, 300.0, 300.0)

    clock = pygame.time.Clock()

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

        screen.fill(bg_color)
        pressed_keys = pygame.key.get_pressed()
        time_passed = clock.tick(30)
        time_passed_seconds = time_passed / 1000.0
        direction = get_direction(pressed_keys)

        if pressed_keys[pygame.K_w]:
            fov = min(179.0, fov + 1.0)
            viewing_distance = calculate_view_distance(fov, SCREEN_W)
        elif pressed_keys[pygame.K_s]:
            fov = max(1.0, fov - 1.0)
            viewing_distance = calculate_view_distance(fov, SCREEN_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_W / 4
        diagram_color = (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, diagram_color, False, diagram_points, 2)

        # Draw the text
        default_font = pygame.font.get_default_font()
        font = pygame.font.SysFont(default_font, 24)
        cam_text = font.render(f"Camera = {str(camera_position)}", True,
                               text_color)
        screen.blit(cam_text, text_pos)

        fov_text = font.render(f"Field of view = {int(fov)}", True, text_color)
        screen.blit(fov_text, fov_text_pos)

        distance_text = font.render(
            f"Viewing distance = {round(viewing_distance, 3)}", True,
            text_color)
        screen.blit(distance_text, distance_text_pos)

        pygame.display.flip()
Ejemplo n.º 7
0
def start():
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
    ball = pygame.image.load("images/ball.png").convert_alpha()

    fov = 75.0 # degrees
    viewing_distance = calculate_view_distance(fov, SCREEN_W)

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

    center_x, center_y = SCREEN_W/2, SCREEN_H/2
    ball_w, ball_h = ball.get_size()
    ball_center_x, ball_center_y = ball_w/2, ball_h/2

    cam_position = Vector3(0.0, 0.0, 600.0)

    rotation = Vector3()
    rotation_speed = Vector3(math.radians(20), math.radians(20), math.radians(20))

    # Labels for the axes
    font = pygame.font.SysFont(pygame.font.get_default_font(), 16)
    x_surface = font.render("X", True, white)
    y_surface = font.render("Y", True, white)
    z_surface = font.render("Z", True, white)

    clock = pygame.time.Clock()

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

        screen.fill(bg_color)
        time_passed = clock.tick(30)
        time_passed_seconds = time_passed / 1000.0

        rotation_direction = Vector3()

        # Adjust the rotation direction depending on key presses
        pressed_keys = pygame.key.get_pressed()

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

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

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

        rotation += rotation_direction * rotation_speed * time_passed_seconds

        rotation_matrix = Matrix44.x_rotation(rotation.x)
        rotation_matrix *= Matrix44.y_rotation(rotation.y)
        rotation_matrix *= Matrix44.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) - cam_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))

        def draw_axis(label, axis, color):
            axis = rotation_matrix.transform_vec3(axis * 150.0)
            x, y, z = axis - cam_position
            x = SCREEN_W/2.0 + x * (-viewing_distance / z)
            y = SCREEN_H/2.0 + (-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(x_surface, x_axis, red)
        draw_axis(y_surface, y_axis, green)
        draw_axis(z_surface, z_axis, blue)

        # Display rotation information on screen
        degrees_txt = tuple(math.degrees(r) for r in rotation)
        rotation_txt = f"Rotation: Q/A {round(degrees_txt[0], 3)}, W/S {round(degrees_txt[1], 3)}, E/D {round(degrees_txt[2], 3)}"
        txt_surface = font.render(rotation_txt, True, white)
        screen.blit(txt_surface, (5, 5))

        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.flip()
Ejemplo n.º 8
0
def get_direction(pressed_keys):
    direction = Vector3()
    if pressed_keys[pygame.K_LEFT]:
        direction.x = -1.0
    elif pressed_keys[pygame.K_RIGHT]:
        direction.x = +1.0
Ejemplo n.º 9
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)