public override bool RayTest(ref Ray ray, ref RigidTransform transform, float maximumLength, out RayHit hit)
{
hit = new RayHit();
Quaternion conjugate;
Quaternion.Conjugate(ref transform.Orientation, out conjugate);
Vector3 localOrigin;
Vector3.Subtract(ref ray.Position, ref transform.Position, out localOrigin);
Vector3.Transform(ref localOrigin, ref conjugate, out localOrigin);
Vector3 localDirection;
Vector3.Transform(ref ray.Direction, ref conjugate, out localDirection);
Vector3 normal = Toolbox.ZeroVector;
float temp, tmin = 0, tmax = maximumLength;
if (Math.Abs(localDirection.X) < Toolbox.Epsilon && (localOrigin.X < -halfWidth || localOrigin.X > halfWidth))
return false;
float inverseDirection = 1 / localDirection.X;
float t1 = (-halfWidth - localOrigin.X) * inverseDirection;
float t2 = (halfWidth - localOrigin.X) * inverseDirection;
var tempNormal = new Vector3(-1, 0, 0);
if (t1 > t2)
{
temp = t1;
t1 = t2;
t2 = temp;
tempNormal *= -1;
}
temp = tmin;
tmin = Math.Max(tmin, t1);
if (temp != tmin)
normal = tempNormal;
tmax = Math.Min(tmax, t2);
if (tmin > tmax)
return false;
if (Math.Abs(localDirection.Y) < Toolbox.Epsilon && (localOrigin.Y < -halfHeight || localOrigin.Y > halfHeight))
return false;
inverseDirection = 1 / localDirection.Y;
t1 = (-halfHeight - localOrigin.Y) * inverseDirection;
t2 = (halfHeight - localOrigin.Y) * inverseDirection;
tempNormal = new Vector3(0, -1, 0);
if (t1 > t2)
{
temp = t1;
t1 = t2;
t2 = temp;
tempNormal *= -1;
}
temp = tmin;
tmin = Math.Max(tmin, t1);
if (temp != tmin)
normal = tempNormal;
tmax = Math.Min(tmax, t2);
if (tmin > tmax)
return false;
if (Math.Abs(localDirection.Z) < Toolbox.Epsilon && (localOrigin.Z < -halfLength || localOrigin.Z > halfLength))
return false;
inverseDirection = 1 / localDirection.Z;
t1 = (-halfLength - localOrigin.Z) * inverseDirection;
t2 = (halfLength - localOrigin.Z) * inverseDirection;
tempNormal = new Vector3(0, 0, -1);
if (t1 > t2)
{
temp = t1;
t1 = t2;
t2 = temp;
tempNormal *= -1;
}
temp = tmin;
tmin = Math.Max(tmin, t1);
if (temp != tmin)
normal = tempNormal;
tmax = Math.Min(tmax, t2);
if (tmin > tmax)
return false;
hit.T = tmin;
Vector3.Multiply(ref ray.Direction, tmin, out hit.Location);
Vector3.Add(ref hit.Location, ref ray.Position, out hit.Location);
Vector3.Transform(ref normal, ref transform.Orientation, out normal);
hit.Normal = normal;
return true;
}