Example #1
0
    def GetPlane(self):
        from PlaneMath import Plane
        boxplane = [Plane(1, 0, 0, self.Vertex[1].x), Plane(1, 0, 0, self.Vertex[0].x), Plane(0, 1, 0, self.Vertex[1].y),\
            Plane(0, 1, 0, self.Vertex[0].y), Plane(0, 0, 1, self.Vertex[1].z), Plane(0, 0, 1, self.Vertex[0].z)]

        if self.UseTransform:
            for i in range(0, 6):
                boxplane[i].TransformPlane(self.TransformMatrix)

        return boxplane[0], boxplane[1], boxplane[2], boxplane[3], boxplane[4], boxplane[5]
Example #2
0
    def IsBoundingBoxVertexInbound(self, sourceBox):
        from Vector3Math import Vector3
        from BoundingBoxMath import BoundingBox
        from Util import MathUtil

        v0 = Vector3(sourceBox.Vertex[0])
        v1 = Vector3(sourceBox.Vertex[1])

        countPlane = 0

        if self.FarNearDisabled:
            countPlane = 4
        else:
            countPlane = 6

        for i in countPlane:
            p = Plane(self.HexahedronPlane[i])
            if MathUtil.PlanePointDistance(p, v0.x, v0.y, v0.z) < 0:
                continue
            if MathUtil.PlanePointDistance(p, v1.x, v0.y, v0.z) < 0:
                continue
            if MathUtil.PlanePointDistance(p, v0.x, v1.y, v0.z) < 0:
                continue
            if MathUtil.PlanePointDistance(p, v1.x, v1.y, v0.z) < 0:
                continue
            if MathUtil.PlanePointDistance(p, v0.x, v0.y, v1.z) < 0:
                continue
            if MathUtil.PlanePointDistance(p, v1.x, v0.y, v1.z) < 0:
                continue
            if MathUtil.PlanePointDistance(p, v0.x, v1.y, v1.z) < 0:
                continue
            if MathUtil.PlanePointDistance(p, v1.x, v1.y, v1.z) < 0:
                continue
            return True
        return False
Example #3
0
    def Clear():
        from Vector3Math import Vector3
        from MatrixMath import Matrix
        from PlaneMath import Plane

        self.ViewProjMatrixCacheEnabled = False
        self.FarNearDisabled = False

        self.ViewProjMatrixCache = Matrix()

        self.HexahedronPlane = [
            Plane.New(),
            Plane.New(),
            Plane.New(),
            Plane.New(),
            Plane.New(),
            Plane.New()
        ]
        self.FrustumVertex = [Vector3.New(), Vector3.New(), Vector3.New(), Vector3.New(),\
            Vector3.New(), Vector3.New(), Vector3.New(), Vector3.New()]
        self.FrustumVertexsource = [Vector3(1,1,0), Vector3(-1,1,0), Vector3(-1,-1,0), Vector3(1,-1,0),\
        Vector3(1,1,1), Vector3(-1,1,1), Vector3(-1,-1,1), Vector3(1,-1,1)]
        self.FrustumID = 0
