Exemple #1
0
 /// <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;
 }
Exemple #2
0
        /// <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();
        }
Exemple #3
0
        /// <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();
 }
Exemple #5
0
 /// <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);
Exemple #6
0
        /// <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;
        }