namespace DarkWynterEngine.Physics { #region Using Statements using System; using System.Collections.Generic; using System.Threading; using System.Diagnostics; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Storage; #endregion using Globals; /// /// BoundingVolume Class supports multiple bounding shapes to define an object in physical space. /// BoundingType is selected during initialization of the object. /// /// Collision Checking is handled by passing another Mass's BoundingVolume into the Intersect(BoundingVolume volume) method. /// No type-specific information is required during collision checks, b/c BoundingVolume handles this internally. /// public class BoundingVolume { /// /// Specifies which bounding object the BoundingVolume is using internally. /// Enums.BoundingType Type; // Bounding Objects : evenually split into seperate classes BoundingSphere sphere; BoundingBox box; BoundingFrustum frustum; Ray ray; // Bounding Object Properties : also seperate classes /// /// The Center of the bounding volume. Used by Sphere and Box /// public Vector3 center; /// /// The Radius of the bounding volume. Used by Sphere /// public float radius; /// /// The Scale of the bounding volume. Used by Box /// public Vector3 scale; #region Constructors /// /// Default /// public BoundingVolume() { center = new Vector3(0.0f); radius = 0.0f; } /// /// Support for Sphere intersections with volumes /// /// The Bounding Sphere to be used in our Bounding volume public BoundingVolume(BoundingSphere Sphere) { center = Sphere.Center; radius = Sphere.Radius; sphere = new BoundingSphere(Sphere.Center, Sphere.Radius); Type = Enums.BoundingType.Sphere; } /// /// Support for Box intersections with volumes /// /// Set this volume's parameters before or while passing in. public BoundingVolume(BoundingBox Box) { box = Box; Type = Enums.BoundingType.Box; } /// /// Support for Frustum intersections with volumes /// /// Set this volume's parameters before or while passing in. public BoundingVolume(BoundingFrustum Frustum) { frustum = Frustum; Type = Enums.BoundingType.Frustum; } /// /// Support for Ray intersections with volumes /// /// Set this volume's parameters before or while passing in. public BoundingVolume(Ray Ray) { ray = Ray; Type = Enums.BoundingType.Ray; } #endregion /// /// Returns true if this BoundingVolume intersects the incoming BoundingVolume. /// /// The BoundingVolume object to check for collision with this. /// True if the two volumes intersect public bool Intersects(BoundingVolume volume) { // Check this.Sphere if (this.Type == Enums.BoundingType.Sphere) { if (volume.Type == Enums.BoundingType.Sphere) { // .. with volume.Sphere if (this.sphere.Intersects(volume.sphere)) { return true; } } else if (volume.Type == Enums.BoundingType.Box) { // .. with volume.Box if (this.sphere.Intersects(volume.box)) { return true; } } else if (volume.Type == Enums.BoundingType.Frustum) { // .. with volume.Frustum if (this.sphere.Intersects(volume.frustum)) { return true; } } else if (volume.Type == Enums.BoundingType.Ray) { // .. with volume.Ray if (volume.ray.Intersects(this.sphere).HasValue) { return true; } } } // Check this.Box else if (this.Type == Enums.BoundingType.Box) { if (volume.Type == Enums.BoundingType.Sphere) { // .. with volume.Sphere if (this.box.Intersects(volume.sphere)) { return true; } } else if (volume.Type == Enums.BoundingType.Box) { // .. with volume.Box if (this.box.Intersects(volume.box)) { return true; } } else if (volume.Type == Enums.BoundingType.Frustum) { // .. with volume.Frustum if (this.box.Intersects(volume.frustum)) { return true; } } else if (volume.Type == Enums.BoundingType.Ray) { // .. with volume.Ray if (volume.ray.Intersects(this.box).HasValue) { return true; } } } // Check this.Frustum else if (this.Type == Enums.BoundingType.Frustum) { if (volume.Type == Enums.BoundingType.Sphere) { // .. with volume.Sphere if (this.frustum.Intersects(volume.sphere)) { return true; } } else if (volume.Type == Enums.BoundingType.Box) { // .. with volume.Box if (this.frustum.Intersects(volume.box)) { return true; } } else if (volume.Type == Enums.BoundingType.Frustum) { // .. with volume.Frustum if (this.frustum.Intersects(volume.frustum)) { return true; } } else if (volume.Type == Enums.BoundingType.Ray) { // .. with volume.Ray if (volume.ray.Intersects(this.frustum).HasValue) { return true; } } } // Check this.Ray else if (this.Type == Enums.BoundingType.Ray) { if (volume.Type == Enums.BoundingType.Sphere) { // .. with volume.Sphere if (this.ray.Intersects(volume.sphere).HasValue) { return true; } } else if (volume.Type == Enums.BoundingType.Box) { // .. with volume.Box if (this.ray.Intersects(volume.box).HasValue) { return true; } } else if (volume.Type == Enums.BoundingType.Frustum) { // .. with volume.Frustum if (this.ray.Intersects(volume.frustum).HasValue) { return true; } } else if (volume.Type == Enums.BoundingType.Ray) { // XNA does not support Ray-Ray intersections } } // Nothing has returned yet, so no collision occured.. return false; } /// /// Update the position of our bounding volume /// /// The current position of the object public void UpdateSphere(Vector3 currentPosition) { sphere.Center = currentPosition; } /// /// Update the position of our bounding volume /// /// The current position of the object /// Box Orientation /// Vector3 scale of the box public void UpdateBox(Vector3 currentPosition, Quaternion rotation, Vector3 boxScale) { box.Min = currentPosition - boxScale; box.Max = currentPosition + boxScale; // CLEAN: Add Rotational Math to support non-axis aligned boxes. // Needs to be multiplied by the rotation } /// /// Update the position of our bounding volume /// /// The current position of the object /// The last position of the object private void UpdateFrustum(Vector3 currentPosition, Vector3 lastPosition) { // Frustum cannot be assigned to; Create new if neccessary } /// /// Update the position of our bounding volume /// /// The current position of the object /// The current orientation of the Ray public void UpdateRay(Vector3 currentPosition, Vector3 currentDirection) { ray.Position = currentPosition; ray.Direction += currentDirection; } /// /// Draw our bounding volume if desired. /// public void Draw() { } } }