Hello guys. I’m trying to improve roblox terrain editor. While I improved results of shapes, I also degrade a lot of performance (256 stud ball with my plugin drop fps up to 7, while roblox built-in one is stable 59)
Can someone help me, and say, how I can optimize this code?
local function GetShapeAffect(Shape, BrushSize, BrushCFrame, VP_X, VP_Y, VP_Z)
if Shape == "Ball" then
local X = VP_X - BrushCFrame.X
local Y = VP_Y - BrushCFrame.Y
local Z = VP_Z - BrushCFrame.Z
local Distance = (X*X + Y*Y + Z*Z)^0.5
if Distance <= BrushSize - 2 then return 1 end
local BrushOccupancy = math.clamp((BrushSize - Distance) / 4 + 0.5, 0, 1)
return if BrushOccupancy >= 0.15 then BrushOccupancy else 0
-- ...other shapes, but I want understand what I'm doing wrong with ball for now.
end
end
--...code which uses this function
if BrushPart.Shape == Enum.PartType.Ball then
local Radius = ToolSettings[Tool]["Brush"]["Size"][2].X / 2 --Getting brush RADIUS (not diameter)
local RegionStart = Vector3.new(math.floor((BrushPart.Position.X - BrushPart.Size.X / 2) / 4) * 4, math.floor((BrushPart.Position.Y - BrushPart.Size.Y / 2) / 4) * 4, math.floor((BrushPart.Position.Z - BrushPart.Size.Z / 2) / 4) * 4) - Vector3.new(4, 4, 4)
local RegionEnd = Vector3.new(math.ceil((BrushPart.Position.X + BrushPart.Size.X / 2) / 4) * 4, math.ceil((BrushPart.Position.Y + BrushPart.Size.Y / 2) / 4) * 4, math.ceil((BrushPart.Position.Z + BrushPart.Size.Z / 2) / 4) * 4) + Vector3.new(4, 4, 4)
local RegionCenter = RegionStart:Lerp(RegionEnd, 0.5)
local Voxels = Region3.new(RegionStart, RegionEnd)
local Materials, Occupancies = workspace.Terrain:ReadVoxels(Voxels, 4)
local OccupanciesModified = {} --Cloning Voxels
for X = 1, #Occupancies, 1 do
OccupanciesModified[X] = {}
for Y = 1, #Occupancies[1], 1 do
OccupanciesModified[X][Y] = {}
for Z = 1, #Occupancies[1][1], 1 do
OccupanciesModified[X][Y][Z] = Occupancies[X][Y][Z]
end
end
end
local BrushPosition = BrushPart.Position
local TargetMaterial = ToolSettings[Tool]["Materials"]["Materials"][2]
for X = RegionStart.X + 2, RegionEnd.X - 2, 4 do
for Y = RegionStart.Y + 2, RegionEnd.Y - 2, 4 do
for Z = RegionStart.Z + 2, RegionEnd.Z - 2, 4 do
local Result = GetShapeAffect("Ball", Radius, BrushPosition, X, Y, Z)
if Result > 0 then
local CeilX = (X - RegionStart.X) / 4 + 0.5
local CeilY = (Y - RegionStart.Y) / 4 + 0.5
local CeilZ = (Z - RegionStart.Z) / 4 + 0.5
if Materials[CeilX][CeilY][CeilZ] == Enum.Material.Air then
Materials[CeilX][CeilY][CeilZ] = Enum.Material[TargetMaterial]
end
OccupanciesModified[CeilX][CeilY][CeilZ] = math.max(Result, OccupanciesModified[CeilX][CeilY][CeilZ])
end
end
end
end
workspace.Terrain:WriteVoxels(Voxels, 4, Materials, OccupanciesModified)
else ...