using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.DirectX;
namespace MdxScene
{
// Define the BoundingBox as a struct, in order to use it on the stack (instead of the heap).
public struct BoundingBox
{
public BoundingBox(Vector3 minimalValues, Vector3 maximalValues)
{
FrontTopLeftPosition = new Vector3(minimalValues.X, maximalValues.Y, maximalValues.Z);
FrontTopRightPosition = new Vector3(maximalValues.X, maximalValues.Y, maximalValues.Z);
FrontBottomLeftPosition = new Vector3(minimalValues.X, minimalValues.Y, maximalValues.Z);
FrontBottomRightPosition = new Vector3(maximalValues.X, minimalValues.Y, maximalValues.Z);
BackTopLeftPosition = new Vector3(minimalValues.X, maximalValues.Y, minimalValues.Z);
BackTopRightPosition = new Vector3(maximalValues.X, maximalValues.Y, minimalValues.Z);
BackBottomLeftPosition = new Vector3(minimalValues.X, minimalValues.Y, minimalValues.Z);
BackBottomRightPosition = new Vector3(maximalValues.X, minimalValues.Y, minimalValues.Z);
}
// Hold the box's points' positions as different data-members (instead of an array),
// for preventing using a memory allocation for the BoundingBox's operations.
public Vector3 FrontTopLeftPosition;
public Vector3 FrontTopRightPosition;
public Vector3 FrontBottomLeftPosition;
public Vector3 FrontBottomRightPosition;
public Vector3 BackTopLeftPosition;
public Vector3 BackTopRightPosition;
public Vector3 BackBottomLeftPosition;
public Vector3 BackBottomRightPosition;
public void TransformCoordinates(Matrix transformationMatrix)
{
FrontTopLeftPosition.TransformCoordinate(transformationMatrix);
FrontTopRightPosition.TransformCoordinate(transformationMatrix);
FrontBottomLeftPosition.TransformCoordinate(transformationMatrix);
FrontBottomRightPosition.TransformCoordinate(transformationMatrix);
BackTopLeftPosition.TransformCoordinate(transformationMatrix);
BackTopRightPosition.TransformCoordinate(transformationMatrix);
BackBottomLeftPosition.TransformCoordinate(transformationMatrix);
BackBottomRightPosition.TransformCoordinate(transformationMatrix);
}
public bool IsOutOfBoundingBox(Vector3 boxMinimalValues, Vector3 boxMaximalValues)
{
return IsOutOfBoundingBox(boxMinimalValues.X, boxMinimalValues.Y, boxMinimalValues.Z,
boxMaximalValues.X, boxMaximalValues.Y, boxMaximalValues.Z);
}
public bool IsOutOfBoundingBox(float boxMinimalX, float boxMinimalY, float boxMinimalZ,
float boxMaximalX, float boxMaximalY, float boxMaximalZ)
{
float thisMinimalX = GetMinimalX();
float thisMinimalY = GetMinimalY();
float thisMinimalZ = GetMinimalZ();
float thisMaximalX = GetMaximalX();
float thisMaximalY = GetMaximalY();
float thisMaximalZ = GetMaximalZ();
bool isOutOfXView = thisMinimalX > boxMaximalX || thisMaximalX < boxMinimalX;
bool isOutOfYView = thisMinimalY > boxMaximalY || thisMaximalY < boxMinimalY;
bool isOutOfZView = thisMinimalZ > boxMaximalZ || thisMaximalZ < boxMinimalZ;
return isOutOfXView || isOutOfYView || isOutOfZView;
}
public float GetMinimalX()
{
return Min(FrontTopLeftPosition.X, FrontTopRightPosition.X, FrontBottomLeftPosition.X,
FrontBottomRightPosition.X, BackTopLeftPosition.X, BackTopRightPosition.X,
BackBottomLeftPosition.X, BackBottomRightPosition.X);
}
public float GetMinimalY()
{
return Min(FrontTopLeftPosition.Y, FrontTopRightPosition.Y, FrontBottomLeftPosition.Y,
FrontBottomRightPosition.Y, BackTopLeftPosition.Y, BackTopRightPosition.Y,
BackBottomLeftPosition.Y, BackBottomRightPosition.Y);
}
public float GetMinimalZ()
{
return Min(FrontTopLeftPosition.Z, FrontTopRightPosition.Z, FrontBottomLeftPosition.Z,
FrontBottomRightPosition.Z, BackTopLeftPosition.Z, BackTopRightPosition.Z,
BackBottomLeftPosition.Z, BackBottomRightPosition.Z);
}
public float GetMaximalX()
{
return Max(FrontTopLeftPosition.X, FrontTopRightPosition.X, FrontBottomLeftPosition.X,
FrontBottomRightPosition.X, BackTopLeftPosition.X, BackTopRightPosition.X,
BackBottomLeftPosition.X, BackBottomRightPosition.X);
}
public float GetMaximalY()
{
return Max(FrontTopLeftPosition.Y, FrontTopRightPosition.Y, FrontBottomLeftPosition.Y,
FrontBottomRightPosition.Y, BackTopLeftPosition.Y, BackTopRightPosition.Y,
BackBottomLeftPosition.Y, BackBottomRightPosition.Y);
}
public float GetMaximalZ()
{
return Max(FrontTopLeftPosition.Z, FrontTopRightPosition.Z, FrontBottomLeftPosition.Z,
FrontBottomRightPosition.Z, BackTopLeftPosition.Z, BackTopRightPosition.Z,
BackBottomLeftPosition.Z, BackBottomRightPosition.Z);
}
private float Min(float a, float b, float c, float d, float e, float f, float g, float h)
{
float minAB = a < b ? a : b;
float minCD = c < d ? c : d;
float minEF = e < f ? e : f;
float minGH = g < h ? g : h;
float minABCD = minAB < minCD ? minAB : minCD;
float minEFGH = minEF < minGH ? minEF : minGH;
return minABCD < minEFGH ? minABCD : minEFGH;
}
private float Max(float a, float b, float c, float d, float e, float f, float g, float h)
{
float maxAB = a > b ? a : b;
float maxCD = c > d ? c : d;
float maxEF = e > f ? e : f;
float maxGH = g > h ? g : h;
float maxABCD = maxAB > maxCD ? maxAB : maxCD;
float maxEFGH = maxEF > maxGH ? maxEF : maxGH;
return maxABCD > maxEFGH ? maxABCD : maxEFGH;
}
}
}