139 lines
4.2 KiB
Text
139 lines
4.2 KiB
Text
-- The 3D viewport (FORGE.md milestone 2): a room with a scene3d layer is shown as the scene,
|
|
-- built from the types' looks under an orbiting editor camera. Entities are picked and dragged
|
|
-- by where they project, the camera orbits by key, and a rail point is put where the camera
|
|
-- stands.
|
|
FORGE_LIBRARY = true
|
|
dofile("Forge/Forge.singe")
|
|
|
|
local font = fontLoad("Singe/FreeSansBold.ttf", 15)
|
|
local out = singeGetDataPath()
|
|
local work = out .. "rail.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("VIEW FAIL could not open " .. work)
|
|
singeQuit()
|
|
end
|
|
|
|
local frames = 0
|
|
local stage = 0
|
|
local wall = nil
|
|
|
|
|
|
local function key(code, character)
|
|
forgeKey(character or 0, code.value)
|
|
end
|
|
|
|
|
|
local function step()
|
|
local room = forgeRoom()
|
|
|
|
if stage == 1 then
|
|
local built = 0
|
|
|
|
for _ in pairs(FORGE.scene and FORGE.scene.nodes or {}) do
|
|
built = built + 1
|
|
end
|
|
debugPrint("VIEW the preview holds " .. built .. " of " .. #room.entities .. " entities")
|
|
if built ~= #room.entities then
|
|
debugPrint("VIEW FAIL the preview is incomplete")
|
|
end
|
|
|
|
elseif stage == 2 then
|
|
-- Pick the left wall by where it projects.
|
|
for index, entry in ipairs(room.entities) do
|
|
if entry.id == "wallL" then
|
|
wall = index
|
|
end
|
|
end
|
|
local entry = room.entities[wall]
|
|
local sx, sy, _, inFront = sceneProject(entry.x, entry.y, entry.z)
|
|
|
|
forgePress(sx, sy)
|
|
if FORGE.selected == wall then
|
|
debugPrint("VIEW picked " .. entry.id .. " at its projection " .. math.floor(sx) .. "," .. math.floor(sy))
|
|
else
|
|
debugPrint("VIEW FAIL the press at the wall selected " .. tostring(FORGE.selected) .. " (in front " .. tostring(inFront) .. ")")
|
|
end
|
|
-- Drag it a little to the right on screen and let go: it moves across the floor.
|
|
forgeDrag(sx + 40, sy)
|
|
forgeRelease()
|
|
if (entry.y == 1.5) and ((entry.x ~= -6) or (entry.z ~= -12)) then
|
|
debugPrint(string.format("VIEW dragged it to %.1f, %.1f, %.1f, staying on its floor", entry.x, entry.y, entry.z))
|
|
else
|
|
debugPrint(string.format("VIEW FAIL the drag left it at %.1f, %.1f, %.1f", entry.x, entry.y, entry.z))
|
|
end
|
|
|
|
elseif stage == 3 then
|
|
local yaw = FORGE.scene.yaw
|
|
local far = FORGE.scene.distance
|
|
|
|
key(SCANCODE.J)
|
|
key(SCANCODE.J)
|
|
key(SCANCODE.I)
|
|
debugPrint(string.format("VIEW orbit: yaw %d to %d, distance %.1f to %.1f", yaw, FORGE.scene.yaw, far, FORGE.scene.distance))
|
|
|
|
elseif stage == 4 then
|
|
-- A rail point where the camera stands, at a typed time.
|
|
key(SCANCODE.TAB)
|
|
key(SCANCODE.TAB)
|
|
key(SCANCODE.TAB)
|
|
local track = room.tracks[1]
|
|
local count = #track.points
|
|
|
|
key(SCANCODE.K)
|
|
key(SCANCODE.RETURN) -- at
|
|
for c in string.gmatch("20", ".") do
|
|
key(SCANCODE.A, string.byte(c))
|
|
end
|
|
key(SCANCODE.RETURN) -- commits at, moves on to x
|
|
key(SCANCODE.ESCAPE)
|
|
track = forgeRoom().tracks[1]
|
|
local last = track.points[#track.points]
|
|
|
|
if (#track.points == count + 1) and (last.at == 20) and (last.look ~= nil) then
|
|
debugPrint(string.format("VIEW a rail point went in at %d: %.1f, %.1f, %.1f looking at %s", last.at, last.x, last.y, last.z, tostring(last.look[1] or last.look.x)))
|
|
else
|
|
debugPrint("VIEW FAIL the rail has " .. #track.points .. " points; the last is at " .. tostring(last and last.at))
|
|
end
|
|
|
|
elseif stage == 5 then
|
|
key(SCANCODE.S)
|
|
local reloaded = authorLoad(work)
|
|
local built = forgeBuild(out .. "rail.singe")
|
|
local text = assert(io.open(built, "r")):read("a")
|
|
|
|
debugPrint("VIEW saved: the rail has " .. #reloaded.rooms[1].tracks[1].points .. " points on disc; compiled carries at = 20: " .. tostring(text:find("at = 20") ~= nil))
|
|
debugPrint("VIEW RESULT done")
|
|
end
|
|
end
|
|
|
|
|
|
function onOverlayUpdate()
|
|
frames = frames + 1
|
|
if frames % 14 == 0 and stage < 6 then
|
|
stage = stage + 1
|
|
step()
|
|
end
|
|
forgeDraw(nil, nil)
|
|
colorForeground(255, 255, 255, 255)
|
|
fontPrint(210, 8, "3D viewport, stage " .. stage)
|
|
if frames == 20 or frames == 50 or frames == 80 then
|
|
singeScreenshot()
|
|
end
|
|
if frames > 100 then
|
|
singeQuit()
|
|
end
|
|
|
|
return OVERLAY_UPDATED
|
|
end
|