from v_math import * import graphics_engine as gh class Camera: def __init__(self, position:Vector3, pitch:float, yaw:float, focalLenth:float=1, nearClip=0.01): self.position, self.pitch, self.yaw, self.focalLenth, self.nearClip = position, pitch, yaw, focalLenth, nearClip def getForward(self): return Vector3(-sin(self.yaw), 0, cos(self.yaw)) def getRight(self): return Vector3(cos(self.yaw), 0, sin(self.yaw)) def getLookAt(self): return Vector3(-sin(self.yaw)*cos(self.pitch), sin(self.pitch), cos(self.yaw)*cos(self.pitch)) def edgePlaneIntersection(edge:Edge3, planeNormal:Vector3, planePoint:Vector3): u = edge.v2.sub(edge.v1) dot = dot3(planeNormal, u) if abs(dot) < 1e-5: return None w = edge.v1.sub(planePoint) si = -dot3(planeNormal, w) / dot u = u.mulK(si) return edge.v1.add(u) def clip(edge:Edge3, camera:Camera, planeNormal:Vector3): planePoint = camera.position.add(planeNormal.mulK(camera.nearClip)) dotV1 = dot3(planePoint.sub(edge.v1), planeNormal) dotV2 = dot3(planePoint.sub(edge.v2), planeNormal) if dotV1 <= 0 and dotV2 <= 0: return edge elif dotV1 > 0 and dotV2 > 0: return None elif dotV1 > 0: return Edge3(edgePlaneIntersection(edge, planeNormal, planePoint), edge.v2) else: return Edge3(edge.v1, edgePlaneIntersection(edge, planeNormal, planePoint)) def drawMesh(mesh:list[Edge3], color, camera:Camera): lookAt = camera.getLookAt() for edge in mesh: edge = clip(edge, camera, lookAt) if edge: gh.drawEdge(edge .translate(camera.position.opposite()) .rotationY(camera.yaw) .rotationX(camera.pitch) .projection(camera.focalLenth) .toScreen(), color)