예제 #1
0
    def findG(self, vertex, newVertex, face):
        c1 = newVertex.x
        c2 = newVertex.y
        c3 = newVertex.z

        u = face.V[0].Position.newVector(face.V[1].Position)
        u1 = u.x
        u2 = u.y
        u3 = u.z

        r = face.V[2].Position.newVector(face.V[1].Position)
        r1 = r.x
        r2 = r.y
        r3 = r.z
        
        s1 = face.V[0].Position.x
        s2 = face.V[0].Position.y
        s3 = face.V[0].Position.z

        g1 = vertex.Position.x - c1
        g2 = vertex.Position.y - c2
        g3 = vertex.Position.z - c3

        #miluju matlab
        try:
            t = (-(c1*r2*u3 - c1*r3*u2 - c2*r1*u3 + c2*r3*u1 + c3*r1*u2 - c3*r2*u1
                   + r1*s2*u3 - r1*s3*u2 - r2*s1*u3 + r2*s3*u1 + r3*s1*u2 - r3*s2*u1)/
                 (g1*r2*u3 - g1*r3*u2 - g2*r1*u3 + g2*r3*u1 + g3*r1*u2 - g3*r2*u1))
        except:
            t = 0

        G = Vector(c1 + t*g1,c2 + t*g2,c3 + t*g3)
        #delky trojuhelniku
        a = face.V[0].Position.pointLen(face.V[1].Position)
        b = face.V[0].Position.pointLen(face.V[2].Position)
        c = face.V[1].Position.pointLen(face.V[2].Position)

        #bod nalezi trojuhelniku
        if (G.pointLen(face.V[0].Position) <= a and
            G.pointLen(face.V[0].Position) <= b and
            G.pointLen(face.V[0].Position) <= c and
            G.pointLen(face.V[1].Position) <= a and
            G.pointLen(face.V[1].Position) <= b and
            G.pointLen(face.V[1].Position) <= c and
            G.pointLen(face.V[2].Position) <= a and
            G.pointLen(face.V[2].Position) <= b and
            G.pointLen(face.V[2].Position) <= c):
            return G
        

        return None
