What's the most perfomant way to get BoundingBox of an rotated model so it's rotation would be zero?

Basically I need to create a box around rotated model with no rotation so model would fit perfectly inside.

In theory I should achive this:

image
(imagine part as rotated model and transparent part is my wanted bounding box)
I’m doing this to get the “global” Y size of a model.

1 Like

Model:GetBoundingBox() :slight_smile:

1 Like

You quite don’t understand what I want to achive. You’re just getting rotated bounding box of the model. I want to get the box that will have no rotation and has the size so model could fit into it.

By using your method, I will get “local” y size of model bounding box

Look at this example:
image
image

1 Like

My bad, I understood what you meant, but misinterpreted the function. I thought it might have been the answer if used on a model with a temproarily deselected primary part. Since it’s an engine calculation, it would have also been much faster than anything manual.

I’ll think about a good solution.

Edit. @ArtemVoronin0

Would you mind also mentioning the use case? For some cases it’s enough to have a small unnoticable primary part always aligned with world axes that doesn’t affect model’s bounds (preferrably in the centre).

image

1 Like

The main use case for this box is to get the “global” Y size of model. (basically getting the size from bottom to top)

Alright. I asked because it could be an XY problem and I cannot know what you need this Y-size for nor how frequently.

GetBoundingBox() is definitely the quickest method, but if having the mentioned world axis-aligned primary part is not an option, then you can use one of the bounding box algorithms.

I recommend taking a look at XAXA’s function, derived from the engine source.

It comes with a caveat. Engine calculations are always going to be much faster. AABB operation complexity is linear. Even if completely optimised and compiled as --!native, this function will be around two orders of magnitude slower at best. With each additional part the execution time grows, while it hardly changes for GetBoundingBox(), even in large models.

Edit. Just below the XAXA’s post Pyseph added a faster version.

I realized I can just get the 8* corner points of a BoundingBox and then subtracting the Y of highest point and Y of lowest point to get the global Y size. It will work for only getting Y size but I bet if you make it for all axis you can make a part that overlaps entire model (for anyone who wants to do that and reading this post)

Tho if you have any faster method without comparing all 4 points would like to know!
Also… Can’t understand why you’re sending me method to create boundingbox again… I need to create a “in theory” box that will have full model inside of it and no orientation. By doing that I will be able to know how to get global y size of the model.

Hey, that’s pretty smart. And no, it won’t get any noticably faster than that.

You answered your own question. GetBoundingBox() returns OOBB, and the linked function returns the axis-aligned box, of which Y you were looking for. Regardless, comparing the corners is better.

Oh, so the post with all boundingbox functions you send me will give me a box with no orientation that overlaps model? If yes, is this faster than comparing 8 corners of bounding box?

Comparing corners is absolutely much faster. I could get the height 1 million times on a model with 100 parts in roughtly 1 second. And the method with axis-aligned primary part is only 3 times faster.

And the advantage is that the results are quite similar in a 1000-part model, whereas the custom function takes linearly more time. In my test it could process a 1000-part model 10 k times in a bit more than a second - this is expected though, and I still find it very useful to have as a utility.

Code
local function GetBoundingBoxCorners(cf: CFrame, size: Vector3): number
	local half = size/2
	return {
		cf.Position + Vector3.new(half.X, half.Y, half.Z);
		cf.Position + Vector3.new(-half.X, half.Y, half.Z);
		cf.Position + Vector3.new(half.X, half.Y, -half.Z);
		cf.Position + Vector3.new(-half.X, half.Y, -half.Z);
		
		cf.Position + Vector3.new(half.X, -half.Y, half.Z);
		cf.Position + Vector3.new(-half.X, -half.Y, half.Z);
		cf.Position + Vector3.new(half.X, -half.Y, -half.Z);
		cf.Position + Vector3.new(-half.X, -half.Y, -half.Z);
	}
end

local cf, size = model:GetBoundingBox()
local lowestY, highestY = 1e6, 0
local diffY: number

for _,corner in GetBoundingBoxCorners(cf, size) do
	if corner.Y < lowestY then
		lowestY = corner.Y
	elseif corner.Y > highestY then
		highestY = corner.Y
	end
end

diffY = highestY - lowestY
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.