Improve precision for BoundingBox.Transform with Transform

This commit is contained in:
Wojtek Figat
2022-07-03 18:12:13 +02:00
parent cb92e3c54c
commit e34e4caf08
2 changed files with 59 additions and 37 deletions

View File

@@ -129,30 +129,28 @@ void BoundingBox::Transform(const BoundingBox& box, const Matrix& matrix, Boundi
const auto zb = backward * box.Maximum.Z;
const auto translation = matrix.GetTranslation();
result = BoundingBox(
Vector3::Min(xa, xb) + Vector3::Min(ya, yb) + Vector3::Min(za, zb) + translation,
Vector3::Max(xa, xb) + Vector3::Max(ya, yb) + Vector3::Max(za, zb) + translation);
/*
// Get box corners
Vector3 corners[8];
box.GetCorners(corners);
// Transform them
for (int32 i = 0; i < 8; i++)
{
corners[i] = Vector3::Transform(corners[i], matrix);
}
// Construct box from the points
result = FromPoints(corners, 8);
*/
const auto min = Vector3::Min(xa, xb) + Vector3::Min(ya, yb) + Vector3::Min(za, zb) + translation;
const auto max = Vector3::Max(xa, xb) + Vector3::Max(ya, yb) + Vector3::Max(za, zb) + translation;
result = BoundingBox(min, max);
}
void BoundingBox::Transform(const BoundingBox& box, const ::Transform& transform, BoundingBox& result)
{
// TODO: optimize it and support large worlds without using Matrix
Matrix matrix;
transform.GetWorld(matrix);
Transform(box, matrix, result);
// Reference: http://dev.theomader.com/transform-bounding-boxes/
const auto right = transform.GetRight();
const auto xa = right * box.Minimum.X;
const auto xb = right * box.Maximum.X;
const auto up = transform.GetUp();
const auto ya = up * box.Minimum.Y;
const auto yb = up * box.Maximum.Y;
const auto backward = transform.GetBackward();
const auto za = backward * box.Minimum.Z;
const auto zb = backward * box.Maximum.Z;
const auto min = Vector3::Min(xa, xb) + Vector3::Min(ya, yb) + Vector3::Min(za, zb) + transform.Translation;
const auto max = Vector3::Max(xa, xb) + Vector3::Max(ya, yb) + Vector3::Max(za, zb) + transform.Translation;
result = BoundingBox(min, max);
}

View File

@@ -454,24 +454,48 @@ namespace FlaxEngine
var zb = backward * box.Maximum.Z;
var translation = transform.TranslationVector;
result = new BoundingBox(
Vector3.Min(xa, xb) + Vector3.Min(ya, yb) + Vector3.Min(za, zb) + translation,
Vector3.Max(xa, xb) + Vector3.Max(ya, yb) + Vector3.Max(za, zb) + translation);
var min = Vector3.Min(xa, xb) + Vector3.Min(ya, yb) + Vector3.Min(za, zb) + translation;
var max = Vector3.Max(xa, xb) + Vector3.Max(ya, yb) + Vector3.Max(za, zb) + translation;
result = new BoundingBox(min, max);
}
/*
// Get box corners
var corners = new Vector3[8];
box.GetCorners(corners);
/// <summary>
/// Transforms bounding box using the given transformation matrix.
/// </summary>
/// <param name="box">The bounding box to transform.</param>
/// <param name="transform">The transformation matrix.</param>
/// <returns>The result of the transformation.</returns>
public static BoundingBox Transform(BoundingBox box, Transform transform)
{
Transform(ref box, ref transform, out BoundingBox result);
return result;
}
// Transform them
for (int i = 0; i < 8; i++)
{
Vector3.Transform(ref corners[i], ref transform, out corners[i]);
}
/// <summary>
/// Transforms bounding box using the given transformation.
/// </summary>
/// <param name="box">The bounding box to transform.</param>
/// <param name="transform">The transformation.</param>
/// <param name="result">The result of the transformation.</param>
public static void Transform(ref BoundingBox box, ref Transform transform, out BoundingBox result)
{
// Reference: http://dev.theomader.com/transform-bounding-boxes/
// Construct box from the points
FromPoints(corners, out result);
*/
Double3 right = transform.Right;
var xa = right * box.Minimum.X;
var xb = right * box.Maximum.X;
Double3 up = transform.Up;
var ya = up * box.Minimum.Y;
var yb = up * box.Maximum.Y;
Double3 backward = transform.Backward;
var za = backward * box.Minimum.Z;
var zb = backward * box.Maximum.Z;
var min = Vector3.Min(xa, xb) + Vector3.Min(ya, yb) + Vector3.Min(za, zb) + transform.Translation;
var max = Vector3.Max(xa, xb) + Vector3.Max(ya, yb) + Vector3.Max(za, zb) + transform.Translation;
result = new BoundingBox(min, max);
}
/// <summary>