提交 dd0ba84c 编写于 作者: 魔术师Dix's avatar 魔术师Dix

更新3d直线与Box3d的相交检测,并优化部分代码;

上级 ce3c2002
......@@ -25,22 +25,15 @@ namespace Oroxylum
public IntrLine2dBox2d(Line2d line, Box2d box)
{
LineParam0 = 0;
LineParam1 = 0;
LineParam0 = -float.MaxValue;
LineParam1 = float.MaxValue;
Point0 = 0;
Point1 = 0;
Result = E_IntersectionResult.NotComputed;
Type = E_IntersectionType.Empty;
Quantity = 0;
float2 direction = line.Direction;
if (!direction.IsNormalized())
direction = math.normalize(direction);
LineParam0 = -float.MaxValue;
LineParam1 = float.MaxValue;
DoClipping(ref LineParam0, ref LineParam1, line.Origin, direction, box,
DoClipping(ref LineParam0, ref LineParam1, line.Origin, line.Direction, box,
true, ref Quantity, ref Point0, ref Point1, ref Type);
Result = (Type != E_IntersectionType.Empty) ?
......
......@@ -8,14 +8,127 @@
*/
using Unity.Mathematics;
namespace Oroxylum
{
/// <summary>
/// 相交计算结果:3d直线与3dBox
/// </summary>
public class IntrLine3dBox3d
public struct IntrLine3dBox3d
{
public int Quantity;
public E_IntersectionResult Result;
public E_IntersectionType Type;
public float LineParam0, LineParam1;
public float3 Point0;
public float3 Point1;
public IntrLine3dBox3d(Line3d line, Box3d box)
{
Result = E_IntersectionResult.NotComputed;
Type = E_IntersectionType.Empty;
LineParam0 = -float.MaxValue;
LineParam1 = float.MaxValue;
Point0 = 0;
Point1 = 1;
Quantity = 0;
DoClipping(ref LineParam0, ref LineParam1, line.Origin, line.Direction, box,
true, ref Quantity, ref Point0, ref Point1, ref Type);
Result = (Type != E_IntersectionType.Empty) ?
E_IntersectionResult.Intersects : E_IntersectionResult.NoIntersection;
}
public static bool DoClipping(ref float t0, ref float t1,
float3 origin, float3 direction,
Box3d box, bool solid, ref int quantity,
ref float3 point0, ref float3 point1,
ref E_IntersectionType intrType)
{
// Convert linear component to box coordinates.
float3 diff = origin - box.Center;
float3 BOrigin = new float3(
diff.Dot(box.AxisX),
diff.Dot(box.AxisY),
diff.Dot(box.AxisZ)
);
float3 BDirection = new float3(
direction.Dot(box.AxisX),
direction.Dot(box.AxisY),
direction.Dot(box.AxisZ)
);
double saveT0 = t0, saveT1 = t1;
bool notAllClipped =
Clip(+BDirection.x, -BOrigin.x - box.Extent.x, ref t0, ref t1) &&
Clip(-BDirection.x, +BOrigin.x - box.Extent.x, ref t0, ref t1) &&
Clip(+BDirection.y, -BOrigin.y - box.Extent.y, ref t0, ref t1) &&
Clip(-BDirection.y, +BOrigin.y - box.Extent.y, ref t0, ref t1) &&
Clip(+BDirection.z, -BOrigin.z - box.Extent.z, ref t0, ref t1) &&
Clip(-BDirection.z, +BOrigin.z - box.Extent.z, ref t0, ref t1);
if (notAllClipped && (solid || t0 != saveT0 || t1 != saveT1))
{
if (t1 > t0)
{
intrType = E_IntersectionType.LineSegment;
quantity = 2;
point0 = origin + t0 * direction;
point1 = origin + t1 * direction;
}
else
{
intrType = E_IntersectionType.Point;
quantity = 1;
point0 = origin + t0 * direction;
}
}
else
{
quantity = 0;
intrType = E_IntersectionType.Empty;
}
return intrType != E_IntersectionType.Empty;
}
private static bool Clip(float denom, float numer, ref float t0, ref float t1)
{
// Return value is 'true' if line segment intersects the current test
// plane. Otherwise 'false' is returned in which case the line segment
// is entirely clipped.
if (denom > 0)
{
if (numer - denom * t1 > OMath.ZeroTolerance)
{
return false;
}
if (numer > denom * t0)
{
t0 = numer / denom;
}
return true;
}
else if (denom < 0)
{
if (numer - denom * t0 > OMath.ZeroTolerance)
{
return false;
}
if (numer > denom * t1)
{
t1 = numer / denom;
}
return true;
}
else
{
return numer <= 0;
}
}
}
}
}
\ No newline at end of file
......@@ -8,6 +8,8 @@
*/
using Unity.Mathematics;
namespace Oroxylum
{
/// <summary>
......@@ -15,6 +17,13 @@ namespace Oroxylum
/// </summary>
public struct Box3d
{
public float3 Center;
public float3 Extent;
public float3 AxisX => new float3(1.0f, 0.0f, 0.0f);
public float3 AxisY => new float3(0.0f, 1.0f, 0.0f);
public float3 AxisZ => new float3(0.0f, 0.0f, 1.0f);
}
......
......@@ -18,13 +18,16 @@ namespace Oroxylum
public struct Line2d
{
public float2 Origin;
public float2 Direction;
/// <summary>
/// 直线方向,已经 normalize
/// </summary>
public float2 Direction;
public Line2d(float2 origin, float2 direction)
{
this.Origin = origin;
this.Direction = direction;
this.Direction = math.normalize(direction);
}
public static Line2d FromPoints(float2 p0, float2 p1)
......@@ -37,7 +40,7 @@ namespace Oroxylum
public float2 ClosestPoint(float2 p)
{
float t = (p - Origin).Dot(Direction);
return Origin + t * Direction;
return Origin + (t * Direction);
}
public double DistanceSquared(float2 p)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册