Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --!optimize 2
- local RepStorage = game:FindService("ReplicatedStorage")
- local blockData = require(RepStorage.BlockData)
- local chunkFolder = workspace.Chunks
- local chunkRef = script.Chunk
- local rand = Random.new()
- local chunks = {}
- local module = {}
- --config:
- local chunkWidth = 16
- local seeds = {
- rand:NextNumber(-1000000,1000000),
- rand:NextNumber(-1000000,1000000),
- rand:NextNumber(-1000000,1000000),
- rand:NextNumber(-1000000,1000000)
- }
- local noiseWidth = 1.8
- local noiseHeight = 30
- local noiseOffset = 1
- --constants:
- local IDX_editMesh = 1
- local IDX_mesh = 2
- local IDX_position = 3
- local IDX_voxels = 4
- local IDX_other = 0
- local IDX_reserved = 1
- --init:
- noiseOffset *= chunkWidth
- noiseWidth = 1/(noiseWidth*55)
- local chunkWidthSquared = chunkWidth^2
- local posLimit = chunkWidth-1
- local chunkVector = Vector3.new(chunkWidth,chunkWidth,chunkWidth)
- local VERT_OFFS_1 = Vector3.new(-0.5, -0.5, -0.5)
- local VERT_OFFS_2 = Vector3.new( 0.5, -0.5, -0.5)
- local VERT_OFFS_3 = Vector3.new(-0.5, -0.5, 0.5)
- local VERT_OFFS_4 = Vector3.new( 0.5, -0.5, 0.5)
- local VERT_OFFS_5 = Vector3.new(-0.5, 0.5, -0.5)
- local VERT_OFFS_6 = Vector3.new( 0.5, 0.5, -0.5)
- local VERT_OFFS_7 = Vector3.new(-0.5, 0.5, 0.5)
- local VERT_OFFS_8 = Vector3.new( 0.5, 0.5, 0.5)
- local stat = {
- one = 0,
- two = 0,
- three = 0
- }
- --logic:
- --[[
- local function ClearEditableMesh(editMesh)
- for i, v in editMesh:GetTriangles() do
- editMesh:RemoveTriangle(v)
- end
- for _, v in editMesh:GetVertices() do
- editMesh:RemoveVertex(v)
- end
- end
- ]]
- local function Flatten(x,y,z)
- local inBounds = x < chunkWidth and y < chunkWidth and z < chunkWidth
- return inBounds and x + (y * chunkWidth) + (z * chunkWidthSquared) + 1
- end
- local function GetVoxel(x,y,z)
- local vectorPos = Vector3.new(x,y,z)
- local chunkPos = vectorPos // chunkWidth
- local chunk = chunks[chunkPos]
- local finalPos = vectorPos - chunkPos*chunkWidth
- return chunk and chunk[IDX_voxels][Flatten(finalPos.X,finalPos.Y,finalPos.Z)]
- end
- local function DeleteVoxel(chunk, x,y,z)
- chunk[IDX_voxels][Flatten(x,y,z)] = nil
- end
- local function NewVoxel(chunk, x,y,z , blockID)
- local buff = buffer.create(7)
- buffer.writeu8(buff, 0, blockID)
- chunk[IDX_voxels][Flatten(x,y,z)] = buff
- end
- local function GetChunkNeighbors(chunkPos)
- return {
- chunks[chunkPos - Vector3.yAxis],
- chunks[chunkPos + Vector3.yAxis],
- chunks[chunkPos - Vector3.zAxis],
- chunks[chunkPos + Vector3.zAxis],
- chunks[chunkPos - Vector3.xAxis],
- chunks[chunkPos + Vector3.xAxis]
- }
- end
- local function UpdateChunkSingle(chunk)
- if not chunk then return end
- local oldEditMesh = chunk[IDX_editMesh]
- local mesh = chunk[IDX_mesh]
- local voxels = chunk[IDX_voxels]
- local replaceEditMesh = #oldEditMesh:GetVertices() ~= 0
- local editMesh
- if replaceEditMesh then
- editMesh = Instance.new("EditableMesh")
- chunk[IDX_editMesh] = editMesh
- else
- editMesh = oldEditMesh
- end
- if next(voxels) then
- local chunkLocalPos = chunk[IDX_position]
- local chunkPos = chunkLocalPos * chunkWidth
- local chunkNeighbors = GetChunkNeighbors(chunkLocalPos)
- for Z = 0,posLimit do
- for Y = 0,posLimit do
- for X = 0,posLimit do
- local voxel = voxels[Flatten(X,Y,Z)]
- if not voxel then continue end
- local centerPos = Vector3.new(X,Y,Z)
- local p1 = centerPos + VERT_OFFS_1
- local p2 = centerPos + VERT_OFFS_2
- local p3 = centerPos + VERT_OFFS_3
- local p4 = centerPos + VERT_OFFS_4
- local p5 = centerPos + VERT_OFFS_5
- local p6 = centerPos + VERT_OFFS_6
- local p7 = centerPos + VERT_OFFS_7
- local p8 = centerPos + VERT_OFFS_8
- local blockID = buffer.readu8(voxel, 0)
- --bottom face
- if buffer.readu8(voxel, 1) ~= IDX_reserved then
- local chunkNeighbor = chunkNeighbors[1]
- local Xlimit = 0
- local Zlimit = 1
- --greedy meshing X
- for x = X, posLimit do
- local nextVoxel = x == X and voxel or voxels[Flatten(x, Y, Z)]
- 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
- break
- end
- Xlimit += 1
- buffer.writeu8(nextVoxel, 1, IDX_reserved)
- end
- --
- if Xlimit ~= 0 then
- --greedy meshing Z
- for i = 1, chunkWidth-Z do
- local toReserve = {}
- local abort
- for j = 0, Xlimit-1 do
- local nextVoxel = voxels[Flatten(X+j, Y, Z+Zlimit)]
- 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
- abort = true
- break
- end
- toReserve[j+1] = nextVoxel
- end
- if abort then
- break
- end
- for _, obj in toReserve do
- buffer.writeu8(obj, 1, IDX_reserved)
- end
- Zlimit += 1
- end
- --
- local color = blockData[blockID][1]
- local greedyOffsetX = Vector3.xAxis*(Xlimit - 1)
- local greedyOffsetZ = Vector3.zAxis*(Zlimit - 1)
- local vert1 = editMesh:AddVertex(p1)
- local vert2 = editMesh:AddVertex(p2+greedyOffsetX)
- local vert3 = editMesh:AddVertex(p3+greedyOffsetZ)
- local vert4 = editMesh:AddVertex(p4+greedyOffsetX+greedyOffsetZ)
- editMesh:SetVertexColor(vert1, color)
- editMesh:SetVertexColor(vert2, color)
- editMesh:SetVertexColor(vert3, color)
- editMesh:SetVertexColor(vert4, color)
- editMesh:AddTriangle(vert1, vert2, vert4)
- editMesh:AddTriangle(vert4, vert3, vert1)
- end
- end
- --
- --top face
- if buffer.readu8(voxel, 2) ~= IDX_reserved then
- local chunkNeighbor = chunkNeighbors[2]
- local Xlimit = 0
- local Zlimit = 1
- --greedy meshing X
- for x = X, posLimit do
- local nextVoxel = x == X and voxel or voxels[Vector3.new(x, Y, Z)]
- 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
- break
- end
- Xlimit += 1
- buffer.writeu8(nextVoxel, 2, IDX_reserved)
- end
- --
- if Xlimit ~= 0 then
- --greedy meshing Z
- for i = 1, chunkWidth-Z do
- local toReserve = {}
- local abort
- for j = 0, Xlimit-1 do
- local nextVoxel = voxels[Flatten(X+j, Y, Z+Zlimit)]
- 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
- abort = true
- break
- end
- toReserve[j+1] = nextVoxel
- end
- if abort then
- break
- end
- for _, obj in toReserve do
- buffer.writeu8(obj, 2, IDX_reserved)
- end
- Zlimit += 1
- end
- --
- local color = blockData[blockID][1]
- local greedyOffsetX = Vector3.xAxis*(Xlimit - 1)
- local greedyOffsetZ = Vector3.zAxis*(Zlimit - 1)
- local vert1 = editMesh:AddVertex(p5)
- local vert2 = editMesh:AddVertex(p6+greedyOffsetX)
- local vert3 = editMesh:AddVertex(p7+greedyOffsetZ)
- local vert4 = editMesh:AddVertex(p8+greedyOffsetX+greedyOffsetZ)
- editMesh:SetVertexColor(vert1, color)
- editMesh:SetVertexColor(vert2, color)
- editMesh:SetVertexColor(vert3, color)
- editMesh:SetVertexColor(vert4, color)
- editMesh:AddTriangle(vert1, vert3, vert4)
- editMesh:AddTriangle(vert4, vert2, vert1)
- end
- end
- --
- --left face
- if buffer.readu8(voxel, 3) ~= IDX_reserved then
- local chunkNeighbor = chunkNeighbors[3]
- local Xlimit = 0
- local Ylimit = 1
- --greedy meshing X
- for x = X, posLimit do
- local nextVoxel = x == X and voxel or voxels[Flatten(x, Y, Z)]
- 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
- break
- end
- Xlimit += 1
- buffer.writeu8(nextVoxel, 3, IDX_reserved)
- end
- --
- if Xlimit ~= 0 then
- --greedy meshing Y
- for i = 1, chunkWidth-Y do
- local toReserve = {}
- local abort
- for j = 0, Xlimit-1 do
- local nextVoxel = voxels[Flatten(X+j, Y+Ylimit, Z)]
- 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
- abort = true
- break
- end
- toReserve[j+1] = nextVoxel
- end
- if abort then
- break
- end
- for _, obj in toReserve do
- buffer.writeu8(obj, 3, IDX_reserved)
- end
- Ylimit += 1
- end
- --
- local color = blockData[blockID][1]
- local greedyOffsetX = Vector3.xAxis*(Xlimit - 1)
- local greedyOffsetY = Vector3.yAxis*(Ylimit - 1)
- local vert1 = editMesh:AddVertex(p1)
- local vert2 = editMesh:AddVertex(p2+greedyOffsetX)
- local vert3 = editMesh:AddVertex(p5+greedyOffsetY)
- local vert4 = editMesh:AddVertex(p6+greedyOffsetX+greedyOffsetY)
- editMesh:SetVertexColor(vert1, color)
- editMesh:SetVertexColor(vert2, color)
- editMesh:SetVertexColor(vert3, color)
- editMesh:SetVertexColor(vert4, color)
- editMesh:AddTriangle(vert4, vert2, vert1)
- editMesh:AddTriangle(vert1, vert3, vert4)
- end
- end
- --
- --right face
- if buffer.readu8(voxel, 4) ~= IDX_reserved then
- local chunkNeighbor = chunkNeighbors[4]
- local Xlimit = 0
- local Ylimit = 1
- --greedy meshing X
- for x = X, posLimit do
- local nextVoxel = x == X and voxel or voxels[Flatten(x, Y, Z)]
- 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
- break
- end
- Xlimit += 1
- buffer.writeu8(nextVoxel, 4, IDX_reserved)
- end
- --
- if Xlimit ~= 0 then
- --greedy meshing Y
- for i = 1, chunkWidth-Y do
- local toReserve = {}
- local abort
- for j = 0, Xlimit-1 do
- local nextVoxel = voxels[Flatten(X+j, Y+Ylimit, Z)]
- 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
- abort = true
- break
- end
- toReserve[j+1] = nextVoxel
- end
- if abort then
- break
- end
- for _, obj in toReserve do
- buffer.writeu8(obj, 4, IDX_reserved)
- end
- Ylimit += 1
- end
- --
- local color = blockData[blockID][1]
- local greedyOffsetX = Vector3.xAxis*(Xlimit - 1)
- local greedyOffsetY = Vector3.yAxis*(Ylimit - 1)
- local vert1 = editMesh:AddVertex(p3)
- local vert2 = editMesh:AddVertex(p4+greedyOffsetX)
- local vert3 = editMesh:AddVertex(p7+greedyOffsetY)
- local vert4 = editMesh:AddVertex(p8+greedyOffsetX+greedyOffsetY)
- editMesh:SetVertexColor(vert1, color)
- editMesh:SetVertexColor(vert2, color)
- editMesh:SetVertexColor(vert3, color)
- editMesh:SetVertexColor(vert4, color)
- editMesh:AddTriangle(vert3, vert1, vert2)
- editMesh:AddTriangle(vert2, vert4, vert3)
- end
- end
- --
- --back face
- if buffer.readu8(voxel, 5) ~= IDX_reserved then
- local chunkNeighbor = chunkNeighbors[5]
- local Zlimit = 0
- local Ylimit = 1
- --greedy meshing Z
- for z = Z, posLimit do
- local nextVoxel = z == Z and voxel or voxels[Flatten(X, Y, z)]
- 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
- break
- end
- Zlimit += 1
- buffer.writeu8(nextVoxel, 5, IDX_reserved)
- end
- if Zlimit ~= 0 then
- --greedy meshing Y
- for i = 1, chunkWidth-Y do
- local toReserve = {}
- local abort
- for j = 0, Zlimit-1 do
- local nextVoxel = voxels[Flatten(X, Y+Ylimit, Z+j)]
- 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
- abort = true
- break
- end
- toReserve[j+1] = nextVoxel
- end
- if abort then
- break
- end
- for _, obj in toReserve do
- buffer.writeu8(obj, 5, IDX_reserved)
- end
- Ylimit += 1
- end
- --
- local color = blockData[blockID][1]
- local greedyOffsetZ = Vector3.zAxis*(Zlimit - 1)
- local greedyOffsetY = Vector3.yAxis*(Ylimit - 1)
- local vert1 = editMesh:AddVertex(p1)
- local vert2 = editMesh:AddVertex(p3+greedyOffsetZ)
- local vert3 = editMesh:AddVertex(p5+greedyOffsetY)
- local vert4 = editMesh:AddVertex(p7+greedyOffsetZ+greedyOffsetY)
- editMesh:SetVertexColor(vert1, color)
- editMesh:SetVertexColor(vert2, color)
- editMesh:SetVertexColor(vert3, color)
- editMesh:SetVertexColor(vert4, color)
- editMesh:AddTriangle(vert3, vert1, vert2)
- editMesh:AddTriangle(vert2, vert4, vert3)
- end
- end
- --
- --front face
- if buffer.readu8(voxel, 6) ~= IDX_reserved then
- local chunkNeighbor = chunkNeighbors[6]
- local Zlimit = 0
- local Ylimit = 1
- for z = Z, posLimit do
- local nextVoxel = z == Z and voxel or voxels[Flatten(X, Y, z)]
- 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
- break
- end
- Zlimit += 1
- buffer.writeu8(nextVoxel, 6, IDX_reserved)
- end
- if Zlimit ~= 0 then
- --greedy meshing Y
- for i = 1, chunkWidth-Y do
- local toReserve = {}
- local abort
- for j = 0, Zlimit-1 do
- local nextVoxel = voxels[Flatten(X, Y+Ylimit, Z+j)]
- 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
- abort = true
- break
- end
- toReserve[j+1] = nextVoxel
- end
- if abort then
- break
- end
- for _, obj in toReserve do
- buffer.writeu8(obj, 6, IDX_reserved)
- end
- Ylimit += 1
- end
- --
- local color = blockData[blockID][1]
- local greedyOffsetZ = Vector3.zAxis*(Zlimit - 1)
- local greedyOffsetY = Vector3.yAxis*(Ylimit - 1)
- local vert1 = editMesh:AddVertex(p2)
- local vert2 = editMesh:AddVertex(p4+greedyOffsetZ)
- local vert3 = editMesh:AddVertex(p6+greedyOffsetY)
- local vert4 = editMesh:AddVertex(p8+greedyOffsetZ+greedyOffsetY)
- editMesh:SetVertexColor(vert1, color)
- editMesh:SetVertexColor(vert2, color)
- editMesh:SetVertexColor(vert3, color)
- editMesh:SetVertexColor(vert4, color)
- editMesh:AddTriangle(vert4, vert2, vert1)
- editMesh:AddTriangle(vert1, vert3, vert4)
- end
- end
- --
- buffer.fill(voxel, 1, IDX_other)
- end
- end
- end
- end
- if replaceEditMesh then
- oldEditMesh:Destroy()
- editMesh.Parent = mesh
- elseif mesh.Transparency == 1 then
- task.spawn(function()
- while true do
- local result = mesh.Transparency - task.wait()*5
- if result <= 0 then
- mesh.Transparency = 0
- return
- end
- mesh.Transparency = result
- end
- end)
- end
- end
- local function ChunkUpdate(chunkPos)
- UpdateChunkSingle(chunks[chunkPos])
- for _, chunk in GetChunkNeighbors(chunkPos) do
- UpdateChunkSingle(chunk)
- end
- end
- local function NewChunk(chunkPos)
- local mesh = chunkRef:Clone()
- mesh.Position = chunkPos * chunkWidth
- local chunk = {
- Instance.new("EditableMesh", mesh),
- mesh,
- chunkPos,
- {}
- }
- mesh.Parent = chunkFolder
- chunks[chunkPos] = chunk
- return chunk
- end
- function GetChunksWithinRange(centerPos, range, createChunks)
- local rangeVector = Vector3.new(range, range, range)
- local minPos = centerPos - rangeVector
- local maxPos = centerPos + rangeVector
- local touchingChunks = {}
- for x = minPos.X // chunkWidth, math.ceil(maxPos.X / chunkWidth) do
- for y =minPos.Y // chunkWidth, math.ceil(maxPos.Y / chunkWidth) do
- for z = minPos.Z // chunkWidth, math.ceil(maxPos.Z / chunkWidth) do
- local iterPos = Vector3.new(x,y,z)
- local chunkMin = iterPos * chunkWidth
- local chunkMax = chunkMin + chunkVector
- local closestPoint = chunkMin:Max(centerPos:Min(chunkMax))
- local distanceToCenter = (closestPoint - centerPos).Magnitude
- if distanceToCenter <= range then
- local chunk = chunks[iterPos] or createChunks and NewChunk(iterPos)
- if chunk then
- table.insert(touchingChunks, chunk)
- end
- end
- end
- end
- end
- return touchingChunks
- end
- local function CreateNoise(X, Z)
- local noise1 = math.noise(X * noiseWidth, seeds[2], Z * noiseWidth)
- local noise2 = math.noise(X * noiseWidth*2.5, seeds[3], Z * noiseWidth*2.5)/3
- local noise3 = math.noise(X * noiseWidth*7, seeds[4], Z * noiseWidth*7)/25
- local specialNoise = math.noise(X * noiseWidth/4, seeds[1], Z * noiseWidth/4)*3
- local noiseSum = (noise1+noise2+noise3+specialNoise)
- return math.floor((noiseSum*noiseHeight)+noiseOffset)
- end
- --
- function module.UpdateAllChunks()
- for _, chunk in chunks do
- UpdateChunkSingle(chunk)
- end
- warn("updated all chunks!")
- end
- function module.ChunkUpdate(chunkPos)
- ChunkUpdate(chunkPos)
- end
- function module.UpdateChunkSingle(chunk)
- UpdateChunkSingle(chunk)
- end
- function module.RemoveVoxelsInRange(pos, range)
- local halfRange = range/2
- for z = -range, range do
- local zSquared = z^2
- if z % 100 == 0 then
- task.wait()
- end
- for y = -range, range do
- local ySquared = y^2
- for x = -range, range do
- if math.sqrt(x^2 + ySquared + zSquared) > halfRange then
- continue
- end
- local truePos = pos+Vector3.new(x,y,z)
- local chunkPos = truePos // chunkWidth
- local chunk = chunks[chunkPos]
- if chunk then
- local lastPos = truePos - chunkPos*chunkWidth
- DeleteVoxel(chunk, lastPos.X, lastPos.Y, lastPos.Z)
- end
- end
- end
- end
- for _, chunk in GetChunksWithinRange(pos, halfRange+1) do
- --[[
- local part = Instance.new("Part")
- part.Transparency = 1
- part.Anchored = true
- part.CanCollide = false
- part.Size = Vector3.new(chunkWidth, chunkWidth, chunkWidth)
- part.Position = chunk[IDX_position] * chunkWidth + Vector3.new((chunkWidth/2)-0.5, (chunkWidth/2)-0.5, (chunkWidth/2)-0.5)
- local box = Instance.new("SelectionBox", part)
- box.Adornee = part
- part.Parent = workspace
- ]]
- task.defer(UpdateChunkSingle, chunk)
- end
- end
- function module.AddVoxelsInRange(pos, range, blockID)
- local halfRange = range/2
- for z = -range, range do
- local zSquared = z^2
- if z % 100 == 0 then
- task.wait()
- end
- for y = -range, range do
- local ySquared = y^2
- for x = -range, range do
- if math.sqrt(x^2 + ySquared + zSquared) > halfRange then
- continue
- end
- local truePos = pos+Vector3.new(x,y,z)
- local chunkPos = truePos // chunkWidth
- local chunk = chunks[chunkPos] or NewChunk(chunkPos)
- local lastPos = truePos - chunkPos*chunkWidth
- NewVoxel(chunk, lastPos.X, lastPos.Y, lastPos.Z, blockID)
- end
- end
- end
- for _, chunk in GetChunksWithinRange(pos, halfRange+1) do
- task.defer(UpdateChunkSingle, chunk)
- end
- end
- function module.Raycast(from, direction, length)
- local res = 0.05
- local half = Vector3.new(.5,.5,.5)
- for i = res,length,res do
- local pos = (from + direction*i + half) // 1
- if GetVoxel(pos.X, pos.Y, pos.Z) then
- return pos
- end
- end
- end
- function module.GetStats()
- local chunkCount = 0
- local voxelCount = 0
- local triCount = 0
- warn("getting stats...")
- for _, chunk in chunks do
- if chunkCount/2 % 140 == 0 then
- task.wait()
- end
- chunkCount += 1
- for _, voxel in chunk[IDX_voxels] do
- voxelCount += 1
- end
- triCount += #chunk[IDX_editMesh]:GetTriangles()
- end
- return {
- "chunk amount: "..chunkCount,
- "voxel amount: "..voxelCount,
- "tri amount: "..triCount,
- stat
- }
- end
- function module.GenerateChunk(x,y,z)
- local trueChunkY = y * chunkWidth
- local maxY = trueChunkY+posLimit
- local chunk
- for Z = 0,posLimit do
- local trueZ = z * chunkWidth + Z
- for X = 0,posLimit do
- local trueX = x * chunkWidth + X
- local noiseY = CreateNoise(trueX, trueZ)
- local finalY = math.max(math.min(noiseY, maxY), 5)
- if finalY >= trueChunkY then
- local color
- if not chunk then
- chunk = NewChunk(Vector3.new(x,y,z))
- end
- if finalY == 5 then
- color = 2
- elseif finalY == 6 then
- color = 4
- end
- for i = 0, finalY-trueChunkY do
- NewVoxel(chunk, X,i,Z, color or (i == noiseY-trueChunkY and 1) or i < noiseY-trueChunkY-7 and 3 or 5)
- end
- end
- end
- end
- return chunk
- end
- function module.IsVoxelAtPos(pos)
- local chunkPos = pos // chunkWidth
- local chunk = chunks[chunkPos]
- if chunk and chunk[IDX_voxels][pos - chunkPos*chunkWidth] then
- return true
- end
- end
- return module
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement