Advertisement
yal_f

Untitled

May 2nd, 2024
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 22.49 KB | None | 0 0
  1. --!optimize 2
  2.  
  3. local RepStorage = game:FindService("ReplicatedStorage")
  4. local blockData = require(RepStorage.BlockData)
  5. local chunkFolder = workspace.Chunks
  6. local chunkRef = script.Chunk
  7. local rand = Random.new()
  8. local chunks = {}
  9. local module = {}
  10.  
  11. --config:
  12.  
  13. local chunkWidth = 16
  14.  
  15. local seeds = {
  16.     rand:NextNumber(-1000000,1000000),
  17.     rand:NextNumber(-1000000,1000000),
  18.     rand:NextNumber(-1000000,1000000),
  19.     rand:NextNumber(-1000000,1000000)
  20. }
  21.  
  22. local noiseWidth = 1.8
  23.  
  24. local noiseHeight = 30
  25. local noiseOffset = 1
  26.  
  27. --constants:
  28. local IDX_editMesh = 1
  29. local IDX_mesh = 2
  30. local IDX_position = 3
  31. local IDX_voxels = 4
  32.  
  33. local IDX_other = 0
  34. local IDX_reserved = 1
  35.  
  36. --init:
  37. noiseOffset *= chunkWidth
  38. noiseWidth = 1/(noiseWidth*55)
  39. local chunkWidthSquared = chunkWidth^2
  40. local posLimit = chunkWidth-1
  41. local chunkVector = Vector3.new(chunkWidth,chunkWidth,chunkWidth)
  42.  
  43. local VERT_OFFS_1 = Vector3.new(-0.5, -0.5, -0.5)
  44. local VERT_OFFS_2 = Vector3.new( 0.5, -0.5, -0.5)
  45. local VERT_OFFS_3 = Vector3.new(-0.5, -0.5,  0.5)
  46. local VERT_OFFS_4 = Vector3.new( 0.5, -0.5,  0.5)
  47. local VERT_OFFS_5 = Vector3.new(-0.5,  0.5, -0.5)
  48. local VERT_OFFS_6 = Vector3.new( 0.5,  0.5, -0.5)
  49. local VERT_OFFS_7 = Vector3.new(-0.5,  0.5,  0.5)
  50. local VERT_OFFS_8 = Vector3.new( 0.5,  0.5,  0.5)
  51.  
  52. local stat = {
  53.     one = 0,
  54.     two = 0,
  55.     three = 0
  56. }
  57.  
  58. --logic:
  59.  
  60. --[[
  61. local function ClearEditableMesh(editMesh)
  62.     for i, v in editMesh:GetTriangles() do
  63.         editMesh:RemoveTriangle(v)
  64.     end
  65.    
  66.     for _, v in editMesh:GetVertices() do
  67.         editMesh:RemoveVertex(v)
  68.     end
  69. end
  70. ]]
  71.  
  72. local function Flatten(x,y,z)
  73.     local inBounds = x < chunkWidth and y < chunkWidth and z < chunkWidth
  74.     return inBounds and x + (y * chunkWidth) + (z * chunkWidthSquared) + 1
  75. end
  76.  
  77. local function GetVoxel(x,y,z)
  78.     local vectorPos = Vector3.new(x,y,z)
  79.     local chunkPos = vectorPos // chunkWidth
  80.     local chunk = chunks[chunkPos]
  81.     local finalPos = vectorPos - chunkPos*chunkWidth
  82.     return chunk and chunk[IDX_voxels][Flatten(finalPos.X,finalPos.Y,finalPos.Z)]
  83. end
  84.  
  85. local function DeleteVoxel(chunk, x,y,z)
  86.     chunk[IDX_voxels][Flatten(x,y,z)] = nil
  87. end
  88.  
  89. local function NewVoxel(chunk, x,y,z , blockID)
  90.     local buff = buffer.create(7)
  91.     buffer.writeu8(buff, 0, blockID)
  92.  
  93.     chunk[IDX_voxels][Flatten(x,y,z)] = buff
  94. end
  95.  
  96. local function GetChunkNeighbors(chunkPos)
  97.     return {
  98.         chunks[chunkPos - Vector3.yAxis],
  99.         chunks[chunkPos + Vector3.yAxis],
  100.         chunks[chunkPos - Vector3.zAxis],
  101.         chunks[chunkPos + Vector3.zAxis],
  102.         chunks[chunkPos - Vector3.xAxis],
  103.         chunks[chunkPos + Vector3.xAxis]
  104.     }
  105. end
  106.  
  107. local function UpdateChunkSingle(chunk)
  108.     if not chunk then return end
  109.  
  110.     local oldEditMesh = chunk[IDX_editMesh]
  111.     local mesh = chunk[IDX_mesh]
  112.     local voxels = chunk[IDX_voxels]
  113.     local replaceEditMesh = #oldEditMesh:GetVertices() ~= 0
  114.  
  115.     local editMesh
  116.     if replaceEditMesh then
  117.         editMesh = Instance.new("EditableMesh")
  118.         chunk[IDX_editMesh] = editMesh
  119.     else
  120.         editMesh = oldEditMesh
  121.     end
  122.  
  123.     if next(voxels) then
  124.         local chunkLocalPos = chunk[IDX_position]
  125.         local chunkPos = chunkLocalPos * chunkWidth
  126.         local chunkNeighbors = GetChunkNeighbors(chunkLocalPos)
  127.  
  128.         for Z = 0,posLimit do
  129.             for Y = 0,posLimit do
  130.                 for X = 0,posLimit do
  131.                     local voxel = voxels[Flatten(X,Y,Z)]
  132.                     if not voxel then continue end
  133.                    
  134.                     local centerPos = Vector3.new(X,Y,Z)
  135.  
  136.                     local p1 = centerPos + VERT_OFFS_1
  137.                     local p2 = centerPos + VERT_OFFS_2
  138.                     local p3 = centerPos + VERT_OFFS_3
  139.                     local p4 = centerPos + VERT_OFFS_4
  140.                     local p5 = centerPos + VERT_OFFS_5
  141.                     local p6 = centerPos + VERT_OFFS_6
  142.                     local p7 = centerPos + VERT_OFFS_7
  143.                     local p8 = centerPos + VERT_OFFS_8
  144.  
  145.                     local blockID = buffer.readu8(voxel, 0)
  146.  
  147.                     --bottom face
  148.                     if buffer.readu8(voxel, 1) ~= IDX_reserved then
  149.                         local chunkNeighbor = chunkNeighbors[1]
  150.                         local Xlimit = 0
  151.                         local Zlimit = 1
  152.  
  153.                         --greedy meshing X
  154.                         for x = X, posLimit do
  155.                             local nextVoxel = x == X and voxel or voxels[Flatten(x, Y, Z)]
  156.  
  157.                             if not nextVoxel or buffer.readu8(nextVoxel, 1) == IDX_reserved or buffer.readu8(nextVoxel, 0) ~= blockID or (Y == 0 and chunkNeighbor and chunkNeighbor[IDX_voxels][Flatten(x,posLimit,Z)]) or (Y ~= 0 and voxels[Flatten(x, Y-1, Z)]) then
  158.                                 break
  159.                             end
  160.  
  161.                             Xlimit += 1
  162.                             buffer.writeu8(nextVoxel, 1, IDX_reserved)
  163.                         end
  164.                         --
  165.  
  166.                         if Xlimit ~= 0 then
  167.                             --greedy meshing Z
  168.                             for i = 1, chunkWidth-Z do
  169.                                 local toReserve = {}
  170.                                 local abort
  171.  
  172.                                 for j = 0, Xlimit-1 do
  173.                                     local nextVoxel = voxels[Flatten(X+j, Y, Z+Zlimit)]
  174.  
  175.                                     if not nextVoxel or buffer.readu8(nextVoxel, 0) ~= blockID or (Y == 0 and chunkNeighbor and chunkNeighbor[IDX_voxels][Flatten(X+j,posLimit,Z+Zlimit)]) or (Y ~= 0 and voxels[Flatten(X+j, Y-1, Z+Zlimit)]) then
  176.                                         abort = true
  177.                                         break
  178.                                     end
  179.  
  180.                                     toReserve[j+1] = nextVoxel
  181.                                 end
  182.  
  183.                                 if abort then
  184.                                     break
  185.                                 end
  186.  
  187.                                 for _, obj in toReserve do
  188.                                     buffer.writeu8(obj, 1, IDX_reserved)
  189.                                 end
  190.                                 Zlimit += 1
  191.                             end
  192.                             --
  193.  
  194.                             local color = blockData[blockID][1]
  195.                             local greedyOffsetX = Vector3.xAxis*(Xlimit - 1)
  196.                             local greedyOffsetZ = Vector3.zAxis*(Zlimit - 1)
  197.  
  198.                             local vert1 = editMesh:AddVertex(p1)
  199.                             local vert2 = editMesh:AddVertex(p2+greedyOffsetX)
  200.                             local vert3 = editMesh:AddVertex(p3+greedyOffsetZ)
  201.                             local vert4 = editMesh:AddVertex(p4+greedyOffsetX+greedyOffsetZ)
  202.  
  203.                             editMesh:SetVertexColor(vert1, color)
  204.                             editMesh:SetVertexColor(vert2, color)
  205.                             editMesh:SetVertexColor(vert3, color)
  206.                             editMesh:SetVertexColor(vert4, color)
  207.  
  208.                             editMesh:AddTriangle(vert1, vert2, vert4)
  209.                             editMesh:AddTriangle(vert4, vert3, vert1)
  210.                         end
  211.                     end
  212.                     --
  213.  
  214.                     --top face
  215.                     if buffer.readu8(voxel, 2) ~= IDX_reserved then
  216.                         local chunkNeighbor = chunkNeighbors[2]
  217.                         local Xlimit = 0
  218.                         local Zlimit = 1
  219.  
  220.                         --greedy meshing X
  221.                         for x = X, posLimit do
  222.                             local nextVoxel = x == X and voxel or voxels[Vector3.new(x, Y, Z)]
  223.  
  224.                             if not nextVoxel or buffer.readu8(nextVoxel, 2) == IDX_reserved or buffer.readu8(nextVoxel, 0) ~= blockID or (Y == posLimit and chunkNeighbor and chunkNeighbor[IDX_voxels][Flatten(x,0,Z)]) or (Y ~= posLimit and voxels[Flatten(x, Y+1, Z)]) then
  225.                                 break
  226.                             end
  227.  
  228.                             Xlimit += 1
  229.                             buffer.writeu8(nextVoxel, 2, IDX_reserved)
  230.                         end
  231.                         --
  232.  
  233.                         if Xlimit ~= 0 then
  234.                             --greedy meshing Z
  235.                             for i = 1, chunkWidth-Z do
  236.                                 local toReserve = {}
  237.                                 local abort
  238.  
  239.                                 for j = 0, Xlimit-1 do
  240.                                     local nextVoxel = voxels[Flatten(X+j, Y, Z+Zlimit)]
  241.  
  242.                                     if not nextVoxel or buffer.readu8(nextVoxel, 0) ~= blockID or (Y == posLimit and chunkNeighbor and chunkNeighbor[IDX_voxels][Flatten(X+j,0,Z+Zlimit)]) or (Y ~= posLimit and voxels[Flatten(X+j, Y+1, Z+Zlimit)]) then
  243.                                         abort = true
  244.                                         break
  245.                                     end
  246.  
  247.                                     toReserve[j+1] = nextVoxel
  248.                                 end
  249.  
  250.                                 if abort then
  251.                                     break
  252.                                 end
  253.  
  254.                                 for _, obj in toReserve do
  255.                                     buffer.writeu8(obj, 2, IDX_reserved)
  256.                                 end
  257.                                 Zlimit += 1
  258.                             end
  259.                             --
  260.  
  261.                             local color = blockData[blockID][1]
  262.                             local greedyOffsetX = Vector3.xAxis*(Xlimit - 1)
  263.                             local greedyOffsetZ = Vector3.zAxis*(Zlimit - 1)
  264.  
  265.                             local vert1 = editMesh:AddVertex(p5)
  266.                             local vert2 = editMesh:AddVertex(p6+greedyOffsetX)
  267.                             local vert3 = editMesh:AddVertex(p7+greedyOffsetZ)
  268.                             local vert4 = editMesh:AddVertex(p8+greedyOffsetX+greedyOffsetZ)
  269.  
  270.                             editMesh:SetVertexColor(vert1, color)
  271.                             editMesh:SetVertexColor(vert2, color)
  272.                             editMesh:SetVertexColor(vert3, color)
  273.                             editMesh:SetVertexColor(vert4, color)
  274.  
  275.                             editMesh:AddTriangle(vert1, vert3, vert4)
  276.                             editMesh:AddTriangle(vert4, vert2, vert1)
  277.                         end
  278.                     end
  279.                     --
  280.  
  281.                     --left face
  282.                     if buffer.readu8(voxel, 3) ~= IDX_reserved then
  283.                         local chunkNeighbor = chunkNeighbors[3]
  284.                         local Xlimit = 0
  285.                         local Ylimit = 1
  286.  
  287.                         --greedy meshing X
  288.                         for x = X, posLimit do
  289.                             local nextVoxel = x == X and voxel or voxels[Flatten(x, Y, Z)]
  290.  
  291.                             if not nextVoxel or buffer.readu8(nextVoxel, 3) == IDX_reserved or buffer.readu8(nextVoxel, 0) ~= blockID or (Z == 0 and chunkNeighbor and chunkNeighbor[IDX_voxels][Flatten(x,Y,posLimit)]) or (Z ~= 0 and voxels[Flatten(x, Y, Z-1)]) then
  292.                                 break
  293.                             end
  294.  
  295.                             Xlimit += 1
  296.                             buffer.writeu8(nextVoxel, 3, IDX_reserved)
  297.                         end
  298.                         --
  299.  
  300.                         if Xlimit ~= 0 then
  301.                             --greedy meshing Y
  302.                             for i = 1, chunkWidth-Y do
  303.                                 local toReserve = {}
  304.                                 local abort
  305.  
  306.                                 for j = 0, Xlimit-1 do
  307.                                     local nextVoxel = voxels[Flatten(X+j, Y+Ylimit, Z)]
  308.  
  309.                                     if not nextVoxel or buffer.readu8(nextVoxel, 3) == IDX_reserved or buffer.readu8(nextVoxel, 0) ~= blockID or (Z == 0 and chunkNeighbor and chunkNeighbor[IDX_voxels][Flatten(X+j,Y+Ylimit,posLimit)]) or (Z ~= 0 and voxels[Flatten(X+j, Y+Ylimit, Z-1)]) then
  310.                                         abort = true
  311.                                         break
  312.                                     end
  313.  
  314.                                     toReserve[j+1] = nextVoxel
  315.                                 end
  316.  
  317.                                 if abort then
  318.                                     break
  319.                                 end
  320.  
  321.                                 for _, obj in toReserve do
  322.                                     buffer.writeu8(obj, 3, IDX_reserved)
  323.                                 end
  324.                                 Ylimit += 1
  325.                             end
  326.                             --
  327.  
  328.                             local color = blockData[blockID][1]
  329.                             local greedyOffsetX = Vector3.xAxis*(Xlimit - 1)
  330.                             local greedyOffsetY = Vector3.yAxis*(Ylimit - 1)
  331.  
  332.                             local vert1 = editMesh:AddVertex(p1)
  333.                             local vert2 = editMesh:AddVertex(p2+greedyOffsetX)
  334.                             local vert3 = editMesh:AddVertex(p5+greedyOffsetY)
  335.                             local vert4 = editMesh:AddVertex(p6+greedyOffsetX+greedyOffsetY)
  336.  
  337.                             editMesh:SetVertexColor(vert1, color)
  338.                             editMesh:SetVertexColor(vert2, color)
  339.                             editMesh:SetVertexColor(vert3, color)
  340.                             editMesh:SetVertexColor(vert4, color)
  341.  
  342.                             editMesh:AddTriangle(vert4, vert2, vert1)
  343.                             editMesh:AddTriangle(vert1, vert3, vert4)
  344.                         end
  345.                     end
  346.                     --
  347.  
  348.                     --right face
  349.                     if buffer.readu8(voxel, 4) ~= IDX_reserved then
  350.                         local chunkNeighbor = chunkNeighbors[4]
  351.                         local Xlimit = 0
  352.                         local Ylimit = 1
  353.  
  354.                         --greedy meshing X
  355.                         for x = X, posLimit do
  356.                             local nextVoxel = x == X and voxel or voxels[Flatten(x, Y, Z)]
  357.  
  358.                             if not nextVoxel or buffer.readu8(nextVoxel, 4) == IDX_reserved or buffer.readu8(nextVoxel, 0) ~= blockID or (Z == posLimit and chunkNeighbor and chunkNeighbor[IDX_voxels][Flatten(x,Y,0)]) or (Z ~= posLimit and voxels[Flatten(x, Y, Z+1)]) then
  359.                                 break
  360.                             end
  361.  
  362.                             Xlimit += 1
  363.                             buffer.writeu8(nextVoxel, 4, IDX_reserved)
  364.                         end
  365.                         --
  366.  
  367.                         if Xlimit ~= 0 then
  368.                             --greedy meshing Y
  369.                             for i = 1, chunkWidth-Y do
  370.                                 local toReserve = {}
  371.                                 local abort
  372.  
  373.                                 for j = 0, Xlimit-1 do
  374.                                     local nextVoxel = voxels[Flatten(X+j, Y+Ylimit, Z)]
  375.  
  376.                                     if not nextVoxel or buffer.readu8(nextVoxel, 4) == IDX_reserved or buffer.readu8(nextVoxel, 0) ~= blockID or (Z == posLimit and chunkNeighbor and chunkNeighbor[IDX_voxels][Flatten(X+j,Y+Ylimit,0)]) or (Z ~= posLimit and voxels[Flatten(X+j, Y+Ylimit, Z+1)]) then
  377.                                         abort = true
  378.                                         break
  379.                                     end
  380.  
  381.                                     toReserve[j+1] = nextVoxel
  382.                                 end
  383.  
  384.                                 if abort then
  385.                                     break
  386.                                 end
  387.  
  388.                                 for _, obj in toReserve do
  389.                                     buffer.writeu8(obj, 4, IDX_reserved)
  390.                                 end
  391.                                 Ylimit += 1
  392.                             end
  393.                             --
  394.  
  395.                             local color = blockData[blockID][1]
  396.                             local greedyOffsetX = Vector3.xAxis*(Xlimit - 1)
  397.                             local greedyOffsetY = Vector3.yAxis*(Ylimit - 1)
  398.  
  399.                             local vert1 = editMesh:AddVertex(p3)
  400.                             local vert2 = editMesh:AddVertex(p4+greedyOffsetX)
  401.                             local vert3 = editMesh:AddVertex(p7+greedyOffsetY)
  402.                             local vert4 = editMesh:AddVertex(p8+greedyOffsetX+greedyOffsetY)
  403.  
  404.                             editMesh:SetVertexColor(vert1, color)
  405.                             editMesh:SetVertexColor(vert2, color)
  406.                             editMesh:SetVertexColor(vert3, color)
  407.                             editMesh:SetVertexColor(vert4, color)
  408.  
  409.                             editMesh:AddTriangle(vert3, vert1, vert2)
  410.                             editMesh:AddTriangle(vert2, vert4, vert3)
  411.                         end
  412.                     end
  413.                     --
  414.  
  415.                     --back face
  416.                     if buffer.readu8(voxel, 5) ~= IDX_reserved then
  417.                         local chunkNeighbor = chunkNeighbors[5]
  418.                         local Zlimit = 0
  419.                         local Ylimit = 1
  420.  
  421.                         --greedy meshing Z
  422.                         for z = Z, posLimit do
  423.                             local nextVoxel = z == Z and voxel or voxels[Flatten(X, Y, z)]
  424.  
  425.                             if not nextVoxel or buffer.readu8(nextVoxel, 5) == IDX_reserved or buffer.readu8(nextVoxel, 0) ~= blockID or (X == 0 and chunkNeighbor and chunkNeighbor[IDX_voxels][Flatten(posLimit,Y,z)]) or (X ~= 0 and voxels[Flatten(X-1, Y, z)]) then
  426.                                 break
  427.                             end
  428.  
  429.                             Zlimit += 1
  430.                             buffer.writeu8(nextVoxel, 5, IDX_reserved)
  431.                         end
  432.  
  433.                         if Zlimit ~= 0 then
  434.                             --greedy meshing Y
  435.                             for i = 1, chunkWidth-Y do
  436.                                 local toReserve = {}
  437.                                 local abort
  438.  
  439.                                 for j = 0, Zlimit-1 do
  440.                                     local nextVoxel = voxels[Flatten(X, Y+Ylimit, Z+j)]
  441.  
  442.                                     if not nextVoxel or buffer.readu8(nextVoxel, 5) == IDX_reserved or buffer.readu8(nextVoxel, 0) ~= blockID or (X == 0 and chunkNeighbor and chunkNeighbor[IDX_voxels][Flatten(posLimit,Y+Ylimit,Z+j)]) or (X ~= 0 and voxels[Flatten(X-1, Y+Ylimit, Z+j)]) then
  443.                                         abort = true
  444.                                         break
  445.                                     end
  446.  
  447.                                     toReserve[j+1] = nextVoxel
  448.                                 end
  449.  
  450.                                 if abort then
  451.                                     break
  452.                                 end
  453.  
  454.                                 for _, obj in toReserve do
  455.                                     buffer.writeu8(obj, 5, IDX_reserved)
  456.                                 end
  457.                                 Ylimit += 1
  458.                             end
  459.                             --
  460.  
  461.                             local color = blockData[blockID][1]
  462.                             local greedyOffsetZ = Vector3.zAxis*(Zlimit - 1)
  463.                             local greedyOffsetY = Vector3.yAxis*(Ylimit - 1)
  464.  
  465.                             local vert1 = editMesh:AddVertex(p1)
  466.                             local vert2 = editMesh:AddVertex(p3+greedyOffsetZ)
  467.                             local vert3 = editMesh:AddVertex(p5+greedyOffsetY)
  468.                             local vert4 = editMesh:AddVertex(p7+greedyOffsetZ+greedyOffsetY)
  469.  
  470.                             editMesh:SetVertexColor(vert1, color)
  471.                             editMesh:SetVertexColor(vert2, color)
  472.                             editMesh:SetVertexColor(vert3, color)
  473.                             editMesh:SetVertexColor(vert4, color)
  474.  
  475.                             editMesh:AddTriangle(vert3, vert1, vert2)
  476.                             editMesh:AddTriangle(vert2, vert4, vert3)
  477.                         end
  478.                     end
  479.                     --
  480.  
  481.                     --front face
  482.                     if buffer.readu8(voxel, 6) ~= IDX_reserved then
  483.                         local chunkNeighbor = chunkNeighbors[6]
  484.                         local Zlimit = 0
  485.                         local Ylimit = 1
  486.  
  487.                         for z = Z, posLimit do
  488.                             local nextVoxel = z == Z and voxel or voxels[Flatten(X, Y, z)]
  489.  
  490.                             if not nextVoxel or buffer.readu8(nextVoxel, 6) == IDX_reserved or buffer.readu8(nextVoxel, 0) ~= blockID or (X == posLimit and chunkNeighbor and chunkNeighbor[IDX_voxels][Flatten(0,Y,z)]) or (X ~= posLimit and voxels[Flatten(X+1, Y, z)]) then
  491.                                 break
  492.                             end
  493.  
  494.                             Zlimit += 1
  495.                             buffer.writeu8(nextVoxel, 6, IDX_reserved)
  496.                         end
  497.  
  498.                         if Zlimit ~= 0 then
  499.                             --greedy meshing Y
  500.                             for i = 1, chunkWidth-Y do
  501.                                 local toReserve = {}
  502.                                 local abort
  503.  
  504.                                 for j = 0, Zlimit-1 do
  505.                                     local nextVoxel = voxels[Flatten(X, Y+Ylimit, Z+j)]
  506.  
  507.                                     if not nextVoxel or buffer.readu8(nextVoxel, 6) == IDX_reserved or buffer.readu8(nextVoxel, 0) ~= blockID or (X == posLimit and chunkNeighbor and chunkNeighbor[IDX_voxels][Flatten(0,Y+Ylimit,Z+j)]) or (X ~= posLimit and voxels[Flatten(X+1, Y+Ylimit, Z+j)]) then
  508.                                         abort = true
  509.                                         break
  510.                                     end
  511.  
  512.                                     toReserve[j+1] = nextVoxel
  513.                                 end
  514.  
  515.                                 if abort then
  516.                                     break
  517.                                 end
  518.  
  519.                                 for _, obj in toReserve do
  520.                                     buffer.writeu8(obj, 6, IDX_reserved)
  521.                                 end
  522.                                 Ylimit += 1
  523.                             end
  524.                             --
  525.  
  526.                             local color = blockData[blockID][1]
  527.                             local greedyOffsetZ = Vector3.zAxis*(Zlimit - 1)
  528.                             local greedyOffsetY = Vector3.yAxis*(Ylimit - 1)
  529.  
  530.                             local vert1 = editMesh:AddVertex(p2)
  531.                             local vert2 = editMesh:AddVertex(p4+greedyOffsetZ)
  532.                             local vert3 = editMesh:AddVertex(p6+greedyOffsetY)
  533.                             local vert4 = editMesh:AddVertex(p8+greedyOffsetZ+greedyOffsetY)
  534.  
  535.                             editMesh:SetVertexColor(vert1, color)
  536.                             editMesh:SetVertexColor(vert2, color)
  537.                             editMesh:SetVertexColor(vert3, color)
  538.                             editMesh:SetVertexColor(vert4, color)
  539.  
  540.                             editMesh:AddTriangle(vert4, vert2, vert1)
  541.                             editMesh:AddTriangle(vert1, vert3, vert4)
  542.                         end
  543.                     end
  544.                     --
  545.                     buffer.fill(voxel, 1, IDX_other)
  546.                 end
  547.             end
  548.         end
  549.     end
  550.     if replaceEditMesh then
  551.         oldEditMesh:Destroy()
  552.         editMesh.Parent = mesh
  553.     elseif mesh.Transparency == 1 then
  554.         task.spawn(function()
  555.             while true do
  556.                 local result = mesh.Transparency - task.wait()*5
  557.                 if result <= 0 then
  558.                     mesh.Transparency = 0
  559.                     return
  560.                 end
  561.                 mesh.Transparency = result
  562.             end
  563.         end)
  564.     end
  565. end
  566.  
  567. local function ChunkUpdate(chunkPos)
  568.     UpdateChunkSingle(chunks[chunkPos])
  569.     for _, chunk in GetChunkNeighbors(chunkPos) do
  570.         UpdateChunkSingle(chunk)
  571.     end
  572. end
  573.  
  574. local function NewChunk(chunkPos)
  575.     local mesh = chunkRef:Clone()
  576.     mesh.Position = chunkPos * chunkWidth
  577.  
  578.     local chunk = {
  579.         Instance.new("EditableMesh", mesh),
  580.         mesh,
  581.         chunkPos,
  582.         {}
  583.     }
  584.     mesh.Parent = chunkFolder
  585.  
  586.     chunks[chunkPos] = chunk
  587.     return chunk
  588. end
  589.  
  590. function GetChunksWithinRange(centerPos, range, createChunks)
  591.     local rangeVector = Vector3.new(range, range, range)
  592.  
  593.     local minPos = centerPos - rangeVector
  594.     local maxPos = centerPos + rangeVector
  595.  
  596.     local touchingChunks = {}
  597.     for x = minPos.X // chunkWidth, math.ceil(maxPos.X / chunkWidth) do
  598.         for y =minPos.Y // chunkWidth, math.ceil(maxPos.Y / chunkWidth) do
  599.             for z = minPos.Z // chunkWidth, math.ceil(maxPos.Z / chunkWidth) do
  600.                 local iterPos = Vector3.new(x,y,z)
  601.  
  602.                 local chunkMin = iterPos * chunkWidth
  603.                 local chunkMax = chunkMin + chunkVector
  604.  
  605.                 local closestPoint = chunkMin:Max(centerPos:Min(chunkMax))
  606.  
  607.                 local distanceToCenter = (closestPoint - centerPos).Magnitude
  608.                 if distanceToCenter <= range then
  609.                     local chunk = chunks[iterPos] or createChunks and NewChunk(iterPos)
  610.                     if chunk then
  611.                         table.insert(touchingChunks, chunk)
  612.                     end
  613.                 end
  614.             end
  615.         end
  616.     end
  617.  
  618.     return touchingChunks
  619. end
  620.  
  621. local function CreateNoise(X, Z)
  622.     local noise1 = math.noise(X * noiseWidth, seeds[2], Z * noiseWidth)
  623.     local noise2 = math.noise(X * noiseWidth*2.5, seeds[3], Z * noiseWidth*2.5)/3
  624.     local noise3 = math.noise(X * noiseWidth*7, seeds[4], Z * noiseWidth*7)/25
  625.     local specialNoise = math.noise(X * noiseWidth/4, seeds[1], Z * noiseWidth/4)*3
  626.  
  627.     local noiseSum = (noise1+noise2+noise3+specialNoise)
  628.     return math.floor((noiseSum*noiseHeight)+noiseOffset)
  629. end
  630.  
  631. --
  632.  
  633. function module.UpdateAllChunks()
  634.     for _, chunk in chunks do
  635.         UpdateChunkSingle(chunk)
  636.     end
  637.     warn("updated all chunks!")
  638. end
  639.  
  640. function module.ChunkUpdate(chunkPos)
  641.     ChunkUpdate(chunkPos)
  642. end
  643.  
  644. function module.UpdateChunkSingle(chunk)
  645.     UpdateChunkSingle(chunk)
  646. end
  647.  
  648. function module.RemoveVoxelsInRange(pos, range)
  649.     local halfRange = range/2
  650.  
  651.     for z = -range, range do
  652.         local zSquared = z^2
  653.         if z % 100 == 0 then
  654.             task.wait()
  655.         end
  656.         for y = -range, range do
  657.             local ySquared = y^2
  658.             for x = -range, range do
  659.                 if math.sqrt(x^2 + ySquared + zSquared) > halfRange then
  660.                     continue
  661.                 end
  662.  
  663.                 local truePos = pos+Vector3.new(x,y,z)
  664.                 local chunkPos = truePos // chunkWidth
  665.                 local chunk = chunks[chunkPos]
  666.  
  667.                 if chunk then
  668.                     local lastPos = truePos - chunkPos*chunkWidth
  669.                     DeleteVoxel(chunk, lastPos.X, lastPos.Y, lastPos.Z)
  670.                 end
  671.             end
  672.         end
  673.     end
  674.  
  675.     for _, chunk in GetChunksWithinRange(pos, halfRange+1) do
  676.         --[[
  677.         local part = Instance.new("Part")
  678.         part.Transparency = 1
  679.         part.Anchored = true
  680.         part.CanCollide = false
  681.         part.Size = Vector3.new(chunkWidth, chunkWidth, chunkWidth)
  682.         part.Position = chunk[IDX_position] * chunkWidth + Vector3.new((chunkWidth/2)-0.5, (chunkWidth/2)-0.5, (chunkWidth/2)-0.5)
  683.         local box = Instance.new("SelectionBox", part)
  684.         box.Adornee = part
  685.         part.Parent = workspace
  686.         ]]
  687.  
  688.         task.defer(UpdateChunkSingle, chunk)
  689.     end
  690. end
  691.  
  692. function module.AddVoxelsInRange(pos, range, blockID)
  693.     local halfRange = range/2
  694.  
  695.     for z = -range, range do
  696.         local zSquared = z^2
  697.         if z % 100 == 0 then
  698.             task.wait()
  699.         end
  700.         for y = -range, range do
  701.             local ySquared = y^2
  702.             for x = -range, range do
  703.                 if math.sqrt(x^2 + ySquared + zSquared) > halfRange then
  704.                     continue
  705.                 end
  706.  
  707.                 local truePos = pos+Vector3.new(x,y,z)
  708.                 local chunkPos = truePos // chunkWidth
  709.                 local chunk = chunks[chunkPos] or NewChunk(chunkPos)
  710.                 local lastPos = truePos - chunkPos*chunkWidth
  711.  
  712.                 NewVoxel(chunk, lastPos.X, lastPos.Y, lastPos.Z, blockID)
  713.             end
  714.         end
  715.     end
  716.  
  717.     for _, chunk in GetChunksWithinRange(pos, halfRange+1) do
  718.         task.defer(UpdateChunkSingle, chunk)
  719.     end
  720. end
  721.  
  722. function module.Raycast(from, direction, length)
  723.     local res = 0.05
  724.  
  725.     local half = Vector3.new(.5,.5,.5)
  726.     for i = res,length,res do
  727.         local pos = (from + direction*i + half) // 1
  728.         if GetVoxel(pos.X, pos.Y, pos.Z) then
  729.             return pos
  730.         end
  731.     end
  732. end
  733.  
  734. function module.GetStats()
  735.     local chunkCount = 0
  736.     local voxelCount = 0
  737.     local triCount = 0
  738.  
  739.     warn("getting stats...")
  740.     for _, chunk in chunks do
  741.         if chunkCount/2 % 140 == 0 then
  742.             task.wait()
  743.         end
  744.         chunkCount += 1
  745.         for _, voxel in chunk[IDX_voxels] do
  746.             voxelCount += 1
  747.         end
  748.         triCount += #chunk[IDX_editMesh]:GetTriangles()
  749.     end
  750.  
  751.     return {
  752.         "chunk amount: "..chunkCount,
  753.         "voxel amount: "..voxelCount,
  754.         "tri amount: "..triCount,
  755.         stat
  756.     }
  757. end
  758.  
  759. function module.GenerateChunk(x,y,z)
  760.     local trueChunkY = y * chunkWidth
  761.     local maxY = trueChunkY+posLimit
  762.     local chunk
  763.  
  764.     for Z = 0,posLimit do
  765.         local trueZ = z * chunkWidth + Z
  766.         for X = 0,posLimit do
  767.             local trueX = x * chunkWidth + X
  768.  
  769.             local noiseY = CreateNoise(trueX, trueZ)
  770.             local finalY = math.max(math.min(noiseY, maxY), 5)
  771.  
  772.             if finalY >= trueChunkY then
  773.                 local color
  774.                 if not chunk then
  775.                     chunk = NewChunk(Vector3.new(x,y,z))
  776.                 end
  777.  
  778.                 if finalY == 5 then
  779.                     color = 2
  780.                 elseif finalY == 6 then
  781.                     color = 4
  782.                 end
  783.  
  784.                 for i = 0, finalY-trueChunkY do
  785.                     NewVoxel(chunk, X,i,Z, color or (i == noiseY-trueChunkY and 1) or i < noiseY-trueChunkY-7 and 3 or 5)
  786.                 end
  787.             end
  788.         end
  789.     end
  790.  
  791.     return chunk
  792. end
  793.  
  794. function module.IsVoxelAtPos(pos)
  795.     local chunkPos = pos // chunkWidth
  796.     local chunk = chunks[chunkPos]
  797.  
  798.     if chunk and chunk[IDX_voxels][pos - chunkPos*chunkWidth] then
  799.         return true
  800.     end
  801. end
  802.  
  803. return module
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement