Esempio n. 1
0
    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)
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
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)
Esempio n. 5
0
    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 = []
Esempio n. 6
0
    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")
Esempio n. 7
0
    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