Detecting Part/Mesh boundaries for a placement system?

I’ve tried looking this up, however I’ve found nothing so I’m creating this topic in hopes of finally finding out about Part/Mesh boundary detection. The soul purpose of this would be the limitation of part placement system outside of the boundary. I’ve tried using region3 , but that turned out to be a bit messy and unreliable. Here’s the code for that bit:


--//Plot is a transparent part

Grid =  2
function snap(pos, modelSize) 
	local X = math.floor(pos.X/Grid+0.5)*Grid 
	local Y = math.floor(pos.Y/Grid+0.5) * Grid + modelSize.Y/2 
	local Z = math.floor(pos.Z/Grid+0.5)*Grid 
	return Vector3.new(X,Y,Z)
end


function checkBoundaries (Object, Offset, Plot)
if Object and Plot then
	
	local pos = Object.PrimaryPart.CFrame

	local min = Vector3.new(pos.X + Offset,pos.Y + Offset, pos.Z + Offset)
	local max = Vector3.new(pos.X - Offset,pos.Y - Offset, pos.Z - Offset)
	
	local region = Region3.new(max, min)
	region = region:ExpandToGrid(4)

for _,Part in pairs(game.Workspace:FindPartsInRegion3(region,nil,math.huge)) do
	if Part == Plot  then 
		return true
	else return false
	end
end
end

function RenderStepped()
	
local IgnoreTable = {}
Switch = checkBoundaries(SampleBlock, Grid, Plot) 

		if GhostBlock and Switch then
	
			local UnitRay = Mouse.UnitRay
			local ray = Ray.new(UnitRay.Origin,UnitRay.Direction*100)
			local modelSize = helperFunctionsDictionary.checkModelSize(GhostBlock , rotationY)
			local target,pos,normal = workspace:FindPartOnRayWithIgnoreList(ray,IgnoreTable)

GhostBlock:SetPrimaryPartCFrame(CFrame.new(snap(pos, modelSize))*CFrame.Angles(0,math.rad(rotationY),0))
			GhostBlock:SetPrimaryPartCFrame(CF)
		end
end

Specific issue with that code(Bits of parts going through the boundary)

I’ve figured that the method that’s used by @EgoMoose in his post Creating A Furniture Placement System (Specific code of his which I’m talking about is written below) is more effective. However it’s limited to a 2D plane. Is there a way to expand/detect the boundaries?

function Placement:CalcCanvas()
	local canvasSize = self.CanvasPart.Size

	-- want to create CFrame such that cf.lookVector == self.CanvasPart.CFrame.upVector
	-- do this by using object space and build the CFrame
	local back = Vector3.new(0, -1, 0)
	local top = Vector3.new(0, 0, -1)
	local right = Vector3.new(-1, 0, 0)

	-- convert to world space
	local cf = self.CanvasPart.CFrame * CFrame.fromMatrix(-back*canvasSize/2, right, top, back)
	-- use object space vectors to find the width and height
	local size = Vector2.new((canvasSize * right).magnitude, (canvasSize * top).magnitude)

	return cf, size
end


function Placement:CalcPlacementCFrame(model, position, rotation)
	-- use other method to get info about the surface
	local cf, size = self:CalcCanvas()

	-- rotate the size so that we can properly constrain to the surface
	local modelSize = CFrame.fromEulerAnglesYXZ(0, rotation, 0) * model.PrimaryPart.Size
	modelSize = Vector3.new(math.abs(modelSize.x), math.abs(modelSize.y), math.abs(modelSize.z))

	-- get the position relative to the surface's CFrame
	local lpos = cf:pointToObjectSpace(position);
	-- the max bounds the model can be from the surface's center
	local size2 = (size - Vector2.new(modelSize.x, modelSize.z))/2

	-- constrain the position using size2
	local x = math.clamp(lpos.x, -size2.x, size2.x);
	local y = math.clamp(lpos.y, -size2.y, size2.y);

	-- create and return the CFrame
	return cf * CFrame.new(x, y, -modelSize.y/2) * CFrame.Angles(-math.pi/2, rotation, 0)
end

I’m not entirely sure what you’re trying to do, but have you seen my replies to the post? I’ve made comments and added a few things to common questions I get. I think this reply should answer your question?

Thank you for your reply.

Yes I did look through the comments, but the problem I’m having wasn’t related to any of those.
What I’m trying to achieve, In other words, is the ability to move and stack models ontop of each other in the plot. Your system does what I want but it’s limited to a 2D plane and you cannot add models ontop of each other.

My apologies for not making myself clear