def __init__(self, file=None, vPos=(0, 0, 0), vRot=(0, 0, 0), vScale=(1, 1, 1)) -> None: self.vPos = vec3d(*vPos) self.initPos = vec3d(*vPos) self.scaleMat = makeScaleMat(*vScale) self.matTrans = makeMatTranslation(*vPos) self.rotate = False self.myupdatefunction = None if(file): self.mesh = mesh() self.mesh.loadmodelfromfile(f"./engine3d/models/{file}") self.ambientColor = vec3d(255, 255, 255)
def setCamera(self): # self.vLookDir = vec3d(0, 0, 1) vUp = vec3d(0, -1, 0) # vTarget = vec_add(self.vCamera, self.vLookDir) vTarget = vec3d(0, 0, 1) matCameraRotX = makeMatRotationX(self.pitch) matCameraRotY = makeMatRotationY(self.yaw) matCameraRotXY = matmatmul(matCameraRotX, matCameraRotY) # matCameraRot = matmatmul(matCameraRot, makeMatRotationX(self.pitch)) self.vLookDir = mulVecMat(vTarget, matCameraRotXY) # self.vLookDir = mulVecMat(self.vLookDir, matCameraRotX) vTarget = vec_add(self.vPos, self.vLookDir) matCamera = matPointAt(self.vPos, vTarget, vUp) self.matView = matQuickInverse(matCamera)
def __init__(self, vPos) -> None: super().__init__(None, vPos) self.yaw = 0 self.pitch = 0 self.roll = 0 # self.vCamera = self.vPos self.vLookDir = vec3d(0.0, 0.0, 0.0)
def fillTriangle_new(self, tri, **kwargs): v3, v2, v1 = sorted(tri.vertices, key=lambda v: v.y, reverse=False) # genericcase! v4 = vec3d(v3.x + (v2.y - v3.y) / (v1.y - v3.y) * (v1.x - v3.x), v2.y, 0) self.fillTopFlatTriangle(v1, v2, v4, **kwargs) self.fillBottomFlatTriangle(v2, v4, v3, **kwargs)
def __init__(self, width=800, height=600): super().__init__(width=800, height=600, background="black", highlightthickness=0) self.width = width self.height = height self.aspectratio = self.height / self.width # half width and height self.hWidth = width * 0.5 self.hHeight = height * 0.5 # self.img = PhotoImage(width=width, height=height) # self.create_image((width/2, height/2), # image=self.img, state="normal") # self.ZBuffer = Zbuffer(width, height) self.tstart = time.perf_counter() # self.vCamera = CAMERA_INIT # self.vLookDir = vec3d(0.0, 0.0, 0.0) # self.yaw = 0.0 # self.pitch = 0.0 self.Player = Player(None, (60, -20, 25)) self.Player.Camera.setup_viewport(self.aspectratio) self.vPointLight = vec3d(-6, -15.0, -50) # self.fillDetail = 5 # scanline resolution self.text_fps_id = self.create_text(50, 10, text=f"Press enter key to start", anchor="w", fill="#fff", font=("TKDefaultFont", 15)) # right facing snake, 3 body elements, 20px width self.bind_all("<Key>", self.on_key_press) self.bind("<Motion>", self.on_motion) # self.matRotZ = mat4x4() # self.matRotX = mat4x4() self.scene_objects = []
def draw(self, tick, engine): # called after update trianglesToRaster = [] for t in self.mesh.tris: triTransformed = triangle([0, 0, 0], [0, 0, 0], [0, 0, 0]) triTransformed.vertices[0] = mulVecMat( t.vertices[0], engine.matWorld) triTransformed.vertices[1] = mulVecMat( t.vertices[1], engine.matWorld) triTransformed.vertices[2] = mulVecMat( t.vertices[2], engine.matWorld) # use each sceneobjects cusom translation triTransformed.vertices[0] = vec_add( triTransformed.vertices[0], self.vPos) triTransformed.vertices[1] = vec_add( triTransformed.vertices[1], self.vPos) triTransformed.vertices[2] = vec_add( triTransformed.vertices[2], self.vPos) # scale object triTransformed.vertices[0] = mulVecMat( triTransformed.vertices[0], self.scaleMat) triTransformed.vertices[1] = mulVecMat( triTransformed.vertices[1], self.scaleMat) triTransformed.vertices[2] = mulVecMat( triTransformed.vertices[2], self.scaleMat) if(self.rotate): rotZ = makeMatRotationY(tick) triTransformed.vertices[0] = mulVecMat( triTransformed.vertices[0], rotZ) triTransformed.vertices[1] = mulVecMat( triTransformed.vertices[1], rotZ) triTransformed.vertices[2] = mulVecMat( triTransformed.vertices[2], rotZ) # get two edges on the triangle line1 = vec_sub( triTransformed.vertices[1], triTransformed.vertices[0]) line2 = vec_sub( triTransformed.vertices[2], triTransformed.vertices[0]) # cross product between line 1 and 2 => orthogonal vector normal = cross(line1, line2) normal = vec_normalize(normal) # get ray from triangle to camera vCameraRay = vec_sub( triTransformed.vertices[0], engine.Player.Camera.vPos) # check if this face should be visualized if(dot(normal, vCameraRay) < 0.0): triProjected = triangle((0, 0, 0), (0, 0, 0), (0, 0, 0)) # each triangle has 3 vertices # transform vertex coords to proj coords 3d->2d # compute correct color dp = dot(normal, vec_normalize(engine.vPointLight)) # dp = 1 color = copy(self.ambientColor) color = vec_mul(color, dp) color.x = int(color.x) # r channel color.y = int(color.y) # g channel color.z = int(color.z) # b channel # color.x = max(color.x, 0) # color.y = max(color.y, 0) # color.z = max(color.z, 0) triViewed = triangle((0, 0, 0), (0, 0, 0), (0, 0, 0)) triViewed.vertices[0] = mulVecMat( triTransformed.vertices[0], engine.Player.Camera.matView) triViewed.vertices[1] = mulVecMat( triTransformed.vertices[1], engine.Player.Camera.matView) triViewed.vertices[2] = mulVecMat( triTransformed.vertices[2], engine.Player.Camera.matView) triViewed.color = color nClippedTris = triangleClipAgainstPlane( vec3d(0, 0, .1), vec3d(0, 0, 1.0), triViewed) clippedTriangles = [] if(nClippedTris[0] >= 1): clippedTriangles = nClippedTris[1:] # print(f"len clipped tris:{nClippedTris[0]}") for clippedTriangle in clippedTriangles: # project triangle to 2d space triProjected = triangle((0, 0, 0), (0, 0, 0), (0, 0, 0)) triProjected.vertices[0] = mulVecMat( clippedTriangle.vertices[0], engine.Player.Camera.matProj) triProjected.vertices[1] = mulVecMat( clippedTriangle.vertices[1], engine.Player.Camera.matProj) triProjected.vertices[2] = mulVecMat( clippedTriangle.vertices[2], engine.Player.Camera.matProj) triProjected.vertices[0] = vec_div( triProjected.vertices[0], triProjected.vertices[0].w) triProjected.vertices[1] = vec_div( triProjected.vertices[1], triProjected.vertices[1].w) triProjected.vertices[2] = vec_div( triProjected.vertices[2], triProjected.vertices[2].w) triProjected.vertices[0].x *= -1 triProjected.vertices[0].y *= -1 triProjected.vertices[1].x *= -1 triProjected.vertices[1].y *= -1 triProjected.vertices[2].x *= -1 triProjected.vertices[2].y *= -1 # put it into view (offset it into x,y direction) vOffsetView = vec3d(1, 1, 0) triProjected.vertices[0] = vec_add( triProjected.vertices[0], vOffsetView) triProjected.vertices[1] = vec_add( triProjected.vertices[1], vOffsetView) triProjected.vertices[2] = vec_add( triProjected.vertices[2], vOffsetView) # scale into view triProjected.vertices[0].x *= engine.hWidth triProjected.vertices[0].y *= engine.hHeight triProjected.vertices[1].x *= engine.hWidth triProjected.vertices[1].y *= engine.hHeight triProjected.vertices[2].x *= engine.hWidth triProjected.vertices[2].y *= engine.hHeight # triProjected.color = copy(triViewed.color) triProjected.color = clippedTriangle.color trianglesToRaster.append(triProjected) # sort triangles in z axis for painters rendering trianglesToRaster = sorted( trianglesToRaster, key=functools.cmp_to_key(sort_triangles_by_z)) for t in trianglesToRaster: listTriangles = [] listTriangles.append(t) nNewTriangles = 1 for p in range(0, 4): nTrisToAdd = 0 while nNewTriangles > 0: test = listTriangles[0] del listTriangles[0] nNewTriangles -= 1 if(p == 0): nTrisToAdd = triangleClipAgainstPlane( vec3d(0, 0, 0), vec3d(0, 1, 0), test) elif(p == 1): nTrisToAdd = triangleClipAgainstPlane( vec3d(0, engine.height-1, 0), vec3d(0, -1, 0), test) elif(p == 2): nTrisToAdd = triangleClipAgainstPlane( vec3d(0, 0, 0), vec3d(1, 0, 0), test) elif(p == 3): nTrisToAdd = triangleClipAgainstPlane( vec3d(engine.width-1, 0, 0), vec3d(-1, 0, 0), test) if(nTrisToAdd[0] >= 1): for n in nTrisToAdd[1:]: listTriangles.append(n) nNewTriangles = len(listTriangles) for t in listTriangles: # t.color = vec3d(255, 255, 255) engine.create_polygon(t.vertices[0].x, t.vertices[0].y, t.vertices[1].x, t.vertices[1].y, t.vertices[2].x, t.vertices[2].y, fill=rgbToHex(t.color), tag="triangle")
def on_key_press(self, e): # model = self.create_cube() # print(e) if (e.keycode == 13): # S = SceneObject(0, 0, -5, "lowpolylevel.obj") S = SceneObject("lowpolylevel.obj", (0, 0, -5)) # model.loadmodelfromfile("./engine3d/models/lowpolylevel.obj") # model.ambientColor = vec3d(64, 224, 208) self.addModelToScene(S) S2 = SceneObject("box.obj", (0, -5, 0), vScale=(5, 5, 5)) S2.rotate = True S2.myupdatefunction = SceneObject.bounce S2.ambientColor = vec3d(64, 224, 208) self.addModelToScene(S2) S3 = SceneObject("box.obj", (5, -5, 0), vScale=(1, 1, 1)) self.addModelToScene(S3) # model = mesh() # model.loadmodelfromfile("./engine3d/models/box.obj") # model.ambientColor = vec3d(64, 224, 208) # # model.ambientColor = vec3d(255, 255, 255) # self.addModelToScene(model) return vForward = vec_mul(self.Player.Camera.vLookDir, 1) if (e.keycode == 40): # key down self.Player.Camera.vPos.y += 1 elif (e.keycode == 38): # key up self.Player.Camera.vPos.y -= 1 elif (e.keycode == 39): # key right self.Player.Camera.vPos.x += 1 elif (e.keycode == 37): # key left self.Player.Camera.vPos.x -= 1 elif (e.keycode == 68): # D self.Player.Camera.yaw -= .1 # self.yaw %= 6.28 if (self.Player.Camera.yaw <= 0): self.Player.Camera.yaw += 6.3 elif (e.keycode == 65): # A self.Player.Camera.yaw += .1 # self.yaw %= 6.28 if (self.Player.Camera.yaw >= 6.3): self.Player.Camera.yaw -= 6.3 elif (e.keycode == 87): # W self.Player.Camera.vPos = vec_add(self.Player.Camera.vPos, vForward) elif (e.keycode == 83): # S self.Player.Camera.vPos = vec_sub(self.Player.Camera.vPos, vForward) elif (e.keycode == 33): # pgup self.Player.Camera.pitch += .1 # self.pitch %= 6.28 elif (e.keycode == 34): # pgdown (tilt camera) self.Player.Camera.pitch -= .1 # self.pitch %= 6.28 elif (e.char == "r"): # reset self.Player.Camera.vPos = self.Player.vPos self.Player.Camera.yaw = 0 self.Player.Camera.pitch = 0 elif (e.keycode == 67): # c self.Player.Camera = self.Player.Camera2 self.Player.Camera.setup_viewport(self.aspectratio) self.Player.Camera.yaw = 5.5 self.Player.Camera.pitch = -0.6