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()
{
}
}
}