From 3fcd45a23625ae8d6dabf27e1fc610c816cded6b Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Thu, 8 Dec 2016 10:59:14 -0800 Subject: [PATCH] Optimized method for transforming axis aligned bounding boxes --- libraries/shared/src/AABox.cpp | 52 +++++++++------------------------- 1 file changed, 13 insertions(+), 39 deletions(-) diff --git a/libraries/shared/src/AABox.cpp b/libraries/shared/src/AABox.cpp index a3afa220c9..82b815b006 100644 --- a/libraries/shared/src/AABox.cpp +++ b/libraries/shared/src/AABox.cpp @@ -568,46 +568,20 @@ void AABox::transform(const Transform& transform) { translate(transform.getTranslation()); } +// Logic based on http://clb.demon.fi/MathGeoLib/nightly/docs/AABB.cpp_code.html#471 void AABox::transform(const glm::mat4& matrix) { - auto minimum = _corner; - auto maximum = _corner + _scale; + auto halfSize = _scale * 0.5f; + auto center = _corner + halfSize; + halfSize = abs(halfSize); + auto newCenter = transformPoint(matrix, center); - glm::vec3 bottomLeftNear(minimum.x, minimum.y, minimum.z); - glm::vec3 bottomRightNear(maximum.x, minimum.y, minimum.z); - glm::vec3 bottomLeftFar(minimum.x, minimum.y, maximum.z); - glm::vec3 bottomRightFar(maximum.x, minimum.y, maximum.z); - glm::vec3 topLeftNear(minimum.x, maximum.y, minimum.z); - glm::vec3 topRightNear(maximum.x, maximum.y, minimum.z); - glm::vec3 topLeftFar(minimum.x, maximum.y, maximum.z); - glm::vec3 topRightFar(maximum.x, maximum.y, maximum.z); + auto mm = glm::transpose(glm::mat3(matrix)); + vec3 newDir = vec3( + glm::dot(glm::abs(vec3(mm[0])), halfSize), + glm::dot(glm::abs(vec3(mm[1])), halfSize), + glm::dot(glm::abs(vec3(mm[2])), halfSize) + ); - glm::vec3 bottomLeftNearTransformed = transformPoint(matrix, bottomLeftNear); - glm::vec3 bottomRightNearTransformed = transformPoint(matrix, bottomRightNear); - glm::vec3 bottomLeftFarTransformed = transformPoint(matrix, bottomLeftFar); - glm::vec3 bottomRightFarTransformed = transformPoint(matrix, bottomRightFar); - glm::vec3 topLeftNearTransformed = transformPoint(matrix, topLeftNear); - glm::vec3 topRightNearTransformed = transformPoint(matrix, topRightNear); - glm::vec3 topLeftFarTransformed = transformPoint(matrix, topLeftFar); - glm::vec3 topRightFarTransformed = transformPoint(matrix, topRightFar); - - minimum = glm::min(bottomLeftNearTransformed, - glm::min(bottomRightNearTransformed, - glm::min(bottomLeftFarTransformed, - glm::min(bottomRightFarTransformed, - glm::min(topLeftNearTransformed, - glm::min(topRightNearTransformed, - glm::min(topLeftFarTransformed, - topRightFarTransformed))))))); - - maximum = glm::max(bottomLeftNearTransformed, - glm::max(bottomRightNearTransformed, - glm::max(bottomLeftFarTransformed, - glm::max(bottomRightFarTransformed, - glm::max(topLeftNearTransformed, - glm::max(topRightNearTransformed, - glm::max(topLeftFarTransformed, - topRightFarTransformed))))))); - - _corner = minimum; - _scale = maximum - minimum; + _corner = newCenter - newDir; + _scale = newDir * 2.0f; }