80933ad1e3
V-GRID now cycles OFF / ON / BTL-OFF. BTL-OFF keeps the wireframe off during battles while leaving it available in the overworld. ON preserves the original behaviour (wireframe forced on in battles regardless of the row).
98 lines
3.9 KiB
Lua
98 lines
3.9 KiB
Lua
-- Voxel world mode: the voxel wireframe, 3D Dot Game Heroes style.
|
|
--
|
|
-- Every mesh in this mode is built on a one-unit-per-voxel grid in its OWN
|
|
-- model space -- terrain in world pixels, a character card in the sprite's
|
|
-- own pixels. So the seams are simply the
|
|
-- integer planes of that space, and drawing them is a pixel-shader job:
|
|
-- measure how far the fragment is from the nearest integer plane, in
|
|
-- DISPLAY pixels, and darken the ones within half a pixel of it. Sitting in
|
|
-- model space is what keeps the wireframe glued to a thing however it is
|
|
-- posed -- a character's card leans back by the camera's pitch and its
|
|
-- seams lean with it, instead of the world's grid sliding across the
|
|
-- sprite.
|
|
--
|
|
-- Deriving "in display pixels" needs shader derivatives (fwidth), which is
|
|
-- the one part of this that a driver can refuse. So the grid is a SECOND
|
|
-- COMPILATION of the scene shader rather than a branch inside the first
|
|
-- one: if it will not build, the mod loses the wireframe and nothing else
|
|
-- (see Voxel3D.shader).
|
|
--
|
|
-- This file owns the toggle rather than the drawing: the level, where it
|
|
-- persists, and the row the player finds it on.
|
|
|
|
-- the mod namespace (see main.lua): V.require loads a sibling module
|
|
local V = ...
|
|
|
|
local ModSetting = V.require("ModSetting")
|
|
|
|
local VoxelGrid = {}
|
|
|
|
-- the key under options.modOptions.DRAMATIC_SHAPE, shared by the row in
|
|
-- OPTIONS and the mod manager's own settings page for this mod
|
|
VoxelGrid.KEY = "grid"
|
|
VoxelGrid.LABEL = "V-GRID"
|
|
|
|
-- How far toward black a seam pulls the surface it cuts across. The
|
|
-- wireframe reads as a shading of the model rather than an overlay drawn
|
|
-- on top of it, so it darkens what is already there instead of painting a
|
|
-- colour -- a seam across dark grass and one across a white roof both stay
|
|
-- in the palette they belong to.
|
|
VoxelGrid.DARK = 0.45
|
|
|
|
-- Line width, in display pixels. The scene canvas renders at window
|
|
-- resolution and composites 1:1, so a canvas pixel IS a display pixel and
|
|
-- 1.0 here is the one-pixel wireframe.
|
|
VoxelGrid.WIDTH = 1.0
|
|
|
|
-- The same width in the CANVAS pixels the shader measures in, which is what
|
|
-- every sender of it actually wants.
|
|
--
|
|
-- The two are the same number until AA renders the pass larger than the
|
|
-- window (see AntiAlias): there a canvas pixel is a fraction of a display
|
|
-- one, and a width left at 1.0 would come out a half or a quarter of a line
|
|
-- after the fold -- the wireframe fading as the smoothing goes up, which
|
|
-- reads as one row breaking the other. Scaled, it stays a one-pixel seam and
|
|
-- simply gains the antialiasing everything else in the frame just gained.
|
|
function VoxelGrid.width()
|
|
return VoxelGrid.WIDTH * V.require("AntiAlias").factor()
|
|
end
|
|
|
|
-- where it persists and the rows that cycle it (see ModSetting)
|
|
VoxelGrid.setting = ModSetting.new(VoxelGrid.KEY, VoxelGrid.LABEL,
|
|
{ false, true, "btloff" }, { "OFF", "ON", "BTL-OFF" })
|
|
|
|
-- The row is the whole answer, everywhere: free-roam and the battle arena
|
|
-- alike. The battle used to force the seams on regardless -- a fight is a
|
|
-- STAGED shot, and the seams are what make it read as constructed rather
|
|
-- than photographed -- but a player who turns the wireframe off means the
|
|
-- whole mod, and a mode that came back for every fight read as the row not
|
|
-- working rather than as a deliberate framing.
|
|
function VoxelGrid.enabled()
|
|
if VoxelGrid.override ~= nil then return VoxelGrid.override end
|
|
local v = VoxelGrid.setting:get()
|
|
if v == "btloff" then return false end
|
|
return v and true or false
|
|
end
|
|
|
|
function VoxelGrid.battleForced()
|
|
return VoxelGrid.setting:get() ~= "btloff"
|
|
end
|
|
|
|
function VoxelGrid.set(enabled, game)
|
|
return VoxelGrid.setting:setIndex(enabled and 2 or 1, game)
|
|
end
|
|
|
|
function VoxelGrid.toggle(game)
|
|
return VoxelGrid.setting:cycle(game)
|
|
end
|
|
|
|
function VoxelGrid.sync(value)
|
|
VoxelGrid.setting:sync(value)
|
|
end
|
|
|
|
function VoxelGrid.row()
|
|
return VoxelGrid.setting:row()
|
|
end
|
|
|
|
return VoxelGrid
|