============ RESTART: C:/Users/seth/AppData/Local/Programs/Python/Python311/Othograthic_3D_drawer.py ===========pygame 2.5.2 (SDL 2.28.3, Python 3.11.2)Hello from the pygame community. https://www.pygame.org/contribute.htmlTraceback (most recent call last):File "C:/Users/seth/AppData/Local/Programs/Python/Python311/Othograthic_3D_drawer.py", line 198, in <module>objects[index].draw(screen)File "C:/Users/seth/AppData/Local/Programs/Python/Python311/Othograthic_3D_drawer.py", line 42, in drawuv_index = int(self.uvs[i][j]) # Convert to integer indexIndexError: list index out of range
failure to index and list out of range
I exspected the UV mapping system to work? heres the source code
tie fighter.txt
v -30 -40 30v -30 40 -30v -30 40 30v -30 -40 -30v 30 -40 30v 30 40 -30v 30 40 30v 30 -40 -30v 30 12.5 -10v -30 12.5 -10v 30 12.5 10v -30 12.5 10v 30 -12.5 10v -30 -12.5 10v 30 -12.5 -10v -30 -12.5 -10f 8/1 9/2 10/3f 10/3 11/4 8/1f 11/4 8/1 9/2f 12/5 13/6 14/7f 14/7 15/8 12/5f 14/9 8/1 9/2f 13/6 10/3 11/4f 14/7 11/4 12/5f 0/10 1/11 2/12f 2/12 3/13 1/11f 0/10 2/12 3/13f 1/11 3/13 0/10f 4/14 5/15 6/16f 6/16 7/17 5/15f 4/14 6/16 7/17f 5/15 7/17 4/14
Star_destroyer.txt
v 0 0 -10v -50 0 0v 0 -20 0v 50 0 0v 0 20 0v 0 0 130vt 0.5 1
vt 0 0.5
vt 0 1
vt 1 0.5vt 0.5 0
vt 0.5 0.5
f 1/1 2/2 3/3
f 1/1 3/3 4/4
f 1/1 4/4 5/5
f 1/1 5/5 2/2
f 2/2 3/3 4/4 5/5
f 2/2 4/4 6/6
f 3/3 5/5 6/6
import pygameimport numpy as np# Initialize Pygamepygame.init()# Set up some constantsWIDTH, HEIGHT = 800, 600BACKGROUND_COLOR = (0, 0, 0)GRID_SIZE = 10# Set up the displayscreen = pygame.display.set_mode((WIDTH, HEIGHT))# Define a class for 3D objectsclass Object3D: def __init__(self, position, vertices, faces, uvs, texture, color=(255, 255, 255)): self.position = np.array(position) self.vertices = np.array(vertices) self.faces = faces self.uvs = uvs self.texture = texture self.color = color self.filled = False self.wireframe_color = (255, 255, 255) # Default wireframe color def draw(self, screen): for i, face in enumerate(self.faces): points = [] uv_points = [] for j, vertex_index in enumerate(face): rotation_matrix = np.array([[np.cos(yaw), 0, np.sin(yaw)], [0, 1, 0], [-np.sin(yaw), 0, np.cos(yaw)]]) @ np.array([[1, 0, 0], [0, np.cos(pitch), -np.sin(pitch)], [0, np.sin(pitch), np.cos(pitch)]]) @ np.array([[np.cos(twist), -np.sin(twist), 0], [np.sin(twist), np.cos(twist), 0], [0, 0, 1]]) vertex = np.matmul(rotation_matrix, self.vertices[vertex_index]) zoom_matrix = np.array([[zoom, 0, 0], [0, zoom, 0], [0, 0, 1]]) vertex = np.matmul(zoom_matrix, vertex) x, y, _ = vertex + self.position points.append((int(x), int(y))) # Removed z-coordinate from points for filled polygons # Get UV coordinates for texture mapping uv_index = int(self.uvs[i][j]) # Convert to integer index uv = self.uvs[uv_index] # Access UV coordinates using integer index uv_points.append((uv[0] * self.texture.get_width(), uv[1] * self.texture.get_height())) if self.texture: pygame.draw.polygon(screen, self.color, points) pygame.draw.lines(screen, self.color, True, points, 1) pygame.draw.polygon(self.texture, self.color, uv_points) else: pygame.draw.lines(screen, self.color, True, points, 1) # Draw wireframe pygame.draw.lines(screen, self.wireframe_color, True, points, 1)# Function to set wireframe colordef set_wireframe_color(): global objects, editing_color editing_color = Truedef update_wireframe_color(color): global objects for obj in objects: obj.wireframe_color = colordef draw_grid(screen): for x in range(-WIDTH//2, WIDTH//2, GRID_SIZE): for z in range(-HEIGHT//2, HEIGHT//2, GRID_SIZE): pygame.draw.line(screen, (100, 100, 100), (x, z), (x+GRID_SIZE, z)) pygame.draw.line(screen, (100, 100, 100), (x, z), (x, z+GRID_SIZE))def read_vertices_faces_and_uvs_from_file(filename): vertices = [] faces = [] uvs = [] with open(filename, 'r') as file: for line in file: data = line.strip().split() if data[0] == 'v': vertices.append(list(map(float, data[1:]))) elif data[0] == 'vt': uvs.append(list(map(float, data[1:]))) elif data[0] == 'f': face = [] uv_face = [] for i in range(1, len(data)): indices = data[i].split('/') face.append(int(indices[0]) - 1) # Adjusting indices to start from 0 if len(indices) > 1: uv_face.append(int(indices[1]) - 1) faces.append(face) if uv_face: uvs.append(uv_face) return vertices, faces, uvs# Load texturesstar_destroyer_texture = pygame.image.load('Ship_Texture_B.png')tie_fighter_texture = pygame.image.load('Ship_Texture_A.png')objects = [ Object3D([WIDTH // 2, HEIGHT // 2, 1000], *read_vertices_faces_and_uvs_from_file('star_destroyer.txt'), texture=star_destroyer_texture, color=(150, 150, 150)), # Star Destroyer Object3D([WIDTH // 3, HEIGHT // 3, 0], *read_vertices_faces_and_uvs_from_file('tie_fighter.txt'), texture=tie_fighter_texture, color=(70, 70, 90)) # Tie Fighter]# Menu buttonsbutton_font = pygame.font.SysFont(None, 34)button_height = 50button_width = 200button_spacing = 20button_color = (100, 100, 100)button_hover_color = (150, 150, 150)button_click_color = (200, 200, 200)buttons = [ {"text": "640x480", "action": lambda: pygame.display.set_mode((640, 480))}, {"text": "800x600", "action": lambda: pygame.display.set_mode((800, 600))}, {"text": "1024x768", "action": lambda: pygame.display.set_mode((1024, 768))}, {"text": "1280x720", "action": lambda: pygame.display.set_mode((1280, 720))}, {"text": "1280x1024", "action": lambda: pygame.display.set_mode((1280, 1024))}, {"text": "1920x1080", "action": lambda: pygame.display.set_mode((1920, 1080))}, {"text": "2560x1440", "action": lambda: pygame.display.set_mode((2560, 1440))}, {"text": "3840x2160", "action": lambda: pygame.display.set_mode((3840, 2160))}, {"text": "Set Wireframe Color", "action": set_wireframe_color},]editing_color = Falseselected_color = (255, 255, 255)running = Trueyaw = 0pitch = 0twist = 0zoom = 1show_grid = Falseshow_menu = Falsewhile running: mouse_pos = pygame.mouse.get_pos() click = pygame.mouse.get_pressed() for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: # Toggle menu visibility show_menu = not show_menu if not show_menu: # Only handle key presses when menu is not shown if event.key == pygame.K_a: yaw -= 0.1 if event.key == pygame.K_d: yaw += 0.1 if event.key == pygame.K_w: pitch -= 0.1 if event.key == pygame.K_s: pitch += 0.1 if event.key == pygame.K_z: zoom *= 1.1 if event.key == pygame.K_x: zoom /= 1.1 if event.key == pygame.K_LEFT: for obj in objects: obj.position[0] -= 10 if event.key == pygame.K_RIGHT: for obj in objects: obj.position[0] += 10 if event.key == pygame.K_UP: for obj in objects: obj.position[1] -= 10 if event.key == pygame.K_DOWN: for obj in objects: obj.position[1] += 10 if event.key == pygame.K_q: twist -= 0.1 if event.key == pygame.K_e: twist += 0.1 if event.key == pygame.K_g: show_grid = not show_grid if event.key == pygame.K_y: for obj in objects: obj.filled = not obj.filled elif event.type == pygame.MOUSEBUTTONDOWN: if editing_color: if 0 <= mouse_pos[0] <= WIDTH and 0 <= mouse_pos[1] <= HEIGHT: selected_color = screen.get_at(mouse_pos) update_wireframe_color(selected_color) editing_color = False screen.fill(BACKGROUND_COLOR) if show_grid: draw_grid(screen) # Calculate distances of objects from the camera distances = [np.linalg.norm(obj.position) for obj in objects] # Sort objects based on distance sorted_indices = np.argsort(distances)[::-1] # Render objects in sorted order for index in sorted_indices: objects[index].draw(screen) if show_menu: # Render menu buttons total_button_height = len(buttons) * (button_height + button_spacing) - button_spacing start_y = (HEIGHT - total_button_height) // 2 for i, button in enumerate(buttons): rect = pygame.Rect((WIDTH - button_width) // 2, start_y + i * (button_height + button_spacing), button_width, button_height) if rect.collidepoint(mouse_pos): pygame.draw.rect(screen, button_hover_color, rect) if click[0]: button["action"]() else: pygame.draw.rect(screen, button_color, rect) text_surface = button_font.render(button["text"], True, (255, 255, 255)) text_rect = text_surface.get_rect(center=rect.center) screen.blit(text_surface, text_rect) pygame.display.flip()pygame.quit()