Куб, нарисованный сплошными многоугольниками на Godot Engine 4

Для отрисовки куба использовал встроенную функцию _draw()

Код:

extends Node2D var fov: float = 450.0 var camera_z: float = 3.0 var angle_x: float = 0.5 var angle_y: float = 0.5 var mouse_sensitivity: float = 0.005 var vertices: Array[Vector3] = [ Vector3(-1, -1, -1), Vector3(1, -1, -1), Vector3(1, 1, -1), Vector3(-1, 1, -1), Vector3(-1, -1, 1), Vector3(1, -1, 1), Vector3(1, 1, 1), Vector3(-1, 1, 1) ] var faces: Array = [ {"indices": [0, 1, 2, 3], "color": Color.RED}, {"indices": [4, 5, 6, 7], "color": Color.GREEN}, {"indices": [0, 1, 5, 4], "color": Color.BLUE}, {"indices": [2, 3, 7, 6], "color": Color.YELLOW}, {"indices": [0, 3, 7, 4], "color": Color.CYAN}, {"indices": [1, 2, 6, 5], "color": Color.MAGENTA} ] func _input(event: InputEvent) -> void: if event is InputEventMouseMotion and Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT): angle_y -= event.relative.x * mouse_sensitivity angle_x += event.relative.y * mouse_sensitivity if event is InputEventMouseButton: if Input.is_mouse_button_pressed(MOUSE_BUTTON_WHEEL_UP): camera_z += 0.25 if Input.is_mouse_button_pressed(MOUSE_BUTTON_WHEEL_DOWN): camera_z -= 0.25 func _process(delta: float) -> void: if not Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT): angle_x -= 0.1 * delta angle_y -= 0.2 * delta queue_redraw() func _draw() -> void: var screen_center = get_viewport_rect().size / 2 var transformed_vertices: Array[Vector3] = [] var projected_points: Array[Vector2] = [] for vertex in vertices: var y1 = vertex.y * cos(angle_x) - vertex.z * sin(angle_x) var z1 = vertex.y * sin(angle_x) + vertex.z * cos(angle_x) var x2 = vertex.x * cos(angle_y) + z1 * sin(angle_y) var z2 = -vertex.x * sin(angle_y) + z1 * cos(angle_y) var final_z = z2 + camera_z if final_z <= 0.1: final_z = 0.1 transformed_vertices.append(Vector3(x2, y1, final_z)) var screen_x = (x2 * fov) / final_z + screen_center.x var screen_y = (y1 * fov) / final_z + screen_center.y projected_points.append(Vector2(screen_x, screen_y)) var render_queue: Array = [] for face in faces: var avg_z: float = 0.0 var face_points: PackedVector2Array = PackedVector2Array() for index in face["indices"]: avg_z += transformed_vertices[index].z face_points.append(projected_points[index]) avg_z /= 4.0 render_queue.append({"points": face_points, "color": face["color"], "z": avg_z}) render_queue.sort_custom(func(a, b): return a["z"] > b["z"]) for face in render_queue: draw_polygon(face["points"], [face["color"]]) for i in range(face["points"].size()): var p1 = face["points"][i] var p2 = face["points"][(i + 1) % face["points"].size()] draw_line(p1, p2, Color.BLACK, 1.5, true)
3