public static bool Intersect(BoundingSphere a, Ray b, out object intersection) { RayIntersection d = new RayIntersection(); bool hit = Ray.Intersects(b, a, out d.Distance); intersection = d; return(hit); }
public static bool Intersect(Bounding.Box a, Bounding.Line b, out object intersection) { intersection = null; Vector3 v = b.P1 - b.P0; RayIntersection rOut = new RayIntersection(); return(Intersect(a, new Ray(b.P0, Vector3.Normalize(v)), out rOut) && rOut.Distance < v.Length()); }
// ---------------------------------------------------------------------------------------------- // -- Plane ------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------- public static bool Intersect(Plane a, Ray b, out object intersection) { float dist; bool i = Ray.Intersects(b, a, out dist); intersection = new RayIntersection { Distance = dist }; return(i); }
public static bool Intersect(BoundingBox a, Ray b, out object intersection) { float dist; bool i = BoundingBox.Intersects(a, b, out dist); intersection = new RayIntersection { Distance = dist }; return(i); }
public static bool Intersect(RectangleF a, Ray b, out object intersection) { intersection = null; float d; bool hit = BoundingBox.Intersects(new BoundingBox(new Vector3(a.X, a.Y, -float.MaxValue), new Vector3(a.X + a.Width, a.Y + a.Height, float.MaxValue)), b, out d); intersection = new RayIntersection { Distance = d }; return(hit); }
public static bool Intersect(object a, Ray b, float maxDistance, out RayIntersection rOut) { var bca = a as Bounding.Chain; if (bca != null) { return(ChainRayIntersect(bca, b, maxDistance, out rOut)); } else { return(Intersect <RayIntersection>(a, b, out rOut)); } }
// ---------------------------------------------------------------------------------------------- // -- Point ------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------- public static bool Intersect(Vector3 a, Ray b, out object intersection) { intersection = null; Vector3 v = a - b.Position; Vector3 vn = Vector3.Normalize(v); if (System.Math.Abs(vn.X - b.Direction.X) < 0.0001f && System.Math.Abs(vn.Y - b.Direction.Y) < 0.0001f && System.Math.Abs(vn.Z - b.Direction.Z) < 0.0001f) { intersection = new RayIntersection { Distance = v.Length() }; return(true); } return(false); }
// ---------------------------------------------------------------------------------------------- // -- Box --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------- public static bool Intersect(Bounding.Box a, Ray b, out object intersection) { var r = new RayIntersection(); intersection = r; Matrix invTransformation = Matrix.Invert(a.Transformation); var newRay = new Ray( Vector3.TransformCoordinate(b.Position, invTransformation), Vector3.Normalize(Vector3.TransformNormal(b.Direction, invTransformation))); bool hit = BoundingBox.Intersects(a.LocalBoundingBox, newRay, out r.Distance); if (hit) { var newPos = Vector3.TransformCoordinate(newRay.Position + newRay.Direction * r.Distance, a.Transformation); r.Distance = (newPos - b.Position).Length(); } return(hit); }
public static bool Intersect(Bounding.Cylinder a, Ray b, out object intersection) // CylHeight implemented { intersection = null; // check if ray is positioned inside cylinder if (Intersect(a, b.Position, out intersection)) { if (a.SolidRayIntersection) { intersection = new RayIntersection { Distance = 0 }; return(true); } else { return(false); } } if (b.Direction.X == 0 && b.Direction.Y == 0) { // check horizontal position if (Common.Math.ToVector2(a.Position - b.Position).Length() > a.Radius) { return(false); } // we can't use Ray.Intersects(ray, plane) since it also intersects with backsides of planes which we don't want unless SolidRayIntersection is set float zPos = b.Position.Z; float floor = a.Position.Z; float ceiling = floor + a.Height; if (b.Direction.Z < 0 && zPos > ceiling) { intersection = new RayIntersection { Distance = zPos - ceiling }; return(true); } else if (b.Direction.Z > 0 && zPos < floor) { intersection = new RayIntersection { Distance = floor - zPos }; return(true); } else if (!a.SolidRayIntersection) { return(false); } } // assume normalized ray direction vector // Ray: P + t*D // Cylinder: O (center), r (Radius) // |P + t*D - O| = radius // (P + t*D - O)(P + t*D - O) - r^2 = 0 // A*t^2 + B*t + C = 0 // with A: (D . D) // B: 2 * ((P - O) . D), // C: (P - O) . (P - O) - r^2 = = |P - O|^2 - r^2 // t = -B/(2A) +- sqrt(B^2/(4A^2) - C) Vector3 cylinderAxis = Vector3.UnitZ; Vector3 P = b.Position - Vector3.Dot(cylinderAxis, b.Position) * cylinderAxis; Vector3 D = b.Direction - Vector3.Dot(cylinderAxis, b.Direction) * cylinderAxis; Vector3 O = a.Position - Vector3.Dot(cylinderAxis, a.Position) * cylinderAxis; float A = Vector3.Dot(D, D); float B = 2 * Vector3.Dot(P - O, D); float C = Vector3.Dot(P - O, P - O) - a.Radius2; float x = -B / (2 * A); float y = x * x - C / A; if (y < 0) { return(false); // imaginary roots } float z = (float)System.Math.Sqrt(y); float t1 = x + z; float t2 = x - z; float minT = float.MaxValue; if (t1 < 0) { if (t2 < 0) { return(false); } minT = t2; } else { if (t2 < 0) { minT = t1; } else { minT = (float)System.Math.Min(t1, t2); } } // Check that the point is within cylinder vertical limits Vector3 Q = b.Position + minT * b.Direction; Vector3 PO = Q - a.Position; Vector3 POp = Vector3.Dot(PO, cylinderAxis) * Vector3.Normalize(cylinderAxis); var debug1 = Vector3.Dot(POp, cylinderAxis); var debug2 = POp.Length(); if (Vector3.Dot(POp, cylinderAxis) >= 0 && // not below POp.Length() <= a.Height) // not above { intersection = new RayIntersection { Distance = minT }; return(true); } else { return(false); } }
public static bool ChainRayIntersect(Bounding.Chain a, Ray b, float maxDistance, out RayIntersection intersection) { intersection = null; foreach (object o in a.Boundings) { if (!Intersect(o, b, out intersection)) { return(false); } else if (intersection.Distance > maxDistance) { return(false); } } return(true); }