예제 #2
0
파일: mesh_old.py 프로젝트: KubaBoi/Snejky
class Mesh:
    def __init__(self, engine, x, y, z, faces):
        self.Position = Vector(x, y, z)
        self.Faces = faces
        self.mode = "faces"

        self.engine = engine

        self.showHitbox = True
        self.hitBox = []
        self.updateFaces()

    def updateMesh(self, camera):
        self.distance = self.Position.pointLen(camera.Position)
        self.updateFaces()

    def updateFaces(self):
        for face in self.Faces:
            face.updateFace(self, self.engine.camera, self.engine.light)
        self.updateHitbox()

    #vykresli vsechny steny, pokud jejich vzdalenost od kamery je mensi
    #nez vzdalenost domaci Mesh od kamery
    #face.distance <= (face.distance - self.distance) + self.distance
    def drawFaces(self, screen, camera):
        for face in self.Faces:
            if (face.render and self.mode == "faces"):
                A = face.A.drawVertex(camera)
                B = face.B.drawVertex(camera)
                C = face.C.drawVertex(camera)
                self.drawFace(screen, face, A, B, C)

            if (self.mode == "mesh"):  #vykresli oboji
                A = face.A.drawVertex(camera)
                B = face.B.drawVertex(camera)
                C = face.C.drawVertex(camera)
                self.drawFace(screen, face, A, B, C)
                #screen.draw([A,B,C], face.distance, (0,0,0), False)

    def drawFace(self, screen, face, A, B, C):
        if (face.actColor != None):
            screen.draw([A, B, C], face.distance + self.distance,
                        face.actColor, True)
            #screen.draw([A,B,C], face.distance, face.actColor, False)

    def sortFaces(self):
        for i in range(0, len(self.Faces) - 1):
            j = i + 1
            tmp = self.Faces[j]
            while (j > 0 and tmp.distance > self.Faces[j - 1].distance):
                self.Faces[j] = self.Faces[j - 1]
                j -= 1
            self.Faces[j] = tmp

    def checkCollisions(self, parent, v):
        self.hitBox[0] = self.hitBox[0] + v.x
        self.hitBox[3] = self.hitBox[3] + v.x
        self.hitBox[1] = self.hitBox[1] + v.y
        self.hitBox[4] = self.hitBox[4] + v.y
        self.hitBox[2] = self.hitBox[2] + v.z
        self.hitBox[5] = self.hitBox[5] + v.z

        answer = self.engine.CollideHitBox(self)
        if (answer[0] and answer[1].solid):
            answer[1].addForce(Force(v.x, v.y, v.z))
            newForce = self.createBounce(v, answer[1], 0.1)
            self.updateHitbox()
            i = 0
            while (self.engine.CollideHitBox(self)[0] == False):
                i += 0.1
                v = v.setVectorLeng(i)
                self.hitBox[0] = self.hitBox[0] + v.x
                self.hitBox[3] = self.hitBox[3] + v.x
                self.hitBox[1] = self.hitBox[1] + v.y
                self.hitBox[4] = self.hitBox[4] + v.y
                self.hitBox[2] = self.hitBox[2] + v.z
                self.hitBox[5] = self.hitBox[5] + v.z

            v = v.setVectorLeng(i - 0.1)

            return True, v, newForce
        if (answer[0]):  #koliduje, ale nema zastavit objekt
            pass
        else:
            parent.Position = self.Position
            return False, v

    def createBounce(self, v, component, slow):
        deltaX = abs(component.Position.x - self.Position.x)
        deltaY = abs(component.Position.y - self.Position.y)
        deltaZ = abs(component.Position.z - self.Position.z)

        if (deltaX >= deltaY and deltaX >= deltaZ):
            return Force(v.x * -slow, v.y * slow, v.z * slow, slow)
        if (deltaY >= deltaX and deltaY >= deltaZ):
            return Force(v.x * slow, v.y * -slow, v.z * slow, slow)
        if (deltaZ >= deltaX and deltaZ >= deltaY):
            return Force(v.x * slow, v.y * slow, v.z * -slow, slow)

    def drawHitbox(self, screen):
        if (self.showHitbox):
            for edge in self.hitBoxEdges:
                edge.drawEdge(screen)

    def updateHitbox(self):
        try:
            maxmin = [
                self.Position.x, self.Position.y, self.Position.z,
                self.Position.x, self.Position.y, self.Position.z
            ]  #maxX,maxY,maxZ,minX,minY,minZ
            for face in self.Faces:
                for vertex in [face.A, face.B, face.C]:
                    if (vertex.Position.x > maxmin[0]):  #nejvetsi X
                        maxmin[0] = vertex.Position.x
                    if (vertex.Position.x < maxmin[3]):  #nejmensi X
                        maxmin[3] = vertex.Position.x

                    if (vertex.Position.y > maxmin[1]):  #nejvetsi Y
                        maxmin[1] = vertex.Position.y
                    if (vertex.Position.y < maxmin[4]):  #nejmensi Y
                        maxmin[4] = vertex.Position.y

                    if (vertex.Position.z > maxmin[2]):  #nejvetsi Z
                        maxmin[2] = vertex.Position.z
                    if (vertex.Position.z < maxmin[5]):  #nejmensi Z
                        maxmin[5] = vertex.Position.z

            self.hitBox = maxmin

            self.hitBoxEdges = []
            self.hitBoxEdges.append(
                Edge(self.engine, Vertex(maxmin[0], maxmin[1], maxmin[2]),
                     Vertex(maxmin[3], maxmin[1], maxmin[2])))

            self.hitBoxEdges.append(
                Edge(self.engine, Vertex(maxmin[0], maxmin[1], maxmin[2]),
                     Vertex(maxmin[0], maxmin[1], maxmin[5])))

            self.hitBoxEdges.append(
                Edge(self.engine, Vertex(maxmin[3], maxmin[1], maxmin[5]),
                     Vertex(maxmin[0], maxmin[1], maxmin[5])))

            self.hitBoxEdges.append(
                Edge(self.engine, Vertex(maxmin[3], maxmin[1], maxmin[2]),
                     Vertex(maxmin[3], maxmin[1], maxmin[5])))
            #down
            self.hitBoxEdges.append(
                Edge(self.engine, Vertex(maxmin[0], maxmin[4], maxmin[2]),
                     Vertex(maxmin[3], maxmin[4], maxmin[2])))

            self.hitBoxEdges.append(
                Edge(self.engine, Vertex(maxmin[0], maxmin[4], maxmin[2]),
                     Vertex(maxmin[0], maxmin[4], maxmin[5])))

            self.hitBoxEdges.append(
                Edge(self.engine, Vertex(maxmin[3], maxmin[4], maxmin[5]),
                     Vertex(maxmin[0], maxmin[4], maxmin[5])))

            self.hitBoxEdges.append(
                Edge(self.engine, Vertex(maxmin[3], maxmin[4], maxmin[2]),
                     Vertex(maxmin[3], maxmin[4], maxmin[5])))
            #between
            self.hitBoxEdges.append(
                Edge(self.engine, Vertex(maxmin[0], maxmin[4], maxmin[2]),
                     Vertex(maxmin[0], maxmin[1], maxmin[2])))

            self.hitBoxEdges.append(
                Edge(self.engine, Vertex(maxmin[0], maxmin[4], maxmin[5]),
                     Vertex(maxmin[0], maxmin[1], maxmin[5])))

            self.hitBoxEdges.append(
                Edge(self.engine, Vertex(maxmin[3], maxmin[4], maxmin[2]),
                     Vertex(maxmin[3], maxmin[1], maxmin[2])))

            self.hitBoxEdges.append(
                Edge(self.engine, Vertex(maxmin[3], maxmin[4], maxmin[5]),
                     Vertex(maxmin[3], maxmin[1], maxmin[5])))

            return maxmin
        except:
            return None

    def changeColor(self, color):
        for face in self.Faces:
            face.color = color

    #metoda, ktera prenacte steny
    def setFaces(self, faces):
        self.Faces = faces
