|
|
|
|
@ -4,8 +4,7 @@ namespace Game
|
|
|
|
|
{
|
|
|
|
|
public static class UtilShape
|
|
|
|
|
{
|
|
|
|
|
public static bool IsOverlap(Shape shape, Shape circle,
|
|
|
|
|
Vector3 shapePos, Vector3 circlePos, Vector3 shapeDir, Vector3 circleDir)
|
|
|
|
|
public static bool IsOverlap(Shape shape, Vector3 shapePos, Vector3 shapeDir, Shape circle, Vector3 circlePos)
|
|
|
|
|
{
|
|
|
|
|
if (circle.Type != EShapeType.Circle)
|
|
|
|
|
{
|
|
|
|
|
@ -14,9 +13,8 @@ namespace Game
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//检查Y
|
|
|
|
|
var (shapeCenter, circleCenter) = (shapePos + shape.Offset, circlePos + circle.Offset);
|
|
|
|
|
var (shapeYMin, shapeYMax) = (shapeCenter.y, shapeCenter.y + shape.Height);
|
|
|
|
|
var (circleYMin, circleYMax) = (circleCenter.y, circleCenter.y + circle.Height);
|
|
|
|
|
var (shapeYMin, shapeYMax) = (shapePos.y, shapePos.y + shape.Height);
|
|
|
|
|
var (circleYMin, circleYMax) = (circlePos.y, circlePos.y + circle.Height);
|
|
|
|
|
|
|
|
|
|
if (shapeYMin > circleYMax || shapeYMax < circleYMin)
|
|
|
|
|
{
|
|
|
|
|
@ -24,22 +22,22 @@ namespace Game
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//保底距离
|
|
|
|
|
var dist = Vector3.Distance(shapeCenter, circleCenter);
|
|
|
|
|
if (dist < 0.01f)
|
|
|
|
|
var distance = Vector3.Distance(shapePos, circlePos);
|
|
|
|
|
if (distance < 0.01f)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//检查AABB
|
|
|
|
|
var (shapeAABB, circleAABB) = (shape.GetAABB(shapeDir), circle.GetAABB(circleDir));
|
|
|
|
|
var shapeXMin = shapeAABB.x + shapeCenter.x;
|
|
|
|
|
var shapeXMax = shapeAABB.y + shapeCenter.x;
|
|
|
|
|
var shapeZMin = shapeAABB.z + shapeCenter.z;
|
|
|
|
|
var shapeZMax = shapeAABB.w + shapeCenter.z;
|
|
|
|
|
var circleXMin = circleAABB.x + circleCenter.x;
|
|
|
|
|
var circleXMax = circleAABB.y + circleCenter.x;
|
|
|
|
|
var circleZMin = circleAABB.z + circleCenter.z;
|
|
|
|
|
var circleZMax = circleAABB.w + circleCenter.z;
|
|
|
|
|
var (shapeAABB, circleAABB) = (shape.GetAABB(shapeDir), circle.GetAABB(Vector3.zero));
|
|
|
|
|
var shapeXMin = shapeAABB.x + shapePos.x;
|
|
|
|
|
var shapeXMax = shapeAABB.y + shapePos.x;
|
|
|
|
|
var shapeZMin = shapeAABB.z + shapePos.z;
|
|
|
|
|
var shapeZMax = shapeAABB.w + shapePos.z;
|
|
|
|
|
var circleXMin = circleAABB.x + circlePos.x;
|
|
|
|
|
var circleXMax = circleAABB.y + circlePos.x;
|
|
|
|
|
var circleZMin = circleAABB.z + circlePos.z;
|
|
|
|
|
var circleZMax = circleAABB.w + circlePos.z;
|
|
|
|
|
|
|
|
|
|
if (shapeXMin > circleXMax || shapeXMax < circleXMin || shapeZMin > circleZMax || shapeZMax < circleZMin)
|
|
|
|
|
{
|
|
|
|
|
@ -47,25 +45,45 @@ namespace Game
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//检查形状
|
|
|
|
|
Vector3 circleCenterNew;
|
|
|
|
|
switch (shape.Type)
|
|
|
|
|
{
|
|
|
|
|
case EShapeType.Dot:
|
|
|
|
|
return true;
|
|
|
|
|
return distance < circle.Radius;
|
|
|
|
|
case EShapeType.Circle:
|
|
|
|
|
case EShapeType.Sector: //TODO
|
|
|
|
|
var distance = Vector3.Distance(shapeCenter, circleCenter);
|
|
|
|
|
return distance < shape.Radius + circle.Radius;
|
|
|
|
|
case EShapeType.Sector:
|
|
|
|
|
if (distance > shape.Radius + circle.Radius)
|
|
|
|
|
return false;
|
|
|
|
|
circleCenterNew = CircleCenterNew(circlePos, shapePos, shapeDir);
|
|
|
|
|
return SectorCircle(shape.Radius, shape.Angle, circle.Radius, circleCenterNew);
|
|
|
|
|
case EShapeType.Box:
|
|
|
|
|
var dir = circleCenter - shapeCenter;
|
|
|
|
|
var circleCenterNew = Quaternion.FromToRotation(shapeDir, Vector3.right) * dir;
|
|
|
|
|
var (shapeSizeX, shapeSizeY) = (SizeX: shape.SizeX, SizeY: shape.SizeY);
|
|
|
|
|
return RectCircleIntersection(shapeSizeX, shapeSizeY, circle.Radius, circleCenterNew);
|
|
|
|
|
circleCenterNew = CircleCenterNew(circlePos, shapePos, shapeDir);
|
|
|
|
|
return RectCircle(shape.SizeX, shape.SizeY, circle.Radius, circleCenterNew);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static bool RectCircleIntersection(float sizeX, float sizeY, float circleRadius, Vector3 circleCenter)
|
|
|
|
|
private static Vector3 CircleCenterNew(Vector3 circlePos, Vector3 shapePos, Vector3 shapeDir)
|
|
|
|
|
{
|
|
|
|
|
var dir = circlePos - shapePos;
|
|
|
|
|
return Quaternion.FromToRotation(shapeDir, Vector3.right) * dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static bool SectorCircle(float radius, float angle, float circleRadius, Vector3 circleCenter)
|
|
|
|
|
{
|
|
|
|
|
if (circleCenter.z < 0)
|
|
|
|
|
circleCenter.z = -circleCenter.z;
|
|
|
|
|
var dist = circleCenter.magnitude; //到原点的距离
|
|
|
|
|
if (dist < circleRadius)
|
|
|
|
|
return true;
|
|
|
|
|
var circleAngle = Mathf.Asin(circleRadius / dist);
|
|
|
|
|
var circleRot = Util.Vec3ToRot(circleCenter);
|
|
|
|
|
return !(circleRot - circleAngle > angle / 2);//边缘情况不管
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static bool RectCircle(float sizeX, float sizeY, float circleRadius, Vector3 circleCenter)
|
|
|
|
|
{
|
|
|
|
|
var distX = Mathf.Abs(circleCenter.x) - sizeX;
|
|
|
|
|
var distY = Mathf.Abs(circleCenter.z) - sizeY;
|
|
|
|
|
|