diff --git a/Source/Engine/Core/Math/BoundingBox.cpp b/Source/Engine/Core/Math/BoundingBox.cpp index 7c35fbe80..91b21cb35 100644 --- a/Source/Engine/Core/Math/BoundingBox.cpp +++ b/Source/Engine/Core/Math/BoundingBox.cpp @@ -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); } diff --git a/Source/Engine/Core/Math/BoundingBox.cs b/Source/Engine/Core/Math/BoundingBox.cs index 188da74cd..bfcbcc0fa 100644 --- a/Source/Engine/Core/Math/BoundingBox.cs +++ b/Source/Engine/Core/Math/BoundingBox.cs @@ -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); + /// + /// Transforms bounding box using the given transformation matrix. + /// + /// The bounding box to transform. + /// The transformation matrix. + /// The result of the transformation. + 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]); - } + /// + /// Transforms bounding box using the given transformation. + /// + /// The bounding box to transform. + /// The transformation. + /// The result of the transformation. + 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); } ///