181 lines
5.0 KiB
Python
181 lines
5.0 KiB
Python
import window
|
|
import math
|
|
import copy
|
|
from matrix import Matrix4x4, Matrix3x3
|
|
from vectors import Vector4d, Vector3d, Vector2d
|
|
from engine import Mesh
|
|
from triangle import Triangle
|
|
|
|
ui = window.Window(600, 600)
|
|
near_plane = 0.1
|
|
far_plane = 1000.0
|
|
fov = 90.0
|
|
#'''
|
|
tris =[
|
|
Matrix3x3(Vector3d(0.0,0.0,0.0),Vector3d(0.0,1.0,0.0),Vector3d(1.0,1.0,0.0)),
|
|
Matrix3x3(Vector3d(0.0,0.0,0.0),Vector3d(1.0,1.0,0.0),Vector3d(1.0,0.0,0.0)),
|
|
Matrix3x3(Vector3d(1.0,0.0,0.0),Vector3d(1.0,1.0,0.0),Vector3d(1.0,1.0,1.0)),
|
|
Matrix3x3(Vector3d(1.0,0.0,0.0),Vector3d(1.0,1.0,1.0),Vector3d(1.0,0.0,1.0)),
|
|
Matrix3x3(Vector3d(1.0,0.0,1.0),Vector3d(1.0,1.0,1.0),Vector3d(0.0,1.0,1.0)),
|
|
Matrix3x3(Vector3d(1.0,0.0,1.0),Vector3d(0.0,1.0,1.0),Vector3d(0.0,0.0,1.0)),
|
|
Matrix3x3(Vector3d(0.0,0.0,1.0),Vector3d(0.0,1.0,1.0),Vector3d(0.0,1.0,0.0)),
|
|
Matrix3x3(Vector3d(0.0,0.0,1.0),Vector3d(0.0,1.0,0.0),Vector3d(0.0,0.0,0.0)),
|
|
Matrix3x3(Vector3d(0.0,1.0,0.0),Vector3d(0.0,1.0,1.0),Vector3d(1.0,1.0,1.0)),
|
|
Matrix3x3(Vector3d(0.0,1.0,0.0),Vector3d(1.0,1.0,1.0),Vector3d(1.0,1.0,0.0)),
|
|
Matrix3x3(Vector3d(1.0,0.0,1.0),Vector3d(0.0,0.0,1.0),Vector3d(0.0,0.0,0.0)),
|
|
Matrix3x3(Vector3d(1.0,0.0,1.0),Vector3d(0.0,0.0,0.0),Vector3d(1.0,0.0,0.0))
|
|
]
|
|
#'''
|
|
#tris = Mesh()
|
|
def main():
|
|
#tris.load_obj_file('shuttle.obj')
|
|
ui.scale = 3
|
|
ui.thetax = 1
|
|
ui.thetaz = 1
|
|
ui.window.bind('<Left>', left)
|
|
ui.window.bind('<Right>', right)
|
|
ui.window.bind('<Up>', up)
|
|
ui.window.bind('<Down>', down)
|
|
ui.window.bind('<Button-4>', wheel)
|
|
ui.window.bind('<Button-5>', wheel)
|
|
#ui.window.bind('<ButtonPress-1>', mouse_start)
|
|
ui.canvas.bind('<B1-Motion>', mouse_end)
|
|
ui.canvas.old_coords = None
|
|
ui.window.after(0, draw_scene)
|
|
ui.show()
|
|
|
|
def wheel(event):
|
|
# respond to Linux or Windows wheel event
|
|
#if event.num == 5 or event.delta == -120:
|
|
if event.num == 4:
|
|
ui.scale -= .5
|
|
else:
|
|
ui.scale += .5
|
|
|
|
if ui.scale < 1.5:
|
|
ui.scale = 1.5
|
|
|
|
draw_scene()
|
|
|
|
def left(event):
|
|
ui.thetaz += .1
|
|
draw_scene()
|
|
|
|
def right(event):
|
|
ui.thetaz -= .1
|
|
draw_scene()
|
|
|
|
def up(event):
|
|
ui.thetax += .1
|
|
draw_scene()
|
|
|
|
def down(event):
|
|
ui.thetax -= .1
|
|
draw_scene()
|
|
|
|
def mouse_start(event):
|
|
ui.canvas.old_coords = event.x, event.y
|
|
|
|
def mouse_end(event):
|
|
x, y = event.x - ui.width / 2, event.y - ui.height / 2
|
|
if x < 0:
|
|
ui.thetax -= .01
|
|
else:
|
|
ui.thetax += .01
|
|
|
|
if y < 0:
|
|
ui.thetaz -= .01
|
|
else:
|
|
ui.thetaz += .01
|
|
|
|
draw_scene()
|
|
|
|
def draw_scene():
|
|
ui.canvas.delete("all")
|
|
aspect_ratio = ui.height / ui.width
|
|
|
|
projection_matrix = Matrix4x4.get_projection_matrix(fov, aspect_ratio, near_plane, far_plane)
|
|
|
|
rotation_matrix_z = Matrix4x4.get_y_rotation_matrix(ui.thetaz * .5)
|
|
|
|
rotation_matrix_x = Matrix4x4.get_x_rotation_matrix(ui.thetax)
|
|
|
|
translation = Matrix4x4.get_translation_matrix(Vector3d(0, 0, ui.scale))
|
|
|
|
world_matrix = Matrix4x4.get_identity_matrix()
|
|
world_matrix = rotation_matrix_z.multiply_matrix(rotation_matrix_x)
|
|
world_matrix = world_matrix.multiply_matrix(translation)
|
|
|
|
|
|
triangles = []
|
|
|
|
for tri in tris:
|
|
row1 = world_matrix.multiply_3d(tri[0])
|
|
row2 = world_matrix.multiply_3d(tri[1])
|
|
row3 = world_matrix.multiply_3d(tri[2])
|
|
|
|
transformed = Matrix3x3(row1, row2, row3)
|
|
|
|
line1 = transformed.row2.subtract_3d(transformed.row1)
|
|
line2 = transformed.row3.subtract_3d(transformed.row1)
|
|
|
|
normal = line1.cross_product(line2)
|
|
|
|
normal = normal.get_normalized_form()
|
|
|
|
# Do we display this triangle?
|
|
if normal.dot_product(transformed.row1) < 0.0:
|
|
# Lighting
|
|
light = Vector3d(0, 0, -1) # Shining at the player.
|
|
|
|
light = light.get_normalized_form()
|
|
|
|
dot_product = normal.dot_product(light)
|
|
r = abs(int(255 * dot_product))
|
|
|
|
# Scale into view
|
|
row1 = projection_matrix.multiply_3d(transformed.row1)
|
|
row2 = projection_matrix.multiply_3d(transformed.row2)
|
|
row3 = projection_matrix.multiply_3d(transformed.row3)
|
|
|
|
projected = Matrix3x3(row1, row2, row3)
|
|
|
|
projected.row1 = projected.row1.divide_3d(1)
|
|
projected.row2 = projected.row2.divide_3d(1)
|
|
projected.row3 = projected.row3.divide_3d(1)
|
|
|
|
offset = Vector3d(1, 1, 0)
|
|
|
|
projected.row1 = projected.row1.add_3d(offset)
|
|
projected.row2 = projected.row2.add_3d(offset)
|
|
projected.row3 = projected.row3.add_3d(offset)
|
|
|
|
projected.row1.x *= .5 * ui.width
|
|
projected.row1.y *= .5 * ui.height
|
|
projected.row2.x *= .5 * ui.width
|
|
projected.row2.y *= .5 * ui.height
|
|
projected.row3.x *= .5 * ui.width
|
|
projected.row3.y *= .5 * ui.height
|
|
|
|
t = Triangle(projected)
|
|
t.color = r
|
|
t.average = (t.coords.row1.z + t.coords.row2.z + t.coords.row3.z) / 3
|
|
triangles.append(t)
|
|
|
|
# Sort the triangles so they are drawn in order.
|
|
triangles.sort(key=lambda r: r.average, reverse = True)
|
|
|
|
for projected in triangles:
|
|
r = projected.color
|
|
coords = [projected.coords.row1.x, projected.coords.row1.y, projected.coords.row2.x, projected.coords.row2.y, projected.coords.row3.x, projected.coords.row3.y]
|
|
ui.canvas.create_polygon(coords, fill=from_rgb(r, r, r), outline="black")
|
|
|
|
ui.canvas.update()
|
|
|
|
#ui.canvas.after(100, draw_scene)
|
|
|
|
def from_rgb(r, b, g):
|
|
return "#%02x%02x%02x" %(r, g, b)
|
|
|
|
main()
|