How should i go about finding parts inside of a rotated regtion?

right now, i have a function that gets a region3 along with a cframe that determines the orientation the region should be at. the purpose of this function is to let the game know if a vector3 could be located inside of this rotated region. it is easy to do this if the region wasn’t rotated, but since it is, how would i go about doing this?

function service.plot_bounds(plot : Model) : Region3 . CFrame
	local part = plot.Obj
	
	local region = Region3.new(part.Position - part.Size, part.Position + part.Size + Vector3.new(0, plot:GetAttribute("height"), 0))
	local cframe = CFrame.new(part.Position + (plot.UpVector * plot:GetAttribute("height")/2)) * part.CFrame:ToEulerAnglesXYZ()
	
	return region, cframe
end

as you see in the code, it generates a region for the plot.
image
then the cframe will let the decoder know the orientation of that region

if anybody could help me out on seeing if a vector is in the region3 along with the extra rotated cframe, it would be amazing.

1 Like

You should use WorldRoot, it basically replaces Region3, and is really solid. It supports rotated “regions” which is amazing.

Alternatively, if you want to verify if a vector is in a region (and not finding all the parts in a region), I made a module for that

local THRESHOLD = 0.00002 -- To combat the awesomness of floating point numbers

local RegionModule = {}
local PlayerRegions = {}

type RegionType = {
	CFrame : CFrame,
	Size : Size,
}

-- // Local Functions

local function IsPointInRegion(Point : Vector3, Region : RegionType)
	local RegionSize = Region.Size
	local RegionCFrame = Region.CFrame
	
	local RelativeVector = RegionCFrame:PointToObjectSpace(Point)
	
	for i, v in ipairs({"X","Y","Z"}) do 
		if math.abs(RelativeVector[v]) > RegionSize[v]/2 + THRESHOLD then return false end
	end

	return true
end

local function IsPartInRegion(PartSize : Vector3, PartCFrame : CFrame, Region : RegionType)
	local RegionSize = Region.Size 
	local RegionCFrame = Region.CFrame
	
	local RelativeCFrame = RegionCFrame:Inverse() * PartCFrame
	
	local MaxX = 0
	local MaxY = 0
	local MaxZ = 0
	
	for i, v in ipairs({Vector3.new(1,1,1),Vector3.new(-1,1,1),Vector3.new(1,1,-1),Vector3.new(-1,1,-1),Vector3.new(1,-1,1),Vector3.new(-1,-1,1),Vector3.new(1,-1,-1),Vector3.new(-1,-1,-1)}) do
		local Point = RelativeCFrame * CFrame.new(PartSize/2 * v)
		MaxX = math.max(math.abs(Point.X),MaxX)
		MaxY = math.max(math.abs(Point.Y),MaxY)
		MaxZ = math.max(math.abs(Point.Z),MaxZ)
	end
	
	local Point = Vector3.new(MaxX,MaxY,MaxZ)
	
	for i, v in ipairs({"X","Y","Z"}) do 
		if Point[v] > RegionSize[v]/2 + THRESHOLD then return false end
	end

	return true
end

-- // Module Functions

function RegionModule:SetRegion(Player : Player, RegionCFrame : CFrame?, RegionSize : Vector3?)
	
	local Region = nil
	
	if typeof(RegionCFrame) == "CFrame" and typeof(RegionSize) == "Vector3" then 
		Region = {CFrame = RegionCFrame, Size = RegionSize}
	end
	
	PlayerRegions[Player.UserId] = Region 
	
	if not RunService:IsServer() then return end 
	
	RemoteEvent:FireAllClients(PlayerRegions) -- [TO FIX] Do not send it to everyone all the time, that's kind of bad
end

The module was made to find if players were inside regions, you can change the SetRegion function to return the region instead of putting it in a table, and renaming it to like CreateRegion

1 Like

thank you very much! it took a little while incorporating everything into my framework and changing some things up to work with the game, but everything works perfectly.

1 Like

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