Part To Region3 Help?

This seems like simple code, but roblox isn’t finding anything in the region. Here’s my code:

function PartToRegion3(part)
    local PointA, PointB = part.CFrame * (0.5 * part.Size) , part.CFrame * (-0.5 * part.Size)
    local rg = Region3.new(PointA, PointB)
    
    return rg
end

local rg = PartToRegion3(game.Workspace.RacePoints.Finish1)
while true do
    for i,v in pairs(game.Workspace:FindPartsInRegion3(rg, nil, math.huge)) do
        print(v.Name)
    end
    wait(3)
end
3 Likes

Remember: A region’s boundaries / faces will always be parallel to world axes. The region’s corners will be located at your part’s corners, but it will be rotated if there’s any rotation on the part which is not a multiple of 90 degree. If your part is rotated, you should be using BasePart:GetTouchingParts instead. Make sure to create a .Touched event for your main part if its uncollidable before, as it won’t work otherwise. You can just connect it to an empty function.

1 Like

Taken from my module, you can easily modify it though:

module.Region3FromPart = function(Part) --Not written by me lel.
    local Size = Part.Size
    return Region3.new(Part.Position-(Size/2),Part.Position+(Size/2))
end

EDIT: didn’t mean to reply to you oof

EDIT 2: I originally got the code from here: https://scriptinghelpers.org/questions/35877/quick-explanation-on-region3 :slight_smile:

7 Likes

Solutions that just add the size fail to account for cases where the part is rotated. I think the best solution is to use the part’s bounding box.

function PartToRegion3(part)
	local abs = math.abs

	local cf = obj.CFrame -- this causes a LuaBridge invocation + heap allocation to create CFrame object - expensive! - but no way around it. we need the cframe
	local size = obj.Size -- this causes a LuaBridge invocation + heap allocation to create Vector3 object - expensive! - but no way around it
	local sx, sy, sz = size.X, size.Y, size.Z -- this causes 3 Lua->C++ invocations

	local x, y, z, R00, R01, R02, R10, R11, R12, R20, R21, R22 = cf:components() -- this causes 1 Lua->C++ invocations and gets all components of cframe in one go, with no allocations

	-- https://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/
	local wsx = 0.5 * (abs(R00) * sx + abs(R01) * sy + abs(R02) * sz) -- this requires 3 Lua->C++ invocations to call abs, but no hash lookups since we cached abs value above; otherwise this is just a bunch of local ops
	local wsy = 0.5 * (abs(R10) * sx + abs(R11) * sy + abs(R12) * sz) -- same
	local wsz = 0.5 * (abs(R20) * sx + abs(R21) * sy + abs(R22) * sz) -- same
	
	-- just a bunch of local ops
	local minx = x - wsx
	local miny = y - wsy
	local minz = z - wsz

	local maxx = x + wsx
	local maxy = y + wsy
	local maxz = z + wsz
   
	local minv, maxv = Vector3.new(minx, miny, minz), Vector3.new(maxx, maxy, maxz)
	return Region3.new(minv, maxv)
end

(bounding box code adapted from zeuxcg’s code)

52 Likes

Thank you so much for this, that is extremely useful and well thought out. Exactly what I was looking for.

5 Likes