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