import window import math import copy from tkinter.font import Font 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 = [ Matrix3x3(Vector3d(0,0,0),Vector3d(0,2000,0.0),Vector3d(1,1,0)) ]''' tris = Mesh() def main(): tris.load_obj_file('reduced.obj') #tris.load_csv('values.csv') ui.scale = 3 ui.thetax = 1 ui.thetaz = 1 ui.canvas.configure(scrollregion = ui.canvas.bbox("all")) ui.window.bind('', left) ui.window.bind('', right) ui.window.bind('', up) ui.window.bind('', down) ui.window.bind('', wheel) ui.window.bind('', wheel) #ui.window.bind('', mouse_start) ui.canvas.bind('', mouse_end) ui.canvas.bind('', mouse_motion) ui.canvas.old_coords = None ui.canvas.just_the_tip = ui.canvas.create_rectangle(0, 0, 0, 0, fill='blue') ui.canvas.just_the_label = ui.canvas.create_text(0, 0) 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() ui.canvas.yview_moveto(.1) ui.canvas.update() def up(event): ui.thetax += .1 draw_scene() ui.canvas.create_text(100, 100, text="Up pressed") 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 mouse_motion(event): x, y = event.x, event.y draw_x = x draw_y = y id = ui.canvas.find_closest(x, y) n = ui.canvas.coords(id) if len(n) != 6: return text = "1250 = 100((1 -1.08 ^ -240) / 0.08) | 95%"#"Nearest Triangle: (%d, %d) (%d, %d) (%d, %d)" %(n[0], n[1], n[2], n[3], n[4], n[5])#"Now the tool tip auto sizes to fit text" width = Font(size=12, family="Hack").measure(text) if width + x > ui.width: draw_x = x - width - 30 if draw_x < 0: draw_x = 0 y += 20 ui.canvas.delete(ui.canvas.just_the_tip) ui.canvas.delete(ui.canvas.just_the_label) ui.canvas.just_the_tip = ui.canvas.create_rectangle(draw_x + 14, y, draw_x + width + 16, y + 20, fill='grey') ui.canvas.just_the_label = ui.canvas.create_text(draw_x + width / 2 + 15, y + 9, font="Hack 12", text=text) ui.canvas.update() #width = tk.font.Font(size=12, family="Times New Roman").measure("Some Tool Tip Nonsense") #heigth = ui.canvas.find_withtag(ui.canvas.just_the_label) #.winfo_height() #print(width) #ui.canvas.delete(ui.canvas.just_the_label) #ui.canvas.just_the_label = ui.canvas.create_text(x + width, y + y/2, text="Some tool tip nonsense") #ui.canvas.update() 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) #print("Z:\n%s" %(rotation_matrix_z)) rotation_matrix_x = Matrix4x4.get_x_rotation_matrix(ui.thetax) #print("X:\n%s" %(rotation_matrix_x)) translation = Matrix4x4.get_translation_matrix(Vector3d(0, 0, ui.scale)) #print("T:\n%s" %(translation)) world_matrix = Matrix4x4.get_identity_matrix() #print("W:\n%s" %(world_matrix)) world_matrix = rotation_matrix_z.multiply_matrix(rotation_matrix_x) #print("W * Z:\n%s" %(world_matrix)) world_matrix = world_matrix.multiply_matrix(translation) #print("W * T:\n%s" %(world_matrix)) 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)) color = compute(r) # 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 = color 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 ''' print("1: x:%f.2 y:%f.2" %(projected.coords.row1.x, projected.coords.row1.y)) print("2: x:%f.2 y:%f.2" %(projected.coords.row2.x, projected.coords.row2.y)) print("3: x:%f.2 y:%f.2" %(projected.coords.row3.x, projected.coords.row3.y)) print() ''' 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[0], r[1], r[2]), outline=from_rgb(0, 255, 0)) ui.canvas.update() #ui.canvas.after(100, draw_scene) def from_rgb(r, b, g): return "#%02x%02x%02x" %(r, g, b) def compute(r): r = r * 0.38 b = r g = r * 1.6 if g > 255: g = 255 return (int(r), int(g), int(b)) main()