Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --!optimize 2
- local debrisHandler = require(script.DebrisModule)
- local module = {}
- --
- local RES = 1
- local DEBRIS_LIFETIME = 15
- --
- local function CubePointCollision(cubeCFrame, cubeSize, params)
- local point = params[1]
- local localSphereCenter = cubeCFrame:PointToObjectSpace(point)
- local closestLocalPoint = localSphereCenter:Min(cubeSize/2):Max(-cubeSize/2)
- local closestGlobalPoint = cubeCFrame:PointToWorldSpace(closestLocalPoint)
- return (closestGlobalPoint - point).Magnitude
- end
- local function CubeLineCollision(cubeCFrame, cubeSize, params)
- local rayStart = params[1]
- local rayDir = params[2]
- local depth = params[3]-1
- local lowestDist = math.huge
- local offset = 0
- for i = 1, depth do
- local stack = math.ldexp(1, i-1)
- local subRayDir = rayDir/stack
- local totalRayOffset = rayStart + (rayDir*offset)
- local dist1 = CubePointCollision(cubeCFrame, cubeSize, {totalRayOffset + (subRayDir*.25)})
- local dist2 = CubePointCollision(cubeCFrame, cubeSize, {totalRayOffset + (subRayDir*.75)})
- if dist1 < dist2 then
- lowestDist = dist1
- else
- lowestDist = dist2
- offset += .5/stack
- end
- end
- return lowestDist
- end
- local collisionMap = {
- point = CubePointCollision,
- line = CubeLineCollision
- }
- --
- function module.DestroyPartInRange(part, range: number, force, power: number, mode: string, params)
- local partRef = part:Clone()
- part:Destroy()
- local collision = collisionMap[mode]
- local partSize = partRef.Size
- local resFull = (partSize//RES)+Vector3.one
- local resX = resFull.X
- local resY = resFull.Y
- local resZ = resFull.Z
- local resXY = resX*resY
- local bitSize = partSize/resFull
- local debrisSize = bitSize*0.9
- local minBound = partRef.CFrame * CFrame.new((bitSize - partSize)/2)
- local reserved = buffer.create(resX*resY*resZ)
- --
- for Z = 0, resZ-1 do
- local ZIndex = Z * resXY
- for Y = 0, resY-1 do
- local YZIndex = (Y * resX) + ZIndex
- for X = 0, resX-1 do
- local gridIndex = X + YZIndex
- if buffer.readu8(reserved, gridIndex) == 1 then
- continue
- end
- local truePos = minBound * CFrame.new(Vector3.new(X,Y,Z)*bitSize)
- local dist = collision(truePos, bitSize, params)
- if dist > range then
- local xMax, yMax, zMax = 1,1,1
- for x = X+1, resX-1 do
- local reserveIndex = gridIndex+xMax
- local nextTruePos = minBound * CFrame.new(Vector3.new(x,Y,Z)*bitSize)
- if buffer.readu8(reserved, reserveIndex) == 1 or collision(nextTruePos, bitSize, params) <= range then
- break
- end
- buffer.writeu8(reserved, reserveIndex, 1)
- xMax += 1
- end
- for y = Y+1, resY-1 do
- if collision(minBound * CFrame.new(Vector3.new(X+(xMax-1)/2,y,Z)*bitSize), Vector3.new(bitSize.X*xMax, bitSize.Y, bitSize.Z), params) <= range then
- break
- end
- local abort
- local yzIndex = (y*resX) + ZIndex
- for x = X, X+xMax-1 do
- if buffer.readu8(reserved, x + yzIndex) == 1 then
- abort = true
- break
- end
- end
- if abort then
- break
- end
- buffer.fill(reserved, X + yzIndex, 1, xMax)
- yMax += 1
- end
- for z = Z+1, resZ-1 do
- if collision(minBound * CFrame.new(Vector3.new(X+(xMax-1)/2, Y+(yMax-1)/2, z)*bitSize), Vector3.new(bitSize.X*xMax, bitSize.Y*yMax, bitSize.Z), params) <= range then
- break
- end
- local abort
- local clock = os.clock()
- local zIndex = z * resXY
- for y = Y, Y+yMax-1 do
- local yzIndex = (y*resX) + zIndex
- for x = X, X+xMax-1 do
- if buffer.readu8(reserved, x + yzIndex) == 1 then
- abort = true
- break
- end
- end
- if abort then
- break
- end
- end
- if abort then
- break
- end
- for y = Y, Y+yMax-1 do
- buffer.fill(reserved, X + (y*resX) + zIndex, 1, xMax)
- end
- stat += os.clock() - clock
- zMax += 1
- end
- --
- local partSize = bitSize * Vector3.new(xMax, yMax, zMax)
- local bit = partRef:Clone()
- bit.CFrame = truePos * CFrame.new((partSize-bitSize)/2)
- bit.Size = partSize
- bit.Parent = workspace
- elseif dist > range*power then
- task.defer(debrisHandler.CreateDebrisFromRef, force, DEBRIS_LIFETIME, partRef, debrisSize, truePos)
- end
- end
- end
- end
- end
- return module
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement