Fix capture grid calculation

The capture grid calculation takes now the rendering rectangle into consideration.
With this fix the capture grid will include all cells that overlap with the given capture rectangle.
This commit is contained in:
David Vogel 2024-02-21 17:55:24 +01:00
parent 20d7c330a6
commit c0fd7aab56

View File

@ -240,7 +240,7 @@ end
---Starts the capturing process of the given area using a hilbert curve. ---Starts the capturing process of the given area using a hilbert curve.
---Use `Capture.MapCapturingCtx` to stop, control or view the process. ---Use `Capture.MapCapturingCtx` to stop, control or view the process.
---@param topLeft Vec2 -- Top left of the to be captured rectangle. ---@param topLeft Vec2 -- Top left of the to be captured rectangle.
---@param bottomRight Vec2 -- Non included bottom left of the to be captured rectangle. ---@param bottomRight Vec2 -- Non inclusive bottom right coordinate of the to be captured rectangle.
---@param captureGridSize number -- The grid size in world pixels. ---@param captureGridSize number -- The grid size in world pixels.
---@param outputPixelScale number? -- The resulting image pixel to world pixel ratio. ---@param outputPixelScale number? -- The resulting image pixel to world pixel ratio.
---@param captureDelay number? -- The number of additional frames to wait before a screen capture. ---@param captureDelay number? -- The number of additional frames to wait before a screen capture.
@ -250,15 +250,19 @@ function Capture:StartCapturingAreaHilbert(topLeft, bottomRight, captureGridSize
local file = io.open("mods/noita-mapcap/output/nonempty", "a") local file = io.open("mods/noita-mapcap/output/nonempty", "a")
if file ~= nil then file:close() end if file ~= nil then file:close() end
---The rectangle in grid coordinates. -- The capture offset which is needed to center the grid cells in the viewport.
local captureOffset = Vec2(captureGridSize / 2, captureGridSize / 2)
-- Get the extended capture rectangle that encloses all grid cells that need to be included in the capture.
-- In this case we only need to extend the capture area by the valid rendering rectangle.
local validTopLeft, validBottomRight = Coords:ValidRenderingRect()
local validTopLeftWorld, validBottomRightWorld = Coords:ToWorld(validTopLeft, topLeft + captureOffset), Coords:ToWorld(validBottomRight, bottomRight + captureOffset)
---The capture rectangle in grid coordinates.
---@type Vec2, Vec2 ---@type Vec2, Vec2
local gridTopLeft, gridBottomRight = (topLeft / captureGridSize):Rounded("floor"), (bottomRight / captureGridSize):Rounded("floor") local gridTopLeft, gridBottomRight = (validTopLeftWorld / captureGridSize):Rounded("floor"), ((validBottomRightWorld) / captureGridSize):Rounded("ceil") - Vec2(1, 1)
-- Handle edge cases. ---Size of the rectangle in grid cells.
if topLeft.x == bottomRight.x then gridBottomRight.x = gridTopLeft.x end
if topLeft.y == bottomRight.y then gridBottomRight.y = gridTopLeft.y end
---Size of the rectangle in grid coordinates.
---@type Vec2 ---@type Vec2
local gridSize = gridBottomRight - gridTopLeft local gridSize = gridBottomRight - gridTopLeft
@ -287,7 +291,7 @@ function Capture:StartCapturingAreaHilbert(topLeft, bottomRight, captureGridSize
---Position in world coordinates. ---Position in world coordinates.
---@type Vec2 ---@type Vec2
local pos = (hilbertPos + gridTopLeft) * captureGridSize local pos = (hilbertPos + gridTopLeft) * captureGridSize
pos:Add(Vec2(captureGridSize / 2, captureGridSize / 2)) -- Move to center of grid cell. pos:Add(captureOffset) -- Move to center of grid cell.
captureScreenshot(pos, true, true, ctx, outputPixelScale, captureDelay) captureScreenshot(pos, true, true, ctx, outputPixelScale, captureDelay)
ctx.state.Current = ctx.state.Current + 1 ctx.state.Current = ctx.state.Current + 1
end end
@ -309,7 +313,7 @@ end
---Starts the capturing process of the given area by scanning from left to right, and top to bottom. ---Starts the capturing process of the given area by scanning from left to right, and top to bottom.
---Use `Capture.MapCapturingCtx` to stop, control or view the process. ---Use `Capture.MapCapturingCtx` to stop, control or view the process.
---@param topLeft Vec2 -- Top left of the to be captured rectangle. ---@param topLeft Vec2 -- Top left of the to be captured rectangle.
---@param bottomRight Vec2 -- Non included bottom left of the to be captured rectangle. ---@param bottomRight Vec2 -- Non inclusive bottom right coordinate of the to be captured rectangle.
---@param captureGridSize number -- The grid size in world pixels. ---@param captureGridSize number -- The grid size in world pixels.
---@param outputPixelScale number? -- The resulting image pixel to world pixel ratio. ---@param outputPixelScale number? -- The resulting image pixel to world pixel ratio.
---@param captureDelay number? -- The number of additional frames to wait before a screen capture. ---@param captureDelay number? -- The number of additional frames to wait before a screen capture.
@ -319,11 +323,19 @@ function Capture:StartCapturingAreaScan(topLeft, bottomRight, captureGridSize, o
local file = io.open("mods/noita-mapcap/output/nonempty", "a") local file = io.open("mods/noita-mapcap/output/nonempty", "a")
if file ~= nil then file:close() end if file ~= nil then file:close() end
---The rectangle in grid coordinates. -- The capture offset which is needed to center the grid cells in the viewport.
---@type Vec2, Vec2 local captureOffset = Vec2(captureGridSize / 2, captureGridSize / 2)
local gridTopLeft, gridBottomRight = (topLeft / captureGridSize):Rounded("floor"), (bottomRight / captureGridSize):Rounded("floor")
---Size of the rectangle in grid coordinates. -- Get the extended capture rectangle that encloses all grid cells that need to be included in the capture.
-- In this case we only need to extend the capture area by the valid rendering rectangle.
local validTopLeft, validBottomRight = Coords:ValidRenderingRect()
local validTopLeftWorld, validBottomRightWorld = Coords:ToWorld(validTopLeft, topLeft + captureOffset), Coords:ToWorld(validBottomRight, bottomRight + captureOffset)
---The capture rectangle in grid coordinates.
---@type Vec2, Vec2
local gridTopLeft, gridBottomRight = (validTopLeftWorld / captureGridSize):Rounded("floor"), ((validBottomRightWorld) / captureGridSize):Rounded("ceil") - Vec2(1, 1)
---Size of the rectangle in grid cells.
---@type Vec2 ---@type Vec2
local gridSize = gridBottomRight - gridTopLeft local gridSize = gridBottomRight - gridTopLeft
@ -345,7 +357,7 @@ function Capture:StartCapturingAreaScan(topLeft, bottomRight, captureGridSize, o
---Position in world coordinates. ---Position in world coordinates.
---@type Vec2 ---@type Vec2
local pos = gridPos * captureGridSize local pos = gridPos * captureGridSize
pos:Add(Vec2(captureGridSize / 2, captureGridSize / 2)) -- Move to center of grid cell. pos:Add(captureOffset) -- Move to center of grid cell.
captureScreenshot(pos, true, true, ctx, outputPixelScale, captureDelay) captureScreenshot(pos, true, true, ctx, outputPixelScale, captureDelay)
ctx.state.Current = ctx.state.Current + 1 ctx.state.Current = ctx.state.Current + 1
end end