def __init__(self, position: Vector = Vector(), focal_length: float = 500, viewport_offset: Vector = Vector()): self.position = position.copy(label="camera") self.rotation = Quaternion.identity() self.bearing = Vector(z=1) self.bearing.projection = Vector(z=1) self.view_port = viewport_offset.copy(label="view_port") self.view_port.z = focal_length self.C = Vector(x=cos(0), y=cos(0), z=cos(0)) self.S = Vector(x=sin(0), y=sin(0), z=sin(0))
class Mesh: def __init__(self, *triangles: Vector): assert (len(triangles) % 3 == 0), "incorrect number of points for triangles" self.rotation = Vector() self.center = Vector() self.viewportPosition = Vector() self.vertices = triangles self.triangles = [] i = 0 while i < len(triangles): self.triangles.append( Triangle(self.vertices[i], self.vertices[i + 1], self.vertices[i + 2])) i += 3 def set_center(self, center: Vector): self.center = center def draw(self, canvas: Canvas, debug=False): for triangle in self.triangles: triangle.draw(canvas) if debug: canvas.create_text(self.viewportPosition.projection.x, self.viewportPosition.projection.y, text="Center = {}\nRotation = {}".format( self.center, self.rotation)) for vertex in self.vertices: vertex.draw(canvas) def translate(self, v: Vector): self.center.translate(v) def translate_projections(self, v: Vector): seen = [] self.viewportPosition.projection.translate(v) for vertex in self.vertices: if vertex in seen: continue vertex.projection.translate(v) seen.append(vertex) def rotate(self, rotation: Quaternion) -> Mesh: seen = [] for vertex in self.vertices: if vertex in seen: continue v = rotation.rotate(vertex) vertex.move_to(v) seen.append(vertex) return self def scale(self, scale_factor: float) -> Mesh: seen = [] for vertex in self.vertices: if vertex in seen: continue v = vertex * scale_factor vertex.move_to(v) seen.append(vertex) return self def project_to(self, camera: Camera): seen = [] for vertex in self.vertices: if vertex in seen: continue camera.project(point=vertex, mesh_position=self.center) seen.append(vertex) camera.project(point=self.viewportPosition, mesh_position=self.center) def copy(self, offset: Vector = Vector()) -> Mesh: vertices = [p.copy() for p in self.vertices] m = Mesh(*vertices) m.set_center(self.center.copy()) m.translate(offset) return m @staticmethod def import_from(file_path: str) -> Mesh: f = open(file_path, "r") vertex_regex = re.compile( "v\\s(-?[.0-9]+)\\s(-?[.0-9]+)\\s(-?[.0-9]+)") triangle_regex = re.compile("f\\s(\\d+)\\s(\\d+)\\s(\\d+)") vertices = [] triangles = [] lines = f.readlines() for line in lines: line_type = line[0] if line_type == "#": continue # line is comment elif line_type == "o": pass # mesh name ignored elif line_type == "v": groups = vertex_regex.search(line).groups() vertex = Vector(x=float(groups[0]), y=float(groups[1]), z=float(groups[2])) vertices.append(vertex) elif line_type == "s": pass # Smooth shading ignored elif line_type == "f": groups = triangle_regex.search(line).groups() triangles.append(vertices[int(groups[0]) - 1]) triangles.append(vertices[int(groups[1]) - 1]) triangles.append(vertices[int(groups[2]) - 1]) else: print("ignored unknown format line {}".format(line)) return Mesh(*triangles)
# Cube(cube_size=cubeSize / 2, origin=Vector(y=-(cubeSize + cubeSize / 2))), # Cube(cube_size=cubeSize / 2, origin=Vector(x=(cubeSize + cubeSize / 2))), # Cube(cube_size=cubeSize / 2, origin=Vector(x=-(cubeSize + cubeSize / 2))), # Cube(cube_size=cubeSize / 2, origin=Vector(z=(cubeSize + cubeSize / 2))), # Cube(cube_size=cubeSize / 2, origin=Vector(z=-(cubeSize + cubeSize / 2))), ] [m.translate(origin) for m in meshes] entities = [Entity(geometry=m) for m in meshes] m.translate(Vector(x=cubeSize * 2)) scene = Scene() [scene.scene_root.add_entity(e) for e in entities] rot_speed = 180 / options.tickRate # deg/s = rot speed/tick cube_rot_axis = Vector(x=random(), y=random(), z=random()) point2 = cube_rot_axis.copy() * 100 point1 = -point2 rotationSpeeds = [ # None, # None, # None, # Quaternion.axis_angle(cube_rot_axis, angle=rot_speed), # Quaternion.axis_angle(Vector(x=1), angle=-rot_speed), # Quaternion.axis_angle(Vector(x=1), angle=rot_speed), # Quaternion.axis_angle(Vector(y=1), angle=rot_speed), # Quaternion.axis_angle(Vector(y=1), angle=-rot_speed), # Quaternion.axis_angle(Vector(z=1), angle=rot_speed), # Quaternion.axis_angle(Vector(z=1), angle=-rot_speed), ] camera_origin = cube.center + Vector(z=-cubeSize * 4)