2
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
3.2 KiB
C#

using UnityEngine;
namespace Game
{
public static class UtilShape
{
public static bool IsOverlap(Shape shape, Shape circle,
Vector3 shapePos, Vector3 circlePos, Vector3 shapeDir, Vector3 circleDir)
{
if (circle.Type != EShapeType.Circle)
{
Util.Print("第二个形状参数必须为圆形:", circle.Type);
return false;
}
//检查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);
if (shapeYMin > circleYMax || shapeYMax < circleYMin)
{
return false;
}
//保底距离
var dist = Vector3.Distance(shapeCenter, circleCenter);
if (dist < 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;
if (shapeXMin > circleXMax || shapeXMax < circleXMin || shapeZMin > circleZMax || shapeZMax < circleZMin)
{
return false;
}
//检查形状
switch (shape.Type)
{
case EShapeType.Dot:
return true;
case EShapeType.Circle:
case EShapeType.Sector: //TODO
var distance = Vector3.Distance(shapeCenter, circleCenter);
return distance < shape.Radius + circle.Radius;
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);
}
return false;
}
private static bool RectCircleIntersection(float sizeX, float sizeY, float circleRadius, Vector3 circleCenter)
{
var distX = Mathf.Abs(circleCenter.x) - sizeX;
var distY = Mathf.Abs(circleCenter.z) - sizeY;
if (distX <= circleRadius && distY <= circleRadius)
{
if (distX <= 0f || distY <= 0f)
{
return true;
}
var cornerDistanceSquared = Mathf.Pow(distX, 2f) + Mathf.Pow(distY, 2f);
return cornerDistanceSquared <= Mathf.Pow(circleRadius, 2f);
}
return false;
}
}
}