Skip to content

Commit c0fd7aa

Browse files
committed
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.
1 parent 20d7c33 commit c0fd7aa

File tree

1 file changed

+26
-14
lines changed

1 file changed

+26
-14
lines changed

files/capture.lua

+26-14
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ end
240240
---Starts the capturing process of the given area using a hilbert curve.
241241
---Use `Capture.MapCapturingCtx` to stop, control or view the process.
242242
---@param topLeft Vec2 -- Top left of the to be captured rectangle.
243-
---@param bottomRight Vec2 -- Non included bottom left of the to be captured rectangle.
243+
---@param bottomRight Vec2 -- Non inclusive bottom right coordinate of the to be captured rectangle.
244244
---@param captureGridSize number -- The grid size in world pixels.
245245
---@param outputPixelScale number? -- The resulting image pixel to world pixel ratio.
246246
---@param captureDelay number? -- The number of additional frames to wait before a screen capture.
@@ -250,15 +250,19 @@ function Capture:StartCapturingAreaHilbert(topLeft, bottomRight, captureGridSize
250250
local file = io.open("mods/noita-mapcap/output/nonempty", "a")
251251
if file ~= nil then file:close() end
252252

253-
---The rectangle in grid coordinates.
254-
---@type Vec2, Vec2
255-
local gridTopLeft, gridBottomRight = (topLeft / captureGridSize):Rounded("floor"), (bottomRight / captureGridSize):Rounded("floor")
253+
-- The capture offset which is needed to center the grid cells in the viewport.
254+
local captureOffset = Vec2(captureGridSize / 2, captureGridSize / 2)
255+
256+
-- Get the extended capture rectangle that encloses all grid cells that need to be included in the capture.
257+
-- In this case we only need to extend the capture area by the valid rendering rectangle.
258+
local validTopLeft, validBottomRight = Coords:ValidRenderingRect()
259+
local validTopLeftWorld, validBottomRightWorld = Coords:ToWorld(validTopLeft, topLeft + captureOffset), Coords:ToWorld(validBottomRight, bottomRight + captureOffset)
256260

257-
-- Handle edge cases.
258-
if topLeft.x == bottomRight.x then gridBottomRight.x = gridTopLeft.x end
259-
if topLeft.y == bottomRight.y then gridBottomRight.y = gridTopLeft.y end
261+
---The capture rectangle in grid coordinates.
262+
---@type Vec2, Vec2
263+
local gridTopLeft, gridBottomRight = (validTopLeftWorld / captureGridSize):Rounded("floor"), ((validBottomRightWorld) / captureGridSize):Rounded("ceil") - Vec2(1, 1)
260264

261-
---Size of the rectangle in grid coordinates.
265+
---Size of the rectangle in grid cells.
262266
---@type Vec2
263267
local gridSize = gridBottomRight - gridTopLeft
264268

@@ -287,7 +291,7 @@ function Capture:StartCapturingAreaHilbert(topLeft, bottomRight, captureGridSize
287291
---Position in world coordinates.
288292
---@type Vec2
289293
local pos = (hilbertPos + gridTopLeft) * captureGridSize
290-
pos:Add(Vec2(captureGridSize / 2, captureGridSize / 2)) -- Move to center of grid cell.
294+
pos:Add(captureOffset) -- Move to center of grid cell.
291295
captureScreenshot(pos, true, true, ctx, outputPixelScale, captureDelay)
292296
ctx.state.Current = ctx.state.Current + 1
293297
end
@@ -309,7 +313,7 @@ end
309313
---Starts the capturing process of the given area by scanning from left to right, and top to bottom.
310314
---Use `Capture.MapCapturingCtx` to stop, control or view the process.
311315
---@param topLeft Vec2 -- Top left of the to be captured rectangle.
312-
---@param bottomRight Vec2 -- Non included bottom left of the to be captured rectangle.
316+
---@param bottomRight Vec2 -- Non inclusive bottom right coordinate of the to be captured rectangle.
313317
---@param captureGridSize number -- The grid size in world pixels.
314318
---@param outputPixelScale number? -- The resulting image pixel to world pixel ratio.
315319
---@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
319323
local file = io.open("mods/noita-mapcap/output/nonempty", "a")
320324
if file ~= nil then file:close() end
321325

322-
---The rectangle in grid coordinates.
326+
-- The capture offset which is needed to center the grid cells in the viewport.
327+
local captureOffset = Vec2(captureGridSize / 2, captureGridSize / 2)
328+
329+
-- Get the extended capture rectangle that encloses all grid cells that need to be included in the capture.
330+
-- In this case we only need to extend the capture area by the valid rendering rectangle.
331+
local validTopLeft, validBottomRight = Coords:ValidRenderingRect()
332+
local validTopLeftWorld, validBottomRightWorld = Coords:ToWorld(validTopLeft, topLeft + captureOffset), Coords:ToWorld(validBottomRight, bottomRight + captureOffset)
333+
334+
---The capture rectangle in grid coordinates.
323335
---@type Vec2, Vec2
324-
local gridTopLeft, gridBottomRight = (topLeft / captureGridSize):Rounded("floor"), (bottomRight / captureGridSize):Rounded("floor")
336+
local gridTopLeft, gridBottomRight = (validTopLeftWorld / captureGridSize):Rounded("floor"), ((validBottomRightWorld) / captureGridSize):Rounded("ceil") - Vec2(1, 1)
325337

326-
---Size of the rectangle in grid coordinates.
338+
---Size of the rectangle in grid cells.
327339
---@type Vec2
328340
local gridSize = gridBottomRight - gridTopLeft
329341

@@ -345,7 +357,7 @@ function Capture:StartCapturingAreaScan(topLeft, bottomRight, captureGridSize, o
345357
---Position in world coordinates.
346358
---@type Vec2
347359
local pos = gridPos * captureGridSize
348-
pos:Add(Vec2(captureGridSize / 2, captureGridSize / 2)) -- Move to center of grid cell.
360+
pos:Add(captureOffset) -- Move to center of grid cell.
349361
captureScreenshot(pos, true, true, ctx, outputPixelScale, captureDelay)
350362
ctx.state.Current = ctx.state.Current + 1
351363
end

0 commit comments

Comments
 (0)