Created
May 26, 2020 16:47
-
-
Save stravant/0fcc931af34fce8c19ebe50c7f101d64 to your computer and use it in GitHub Desktop.
Compute Two Bounding Boxes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
Micro-optimized code for computing a local space and the global space | |
bounding box for a set of parts and attachments as fast as possible. | |
]] | |
local function computeTwoBoundingBoxes(basisCFrame1, allParts, allAttachments) | |
local basisX, basisY, basisZ = basisCFrame1.X, basisCFrame1.Y, basisCFrame1.Z | |
local inverseBasis1 = basisCFrame1:Inverse() | |
local xmin1, xmax1 = math.huge, -math.huge | |
local ymin1, ymax1 = math.huge, -math.huge | |
local zmin1, zmax1 = math.huge, -math.huge | |
local xmin2, xmax2 = math.huge, -math.huge | |
local ymin2, ymax2 = math.huge, -math.huge | |
local zmin2, zmax2 = math.huge, -math.huge | |
for _, part in ipairs(allParts) do | |
if not part:IsA("Terrain") then | |
local cframe = part.CFrame | |
local size = part.Size | |
local sx, sy, sz = size.X, size.Y, size.Z | |
-- Calculation for bounding box in the space of basisCFrame1 | |
local localCFrame1 = inverseBasis1 * cframe -- put cframe in our local basis | |
local _, _, _, | |
t00, t01, t02, | |
t10, t11, t12, | |
t20, t21, t22 = localCFrame1:components() | |
local hw1 = 0.5 * (math.abs(sx * t00) + math.abs(sy * t10) + math.abs(sz * t20)) | |
local hh1 = 0.5 * (math.abs(sx * t01) + math.abs(sy * t11) + math.abs(sz * t21)) | |
local hd1 = 0.5 * (math.abs(sx * t02) + math.abs(sy * t12) + math.abs(sz * t22)) | |
local at1x, at1y, at1z = localCFrame1.X, localCFrame1.Y, localCFrame1.Z | |
xmin1 = math.min(xmin1, at1x - hw1) | |
xmax1 = math.max(xmax1, at1x + hw1) | |
ymin1 = math.min(ymin1, at1y - hh1) | |
ymax1 = math.max(ymax1, at1y + hh1) | |
zmin1 = math.min(zmin1, at1z - hd1) | |
zmax1 = math.max(zmax1, at1z + hd1) | |
-- Calculation for the bounding box in the global coordinate space | |
_, _, _, | |
t00, t01, t02, | |
t10, t11, t12, | |
t20, t21, t22 = cframe:components() | |
local hw2 = 0.5 * (math.abs(sx * t00) + math.abs(sy * t01) + math.abs(sz * t02)) | |
local hh2 = 0.5 * (math.abs(sx * t10) + math.abs(sy * t11) + math.abs(sz * t12)) | |
local hd2 = 0.5 * (math.abs(sx * t20) + math.abs(sy * t21) + math.abs(sz * t22)) | |
local at2x, at2y, at2z = cframe.X, cframe.Y, cframe.Z | |
xmin2 = math.min(xmin2, at2x - hw2) | |
xmax2 = math.max(xmax2, at2x + hw2) | |
ymin2 = math.min(ymin2, at2y - hh2) | |
ymax2 = math.max(ymax2, at2y + hh2) | |
zmin2 = math.min(zmin2, at2z - hd2) | |
zmax2 = math.max(zmax2, at2z + hd2) | |
end | |
end | |
for _, attachment in ipairs(allAttachments) do | |
local worldPosition = attachment.WorldPosition | |
local localPosition = inverseBasis1 * worldPosition | |
local localx, localy, localz = localPosition.X, localPosition.Y, localPosition.Z | |
xmin1 = math.min(xmin1, localx) | |
xmax1 = math.max(xmax1, localx) | |
ymin1 = math.min(ymin1, localy) | |
ymax1 = math.max(ymax1, localy) | |
zmin1 = math.min(zmin1, localz) | |
zmax1 = math.max(zmax1, localz) | |
local globalx, globaly, globalz = worldPosition.X, worldPosition.Y, worldPosition.Z | |
xmin2 = math.min(xmin2, globalx) | |
xmax2 = math.max(xmax2, globalx) | |
ymin2 = math.min(ymin2, globaly) | |
ymax2 = math.max(ymax2, globaly) | |
zmin2 = math.min(zmin2, globalz) | |
zmax2 = math.max(zmax2, globalz) | |
end | |
local localBoundingBoxOffset = Vector3.new( | |
0.5 * (xmin1 + xmax1), | |
0.5 * (ymin1 + ymax1), | |
0.5 * (zmin1 + zmax1) | |
) | |
local localBoundingBoxSize = Vector3.new( | |
xmax1 - xmin1, | |
ymax1 - ymin1, | |
zmax1 - zmin1 | |
) | |
local globalBoundingBoxOffset = Vector3.new( | |
0.5 * (xmin2 + xmax2) - basisX, | |
0.5 * (ymin2 + ymax2) - basisY, | |
0.5 * (zmin2 + zmax2) - basisZ | |
) | |
local globalBoundingBoxSize = Vector3.new( | |
xmax2 - xmin2, | |
ymax2 - ymin2, | |
zmax2 - zmin2 | |
) | |
return localBoundingBoxOffset, localBoundingBoxSize, | |
globalBoundingBoxOffset, globalBoundingBoxSize | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment