diff --git a/Intersection/IntrLine2dBox2d.cs b/Intersection/IntrLine2dBox2d.cs
index 32054615941b22002652b43c257042373303b8ae..2d1ea372a5bd91bd523da42b01147e3275afde30 100644
--- a/Intersection/IntrLine2dBox2d.cs
+++ b/Intersection/IntrLine2dBox2d.cs
@@ -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) ?
diff --git a/Intersection/IntrLine3dBox3d.cs b/Intersection/IntrLine3dBox3d.cs
index 8d2fc7008949b3292efbf03eb25a2dbbd9fc9360..775c7ca3a1ed3c9676bad3c3c4f0f94f9c752f71 100644
--- a/Intersection/IntrLine3dBox3d.cs
+++ b/Intersection/IntrLine3dBox3d.cs
@@ -8,14 +8,127 @@
*/
+using Unity.Mathematics;
+
namespace Oroxylum
{
///
/// 相交计算结果:3d直线与3dBox
///
- 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
diff --git a/Math/Box3d.cs b/Math/Box3d.cs
index 45c3099c4f6b41bf1e568cfc1a8aa364ae513c02..76e5f0f8b662b90f99d2aee4b6f449238349397c 100644
--- a/Math/Box3d.cs
+++ b/Math/Box3d.cs
@@ -8,6 +8,8 @@
*/
+using Unity.Mathematics;
+
namespace Oroxylum
{
///
@@ -15,6 +17,13 @@ namespace Oroxylum
///
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);
+
}
diff --git a/Math/Line2d.cs b/Math/Line2d.cs
index 3781f885ed6ba8468e5ae8e680b5f0326509dd9a..c64a16f49f43f09540554f79056602875277476f 100644
--- a/Math/Line2d.cs
+++ b/Math/Line2d.cs
@@ -18,13 +18,16 @@ namespace Oroxylum
public struct Line2d
{
public float2 Origin;
- public float2 Direction;
+ ///
+ /// 直线方向,已经 normalize
+ ///
+ 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)