예제 #3
0
class Mesh:
    def __init__(self, engine, parent, x, y, z, faces):
        self.Position = Vector(x, y, z)
        self.Faces = faces
        self.mode = "faces"

        self.parent = parent
        
        self.engine = engine

        self.showHitbox = True
        self.updateFaces()
        self.updateRadius()

        self.collider = MeshCollider(self)

    def updateMesh(self, camera):
        self.distance = self.Position.pointLen(camera.Position)
        self.updateFaces()

    def updateFaces(self):
        for face in self.Faces:
            face.updateFace(self, self.engine.camera, self.engine.light)

    #vykresli vsechny steny, pokud jejich vzdalenost od kamery je mensi
    #nez vzdalenost domaci Mesh od kamery
    #face.distance <= (face.distance - self.distance) + self.distance
    def drawFaces(self, screen, camera):     
        for face in self.Faces:
            if (face.render and self.mode == "faces"):
                vertices = []
                for vert in face.V:
                    vertices.append(vert.drawVertex(camera))
                self.drawFace(screen, face, vertices)

            if (self.mode == "mesh"): #vykresli oboji
                A = face.A.drawVertex(camera)
                B = face.B.drawVertex(camera)
                C = face.C.drawVertex(camera)
                self.drawFace(screen, face, A, B, C)
                #screen.draw([A,B,C], face.distance, (0,0,0), False)
        #self.drawRadius(screen)


    def drawFace(self, screen, face, vertices):
        if (face.actColor != None):
            screen.draw(vertices, face.distance, face.actColor, True)
            #screen.draw(vertices, face.distance, face.actColor, False)

    def checkCollisions(self, parent, v):
        answer = self.engine.CollideRadius(self, self.radius,
                                           self.Position.addVectorReturn(v))
        
        if (answer[0]):            
            v, obj, collide = self.collider.collision(answer[1], v)

            if (collide):
                #v = Vector(v.Position.x, v.Position.y, v.Position.z)
                obj.addForce(Force(v.x/2,
                               v.y/2,
                               v.z/2))
                newForce = self.createBounce(v, obj, 0.5)
            else:
                newForce = Force(0,0,0)
            
            return collide, v, newForce

        if (answer[0]): #koliduje, ale nema zastavit objekt
            pass
        else:
            return False, v

    def createBounce(self, v, component, slow):
        deltaX = abs(component.Position.x - self.Position.x)
        deltaY = abs(component.Position.y - self.Position.y)
        deltaZ = abs(component.Position.z - self.Position.z)

        if (deltaX >= deltaY and deltaX >= deltaZ):
            return Force(v.x*-slow, v.y*slow, v.z*slow, slow)
        if (deltaY >= deltaX and deltaY >= deltaZ):
            return Force(v.x*slow, v.y*-slow, v.z*slow, slow)
        if (deltaZ >= deltaX and deltaZ >= deltaY):
            return Force(v.x*slow, v.y*slow, v.z*-slow, slow)
            
    #najde nejvzdalensejsi bod meshe a spocte jeho vzdalenost od stredu
    #najde polomer hitBoxu
    def updateRadius(self):
        self.radius = 0
        for face in self.Faces:
            for vector in face.v:
                newRadius = vector.length()
                if (newRadius > self.radius):
                    self.radius = newRadius
        

    def changeColor(self, color):
        for face in self.Faces:
            face.color = color

    #metoda, ktera prenacte steny
    def setFaces(self, faces):
        self.Faces = faces

    def drawRadius(self, screen):
        step = 40
        for i in range(0, 360, step):
            radian = i*math.pi/180
            
            x1 = self.Position.x + self.radius*math.sin(radian)
            y1 = self.Position.y + self.radius*math.cos(radian)

            radian = (i+step)*math.pi/180
            x2 = self.Position.x + self.radius*math.sin(radian)
            y2 = self.Position.y + self.radius*math.cos(radian)

            a1 = Vertex(x1,y1,self.Position.z)
            a2 = Vertex(x2,y2,self.Position.z)
            
            edge = Edge(self.engine, a1, a2).drawEdge(screen)
            
        for i in range(0, 360, step):
            radian = i*math.pi/180
            
            z1 = self.Position.z + self.radius*math.sin(radian)
            y1 = self.Position.y + self.radius*math.cos(radian)

            radian = (i+step)*math.pi/180
            z2 = self.Position.z + self.radius*math.sin(radian)
            y2 = self.Position.y + self.radius*math.cos(radian)

            a1 = Vertex(self.Position.x,y1,z1)
            a2 = Vertex(self.Position.x,y2,z2)
            
            edge = Edge(self.engine, a1, a2).drawEdge(screen)
            
        for i in range(0, 360, step):
            radian = i*math.pi/180
            
            x1 = self.Position.x + self.radius*math.sin(radian)
            z1 = self.Position.z + self.radius*math.cos(radian)

            radian = (i+step)*math.pi/180
            x2 = self.Position.x + self.radius*math.sin(radian)
            z2 = self.Position.z + self.radius*math.cos(radian)

            a1 = Vertex(x1,self.Position.y,z1)
            a2 = Vertex(x2,self.Position.y,z2)
            
            edge = Edge(self.engine, a1, a2).drawEdge(screen)