diff --git a/engine.py b/engine.py index 5e320ac..8542a54 100644 --- a/engine.py +++ b/engine.py @@ -1,5 +1,6 @@ from vectors import Vector2d, Vector3d, Vector4d from matrix import Matrix3x3 +from triangle import Triangle class Engine: def __init__(self, width, height): @@ -40,7 +41,5 @@ class Mesh: row0 = self.vertices[int(tmp[1]) - 1] row1 = self.vertices[int(tmp[2]) - 1] row2 = self.vertices[int(tmp[3]) - 1] - - tri = Matrix3x3(row0, row1, row2) - self.triangles.append(tri)#Vector3d(x - 1, y - 1, z - 1)) + self.triangles.append(Triangle(Matrix3x3(row0, row1, row2))) diff --git a/main.py b/main.py index 4e7f813..d156dd3 100644 --- a/main.py +++ b/main.py @@ -4,16 +4,31 @@ 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 = Mesh() +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') + #tris.load_obj_file('shuttle.obj') ui.thetax = 1 ui.window.bind('', left) @@ -31,8 +46,7 @@ def right(event): ui.theta += .01 def mouse_start(event): - #x, y = - ui.canvas.old_coords = event.x, event.y #x, y + ui.canvas.old_coords = event.x, event.y def mouse_end(event): x, y = ui.canvas.old_coords[0] - event.x, ui.canvas.old_coords[1] - event.y @@ -47,6 +61,8 @@ def mouse_end(event): ui.thetax += .01 else: ui.thetax -= .01 + + draw_scene() #ui.theta += x / ui.width def draw_scene(): @@ -76,7 +92,9 @@ def draw_scene(): rotation_matrix_x = Matrix4x4(row0, row1, row2, row3) - for tri in tris.triangles: + triangles = [] + + for tri in tris: # Rotate on the z-axis row0 = rotation_matrix_z.multiply_3d(tri.row0) row1 = rotation_matrix_z.multiply_3d(tri.row1) @@ -91,34 +109,76 @@ def draw_scene(): rotated_x = Matrix3x3(row0, row1, row2) # The offset into the screen translated = copy.copy(rotated_x) - translated.row0.z += 8.0 - translated.row1.z += 8.0 - translated.row2.z += 8.0 - # Scale into view - row0 = projection_matrix.multiply_3d(translated.row0) - row1 = projection_matrix.multiply_3d(translated.row1) - row2 = projection_matrix.multiply_3d(translated.row2) + translated.row0.z += 3.0 + translated.row1.z += 3.0 + translated.row2.z += 3.0 - projected = Matrix3x3(row0, row1, row2) + # Use cross-product to get the surface normal (a Vector3d) + x = translated.row1.x - translated.row0.x + y = translated.row1.y - translated.row0.y + z = translated.row1.z - translated.row0.z + line1 = Vector3d(x, y, z) - projected.row0.x += 1 - projected.row0.y += 1 - projected.row1.x += 1 - projected.row1.y += 1 - projected.row2.x += 1 - projected.row2.y += 1 - projected.row0.x *= .5 * ui.width - projected.row0.y *= .5 * ui.height - projected.row1.x *= .5 * ui.width - projected.row1.y *= .5 * ui.height - projected.row2.x *= .5 * ui.width - projected.row2.y *= .5 * ui.height + x = translated.row2.x - translated.row0.x + y = translated.row2.y - translated.row0.y + z = translated.row2.z - translated.row0.z + line2 = Vector3d(x, y, z) - coords = [projected.row0.x, projected.row0.y, projected.row1.x, projected.row1.y, projected.row2.x, projected.row2.y] - ui.canvas.create_polygon(coords, fill="", outline="black") + normal = line1.cross_product(line2) + + # Now we normalize the normal + w = math.sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z) + normal.x /= w + normal.y /= w + normal.z /= w + + # Do we display this triangle? + if normal.dot_product(translated.row0) < 0.0: + # Lighting + light = Vector3d(0, 0, -1) # Shining at the player. + + w = math.sqrt(light.x * light.x + light.y * light.y + light.z * light.z) + light.x /= w + light.y /= w + light.z /= w + + dot_product = normal.dot_product(light) + r = abs(int(255 * dot_product)) + + # Scale into view + row0 = projection_matrix.multiply_3d(translated.row0) + row1 = projection_matrix.multiply_3d(translated.row1) + row2 = projection_matrix.multiply_3d(translated.row2) + + projected = Matrix3x3(row0, row1, row2) + + projected.row0.x += 1 + projected.row0.y += 1 + projected.row1.x += 1 + projected.row1.y += 1 + projected.row2.x += 1 + projected.row2.y += 1 + projected.row0.x *= .5 * ui.width + projected.row0.y *= .5 * ui.height + projected.row1.x *= .5 * ui.width + projected.row1.y *= .5 * ui.height + projected.row2.x *= .5 * ui.width + projected.row2.y *= .5 * ui.height + + t = Triangle(projected) + t.color = r + triangles.append(t) + + for projected in triangles: + r = projected.color + coords = [projected.coords.row0.x, projected.coords.row0.y, projected.coords.row1.x, projected.coords.row1.y, projected.coords.row2.x, projected.coords.row2.y] + ui.canvas.create_polygon(coords, fill=from_rgb(r, r, r), outline="black") ui.canvas.update() - ui.canvas.after(100, draw_scene) + #ui.canvas.after(100, draw_scene) + +def from_rgb(r, b, g): + return "#%02x%02x%02x" %(r, g, b) main() diff --git a/triangle.py b/triangle.py new file mode 100644 index 0000000..cdb920c --- /dev/null +++ b/triangle.py @@ -0,0 +1,7 @@ +import vectors + +class Triangle: + def __init__(self, coords): + self.coords = coords # Matrix3x3 + self.object_id = None + self.color = None diff --git a/vectors.py b/vectors.py index 6746239..aad8106 100644 --- a/vectors.py +++ b/vectors.py @@ -17,7 +17,7 @@ class Vector3d: # Returns the 'normal'. x = self.y * vector3d.z - self.z * vector3d.y y = self.z * vector3d.x - self.x * vector3d.z - z = self.x * vectored.y - self.y * vector3d.x + z = self.x * vector3d.y - self.y * vector3d.x return Vector3d(x, y, z)