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
I have now finally figured out how to use your module on real time and these are the results:
https://gyazo.com/5c7867d88a8e16129d471cfc879c0ee9
You are my hero truly
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
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
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)
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.
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.
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.
How did you get that to work so smooth?
Why not just use solid modeling? Roblox supports it in scripts now.
It is very slow for live refreshment currently…but they announced they were going to do it much much faster so maybe then i will change into that
This is very late, but for people who are still struggling, try this out
How did you make it repeat when you move the part? A download to something that works like Bloxburg’s building system would be nice
Can I have the code? I want to try and use it to learn more about scripting. Also sorry about notifying everyone
Of course its all open source here ^-^
Your module creates like 20 parts of size Vector3.new(0.1, 4, 0.1)
per every “window” and it makes a lot of lag even if it refreshes using Heartbeat or Change, I think using CSG API it’s better. (not the best option but won’t have very big performance impacts)
Sorry if this is off-topic, but I required my module (csgservice) yet it’s still crashing.
I’ve been trying to use this for a project but theres an odd floating point error happening with the original part’s CFrame. It causes many very thin parts to be placed between cuts.