singe/testScripts/scene80.singe
2026-09-14 14:20:17 -05:00

131 lines
3.9 KiB
Text

-- Gizmos in the 3D viewport (FORGE.md): the selected entity carries three arms along the world
-- axes, and dragging an arm's handle moves the entity along that axis alone -- the pointer's
-- travel along the arm, as a fraction of the arm, is the distance moved.
FORGE_LIBRARY = true
dofile("Forge/Forge.singe")
local font = fontLoad("Singe/FreeSansBold.ttf", 15)
local out = singeGetDataPath()
local work = out .. "gizmo.game"
fontSelect(font)
fontQuality(FONT_QUALITY_BLENDED)
overlaySetResolution(720, 480)
local source = assert(io.open("testScripts/author/railshooter.game", "r"))
local copy = assert(io.open(work, "w"))
copy:write(source:read("a"))
source:close()
copy:close()
if not forgeBegin(work) then
debugPrint("GIZMO FAIL could not open " .. work)
singeQuit()
end
local frames = 0
local stage = 0
local function handle(axis)
for _, item in ipairs(forgeGizmoHandles()) do
if item.axis == axis then
return item
end
end
return nil
end
local function step()
local room = forgeRoom()
if stage == 1 then
for index, entry in ipairs(room.entities) do
if entry.id == "wallL" then
forgeSelect(index)
end
end
local arms = forgeGizmoHandles()
debugPrint("GIZMO the selected wall shows " .. #arms .. " arms")
if #arms ~= 4 then
debugPrint("GIZMO FAIL expected three axis arms and the turn handle")
end
elseif stage == 2 then
-- Drag the Y handle the length of its own arm: the wall rises one arm's length (1.5) and
-- nothing else about it changes.
local entry = room.entities[FORGE.selected]
local was = { x = entry.x, y = entry.y, z = entry.z }
local arm = handle("y")
forgePress(arm.tx, arm.ty)
forgeDrag(arm.tx + (arm.tx - arm.sx), arm.ty + (arm.ty - arm.sy))
forgeRelease()
debugPrint(string.format("GIZMO the Y arm took the wall from %.1f to %.1f; x %.1f to %.1f, z %.1f to %.1f", was.y, entry.y, was.x, entry.x, was.z, entry.z))
if math.abs(entry.y - (was.y + 1.5)) > 0.2 or entry.x ~= was.x or entry.z ~= was.z then
debugPrint("GIZMO FAIL the Y drag did not move along Y alone")
end
elseif stage == 3 then
-- And the X handle, dragged half an arm back.
local entry = room.entities[FORGE.selected]
local was = entry.x
local arm = handle("x")
forgePress(arm.tx, arm.ty)
forgeDrag(arm.tx - (arm.tx - arm.sx) / 2, arm.ty - (arm.ty - arm.sy) / 2)
forgeRelease()
debugPrint(string.format("GIZMO the X arm took the wall from %.1f to %.1f", was, entry.x))
if math.abs(entry.x - (was - 0.75)) > 0.2 then
debugPrint("GIZMO FAIL the X drag did not move half an arm back")
end
forgeKey(0, SCANCODE.U.value)
forgeKey(0, SCANCODE.U.value)
-- Undo puts a copy of the description in place, so the room is looked up again.
local back = forgeRoom().entities[FORGE.selected]
debugPrint(string.format("GIZMO two undos: the wall is back at x %.1f, y %.1f", back.x, back.y))
if back.x ~= -6 or back.y ~= 1.5 then
debugPrint("GIZMO FAIL undo did not put the wall back")
end
elseif stage == 4 then
-- The turn handle: dragged a quarter turn round the entity on screen.
local entry = forgeRoom().entities[FORGE.selected]
local arm = handle("ry")
local dx, dy = arm.tx - arm.sx, arm.ty - arm.sy
forgePress(arm.tx, arm.ty)
forgeDrag(arm.sx - dy, arm.sy + dx)
forgeRelease()
debugPrint(string.format("GIZMO the turn handle set ry to %s", tostring(entry.ry)))
if (entry.ry == nil) or (math.abs(((entry.ry - 270 + 180) % 360) - 180) > 15) then
debugPrint("GIZMO FAIL a quarter turn clockwise on screen should read about 270")
end
debugPrint("GIZMO RESULT done")
end
end
function onOverlayUpdate()
frames = frames + 1
if frames % 14 == 0 and stage < 5 then
stage = stage + 1
step()
end
forgeDraw(nil, nil)
colorForeground(255, 255, 255, 255)
fontPrint(210, 8, "gizmos, stage " .. stage)
if frames == 20 or frames == 34 then
singeScreenshot()
end
if frames > 80 then
singeQuit()
end
return OVERLAY_UPDATED
end