131 lines
3.9 KiB
Text
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
|