private void GetBoundingBox(ref Matrix3x3 o, out BoundingBox boundingBox)
{
#if !WINDOWS
boundingBox = new BoundingBox();
#endif
//Sample the local directions from the matrix, implicitly transposed.
var rightDirection = new Vector3(o.M11, o.M21, o.M31);
var upDirection = new Vector3(o.M12, o.M22, o.M32);
var backDirection = new Vector3(o.M13, o.M23, o.M33);
int right = 0, left = 0, up = 0, down = 0, backward = 0, forward = 0;
float minX = float.MaxValue, maxX = -float.MaxValue, minY = float.MaxValue, maxY = -float.MaxValue, minZ = float.MaxValue, maxZ = -float.MaxValue;
for (int i = 0; i < surfaceVertices.Count; i++)
{
float dotX, dotY, dotZ;
Vector3.Dot(ref rightDirection, ref surfaceVertices.Elements[i], out dotX);
Vector3.Dot(ref upDirection, ref surfaceVertices.Elements[i], out dotY);
Vector3.Dot(ref backDirection, ref surfaceVertices.Elements[i], out dotZ);
if (dotX < minX)
{
minX = dotX;
left = i;
}
if (dotX > maxX)
{
maxX = dotX;
right = i;
}
if (dotY < minY)
{
minY = dotY;
down = i;
}
if (dotY > maxY)
{
maxY = dotY;
up = i;
}
if (dotZ < minZ)
{
minZ = dotZ;
forward = i;
}
if (dotZ > maxZ)
{
maxZ = dotZ;
backward = i;
}
}
//Incorporate the collision margin.
Vector3.Multiply(ref rightDirection, meshCollisionMargin / (float)Math.Sqrt(rightDirection.Length()), out rightDirection);
Vector3.Multiply(ref upDirection, meshCollisionMargin / (float)Math.Sqrt(upDirection.Length()), out upDirection);
Vector3.Multiply(ref backDirection, meshCollisionMargin / (float)Math.Sqrt(backDirection.Length()), out backDirection);
var rightElement = surfaceVertices.Elements[right];
var leftElement = surfaceVertices.Elements[left];
var upElement = surfaceVertices.Elements[up];
var downElement = surfaceVertices.Elements[down];
var backwardElement = surfaceVertices.Elements[backward];
var forwardElement = surfaceVertices.Elements[forward];
Vector3.Add(ref rightElement, ref rightDirection, out rightElement);
Vector3.Subtract(ref leftElement, ref rightDirection, out leftElement);
Vector3.Add(ref upElement, ref upDirection, out upElement);
Vector3.Subtract(ref downElement, ref upDirection, out downElement);
Vector3.Add(ref backwardElement, ref backDirection, out backwardElement);
Vector3.Subtract(ref forwardElement, ref backDirection, out forwardElement);
//TODO: This could be optimized. Unnecessary transformation information gets computed.
Vector3 vMinX, vMaxX, vMinY, vMaxY, vMinZ, vMaxZ;
Matrix3x3.Transform(ref rightElement, ref o, out vMaxX);
Matrix3x3.Transform(ref leftElement, ref o, out vMinX);
Matrix3x3.Transform(ref upElement, ref o, out vMaxY);
Matrix3x3.Transform(ref downElement, ref o, out vMinY);
Matrix3x3.Transform(ref backwardElement, ref o, out vMaxZ);
Matrix3x3.Transform(ref forwardElement, ref o, out vMinZ);
boundingBox.Max.X = vMaxX.X;
boundingBox.Max.Y = vMaxY.Y;
boundingBox.Max.Z = vMaxZ.Z;
boundingBox.Min.X = vMinX.X;
boundingBox.Min.Y = vMinY.Y;
boundingBox.Min.Z = vMinZ.Z;
}