This was actually the response that helped me figure it out.
I’ve basically perfected the system that I had tried to make from the beginning:
To explain a bit, I’m using quadtree partitioning with a function sourced from this post
But before I divide the part into four, I use this function to check if the part is rectangular:
local function partCanSubdivide(part)
-- can we run the subcubes algorithm on this part w/o artifacts?
local largest = math.max(part.Size.X, part.Size.Y, part.Size.Z)
local smallest = math.min(part.Size.Y, part.Size.Z)
if smallest == part.Size.X then
smallest = math.min(part.Size.Y, part.Size.Z)
elseif smallest == part.Size.Y then
smallest = math.min(part.Size.X, part.Size.Z)
elseif smallest == part.Size.Z then
smallest = math.min(part.Size.X, part.Size.Y)
end
print(largest)
print(smallest * 1.5)
return largest >= 1.5 * smallest
--returns true if part is rectangular.
--Part is rectangular if the largest axis is at least 1.5x bigger than the smallest axis
end
Then I have a separate function to check what the longest axis of the part is:
local function getLargestAxis(part:Part)
return math.max(part.Size.X, part.Size.Y, part.Size.Z)
end
Then, if it is rectangular, I cut the part in half to turn it into squares with this function:
local function CutPartinHalf(block : Part)
local partTable = {}
local bipolarVectorSet = {}
local X = block.Size.X
local Y = block.Size.Y
local Z = block.Size.Z
if getLargestAxis(block) == X then
X /= 2
bipolarVectorSet = {
Vector3.new(1,0,0),
Vector3.new(-1,0,0),
}
elseif getLargestAxis(block) == Y then
Y/=2
bipolarVectorSet = {
Vector3.new(0,1,0),
Vector3.new(0,-1,0),
}
elseif getLargestAxis(block) == Z then
Z/=2
bipolarVectorSet = {
Vector3.new(0,0,1),
Vector3.new(0,0,-1),
}
end
local halfSize = Vector3.new(X,Y,Z)
for _, offsetVector in pairs(bipolarVectorSet) do
local clone = block:Clone()
clone.Parent = workspace
clone.Size = halfSize
clone.CFrame += block.CFrame:VectorToWorldSpace((halfSize / 2.0) * offsetVector)
table.insert(partTable,clone)
end
block:Destroy()
return partTable
end
And otherwise if the part isn’t rectangular (meaning it’s a cube), I just use quadtree partitioning to divide the part into four, resulting in evenly shaped cubes across the entire original part.
-Which is what I would say if you could divide every possible part into perfect cubes. Because that isn’t possible, my system turns cuboids into squares in the event that fitting perfect cubes isn’t possible, and will make the smallest axis of the original part match up with the divided cubes.
-In simpler terms, if I have a thin wall and divide it with my system, since cubes can’t be perfectly made, it will instead make squares that match the thickness of the wall
And as for actually writing the function that destroys the wall based on a hitbox, I’m gonna keep that to myself, BUT it’s pretty simple. Just create a part of any shape (your ‘hitbox’), and use a loop or run service to constantly check for parts touching your hitbox
. Then, continuously divide the parts that are touching your hitbox until they reach a minimum size.
Now obviously this isn’t super performant with larger destruction, but I’m just gonna chalk that up to a limitation of roblox.
and @treebee63, I ended up not using the cube division script you gave me, so sorry for the trouble with that.