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
def FromString(self, s): from Vector3Math import Vector3 from MatrixMath import Matrix if isinstance(s, bytes): vectorString = s.decode('utf-8') else: vectorString = s.encode().decode('utf-8') sp = vectorString.split(",") self.Vertex = [Vector3(float(sp[0]), float(sp[1]), float(sp[2])), Vector3(float(sp[3]), float(sp[4]), float(sp[5]))]
def Cover(self, *args): from Vector3Math import Vector3 if len(args) == 1: if isinstance(args[0], BoundingBox): sbox = ToLocal(args[0]) if self.Vertex[0].x > sbox.Vertex[0].x: self.Vertex[0].x = sbox.Vertex[0].x if self.Vertex[0].y > sbox.Vertex[0].y: self.Vertex[0].y = sbox.Vertex[0].y if self.Vertex[0].z > sbox.Vertex[0].z: self.Vertex[0].z = sbox.Vertex[0].z if self.Vertex[1].x < sbox.Vertex[1].x: self.Vertex[1].x = sbox.Vertex[1].x if self.Vertex[1].y > sbox.Vertex[1].y: self.Vertex[1].y = sbox.Vertex[1].y if self.Vertex[1].z < sbox.Vertex[1].z: self.Vertex[1].z = sbox.Vertex[1].z elif isinstance(args[0], Vector3): if self.Vertex[0].x > self.Vertex[1].x: self.Vertex[0] = Vector3(args[0]) self.Vertex[1] = Vector3(args[0]) else: self.Cover(args[0].x, args[0].y, args[0].z) elif len(args) == 3: if(self.Vertex[0] > x): self.Vertex[0].x = x if(self.Vertex[1] < x): self.Vertex[1].x = x if(self.Vertex[0] > y): self.Vertex[0].y = y if(self.Vertex[1] < y): self.Vertex[1].y = y if(self.Vertex[0] > z): self.Vertex[0].z = z if(self.Vertex[1] < z): self.Vertex[1].z = z
def DistanceFromPoint(self, point): from Vector3Math import Vector3 normal = Vector3(self.a, self.b, self.c) normal.Normalize() return point.Dot(normal) + self.d
def ToLocal(self, source): from Vector3Math import Vector3 from MatrixMath import Matrix if isinstance(source, Vector3): p = Vector3(pos) if UseTransform: p.TransformCoord(self.TransformMatrixInverse) return p elif isinstance(source, BoundingBox): usemat = True if source.UseTransform and self.UseTransform: mat = self.TransformMatrixInverse * source.TransformMatrix else: if source.UseTransform: mat = source.TransformMatrix else: if self.UseTransform: mat = TransformMatrixInverse else: usemat = False if usemat: source.Transform(mat) else: res = BoundingBox(source) return res
def Transform(self, mat): from Vector3Math import Vector3 v0, v1, v2, v3, v4, v5, v6, v7 = self.GetVertices() v = [v0, v1, v2, v3, v4, v5, v6, v7] box = BoundingBox.New() for i in range(0,8): nv = Vector3(v[i].TransformCoord(mat)) v[i] = Vector3(nv) box.Cover(nv) self.Vertex[0] = box.Vertex[0] self.Vertex[1] = box.Vertex[1] return box, v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]
def EulerDegreeToQuaternionFloat(Euler): from Vector3Math import Vector3 v = Vector3() result = Quaternion() v.x = Quaternion.DegreeToRadian(Euler.x) v.y = Quaternion.DegreeToRadian(Euler.y) v.z = Quaternion.DegreeToRadian(Euler.z) return result.EulerToQuaternionFloat(v)
def ProjectPoint(self, point): from Vector3Math import Vector3 dist = DistanceFromPoint(point) normal = Vector3(self.a, self.b, self.c) normal.Normalize() return point - dist * normal
def QuaternionToEulerDegreeFloat(quat): from Vector3Math import Vector3 v = Vector3() result = Quaternion() v = result.QuaternionToEulerFloat(quat) v.x = Quaternion.RadianToDegree(v.x) v.y = Quaternion.RadianToDegree(v.y) v.z = Quaternion.RadianToDegree(v.z) return v
def TransformPlane(plane, mat): from Vector3Math import Vector3 from Vector4Math import Vector4 from MatrixMath import Matrix o = Vector4(plane.a * plane.d, plane.b * plane.d, plane.c * plane.d, 1.0) n = (plane.a, plane.b, plane.c, 0.0) o.Transform(mat) mati = Matrix(mat) mati.Inverse() mat.Transpose() n.Transform(mati) on = Vector3(o.x, o.y, o.z) nn = Vector3(n.x, n.y, n.z) return Plane(n.x, n.y, n.z, on.Dot(nn))
def __init__(self, *args): from Vector3Math import Vector3 from MatrixMath import Matrix self.UseTransform = False self.TransformMatrix = Matrix.New() self.TransformMatrixInverse = Matrix.New() if len(args) == 6: self.Vertex = [Vector3(args[0], args[1], args[2]), Vector3(args[3], args[4], args[5])] elif len(args) == 1: if isinstance(args[0], BoundingBox): self.Vertex = [Vector3(args[0].Vertex[0]), Vector3(args[0].Vertex[1])] self.UseTransform = args[0].UseTransform self.TransformMatrix = args[0].TransformMatrix self.TransformMatrixInverse = args[0].TransformMatrixInverse elif len(args) == 2: if isinstance(args[0], Vector3) and isinstance(args[1], Vector3): self.Vertex = [args[0], args[1]] else: self.Vertex = [Vector3(1.7976931348623157e+308, 1.7976931348623157e+308, 1.7976931348623157e+308), Vector3(-1.7976931348623157e+308, -1.7976931348623157e+308, -1.7976931348623157e+308)]
def RotationAxis(pv, angle): from Vector3Math import Vector3 result = Quaternion.Identity() temp = Vector3(pv) temp.Normalize() sinangle2 = math.sin(angle / 2.0) cosangle2 = math.cos(angle / 2.0) result.x = sinangle2 * temp.x result.y = sinangle2 * temp.y result.z = sinangle2 * temp.z result.w = cosangle2 return result
def GetVertices(self): from Vector3Math import Vector3 v = [Vector3(self.Vertex[0].x, self.Vertex[0].y, self.Vertex[0].z),\ Vector3(self.Vertex[1].x, self.Vertex[0].y, self.Vertex[0].z),\ Vector3(self.Vertex[0].x, self.Vertex[1].y, self.Vertex[0].z),\ Vector3(self.Vertex[1].x, self.Vertex[1].y, self.Vertex[0].z),\ Vector3(self.Vertex[0].x, self.Vertex[0].y, self.Vertex[1].z),\ Vector3(self.Vertex[1].x, self.Vertex[0].y, self.Vertex[1].z),\ Vector3(self.Vertex[0].x, self.Vertex[1].y, self.Vertex[1].z),\ Vector3(self.Vertex[1].x, self.Vertex[1].y, self.Vertex[1].z)] if self.UseTransform: for i in range(0, 8): v[i] = ToWorld(v[i]) return v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]
def PlaneIntersectLine(self, p1, p2): from Vector3Math import Vector3 normal = Vector3(self.a, self.b, self.c) direction = p2 - p1 dotVal = Vector3.Dot(normal, direction) if dotVal == 0.0: return -1 temp = (self.d + Vector3.Dot(normal, p1)) / dot result = Vector3.New() result.x = p1.x - temp * direction.x result.y = p1.y - temp * direction.y result.z = p1.z - temp * direction.z return result
def IsPointOutbound(self, x, y, z): from Vector3Math import Vector3 p = Vector3(x, y, z) if self.FarNearDisabled: if MathUtil.PlanePointDistance(HexahedronPlane[0], p) > 0 or\ MathUtil.PlanePointDistance(HexahedronPlane[1], p) > 0 or\ MathUtil.PlanePointDistance(HexahedronPlane[2], p) > 0 or\ MathUtil.PlanePointDistance(HexahedronPlane[3], p) > 0: return True return False else: if MathUtil.PlanePointDistance(HexahedronPlane[0], p) > 0 or\ MathUtil.PlanePointDistance(HexahedronPlane[1], p) > 0 or\ MathUtil.PlanePointDistance(HexahedronPlane[2], p) > 0 or\ MathUtil.PlanePointDistance(HexahedronPlane[3], p) > 0 or\ MathUtil.PlanePointDistance(HexahedronPlane[4], p) > 0 or\ MathUtil.PlanePointDistance(HexahedronPlane[5], p) > 0: return True return False
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
def QuaternionToEulerFloat(self,quat): from Vector3Math import Vector3 result = Vector3() q0 = quat.w q1 = quat.y q2 = quat.x q3 = quat.z result.x = math.asin(2.0 * (q0 * q2 - q3 * q1)) result.y = math.atan2(2.0 * (q0 * q1 + q2 * q3), 1 - 2.0 * (math.pow(q1, 2) + math.pow(q2, 2))) result.z = math.atan2(2.0 * (q0 * q3 + q1 * q2), 1 - 2.0 * (math.pow(q2, 2) + math.pow(q3, 2))) if result.x < 0: result.x = 2.0 * math.pi + result.x if result.y < 0: result.y = 2.0 * math.pi + result.y if result.z < 0: result.z = 2.0 * math.pi + result.z return result
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
def OBBIntersect(self, arg): from Vector3Math import Vector3 PointsA = [Vector3.New(), Vector3.New(), Vector3.New(), Vector3.New(), Vector3.New(), Vector3.New(), Vector3.New(), Vector3.New()] PointsB = [Vector3.New(), Vector3.New(), Vector3.New(), Vector3.New(), Vector3.New(), Vector3.New(), Vector3.New(), Vector3.New()] CenterA = Vector3(0, 0, 0) CenterB = Vector3(0, 0, 0) PointsA[0], PointsA[1], PointsA[2], PointsA[3], PointsA[4], PointsA[5], PointsA[6], PointsA[7] = self.GetVertices() PointsB[0], PointsB[1], PointsB[2], PointsB[3], PointsB[4], PointsB[5], PointsB[6], PointsB[7] = arg.GetVertices() for i in range(0,8): CenterA += PointsA[i] CenterB += PointsB[i] #// 중점 CenterA /= 8 CenterB /= 8 #// A박스 3개 축 Ax = PointsA[1] - PointsA[0] Ax.Normalize(); Ay = PointsA[2] - PointsA[0] Ay.Normalize() Az = PointsA[4] - PointsA[0] Az.Normalize() #// B박스 3개 축 Bx = PointsB[1] - PointsB[0] Bx.Normalize() By = PointsB[2] - PointsB[0] By.Normalize() Bz = PointsB[4] - PointsB[0] Bz.Normalize() Wa = (PointsA[1] - PointsA[0]).Length() * 0.5 Ha = (PointsA[2] - PointsA[0]).Length() * 0.5 Da = (PointsA[4] - PointsA[0]).Length() * 0.5 Wb = (PointsB[1] - PointsB[0]).Length() * 0.5 Hb = (PointsB[2] - PointsB[0]).Length() * 0.5 Db = (PointsB[4] - PointsB[0]).Length() * 0.5 isParallel = False #// 중점사이의 거리 T = CenterB - CenterA cutoff = 0.999999 absC = [[0,0,0], [0,0,0], [0,0,0]] c = [[0,0,0], [0,0,0], [0,0,0]] d = [0,0,0] r0 = 0 r1 = 0 r = 0 #// 1 c[0][0] = Ax.Dot(Bx) c[0][1] = Ax.Dot(By) c[0][2] = Ax.Dot(Bz) for i in range(0,3): absC[0][i] = math.fabs(c[0][i]) if absC[0][i] > cutoff: isParallel = True d[0] = T.Dot(Ax) r = math.fabs(d[0]) r0 = Wa r1 = Wb * absC[0][0] + Hb * absC[0][1] + Db * absC[0][2] if r > r0 + r1: return False #// 2 c[1][0] = Ay.Dot(Bx) c[1][1] = Ay.Dot(By) c[1][2] = Ay.Dot(Bz) for i in range(0,3): absC[1][i] = math.fabs(c[1][i]) if (absC[1][i] > cutoff): isParallel = True d[1] = T.Dot(Ay) r = math.fabs(d[1]) r0 = Ha r1 = Wb * absC[1][0] + Hb * absC[1][1] + Db * absC[1][2] if r > r0 + r1: return False #// 3 c[2][0] = Az.Dot(Bx) c[2][1] = Az.Dot(By) c[2][2] = Az.Dot(Bz) for i in range(0,3): absC[2][i] = math.fabs(c[2][i]) if absC[2][i] > cutoff: isParallel = True d[2] = T.Dot(Az) r = math.fabs(d[2]) r0 = Da r1 = Wb * absC[2][0] + Hb * absC[2][1] + Db * absC[2][2] if r > r0 + r1: return False #// 4 r = math.fabs(T.Dot(Bx)) r0 = Wa * absC[0][0] + Ha * absC[1][0] + Da * absC[2][0] r1 = Wb if r > r0 + r1: return False #// 5 r = math.fabs(T.Dot(By)) r0 = Wa * absC[0][1] + Ha * absC[1][1] + Da * absC[2][1] r1 = Hb if r > r0 + r1: return False #// 6 r = math.fabs(T.Dot(Bz)) r0 = Wa * absC[0][2] + Ha * absC[1][2] + Da * absC[2][2] r1 = Db if r > r0 + r1: return False if isParallel == True: return True #// 7 r = math.fabs(d[2] * c[1][0] - d[1] * c[2][0]) r0 = Ha * absC[2][0] + Da * absC[1][0] r1 = Hb * absC[0][2] + Db * absC[0][1] if r > r0 + r1: return False #// 8 r = math.fabs(d[2] * c[1][1] - d[1] * c[2][1]) r0 = Ha * absC[2][1] + Da * absC[1][1] r1 = Wb * absC[0][2] + Db * absC[0][0] if r > r0 + r1: return False #// 9 r = math.fabs(d[2] * c[1][2] - d[1] * c[2][2]) r0 = Ha * absC[2][2] + Da * absC[1][2] r1 = Wb * absC[0][1] + Hb * absC[0][0] if r > r0 + r1: return False #// 10 r = math.fabs(d[0] * c[2][0] - d[2] * c[0][0]) r0 = Wa * absC[2][0] + Da * absC[0][0] r1 = Hb * absC[1][2] + Db * absC[1][1] if r > r0 + r1: return False #// 11 r = math.fabs(d[0] * c[2][1] - d[2] * c[0][1]) r0 = Wa * absC[2][1] + Da * absC[0][1] r1 = Wb * absC[1][2] + Db * absC[1][0] if r > r0 + r1: return False #// 12 r = math.fabs(d[0] * c[2][2] - d[2] * c[0][2]) r0 = Wa * absC[2][2] + Da * absC[0][2] r1 = Wb * absC[1][1] + Hb * absC[1][0] if r > r0 + r1: return False #// 13 r = math.fabs(d[1] * c[0][0] - d[0] * c[1][0]) r0 = Wa * absC[1][0] + Ha * absC[0][0] r1 = Hb * absC[2][2] + Db * absC[2][1] if r > r0 + r1: return False #// 14 r = math.fabs(d[1] * c[0][1] - d[0] * c[1][1]) r0 = Wa * absC[1][1] + Ha * absC[0][1] r1 = Wb * absC[2][2] + Db * absC[2][0] if r > r0 + r1: return False #// 15 r = math.fabs(d[1] * c[0][2] - d[0] * c[1][2]) r0 = Wa * absC[1][2] + Ha * absC[0][2] r1 = Wb * absC[2][1] + Hb * absC[2][0] if r > r0 + r1: return False return True
def MakeObjectFrustum(self, viewPos, objectBox): from Vector3Math import Vector3 from BoundingBoxMath import BoundingBox from Util import MathUtil from MatrixMath import Matrix pos = objectBox.GetCenter() dist = pos - viewPos distance = dist.Length() ydir = Vector3(0, 1, 0) posTop = pos + distance * Vector3(0, 1, 0) #//Vector3 posBottom = pos + distance * Vector3(0,-1,0); leftdir = Vector3.New() leftdir.Cross(dist) #//NXVec3Cross(&leftdir, &dist, &ydir); // right handed posLeft = pos + leftdir #//Vector3 posRight = pos - leftdir; viewMatrix = Matrix.New() #//NXMatrixLookAtLH(&viewMatrix, &viewPos, &pos, &ydir); viewMatrix = Matrix.LookAtLH(viewPos, pos, ydir) sumBox = BoundingBox.New() #//objectbox.Transform(buffer8, viewMatrix, NULL); sumBox, tv0, tv1, tv2, tv3, tv4, tv5, tv6, tv7 = objectBox.Transform( viewMatrix) buffer8 = [tv0, tv1, tv2, tv3, tv4, tv5, tv6, tv7] bv0 = Vector3(objectBox.Vertex[0]) bv1 = Vector3(objectBox.Vertex[1]) #// original reffere v0 = [Vector3( bv0.x, bv0.y, bv0.z ),\ Vector3( bv1.x, bv0.y, bv0.z ),\ Vector3( bv0.x, bv1.y, bv0.z ),\ Vector3( bv1.x, bv1.y, bv0.z ),\ Vector3( bv0.x, bv0.y, bv1.z ),\ Vector3 (bv1.x, bv0.y, bv1.z ),\ Vector3( bv0.x, bv1.y, bv1.z ),\ Vector3 (bv1.x, bv1.y, bv1.z )] topIndex = 0 max = -1.7976931348623157e+308 for i in range(0, 8): if buffer8[i].y > max: max = buffer8[i].y topIndex = i bottomIndex = 0 max = 1.7976931348623157e+308 for i in range(0, 8): if buffer8[i].y < max: max = buffer8[i].y bottomIndex = i leftIndex = 0 #//## 확인 사항 max = 1.7976931348623157e+308 for i in range(0, 8): if buffer8[i].x < max: max = buffer8[i].x leftIndex = i rightIndex = 0 #//## 확인 사항 max = -1.7976931348623157e+308 for i in range(0, 8): if buffer8[i].x > max: max = buffer8[i].x rightIndex = i self.HexahedronPlane[2] = MathUtil.GetPlaneFromPolygon( viewPos, posLeft, v0[topIndex]) self.HexahedronPlane[3] = MathUtil.GetPlaneFromPolygon( viewPos, posLeft, v0[bottomIndex]) self.HexahedronPlane[0] = MathUtil.GetPlaneFromPolygon( viewPos, posTop, v0[leftIndex]) self.HexahedronPlane[1] = MathUtil.GetPlaneFromPolygon( viewPos, posTop, v0[rightIndex]) self.FarNearDisabled = False return True
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
def ToWorld(self, pos): from Vector3Math import Vector3 p = Vector3(pos) if self.UseTransform: p.TransformCoord(self.TransformMatrix) return p
def ToLocalNormal(self, normal): from Vector3Math import Vector3 n = Vector3(normal) if self.UseTransform: n.TransformNormal(self.TransformMatrixInverse) return n