Author: alanmc
Date: 2007-01-13 10:50:32 -0500 (Sat, 13 Jan 2007)
New Revision: 70958

Modified:
   trunk/Mono.Xna/src/Microsoft.Xna.Framework/BoundingBox.cs
   trunk/Mono.Xna/src/Microsoft.Xna.Framework/BoundingSphere.cs
   trunk/Mono.Xna/src/Microsoft.Xna.Framework/Ray.cs
   trunk/Mono.Xna/src/Microsoft.Xna.Framework/Vector3.cs
Log:
Implementation complete for ray.Intersects(BoundingSphere) and 
boundingSphere.Intersects(Ray)

Modified: trunk/Mono.Xna/src/Microsoft.Xna.Framework/BoundingBox.cs
===================================================================
--- trunk/Mono.Xna/src/Microsoft.Xna.Framework/BoundingBox.cs   2007-01-13 
15:44:45 UTC (rev 70957)
+++ trunk/Mono.Xna/src/Microsoft.Xna.Framework/BoundingBox.cs   2007-01-13 
15:50:32 UTC (rev 70958)
@@ -201,7 +201,7 @@
 
         public Nullable<float> Intersects(Ray ray)
         {
-            throw new NotImplementedException();
+            return ray.Intersects(this);
         }
 
         public void Intersects(ref Ray ray, out Nullable<float> result)

Modified: trunk/Mono.Xna/src/Microsoft.Xna.Framework/BoundingSphere.cs
===================================================================
--- trunk/Mono.Xna/src/Microsoft.Xna.Framework/BoundingSphere.cs        
2007-01-13 15:44:45 UTC (rev 70957)
+++ trunk/Mono.Xna/src/Microsoft.Xna.Framework/BoundingSphere.cs        
2007-01-13 15:50:32 UTC (rev 70958)
@@ -223,7 +223,7 @@
 
         public Nullable<float> Intersects(Ray ray)
         {
-            throw new NotImplementedException();
+            return ray.Intersects(this);
         }
 
         public void Intersects(ref Ray ray, out Nullable<float> result)

