/// <summary> /// Creates a new PickResult. /// </summary> /// <param name="ray">Ray used in the test</param> /// <param name="target">Target object</param> /// <param name="boundingIntersection">The bounding intersection record.</param> public PickResult(Ray ray, IPickable target, BoundingIntersectionRecord boundingIntersection) { _ray = ray; _target = target; _boundRecord = boundingIntersection; _primRecord = null; }
/// <summary> /// Tests where on the volume the ray intersects, if it does. Uses the /// Liang-Barsky clipping algorithm as described by David Eberly. /// </summary> /// <param name="ray">Ray to test</param> /// <param name="result">The intersection result</param> public override void IntersectsWhere(ref Ray ray, out BoundingIntersectionRecord result) { Vector3 rDir = ray.Direction; Vector3 rOrigin = ray.Origin; Vector3 diff; Vector3.Subtract(ref rOrigin, ref m_center, out diff); float t0 = float.NegativeInfinity; float t1 = float.PositiveInfinity; bool notCulled = Clip(rDir.X, -diff.X - m_extents.X, ref t0, ref t1) && Clip(-rDir.X, diff.X - m_extents.X, ref t0, ref t1) && Clip(rDir.Y, -diff.Y - m_extents.Y, ref t0, ref t1) && Clip(-rDir.Y, diff.Y - m_extents.Y, ref t0, ref t1) && Clip(rDir.Z, -diff.Z - m_extents.Z, ref t0, ref t1) && Clip(-rDir.Z, diff.Z - m_extents.Z, ref t0, ref t1); if (notCulled && (!float.IsNegativeInfinity(t0) || !float.IsPositiveInfinity(t1))) { if (t1 > t0) { Vector3 p0; Vector3.Multiply(ref rDir, t0, out p0); Vector3.Add(ref p0, ref rOrigin, out p0); IntersectionRecord rec1 = new IntersectionRecord(p0, t0); Vector3 p1; Vector3.Multiply(ref rDir, t1, out p1); Vector3.Add(ref p1, ref rOrigin, out p1); IntersectionRecord rec2 = new IntersectionRecord(p1, t1); result = new BoundingIntersectionRecord(rec1, rec2); return; } Vector3 p; Vector3.Multiply(ref rDir, t0, out p); Vector3.Add(ref p, ref rOrigin, out p); IntersectionRecord rec = new IntersectionRecord(p, t0); result = new BoundingIntersectionRecord(rec); return; } result = new BoundingIntersectionRecord(); }
/// <summary> /// Adds a ray and target to test an intersection. If the target is pickable, /// and an intersection exists, the records are added to the query. /// </summary> /// <param name="ray">Ray to test with</param> /// <param name="pickable">Target to test against</param> /// <returns>True if an intersection was found, false otherwise.</returns> public bool AddPick(Ray ray, IPickable pickable) { if (pickable == null) { return(false); } if (pickable.IsPickable) { BoundingVolume bv = pickable.WorldBounding; BoundingIntersectionRecord bvRecord = new BoundingIntersectionRecord(); PrimitiveIntersectionRecord primRecord = new PrimitiveIntersectionRecord(); if (bv != null) { bv.IntersectsWhere(ref ray, out bvRecord); } else { return(false); } if (bvRecord.IntersectionCount > 0 && _primitivePickingEnabled) { primRecord = pickable.IntersectsPrimitivesWhere(ray); if (primRecord.IntersectionCount > 0) { _results.Add(new PickResult(ray, pickable, bvRecord, primRecord)); _sorted = false; return(true); } } else if (bvRecord.IntersectionCount > 0) { _results.Add(new PickResult(ray, pickable, bvRecord)); _sorted = false; return(true); } } return(false); }
public override void IntersectsWhere(ref Ray ray, out BoundingIntersectionRecord result) { throw new System.NotImplementedException(); }
/// <summary> /// Tests where on the volume the ray intersects, if it does. /// </summary> /// <param name="ray">Ray to test</param> /// <param name="result">The intersection result</param> public abstract void IntersectsWhere(ref Ray ray, out BoundingIntersectionRecord result);
/// <summary> /// Tests where on the sphere the ray intersects, if it does. /// </summary> /// <param name="ray">Ray to test</param> /// <param name="result">The intersection result</param> public override void IntersectsWhere(ref Ray ray, out BoundingIntersectionRecord result) { Vector3 diff; Vector3 rOrigin = ray.Origin; Vector3 rDir = ray.Direction; Vector3.Subtract(ref rOrigin, ref m_center, out diff); float a, a1, discr, sqrt; Vector3.Dot(ref diff, ref diff, out a); a -= m_radius * m_radius; //Check if we're inside the sphere, if so then the result must have //one exit point if (a <= 0.0f) { Vector3.Dot(ref rDir, ref diff, out a1); discr = (a1 * a1) - a; sqrt = MathHelper.Sqrt(discr); //Calc the distance and exit point float dist = sqrt - a1; Vector3 p; Vector3.Multiply(ref rDir, dist, out p); Vector3.Add(ref p, ref rOrigin, out p); IntersectionRecord rec = new IntersectionRecord(p, dist); result = new BoundingIntersectionRecord(rec); return; } Vector3.Dot(ref rDir, ref diff, out a1); if (a1 >= 0.0f) { //No intersections result = new BoundingIntersectionRecord(); return; } discr = a1 * a1 - a; if (discr < 0.0f) { //No intersections result = new BoundingIntersectionRecord(); return; } else if (discr >= MathHelper.ZeroTolerance) { //Entry and exit exist sqrt = MathHelper.Sqrt(discr); float dist1 = System.Math.Abs(-a1 - sqrt); float dist2 = System.Math.Abs(-a1 + sqrt); Vector3 p1; Vector3.Multiply(ref rDir, dist1, out p1); Vector3.Add(ref p1, ref rOrigin, out p1); IntersectionRecord rec1 = new IntersectionRecord(p1, dist1); Vector3 p2; Vector3.Multiply(ref rDir, dist2, out p2); Vector3.Add(ref p2, ref rOrigin, out p2); IntersectionRecord rec2 = new IntersectionRecord(p2, dist2); result = new BoundingIntersectionRecord(rec1, rec2); return; } //The ray intersects the sphere at exactly one point. float dis = -a1; Vector3 point; Vector3.Multiply(ref rDir, dis, out point); Vector3.Add(ref point, ref rOrigin, out point); IntersectionRecord rec0 = new IntersectionRecord(point, dis); result = new BoundingIntersectionRecord(rec0); return; }