From 7136aeb9cb24348f119a7783181a7aba1484c3c6 Mon Sep 17 00:00:00 2001 From: Cruor Date: Mon, 30 Sep 2019 13:29:19 +0200 Subject: [PATCH] Brush helper now uses the correct randomness This also causes general improvement upgrades to brushing speed --- src/brush_helper.lua | 13 ++++++------ src/celeste_render.lua | 46 ++++++++++++++++++++++++++++++++++++------ src/matrix.lua | 29 ++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 12 deletions(-) diff --git a/src/brush_helper.lua b/src/brush_helper.lua index 0b96c73b..30a100d2 100644 --- a/src/brush_helper.lua +++ b/src/brush_helper.lua @@ -71,20 +71,21 @@ function brushHelper.generateFakeTiles(room, x, y, material, layer) return fakeTiles end -function brushHelper.generateFakeTilesBatch(room, fakeTiles, layer) +function brushHelper.generateFakeTilesBatch(room, x, y, fakeTiles, layer) local fg = layer == "tilesFg" local meta = fg and celesteRender.tilesMetaFg or celesteRender.tilesMetaBg + local width, height = fakeTiles.matrix:size() + local random = celesteRender.getRoomRandomMatrix(room, layer) + local randomSlice = random:getSlice(x - 2, y - 2, x + width - 3, y + height - 3, "0") - return celesteRender.getTilesBatch(room, fakeTiles, meta, fg) + return celesteRender.getTilesBatch(room, fakeTiles, meta, fg, randomSlice) end --- TODO - This doesn't use the same random quads as the initial render would --- Making it inconsistent, and also wasting time on unneeded rerendering function brushHelper.updateRender(room, x, y, material, layer) local batch = celesteRender.getRoomCache(room.name, layer).result local fakeTiles = brushHelper.generateFakeTiles(room, x, y, material, layer) - local fakeBatch = brushHelper.generateFakeTilesBatch(room, fakeTiles, layer) + local fakeBatch = brushHelper.generateFakeTilesBatch(room, x, y, fakeTiles, layer) local width, height = fakeBatch._matrix:size() @@ -104,7 +105,7 @@ function brushHelper.updateRender(room, x, y, material, layer) end end - if batch.process then + if batch.process then batch:process() end end diff --git a/src/celeste_render.lua b/src/celeste_render.lua index 1a6964c4..5bd4e5ec 100644 --- a/src/celeste_render.lua +++ b/src/celeste_render.lua @@ -37,8 +37,8 @@ local PRINT_BATCHING_DURATION = false local ALWAYS_REDRAW_UNSELECTED_ROOMS = false local ALLOW_NON_VISIBLE_BACKGROUND_DRAWING = true --- Room cache local roomCache = {} +local roomRandomMatrixCache = {} local batchingTasks = {} @@ -99,6 +99,39 @@ function celesteRender.invalidateRoomCache(roomName, key) end end +function celesteRender.getRoomRandomMatrix(room, key) + local roomName = room.name + local tileWidth, tileHeight = room[key].matrix:size() + local regen = false + + if roomRandomMatrixCache[roomName] and roomRandomMatrixCache[roomName][key] then + local m = roomRandomMatrixCache[roomName][key] + local randWidth, randHeight = m:size() + + regen = tileWidth ~= randWidth or tileHeight ~= randHeight + + else + regen = true + end + + if regen then + utils.setRandomSeed(roomName) + + local m = matrix.filled(0, tileWidth, tileHeight) + + for x = 1, tileWidth do + for y = 1, tileHeight do + m:setInbounds(x, y, math.random(1, 256)) + end + end + + roomRandomMatrixCache[roomName] = roomRandomMatrixCache[roomName] or {} + roomRandomMatrixCache[roomName][key] = m + end + + return roomRandomMatrixCache[roomName][key] +end + function celesteRender.getRoomCache(roomName, key) if utils.typeof(roomName) == "room" then roomName = roomName.name @@ -149,7 +182,7 @@ function celesteRender.getOrCacheTileSpriteQuad(cache, tile, texture, quad, fg) if not quadCache:get0(quadX, quadY) then local spriteMeta = atlases.gameplay[texture] - local spritesWidth, spritesHeight = spriteMeta.image:getDimensions + local spritesWidth, spritesHeight = spriteMeta.image:getDimensions() local res = love.graphics.newQuad(spriteMeta.x - spriteMeta.offsetX + quadX * 8, spriteMeta.y - spriteMeta.offsetY + quadY * 8, 8, 8, spritesWidth, spritesHeight) quadCache:set0(quadX, quadY, res) @@ -160,7 +193,8 @@ function celesteRender.getOrCacheTileSpriteQuad(cache, tile, texture, quad, fg) return quadCache:get0(quadX, quadY) end -function celesteRender.getTilesBatch(room, tiles, meta, fg) +-- randomMatrix is for custom randomness, mostly to give the correct "slice" of the matrix when making fake tiles +function celesteRender.getTilesBatch(room, tiles, meta, fg, randomMatrix) local tilesMatrix = tiles.matrix -- Getting upvalues @@ -181,11 +215,11 @@ function celesteRender.getTilesBatch(room, tiles, meta, fg) local width, height = tilesMatrix:size() local batch = smartDrawingBatch.createGridCanvasBatch(false, width, height, 8, 8) - utils.setRandomSeed(room.name) + local random = randomMatrix or celesteRender.getRoomRandomMatrix(room, fg and "tilesFg" or "tilesBg") for x = 1, width do for y = 1, height do - local rng = math.random(1, 256) + local rng = random:getInbounds(x, y) local tile = tilesMatrix:getInbounds(x, y) if tile ~= airTile then @@ -208,7 +242,7 @@ function celesteRender.getTilesBatch(room, tiles, meta, fg) coroutine.yield() end - if batch.process then + if batch.process then batch:process() end diff --git a/src/matrix.lua b/src/matrix.lua index 8a5feddb..b9d57ce8 100644 --- a/src/matrix.lua +++ b/src/matrix.lua @@ -65,6 +65,20 @@ function matrixMt.__index.size(self) return self._width, self._height end +function matrixMt.__index.getSlice(self, x1, y1, x2, y2, def) + local res = matrix.filled(def, math.abs(x2 - x1) + 1, math.abs(y2 - y1) + 1) + + local startX, endX = math.min(x1, x2), math.max(x1, x2) + local startY, endY = math.min(y1, y2), math.max(y1, y2) + + for x = startX, endX do + for y = startY, endY do + res:setInbounds(x - startX + 1, y - startY + 1, self:get(x, y, def)) + end + end + + return res +end function matrix.filled(default, width, height) local m = { @@ -100,4 +114,19 @@ function matrix.fromTable(t, width, height) return setmetatable(new, matrixMt) end +function matrix.fromFunction(func, width, height) + local m = { + _type = "matrix" + } + + for i = 1, width * height do + m[i] = func(i, width, height) + end + + m._width = width + m._height = height + + return setmetatable(m, matrixMt) +end + return matrix \ No newline at end of file