Example #4
0
    def FindNearCollision(self, posfrom0, posto0):
        from Vector3Math import Vector3
        from Util import Collision
        from PlaneMath import Plane

        posfrom = ToLocal(posfrom0)
        posto = ToLocal(posto0)
        
        planex0 = Plane(1, 0, 0, -self.Vertex[0].x)
        planex1 = Plane(1, 0, 0, -self.Vertex[1].x)
        planey0 = Plane(0, 1, 0, -self.Vertex[0].y)
        planey1 = Plane(0, 1, 0, -self.Vertex[1].y)
        planez0 = Plane(0, 0, 1, -self.Vertex[0].z)
        planez1 = Plane(0, 0, 1, -self.Vertex[1].z)
        
        intersection = Vector3.New()
        minDist = 1.7976931348623157e+308
        minIntersect = Vector3.New()
        collide = False

        colCheck, intersection = Collision.PlaneLineIntersectionFast(planex0, posfrom, posto)

        if colCheck:
            if (intersection.y >= self.Vertex[0].y and intersection.y <= self.Vertex[1].y) and (intersection.z >= self.Vertex[0].z and intersection.z <= self.Vertex[1].z):
                intersectionWorld = ToWorld(intersection)
                distv = intersectionWorld - posfrom0
                dist = distv.LengthSq()
                minIntersect = intersectionWorld
                collide = True
                minDist = dist


        colCheck, intersection = Collision.PlaneLineIntersectionFast(planex1, posfrom, posto)
        
        if colCheck:
            if ((intersection.y >= self.Vertex[0].y and intersection.y <= self.Vertex[1].y) and (intersection.z >= self.Vertex[0].z and intersection.z <= self.Vertex[1].z)):
                intersectionWorld = ToWorld(intersection)
                distv = intersectionWorld - posfrom0
                dist = distv.LengthSq()
                if collide == False or dist < minDist:
                    collide = True
                    minIntersect = intersectionWorld
                    minDist = dist

        colCheck, intersection = Collision.PlaneLineIntersectionFast(planey0, posfrom, posto)

        if colCheck:
            if ((intersection.x >= self.Vertex[0].x and intersection.x <= self.Vertex[1].x) and (intersection.z >= self.Vertex[0].z and intersection.z <= self.Vertex[1].z)):
                intersectionWorld = ToWorld(intersection)
                distv = intersectionWorld - posfrom0
                dist = distv.LengthSq()
                if collide == False or dist < minDist:
                    collide = True
                    minIntersect = intersectionWorld
                    minDist = dist

        colCheck, intersection = Collision.PlaneLineIntersectionFast(planey1, posfrom, posto)
        
        if colCheck:
            if ((intersection.x >= self.Vertex[0].x and intersection.x <= self.Vertex[1].x) and (intersection.z >= self.Vertex[0].z and intersection.z <= self.Vertex[1].z)):
                intersectionWorld = ToWorld(intersection)
                distv = intersectionWorld - posfrom0
                dist = distv.LengthSq()
                if collide == False or dist < minDist:
                    collide = True
                    minIntersect = intersectionWorld
                    minDist = dist

        colCheck, intersection = Collision.PlaneLineIntersectionFast(planez0, posfrom, posto)

        if colCheck:
            if ((intersection.x >= self.Vertex[0].x and intersection.x <= self.Vertex[1].x) and (intersection.y >= self.Vertex[0].y and intersection.y <= self.Vertex[1].y)):
                intersectionWorld = ToWorld(intersection)
                distv = intersectionWorld - posfrom0
                dist = distv.LengthSq()
                
                if collide == False or dist < minDist:
                    collide = True
                    minIntersect = intersectionWorld
                    minDist = dist

        colCheck, intersection = Collision.PlaneLineIntersectionFast(planez1, posfrom, posto)

        if colCheck:
            if ((intersection.x >= self.Vertex[0].x and intersection.x <= self.Vertex[1].x) and (intersection.y >= self.Vertex[0].y and intersection.y <= self.Vertex[1].y)):
                intersectionWorld = ToWorld(intersection)
                distv = intersectionWorld - posfrom0
                dist = distv.LengthSq()

                if collide == False or dist < minDist:
                    collide = True
                    minIntersect = intersectionWorld
                    minDist = dist
                    
        if collide:
            return True, minIntersect, minDist
        
        return False, Vector3.New(), 0
Example #5
0
    def ExtractFromProjectMatrix(self, viewProj, viewProjInverse):
        from MatrixMath import Matrix
        if ViewProjMatrixCacheEnabled:
            if ViewProjMatrixCache == viewProj:
                return

        self.FrustumID += 1
        self.ViewProjMatrixCacheEnabled = True
        selfViewProjMatrixCache = Matrix(viewProj)

        for i in range(0, 8):
            self.FrustumVertex[i] = Vector3.TransformCoord(
                self.FrustumVertexsource[i], viewProjInverse)

        self.HexahedronPlane[0] = Plane(viewProj.m[0][3] + viewProj.m[0][0],\
  viewProj.m[1][3] + viewProj.m[1][0],\
  viewProj.m[2][3] + viewProj.m[2][0],\
  viewProj.m[3][3] + viewProj.m[3][0])

        self.HexahedronPlane[0].Normalize()

        self.HexahedronPlane[1] = Plane(viewProj.m[0][3] - viewProj.m[0][0],\
  viewProj.m[1][3] - viewProj.m[1][0],\
  viewProj.m[2][3] - viewProj.m[2][0],\
  viewProj.m[3][3] - viewProj.m[3][0])
        self.HexahedronPlane[1].Normalize()

        #// index bug (code mistake) fix  2015.09.03
        self.HexahedronPlane[2] = Plane( viewProj.m[0][3] - viewProj.m[0][1],\
            viewProj.m[1][3] - viewProj.m[1][1],\
            viewProj.m[2][3] - viewProj.m[2][1],\
            viewProj.m[3][3] - viewProj.m[3][1])
        self.HexahedronPlane[2].Normalize()

        self.HexahedronPlane[3] = Plane(viewProj.m[0][3] + viewProj.m[0][1],\
            viewProj.m[1][3] + viewProj.m[1][1],\
            viewProj.m[2][3] + viewProj.m[2][1],\
            viewProj.m[3][3] + viewProj.m[3][1])
        self.HexahedronPlane[3].Normalize()

        self.HexahedronPlane[4] = Plane(viewProj.m[0][2], viewProj.m[1][2],
                                        viewProj.m[2][2], viewProj.m[3][2])
        self.HexahedronPlane[4].Normalize()

        self.HexahedronPlane[5] = Plane( viewProj.m[0][3] - viewProj.m[0][2],\
            viewProj.m[1][3] - viewProj.m[1][2],\
            viewProj.m[2][3] - viewProj.m[2][2],\
            viewProj.m[3][3] - viewProj.m[3][2])
        self.HexahedronPlane[5].Normalize()

        def IsPointInbound(self, x, y, z):
            from Vector3Math import Vector3
            from Util import MathUtil
            p = Vector3(x, y, z)

            if self.FarNearDisabled:
                if MathUtil.PlanePointDistance(self.HexahedronPlane[0], p) < 0 and\
                    MathUtil.PlanePointDistance(self.HexahedronPlane[1], p) < 0 and\
                    MathUtil.PlanePointDistance(self.HexahedronPlane[2], p) < 0 and\
                    MathUtil.PlanePointDistance(self.HexahedronPlane[3], p) < 0:
                    return True

                return False
            else:
                if (MathUtil.PlanePointDistance(self.HexahedronPlane[0], p) < 0 and\
                    MathUtil.PlanePointDistance(self.HexahedronPlane[1], p) < 0 and\
                    MathUtil.PlanePointDistance(self.HexahedronPlane[2], p) < 0 and\
                    MathUtil.PlanePointDistance(self.HexahedronPlane[3], p) < 0 and\
                    MathUtil.PlanePointDistance(self.HexahedronPlane[4], p)< 0 and\
                    MathUtil.PlanePointDistance(self.HexahedronPlane[5], p) < 0):
                    return True
                return False
Example #6
0
    def IsBoundingBoxCollide(self, sourceBox):
        from Vector3Math import Vector3
        from MatrixMath import Matrix
        from PlaneMath import Plane
        from BoundingBoxMath import BoundingBox

        # 1) frustum 어떤 하나의 면 밖으로 obb의 모든 점들이 모여 있다면 시야에 없음.(끝)
        if self.IsBoundingBoxOutbound(sourceBox):
            return False

        #   2) frustum 6면의 면 안쪽으로 obb의 점들이 모두 있다면 시야 안에 물체가 완전히 들어옴.(끝)
        #   3) obb점들의 일부는 frustum 6면의 안쪽에 있고 일부는 6면의 밖에 있다면 시야 안에 물체의 일부만 들어옴.(끝)

        if self.IsBoundingBoxVertexInbound(sourceBox):
            return True

        #  3) box의 어떤 하나의 면 밖으로 frustum의 모든 점들이 모여 있다면 시야에 없음.(끝)

        if self.FrustumVertex[0].x <= sourceBox.Vertex[0].x and\
            self.FrustumVertex[1].x <= sourceBox.Vertex[0].x and\
            self.FrustumVertex[2].x <= sourceBox.Vertex[0].x and\
            self.FrustumVertex[3].x <= sourceBox.Vertex[0].x and\
            self.FrustumVertex[4].x <= sourceBox.Vertex[0].x and\
            self.FrustumVertex[5].x <= sourceBox.Vertex[0].x and\
            self.FrustumVertex[6].x <= sourceBox.Vertex[0].x and\
            self.FrustumVertex[7].x <= sourceBox.Vertex[0].x:
            return False

        if self.FrustumVertex[0].x >= sourceBox.Vertex[1].x and\
            self.FrustumVertex[1].x >= sourceBox.Vertex[1].x and\
            self.FrustumVertex[2].x >= sourceBox.Vertex[1].x and\
            self.FrustumVertex[3].x >= sourceBox.Vertex[1].x and\
            self.FrustumVertex[4].x >= sourceBox.Vertex[1].x and\
            self.FrustumVertex[5].x >= sourceBox.Vertex[1].x and\
            self.FrustumVertex[6].x >= sourceBox.Vertex[1].x and\
            self.FrustumVertex[7].x >= sourceBox.Vertex[1].x:
            return False

        if self.FrustumVertex[0].y <= sourceBox.Vertex[0].y and\
            self.FrustumVertex[1].y <= sourceBox.Vertex[0].y and\
            self.FrustumVertex[2].y <= sourceBox.Vertex[0].y and\
            self.FrustumVertex[3].y <= sourceBox.Vertex[0].y and\
            self.FrustumVertex[4].y <= sourceBox.Vertex[0].y and\
            self.FrustumVertex[5].y <= sourceBox.Vertex[0].y and\
            self.FrustumVertex[6].y <= sourceBox.Vertex[0].y and\
            self.FrustumVertex[7].y <= sourceBox.Vertex[0].y:
            return False

        if self.FrustumVertex[0].y >= sourceBox.Vertex[1].y and\
            self.FrustumVertex[1].y >= sourceBox.Vertex[1].y and\
            self.FrustumVertex[2].y >= sourceBox.Vertex[1].y and\
            self.FrustumVertex[3].y >= sourceBox.Vertex[1].y and\
            self.FrustumVertex[4].y >= sourceBox.Vertex[1].y and\
            self.FrustumVertex[5].y >= sourceBox.Vertex[1].y and\
            self.FrustumVertex[6].y >= sourceBox.Vertex[1].y and\
            self.FrustumVertex[7].y >= sourceBox.Vertex[1].y:
            return False

        if self.FrustumVertex[0].z <= sourceBox.Vertex[0].z and\
            self.FrustumVertex[1].z <= sourceBox.Vertex[0].z and\
            self.FrustumVertex[2].z <= sourceBox.Vertex[0].z and\
            self.FrustumVertex[3].z <= sourceBox.Vertex[0].z and\
            self.FrustumVertex[4].z <= sourceBox.Vertex[0].z and\
            self.FrustumVertex[5].z <= sourceBox.Vertex[0].z and\
            self.FrustumVertex[6].z <= sourceBox.Vertex[0].z and\
            self.FrustumVertex[7].z <= sourceBox.Vertex[0].z:
            return False

        if self.FrustumVertex[0].z >= sourceBox.Vertex[1].z and\
            self.FrustumVertex[1].z >= sourceBox.Vertex[1].z and\
            self.FrustumVertex[2].z >= sourceBox.Vertex[1].z and\
            self.FrustumVertex[3].z >= sourceBox.Vertex[1].z and\
            self.FrustumVertex[4].z >= sourceBox.Vertex[1].z and\
            self.FrustumVertex[5].z >= sourceBox.Vertex[1].z and\
            self.FrustumVertex[6].z >= sourceBox.Vertex[1].z and\
            self.FrustumVertex[7].z >= sourceBox.Vertex[1].z:
            return False
        #  1) frustum 의 edge들이 obb의 면들과 충돌 한다면 시야 안의 물체가 일부만 들어옴.(끝)
        intersect = Vector3.New()
        for i in range(0, 12):
            check, intersect = sourceBox.GetLineIntersect(
                self.FrustumVertex[edgeCheckIndex[i][0]],
                self.FrustumVertex[edgeCheckIndex[i][1]])
            if check:
                return True

        countPlane = 0

        if self.FarNearDisabled:
            countPlane = 4
        else:
            countPlnae = 6

        # 2) box의 edge들이 frustum의 면들과 충돌 한다면 시야 안의 물체가 일부만 들어옴.(끝)
        boxVertex = [Vector3(sourceBox.Vertex[0].x, sourceBox.Vertex[0].y, sourceBox.Vertex[0].z),\
            Vector3(sourceBox.Vertex[0].x, sourceBox.Vertex[1].y, sourceBox.Vertex[0].z),\
            Vector3(sourceBox.Vertex[1].x, sourceBox.Vertex[1].y, sourceBox.Vertex[0].z),\
            Vector3(sourceBox.Vertex[1].x, sourceBox.Vertex[0].y, sourceBox.Vertex[0].z),\
            Vector3(sourceBox.Vertex[0].x, sourceBox.Vertex[0].y, sourceBox.Vertex[1].z),\
            Vector3(sourceBox.Vertex[0].x, sourceBox.Vertex[1].y, sourceBox.Vertex[1].z),\
            Vector3(sourceBox.Vertex[1].x, sourceBox.Vertex[1].y, sourceBox.Vertex[1].z),\
            Vector3(sourceBox.Vertex[1].x, sourceBox.Vertex[0].y, sourceBox.Vertex[1].z)]

        for i in range(0, 12):
            for k in countPlane:
                p = Plane(self.HexahedronPlane[k])
                # if plus point in bound
                # if minus point out of bound
                d0 = MathUtil.PlanePointDistance(
                    p, boxVertex[edgeCheckIndex[i][0]].x,
                    boxVertex[edgeCheckIndex[i][0]].y,
                    boxVertex[edgeCheckIndex[i][0]].z)
                d1 = MathUtil.PlanePointDistance(
                    p, boxVertex[edgeCheckIndex[i][1]].x,
                    boxVertex[edgeCheckIndex[i][1]].y,
                    boxVertex[edgeCheckIndex[i][1]].z)
                if d0 * d1 <= 0:
                    return True

        return False