Modified: trunk/Mono.Xna/src/Microsoft.Xna.Framework/Ray.cs
===================================================================
--- trunk/Mono.Xna/src/Microsoft.Xna.Framework/Ray.cs   2007-01-13 15:44:45 UTC 
(rev 70957)
+++ trunk/Mono.Xna/src/Microsoft.Xna.Framework/Ray.cs   2007-01-13 15:50:32 UTC 
(rev 70958)
@@ -35,112 +35,126 @@
     [TypeConverter("Microsoft.Xna.Framework.Design.RayConverter, 
Microsoft.Xna.Framework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ff")]
     public struct Ray : IEquatable<Ray>
     {
-        /// <summary>Specifies the Vector3 direction of the ray.</summary>
+        #region Public Fields
+
         public Vector3 Direction;
-        /// <summary>Specifies the Vector3 position of the ray.</summary>
+
         public Vector3 Position;
 
+        #endregion
 
-        /// <summary>Initializes a new instance of Ray.</summary>
-        /// <param name="position">Position of the ray.</param>
-        /// <param name="direction">Direction of the ray.</param>
+
+        #region Public Constructors
+
         public Ray(Vector3 position, Vector3 direction)
         {
             this.Position = position;
             this.Direction = direction;
         }
 
-        /// <summary>Compares two rays for inequality.</summary>
-        /// <param name="a">Source ray.</param>
-        /// <param name="b">Source ray.</param>
-        /// <returns>true if the rays are not equal; false otherwise.</returns>
-        public static bool operator !=(Ray a, Ray b)
-        {
-            return !a.Equals(b);
-        }
+        #endregion
 
-        /// <summary>Compares two rays for equality.</summary>
-        /// <param name="a">Source ray.</param>
-        /// <param name="b">Source ray.</param>
-        /// <returns>true if the rays are equal; false otherwise.</returns>
-        public static bool operator ==(Ray a, Ray b)
-        {
-            return a.Equals(b);
-        }
 
-        /// <summary>Returns a value that indicates whether the current 
instance is equal to a specified object.</summary>
-        /// <param name="obj">Object to make the comparison with.</param>
-        /// <returns>true if the current instance is equal to the specified 
object; false otherwise.</returns>
+        #region Public Methods
         public override bool Equals(object obj)
         {
             return (obj is Ray) ? this.Equals((Ray)obj) : false;
         }
 
-        /// <summary>Determines whether the specified System.Object is equal 
to the Ray.</summary>
-        /// <param name="other">The System.Object to compare with the current 
Ray.</param>
-        /// <returns>true if the specified System.Object is equal to the 
current Ray; false otherwise.</returns>
+        
         public bool Equals(Ray other)
         {
-#warning Is the direction normalised?
-            return Position.Equals(other.Position) && 
Direction.Equals(other.Direction);
+            return this.Position.Equals(other.Position) && 
this.Direction.Equals(other.Direction);
         }
 
-        /// <summary>Gets the hash code for this object.</summary>
-        /// <returns>Hash code for this object.</returns>
+        
         public override int GetHashCode()
         {
             return Position.GetHashCode() ^ Direction.GetHashCode();
         }
 
-        /// <summary>Determines whether the specified BoundingBox intersects 
with the Ray.</summary>
-        /// <param name="box">The BoundingBox to test.</param>
-        /// <returns>The position of intersection; otherwize null.</returns>
+        
         public float? Intersects(BoundingBox box)
         {
-            return box.Intersects(this);
+            float? result;
+            Intersects(ref box, out result);
+            return result;
         }
 
-        /// <summary>Determines whether the specified BoundingFrustum 
intersects with the Ray.</summary>
-        /// <param name="frustum">The BoundingFrustum to test.</param>
-        /// <returns>The position of intersection; otherwize null.</returns>
+
+        public void Intersects(ref BoundingBox box, out float? result)
+        {
+            throw new NotImplementedException();
+        }
+
+
         public float? Intersects(BoundingFrustum frustum)
         {
-#warning return null or throw exception?
-            if (frustum == null)
-                return null;
-
-            return frustum.Intersects(this);
+            throw new NotImplementedException();
         }
 
-        /// <summary>Determines whether the specified BoundingSphere 
intersects with the Ray.</summary>
-        /// <param name="sphere">The BoundingSphere to test.</param>
-        /// <returns>The position of intersection; otherwize null.</returns>
+
         public float? Intersects(BoundingSphere sphere)
         {
-            return sphere.Intersects(this);
+            float? result;
+            Intersects(ref sphere, out result);
+            return result;
         }
 
-        /// <summary>Determines whether the specified BoundingBox intersects 
with the Ray.</summary>
-        /// <param name="box">The BoundingBox to test.</param>
-        /// <param name="result">The position of intersection; otherwize 
null.</param>
-        public void Intersects(ref BoundingBox box, out float? result)
+
+        public void Intersects(ref BoundingSphere sphere, out float? result)
         {
-            result = Intersects(box);
+            // Find the vector between where the ray starts the the sphere's 
centre
+            Vector3 difference = sphere.Center - this.Position;
+
+            float differenceLengthSquared = difference.LengthSquared();
+            float sphereRadiusSquared = sphere.Radius * sphere.Radius;
+
+            float distanceAlongRay;
+
+            // If the distance between the ray start and the sphere's centre 
is less than
+            // the radius of the sphere, it means we've intersected. N.B. 
checking the LengthSquared is faster.
+            if (differenceLengthSquared < sphereRadiusSquared)
+            {
+                result = 0.0f;
+                return;
+            }
+
+            Vector3.Dot(ref this.Direction, ref difference, out 
distanceAlongRay);
+            // If the ray is pointing away from the sphere then we don't ever 
intersect
+            if (distanceAlongRay < 0)
+            {
+                result = null;
+                return;
+            }
+
+            // Next we kinda use Pythagoras to check if we are within the 
bounds of the sphere
+            // if x = radius of sphere
+            // if y = distance between ray position and sphere centre
+            // if z = the distance we've travelled along the ray
+            // if x^2 + z^2 - y^2 < 0, we do not intersect
+            float dist = sphereRadiusSquared + distanceAlongRay * 
distanceAlongRay - differenceLengthSquared;
+
+            result = (dist < 0) ? null : distanceAlongRay - 
(float?)Math.Sqrt(dist);
         }
 
-        /// <summary>Determines whether the specified BoundingSphere 
intersects with the Ray.</summary>
-        /// <param name="sphere">The BoundingSphere to test.</param>
-        /// <param name="result">The position of intersection; otherwize 
null.</param>
-        public void Intersects(ref BoundingSphere sphere, out float? result)
+
+        public static bool operator !=(Ray a, Ray b)
         {
-            result = Intersects(sphere);
+            return !a.Equals(b);
         }
 
-        /// <summary>Retrieves a string representation of the current 
instance.</summary>
-        /// <returns>String that represents the object.</returns>
+
+        public static bool operator ==(Ray a, Ray b)
+        {
+            return a.Equals(b);
+        }
+
+
         public override string ToString()
         {
-            return string.Format("Position:{0} Direction:{1}", 
this.Position.ToString(), Direction.ToString());
+            return string.Format("/{Position:{0} Direction:{1}/}", 
this.Position.ToString(), Direction.ToString());
         }
+        #endregion
     }
 }

Modified: trunk/Mono.Xna/src/Microsoft.Xna.Framework/Vector3.cs
===================================================================
--- trunk/Mono.Xna/src/Microsoft.Xna.Framework/Vector3.cs       2007-01-13 
15:44:45 UTC (rev 70957)
+++ trunk/Mono.Xna/src/Microsoft.Xna.Framework/Vector3.cs       2007-01-13 
15:50:32 UTC (rev 70958)
@@ -246,7 +246,9 @@
         /// <returns>The dot product of the two vectors.</returns>
         public static float Dot(Vector3 vector1, Vector3 vector2)
         {
-            return (((vector1.X * vector2.X) + (vector1.Y * vector2.Y)) + 
(vector1.Z * vector2.Z));
+            float result;
+            Dot(ref vector1, ref vector2, out result);
+            return result;
         }
 
         /// <summary>Calculates the dot product of two vectors.</summary>
@@ -255,7 +257,7 @@
         /// <param name="result">The dot product of the two vectors.</param>
         public static void Dot(ref Vector3 vector1, ref Vector3 vector2, out 
float result)
         {
-            result = Dot(vector1, vector2);
+            result = (vector1.X * vector2.X) + (vector1.Y * vector2.Y) + 
(vector1.Z * vector2.Z);
         }
         
         /// <summary>Creates a unit vector from the specified vector.</summary>

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to