From 7ab2f74e6d1d4fc1d1eea41bb94b3ecc0899ce92 Mon Sep 17 00:00:00 2001 From: quentin452 <42176772+quentin452@users.noreply.github.com> Date: Tue, 27 Feb 2024 22:18:11 +0100 Subject: [PATCH] fixing again render distance/Chunk Slice bugs... --- src/utils/mouselogic.lua | 13 +++++-- src/world/chunk.lua | 60 ++++++++++++++++++++++++++----- src/world/lighting.lua | 2 +- src/world/updatelogic.lua | 75 ++++++++++++++++++++------------------- 4 files changed, 100 insertions(+), 50 deletions(-) diff --git a/src/utils/mouselogic.lua b/src/utils/mouselogic.lua index 67ed00b08..bcd73db52 100644 --- a/src/utils/mouselogic.lua +++ b/src/utils/mouselogic.lua @@ -25,10 +25,9 @@ function MouseLogicOnPlay(x, y, b) chunk:setVoxel(pos.x, pos.y, pos.z, value, true) LightingUpdate() - for _, chunkSlice in ipairs(chunk.slices) do - renderChunkSlice(chunkSlice, ThePlayer.x, ThePlayer.y, ThePlayer.z) - -- UpdateNeighboringChunks(chunk, pos.y) + -- renderChunkSlice(chunkSlice, ThePlayer.x, ThePlayer.y, ThePlayer.z) + -- UpdateNeighboringChunks(chunk, pos.y) end if chunk.slices and chunk and #chunk.changes > 0 then chunk:updateModel() @@ -38,6 +37,7 @@ function MouseLogicOnPlay(x, y, b) hudTimeLeft = 3 end end + function UpdateNeighboringChunks(chunk, y) local neighborOffsets = { { -1, 0 }, @@ -88,6 +88,13 @@ function KeyPressed(k) enableF8 = not enableF8 elseif k == "f1" then enableTESTBLOCK = not enableTESTBLOCK + elseif k == "f2" then + -- for _, chunk in ipairs(renderChunks) do + -- if chunk.active then + -- chunk:sunlight() + -- chunk:processRequests() + -- end + -- end end end if gamestate == gamestateGamePausing then diff --git a/src/world/chunk.lua b/src/world/chunk.lua index e1e292a13..8ec59bcaf 100644 --- a/src/world/chunk.lua +++ b/src/world/chunk.lua @@ -15,13 +15,11 @@ function NewChunk(x, z) -- store a list of voxels to be updated on next modelUpdate chunk.changes = {} - + chunk.updatedSunLight = false + chunk.isPopulated = false for i = 1, ChunkSize do chunk.heightMap[i] = {} end - chunk.isInitialLightningInititalized = false - chunk.isPopulated = false - chunk.isInitialized = false GenerateTerrain(chunk, x, z, StandardTerrain) @@ -58,9 +56,41 @@ function NewChunk(x, z) end end end - --LightingUpdate() + LightingUpdate() + end + chunk.sunlightUpdateAllTheChunk = function(self) + for x = 1, ChunkSize do + for y = 1, WorldHeight do + for z = 1, ChunkSize do + -- Mettez à jour l'éclairage pour le voxel à la position (x, y, z) + local blockvalue = self:getVoxel(x, y, z) + local gx, gy, gz = (self.x - 1) * ChunkSize + x - 1, y, (self.z - 1) * ChunkSize + z - 1 + + if TileLightable(blockvalue) then + local sunget = self:getVoxel(x, y + 1, z) + local sunlight = self:getVoxelFirstData(x, y + 1, z) + local inDirectSunlight = TileLightable(sunget) and sunlight == 15 + + if inDirectSunlight then + NewSunlightDownAddition(gx, gy, gz, sunlight) + else + for dx = -1, 1 do + for dy = -1, 1 do + for dz = -1, 1 do + NewSunlightAdditionCreation(gx + dx, gy + dy, gz + dz) + end + end + end + end + else + NewSunlightDownSubtraction(gx, gy - 1, gz) + end + end + end + end + -- Mettez à jour l'éclairage pour tous les voxels + LightingUpdate() end - chunk.processRequests = function(self) for j = 1, #self.requests do local block = self.requests[j] @@ -70,6 +100,17 @@ function NewChunk(x, z) end LightingUpdate() end + chunk.updateLightingForAllVoxels = function(self) + for x = 1, ChunkSize do + for y = 1, WorldHeight do + for z = 1, ChunkSize do + self:setVoxel(x, y, z, -1, false) + end + end + end + -- Mettez à jour l'éclairage pour tous les voxels + LightingUpdate() + end -- populate chunk with trees and flowers chunk.populate = function(self) @@ -245,10 +286,11 @@ function NewChunk(x, z) end end end + if blockvalue ~= -1 then + self.voxels[x][z] = ReplaceChar(self.voxels[x][z], (y - 1) * TileDataSize + 1, string.char(blockvalue)) - self.voxels[x][z] = ReplaceChar(self.voxels[x][z], (y - 1) * TileDataSize + 1, string.char(blockvalue)) - - self.changes[#self.changes + 1] = { x, y, z } + self.changes[#self.changes + 1] = { x, y, z } + end end end diff --git a/src/world/lighting.lua b/src/world/lighting.lua index 7096d5c51..f91bb5b06 100644 --- a/src/world/lighting.lua +++ b/src/world/lighting.lua @@ -319,4 +319,4 @@ function NewLocalLightAdditionCreation(x, y, z) end LightingQueueAdd(t) -end +end \ No newline at end of file diff --git a/src/world/updatelogic.lua b/src/world/updatelogic.lua index 636371c1d..1577fafbe 100644 --- a/src/world/updatelogic.lua +++ b/src/world/updatelogic.lua @@ -1,9 +1,8 @@ -local ChunkSize = 16 --TODO FIX : currently render distance does not support renderdistance lower than 6 (it seem to be caused by Slices not being created) ---TODO FIX : Slices stop to be created after generating some chunks ---TODO FIX : sometimes when i create a world the first time , the world become empty - --TODO MADE : support renderdistance setting from settingshandling/filesystem +--TODO FIX : chunks are not removed if there are outside of render distance +--TODO FIX : update light are not correct at high distance of spawn +local ChunkSize = 16 local RenderDistance = 6 * ChunkSize ChunkSet = {} ChunkHashTable = {} @@ -17,8 +16,7 @@ function UpdateGame(dt) local playerX, playerY, playerZ = ThePlayer.x, ThePlayer.y, ThePlayer.z -- Generate and update chunks within render distance - local renderChunks = {} - --table.remove(renderChunks) + renderChunks = {} local playerChunkX = math.floor(playerX / ChunkSize) local playerChunkZ = math.floor(playerZ / ChunkSize) @@ -38,46 +36,40 @@ function UpdateGame(dt) ChunkHashTable[ChunkHash(chunkX)] = ChunkHashTable[ChunkHash(chunkX)] or {} ChunkHashTable[ChunkHash(chunkX)][ChunkHash(chunkZ)] = chunk UpdateCaves() + --chunk:sunlight() + --chunk:populate() + --chunk:processRequests() + --chunk:updateLightingForAllVoxels() + for _ = 1, WorldHeight / SliceHeight do + chunk.slices[_] = + NewChunkSlice(chunk.x, chunk.y + (_ - 1) * SliceHeight + 1, chunk.z, chunk) + end + --chunk:sunlightUpdateAllTheChunk() + -- LightingUpdate() LuaCraftPrintLoggingNormal("Generated chunk with coordinates:", chunkX, chunkZ) end - local mx, y, mz = chunk.x, chunk.y, chunk.z + local mx, y, mz = chunk.x + ChunkSize / 2, chunk.y, chunk.z + ChunkSize / 2 local dx, dy, dz = playerX - mx, playerY - y, playerZ - mz -- Calculate Euclidean distance local chunkDistance = math.sqrt(dx * dx + dy * dy + dz * dz) if chunkDistance < RenderDistance then - if not chunk.isInitialLightningInititalized then - chunk:sunlight() - chunk.isInitialLightningInititalized = true - elseif not chunk.isPopulated then - chunk:populate() - chunk.isPopulated = true - elseif not chunk.isInitialized then - chunk.changes = {} - - -- Populate the chunk before initializing slices - for sliceIndex = 1, WorldHeight / SliceHeight do - if not chunk.slices[sliceIndex] then - local sliceY = chunk.y + (sliceIndex - 1) * SliceHeight + 1 - chunk.slices[sliceIndex] = NewChunkSlice(chunk.x, sliceY, chunk.z, chunk) - end - end - - chunk:processRequests() - for _, chunkSlice in ipairs(chunk.slices) do - renderChunkSlice(chunkSlice, ThePlayer.x, ThePlayer.y, ThePlayer.z) - end - chunk.isInitialized = true - end - chunk.active = true for i = 1, #chunk.slices do -- LuaCraftPrintLoggingNormal("test2") local chunkSlice = chunk.slices[i] chunkSlice.active = true end + if chunk.updatedSunLight == false then + chunk:sunlight() + chunk.updatedSunLight = true + elseif chunk.isPopulated == false then + chunk:populate() + chunk:processRequests() + chunk.isPopulated = true + end else chunk.active = false for i = 1, #chunk.slices do @@ -90,9 +82,9 @@ function UpdateGame(dt) for j = #renderChunks, 1, -1 do if not renderChunks[j].active then table.remove(renderChunks, j) + table.remove(ChunkSet, j) end end - -- LuaCraftPrintLoggingNormal("Chunk at coordinates (", chunk.x, ",", chunk.z, ") is inactive") end @@ -103,16 +95,18 @@ function UpdateGame(dt) end end end + local updatedRenderChunks = {} - -- Update the rendered chunks for _, chunk in ipairs(renderChunks) do - if chunk.isInitialized and chunk.active then + if chunk.active then -- Only update the model if there are changes if #chunk.changes > 0 then chunk:updateModel() end - - for _, chunkSlice in ipairs(chunk.slices) do + + local i = #chunk.slices + while i > 0 do + local chunkSlice = chunk.slices[i] if chunkSlice.active == false then -- Remove the inactive ChunkSlice LuaCraftPrintLoggingNormal( @@ -126,10 +120,17 @@ function UpdateGame(dt) table.remove(chunk.slices, i) chunkSlice.alreadyrendered = false end + i = i - 1 end + + -- Keep track of active chunks for later use + table.insert(updatedRenderChunks, chunk) end end - + + -- Update the main renderChunks table + renderChunks = updatedRenderChunks + LogicAccumulator = LogicAccumulator + dt -- update all things in ThingList update queue