Part to parts breaker to fit window,door

Sorry, I went afk

Yeah, you can do that and I can take a look at it and try to help

I am not using csg :slight_smile:
I am fragmentating the wall into 4 pieces

Instead of doing this, I would use CSG as stated above, as it is more efficient than creating 4 different parts, especially when you want to have multiple windows as shown in the video.

You can find the API here:

Example of how to use this:

part:SubtractAsync(window)
1 Like

But this is a very slow task…

1 Like

Luckily i have solved this problem with a really random technique

:innocent:

So I actually had @alertcoderf ask a similar question not too long ago so I luckily have some code just for this. I don’t claim it’s the most efficient approach since it doesn’t attempt to group like parts, etc, but it works.

Keep in mind, much like your videos the code only works with parts that are relatively axis aligned.

In essence the idea is to first have a function that can slice a part on any of it’s given axes.

2019-08-31_11-33-02

Once you have that down cutting out a window is quite simple. You start with a part(s) you want to cut into and slice it up using the surfaces of the window you want to cut out. This leaves you with many cut up parts that make up the original so all that’s left to do is find the parts overlapping with your window and destroy them.

2019-08-31_11-26-33

Here’s the placefile:
slice.rbxl (17.7 KB)

45 Likes

You are a life savior! :heart:

Well glad I could help. Sorry I didn’t reply faster I see you came up with your own fix. :grin:

4 Likes

That fix has its own other porblems though :stuck_out_tongue:

1 Like

No i wasnt saying to use CSG, it would better to use a bunch of parts, because CSG is not reliable and sometimes the new union does not load. I was asking because i scripted a similar system for the game im working on

1 Like

I have now finally figured out how to use your module on real time and these are the results:

You are my hero truly :heart:

13 Likes

Did you store the canvas in a table and it each time the window moved it would give you a new canvas and cut the window then?

Yes somehow like somehow like that i can handle that live update

1 Like

I tried using the modules aswell. The touch connection causes studio to crash. I don’t see how you were able to update it live seeing how costly calculation and many loops are used in the module.

local Canvas = game.ReplicatedStorage.Canvas:Clone()
local cut = require(script:WaitForChild("Cut"))
local Window = game.Workspace.Windows.Part


while wait(2) do 
local Wall = Canvas:Clone()
Wall.Parent = game.Workspace.Wall
local touching = Window:GetTouchingParts()
cut(Window,touching)
Wall:Destroy()
end
1 Like

I had the same problem initially when i came across this, You have edit the module so that the parts are initially generated once and the touch event isn’t as “OverLoaded” , instead of multiple times which causes the game to crash.

CodeExample

Here a modified version of this code: (its a bit messy but you should get the idea, hopefully)

local CSGService = {}


--inital
local RIGHT = Vector3.new(1, 0, 0)
local UP  = Vector3.new(0, 1, 0)
local BACK = Vector3.new(0, 0, 1)
local  CurrentUnUsedFolder
local oldcanvascf 
local OldcanvasSize 





local function vec3Func(f, v)
	return Vector3.new(f(v.x), f(v.y), f(v.z))
end




local function slice(part, wPoint, axis, part2)
	local pSize, pCF = part.Size, part.CFrame
	local pRot = pCF - pCF.p
	
	local length = axis:Dot(pSize)
	local mSize = pSize - axis*length
	local max, min = length/2, -length/2
	local split = axis:Dot(pCF:PointToObjectSpace(wPoint))
	
	if (split >= min and split <= max) then
		local l1, l2 = max - split, split - min
		local p1, p2 = pCF*(axis*(l1/2 + split)), pCF*(axis*(-l2/2 + split))
		
		local part1 = part
		part1.CFrame = CFrame.new(p1) * pRot
		part1.Size = mSize + axis*l1
		
	if part2 then
		
	
		part2.CFrame = CFrame.new(p2) * pRot
		part2.Size = mSize + axis*l2
		part2.Parent =   CurrentUnUsedFolder
	   
		return part1, part2
	end
	
	end
	
	return part
end

function  CSGService.Cut(part, canvas, Folder, Folder2)
	
	
if part then
part.Orientation = Vector3.new(90, 180 +  canvas[1].Orientation.Y , 0) --- you can mess around with this, i just used this just for my configuration 


	      CurrentUnUsedFolder = Folder2
	      local cf, size2 = part.CFrame, part.Size/2
	      local canvasCF = canvas[1].CFrame
		local axis = Vector3.FromAxis(Enum.Axis.Z)
		local p1, p2 = cf*(axis*size2), cf*(-axis*size2)
		
				
		
		
		local sliceAxis = canvasCF:VectorToObjectSpace(cf:VectorToWorldSpace(axis))
		sliceAxis = vec3Func(function(c) return math.min(1, math.abs(c)) end, sliceAxis)
		
		for i = 1, #canvas do
			local Children =Folder:GetChildren()
			local a, b = slice(canvas[i], p1, sliceAxis, Children[i] )
			canvas[#canvas+1] = a
			canvas[#canvas+1] = b
		end
		
		for i = 1, #canvas do
			local Children = Folder:GetChildren()
			local a, b = slice(canvas[i], p2, sliceAxis, Children[i] )
			canvas[#canvas+1] = a
			canvas[#canvas+1] = b
		end
		
	
		local axis = Vector3.FromAxis(Enum.Axis.X)
		local p1, p2 = cf*(axis*size2), cf*(-axis*size2)
		
		local sliceAxis = canvasCF:VectorToObjectSpace(cf:VectorToWorldSpace(axis))
		sliceAxis = vec3Func(function(c) return math.min(1, math.abs(c)) end, sliceAxis)
		
		for i = 1, #canvas do
			local Children = Folder:GetChildren()
			local a, b = slice(canvas[i], p1, sliceAxis, Children[i])
			canvas[#canvas+1] = a
			canvas[#canvas+1] = b
		end
		
		
	for i = 1, #canvas do
			local Children = Folder:GetChildren()
			local a, b = slice(canvas[i], p2, sliceAxis,  Children[i])
			canvas[#canvas+1] = a
			canvas[#canvas+1] = b
		end

	
	
	local lookup = {}
	for i = 1, #canvas do
		lookup[canvas[i]] = true
end

	



for i,v in pairs(Folder2:GetChildren()) do
		if v then
		v.Transparency = 0
		v.CanCollide =true
		v.Parent = Folder
		end
	end
	
	




local t = part.Touched:Connect(function() end)
	local touching = part:GetTouchingParts()
	t:Disconnect()
	for i = 1, #touching do
		if (lookup[touching[i]]) then

			
		if touching[i].Name == "Part" then
	
		
		touching[i].Transparency = 1
		touching[i].CanCollide = false
	
			
			end
	end
	
end


end


end








return CSGService




---------Script
local CSgservice = require(game.ReplicatedStorage.CSGService) 

----insert parts into the MainFolder
local NumberOfParts  = 22---  i found 22 parts to be enough to cover a whole wall/part,  You might want to add a way to calculte this instead

for i = 1, NumberOfParts do 
			local Part = Instance.new("Part")
		   	Part.Transparency = .5
			Part.Parent = MainFolder
			Part.Anchored = true
			Part.CastShadow = false	
end
		


CSgservice.Cut(Part, Canvas, MainFolder, Temporary Folder)
3 Likes

I reprogrammed this module. It’s possible to brute force recombinations on each axis before the next cutting pass. This results in better real-time performance with low N (< is 10). Chances of having a higher N is low.

3 Likes

Thank you so much. The canvas was changing its position and size by the end of each cut so i had to reposition it back to the original place and size it. This seems to work fine in a renderstep aswell. Im just wondering if there is any possible way to limit the number of parts to 4 as shown underneath.

Wall

I will only be having rectangle shaped objects and 4 parts (1 above window, one right side of window, one left side of window and one underneath window) would be a very optimal situation. Do you know how i would be able to achieve it? Anyways thank you so much for sharing the code.

local CSgservice = require(game.ReplicatedStorage.CSGService) 
local Window = game.Workspace.Window
local Canvas = game.Workspace.Canvas

local size,pos = Canvas.Size,Canvas.Position


local MainFolder = game.Workspace.MainFolder
local TempFolder = game.Workspace.TempFolder


----insert parts into the MainFolder
local NumberOfParts  = 22---  i found 22 parts to be enough to cover a whole wall/part,  You might want to add a way to calculte this instead

for i = 1, NumberOfParts do 
	local Part = Instance.new("Part")
   	Part.Transparency = .5
	Part.Parent = MainFolder
	Part.Anchored = true
	Part.CastShadow = false
end
		



game:GetService("RunService").RenderStepped:Connect(function()
	Canvas.Size = size
	Canvas.Position = pos 
	CSgservice.Cut(Window, {Canvas}, MainFolder, TempFolder)
	TempFolder:ClearAllChildren()
end)

Hey, do you have any plans for open-sourcing it? If not, mind sharing the method you used to make the code work better in real-time?

No plans to open source it since it’s linked with other code.

Just check all axis to try to combine into a larger part.

1 Like

How did you get that to work so smooth?

2 Likes