Advertisement
yal_f

destruction rewrite

Jul 26th, 2024 (edited)
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.10 KB | None | 0 0
  1. --!optimize 2
  2. --!native
  3.  
  4. local VecMin, VecMax = Vector3.one.Min, Vector3.one.Max
  5.  
  6. local BIT_RES = .9
  7.  
  8. --
  9.  
  10. local function CubePointCollision(cubePos: Vector3, cubeSize: Vector3, pointPos: Vector3)
  11.     local halfSize = cubeSize*.5
  12.     local transform = (pointPos - cubePos)
  13.     --local difference = transform - VecMax(VecMin(transform, cubeSize*.5), cubeSize*-.5)
  14.    
  15.     local difference = transform - Vector3.new(
  16.         math.clamp(transform.X, -halfSize.X, halfSize.X),
  17.         math.clamp(transform.Y, -halfSize.Y, halfSize.Y),
  18.         math.clamp(transform.Z, -halfSize.Z, halfSize.Z)
  19.     ) --this turned out to be much faster than vector minmax in native
  20.  
  21.     return (difference.X^2 + difference.Y^2 + difference.Z^2)
  22. end
  23.  
  24. local function CubeLineCollision(cubePos: Vector3, cubeSize: Vector3, lineStart: Vector3, lineDir: Vector3, depth: number)
  25.     local lowestDist = math.huge
  26.    
  27.     local A = lineStart
  28.     local B = lineDir
  29.  
  30.     for _ = 0, depth do
  31.         local dist1 = CubePointCollision(cubePos, cubeSize, A + (B*.25))
  32.         local dist2 = CubePointCollision(cubePos, cubeSize, A + (B*.75))
  33.  
  34.         B /= 2
  35.         if dist1 < dist2 then
  36.             lowestDist = dist1
  37.         else
  38.             A += B
  39.             lowestDist = dist2
  40.         end
  41.     end
  42.  
  43.     return lowestDist
  44. end
  45.  
  46. local function DestroyPart(rootPart: Part, bitRes: number, radius: number, CollisionFunc, ...)
  47.     local partSize = rootPart.Size
  48.     local radiusSqrd = radius^2
  49.    
  50.     if CollisionFunc(partSize*.5, partSize, ...) > radiusSqrd then --quick edge check to see if its colliding atall
  51.         return
  52.     end
  53.    
  54.     rootPart:AddTag("destroying")
  55.    
  56.     local partParent = rootPart.Parent
  57.     local partCFrame = rootPart.CFrame
  58.    
  59.     local sizeFull = (partSize // bitRes) + Vector3.one
  60.     local bitSize = (partSize / sizeFull)
  61.  
  62.     local sizeX = sizeFull.X
  63.     local sizeY = sizeFull.Y
  64.     local sizeZ = sizeFull.Z
  65.     local sizeXY = sizeX*sizeY
  66.  
  67.     local minBound = partCFrame * CFrame.new((bitSize - partSize)*.5)
  68.     local reserved = buffer.create(sizeXY*sizeZ)
  69.  
  70.     --
  71.  
  72.     for Z = 0, sizeZ-1 do
  73.         local Zindex = (Z * sizeXY)
  74.  
  75.         for Y = 0, sizeY-1 do
  76.             local YZindex = (Y * sizeX) + Zindex
  77.  
  78.             for X = 0, sizeX-1 do
  79.                 local startIndex = X + YZindex
  80.  
  81.                 if buffer.readu8(reserved, startIndex) == 1 then
  82.                     continue
  83.                 end
  84.  
  85.                 --point check
  86.                 if CollisionFunc(Vector3.new(X,Y,Z) * bitSize, bitSize, ...) <= radiusSqrd then
  87.                     continue
  88.                 end
  89.                 --
  90.  
  91.                 local maxX, maxY, maxZ = 1,1,1
  92.  
  93.                 --X check
  94.                 for x = 1, sizeX-1-X do
  95.                     if buffer.readu8(reserved, startIndex+x) == 1 or CollisionFunc(Vector3.new(X+x,Y,Z) * bitSize, bitSize, ...) <= radiusSqrd then
  96.                         break
  97.                     end
  98.  
  99.                     maxX += 1
  100.                 end
  101.                 --
  102.                 buffer.fill(reserved, startIndex, 1, maxX)
  103.  
  104.                 local XOffset = X+(maxX-1)*.5
  105.  
  106.                 --Y check
  107.                 local lineSize = Vector3.new(maxX, 1, 1) * bitSize
  108.                 for y = 1, sizeY-1-Y do
  109.                     if CollisionFunc(Vector3.new(XOffset,Y+y,Z) * bitSize, lineSize, ...) <= radiusSqrd then
  110.                         break
  111.                     end
  112.  
  113.                     local exit
  114.                     local currYIndex = startIndex + (y * sizeX)
  115.  
  116.                     for x = 0, maxX-1 do
  117.                         if buffer.readu8(reserved, currYIndex+x) == 1 then
  118.                             exit = true
  119.                             break
  120.                         end
  121.                     end
  122.  
  123.                     if exit then
  124.                         break
  125.                     end
  126.  
  127.                     maxY += 1
  128.                     buffer.fill(reserved, currYIndex, 1, maxX)
  129.                 end
  130.                 --
  131.                 local YOffset = Y+(maxY-1)*.5
  132.  
  133.                 --Z check
  134.                 local planeSize = Vector3.new(maxX, maxY, 1) * bitSize
  135.                 for z = 1, sizeZ-1-Z do
  136.                     if CollisionFunc(Vector3.new(XOffset,YOffset,Z+z) * bitSize, planeSize, ...) <= radiusSqrd then
  137.                         break
  138.                     end
  139.  
  140.                     local exit
  141.                     local currZIndex = startIndex + (z * sizeXY)
  142.  
  143.                     for y = 0, maxY-1 do
  144.                         local currYZIndex = currZIndex + (y * sizeX)
  145.  
  146.                         for x = 0, maxX-1 do
  147.                             if buffer.readu8(reserved, currYZIndex+x) == 1 then
  148.                                 exit = true
  149.                                 break
  150.                             end
  151.                         end
  152.  
  153.                         if exit then
  154.                             break
  155.                         end
  156.                     end
  157.  
  158.                     if exit then
  159.                         break
  160.                     end
  161.  
  162.                     maxZ += 1
  163.                     for y = 0, maxY-1 do
  164.                         buffer.fill(reserved, currZIndex + (y * sizeX), 1, maxX)
  165.                     end
  166.                 end
  167.                 --
  168.  
  169.                 local part = Instance.fromExisting(rootPart)
  170.                 part.CFrame = minBound * CFrame.new(Vector3.new(XOffset, YOffset, Z+(maxZ-1)*.5) * bitSize)
  171.                 part.Size = Vector3.new(maxX, maxY, maxZ) * bitSize
  172.                 part.Parent = partParent
  173.             end
  174.         end
  175.     end
  176.     rootPart:Destroy()
  177. end
  178.  
  179. --
  180.  
  181. local function DestroyPartAtPoint(rootPart: Part, radius: number, point: Vector3)
  182.     DestroyPart(rootPart, BIT_RES, radius, CubePointCollision,
  183.         rootPart.CFrame:PointToObjectSpace(point) + rootPart.Size*.5
  184.     )
  185. end
  186.  
  187. local function DestroyPartAtLine(rootPart: Part, radius: number, lineStart: Vector3, lineEnd: Vector3, depth: number)
  188.     local rootCFrame = rootPart.CFrame
  189.     local rootHalfSize = rootPart.Size*.5
  190.    
  191.     local axisAlignedLineStart = rootCFrame:PointToObjectSpace(lineStart) + rootHalfSize
  192.     local axisAlignedLineDir = rootCFrame:PointToObjectSpace(lineEnd) + rootHalfSize - axisAlignedLineStart
  193.    
  194.     DestroyPart(rootPart, BIT_RES, radius, CubeLineCollision,
  195.         axisAlignedLineStart,
  196.         axisAlignedLineDir,
  197.         depth-1
  198.     )
  199. end
  200.  
  201. --
  202.  
  203. return {
  204.     DestroyPartAtPoint = DestroyPartAtPoint,
  205.     DestroyPartAtLine = DestroyPartAtLine,
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement