Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --!optimize 2
- --!native
- local VecMin, VecMax = Vector3.one.Min, Vector3.one.Max
- local BIT_RES = .9
- --
- local function CubePointCollision(cubePos: Vector3, cubeSize: Vector3, pointPos: Vector3)
- local halfSize = cubeSize*.5
- local transform = (pointPos - cubePos)
- --local difference = transform - VecMax(VecMin(transform, cubeSize*.5), cubeSize*-.5)
- local difference = transform - Vector3.new(
- math.clamp(transform.X, -halfSize.X, halfSize.X),
- math.clamp(transform.Y, -halfSize.Y, halfSize.Y),
- math.clamp(transform.Z, -halfSize.Z, halfSize.Z)
- ) --this turned out to be much faster than vector minmax in native
- return (difference.X^2 + difference.Y^2 + difference.Z^2)
- end
- local function CubeLineCollision(cubePos: Vector3, cubeSize: Vector3, lineStart: Vector3, lineDir: Vector3, depth: number)
- local lowestDist = math.huge
- local A = lineStart
- local B = lineDir
- for _ = 0, depth do
- local dist1 = CubePointCollision(cubePos, cubeSize, A + (B*.25))
- local dist2 = CubePointCollision(cubePos, cubeSize, A + (B*.75))
- B /= 2
- if dist1 < dist2 then
- lowestDist = dist1
- else
- A += B
- lowestDist = dist2
- end
- end
- return lowestDist
- end
- local function DestroyPart(rootPart: Part, bitRes: number, radius: number, CollisionFunc, ...)
- local partSize = rootPart.Size
- local radiusSqrd = radius^2
- if CollisionFunc(partSize*.5, partSize, ...) > radiusSqrd then --quick edge check to see if its colliding atall
- return
- end
- rootPart:AddTag("destroying")
- local partParent = rootPart.Parent
- local partCFrame = rootPart.CFrame
- local sizeFull = (partSize // bitRes) + Vector3.one
- local bitSize = (partSize / sizeFull)
- local sizeX = sizeFull.X
- local sizeY = sizeFull.Y
- local sizeZ = sizeFull.Z
- local sizeXY = sizeX*sizeY
- local minBound = partCFrame * CFrame.new((bitSize - partSize)*.5)
- local reserved = buffer.create(sizeXY*sizeZ)
- --
- for Z = 0, sizeZ-1 do
- local Zindex = (Z * sizeXY)
- for Y = 0, sizeY-1 do
- local YZindex = (Y * sizeX) + Zindex
- for X = 0, sizeX-1 do
- local startIndex = X + YZindex
- if buffer.readu8(reserved, startIndex) == 1 then
- continue
- end
- --point check
- if CollisionFunc(Vector3.new(X,Y,Z) * bitSize, bitSize, ...) <= radiusSqrd then
- continue
- end
- --
- local maxX, maxY, maxZ = 1,1,1
- --X check
- for x = 1, sizeX-1-X do
- if buffer.readu8(reserved, startIndex+x) == 1 or CollisionFunc(Vector3.new(X+x,Y,Z) * bitSize, bitSize, ...) <= radiusSqrd then
- break
- end
- maxX += 1
- end
- --
- buffer.fill(reserved, startIndex, 1, maxX)
- local XOffset = X+(maxX-1)*.5
- --Y check
- local lineSize = Vector3.new(maxX, 1, 1) * bitSize
- for y = 1, sizeY-1-Y do
- if CollisionFunc(Vector3.new(XOffset,Y+y,Z) * bitSize, lineSize, ...) <= radiusSqrd then
- break
- end
- local exit
- local currYIndex = startIndex + (y * sizeX)
- for x = 0, maxX-1 do
- if buffer.readu8(reserved, currYIndex+x) == 1 then
- exit = true
- break
- end
- end
- if exit then
- break
- end
- maxY += 1
- buffer.fill(reserved, currYIndex, 1, maxX)
- end
- --
- local YOffset = Y+(maxY-1)*.5
- --Z check
- local planeSize = Vector3.new(maxX, maxY, 1) * bitSize
- for z = 1, sizeZ-1-Z do
- if CollisionFunc(Vector3.new(XOffset,YOffset,Z+z) * bitSize, planeSize, ...) <= radiusSqrd then
- break
- end
- local exit
- local currZIndex = startIndex + (z * sizeXY)
- for y = 0, maxY-1 do
- local currYZIndex = currZIndex + (y * sizeX)
- for x = 0, maxX-1 do
- if buffer.readu8(reserved, currYZIndex+x) == 1 then
- exit = true
- break
- end
- end
- if exit then
- break
- end
- end
- if exit then
- break
- end
- maxZ += 1
- for y = 0, maxY-1 do
- buffer.fill(reserved, currZIndex + (y * sizeX), 1, maxX)
- end
- end
- --
- local part = Instance.fromExisting(rootPart)
- part.CFrame = minBound * CFrame.new(Vector3.new(XOffset, YOffset, Z+(maxZ-1)*.5) * bitSize)
- part.Size = Vector3.new(maxX, maxY, maxZ) * bitSize
- part.Parent = partParent
- end
- end
- end
- rootPart:Destroy()
- end
- --
- local function DestroyPartAtPoint(rootPart: Part, radius: number, point: Vector3)
- DestroyPart(rootPart, BIT_RES, radius, CubePointCollision,
- rootPart.CFrame:PointToObjectSpace(point) + rootPart.Size*.5
- )
- end
- local function DestroyPartAtLine(rootPart: Part, radius: number, lineStart: Vector3, lineEnd: Vector3, depth: number)
- local rootCFrame = rootPart.CFrame
- local rootHalfSize = rootPart.Size*.5
- local axisAlignedLineStart = rootCFrame:PointToObjectSpace(lineStart) + rootHalfSize
- local axisAlignedLineDir = rootCFrame:PointToObjectSpace(lineEnd) + rootHalfSize - axisAlignedLineStart
- DestroyPart(rootPart, BIT_RES, radius, CubeLineCollision,
- axisAlignedLineStart,
- axisAlignedLineDir,
- depth-1
- )
- end
- --
- return {
- DestroyPartAtPoint = DestroyPartAtPoint,
- DestroyPartAtLine = DestroyPartAtLine,
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement