singe/testScripts/scene23.singe

118 lines
3.9 KiB
Text

-- Vehicles, second kind: a tank on six wheels that drives, pivots on the spot and climbs a slope,
-- and a motorcycle that leans through a turn, both from primitives, side by side.
local font = fontLoad("Singe/FreeSansBold.ttf", 28)
local frames = 0
fontSelect(font)
discPlay()
sceneEnable(true)
sceneSetBackground(0, 0, 0, 0)
sceneSetAmbient(70, 70, 80)
local ground = materialNew()
materialSetColor(ground, 90, 110, 70)
materialSetRoughness(ground, 0.95)
local armour = materialNew()
materialSetColor(armour, 80, 90, 70)
local rubber = materialNew()
materialSetColor(rubber, 30, 30, 30)
local chrome = materialNew()
materialSetColor(chrome, 200, 200, 210)
materialSetMetallic(chrome, 0.8)
materialSetRoughness(chrome, 0.2)
local floor = nodeNew()
nodeSetMesh(floor, meshBox(160, 0.2, 160), ground)
nodeSetPosition(floor, 0, -0.1, -30)
bodyNew(floor, BODY_STATIC, SHAPE_BOX, 160, 0.2, 160)
local slope = nodeNew()
nodeSetMesh(slope, meshBox(8, 0.2, 8), ground)
nodeSetPosition(slope, -6, 0.7, -24)
nodeSetRotation(slope, 20, 0, 0)
bodyNew(slope, BODY_STATIC, SHAPE_BOX, 8, 0.2, 8)
local function wheel(parent, x, y, z, radius, width)
local node = nodeNew()
nodeSetParent(node, parent)
nodeSetPosition(node, x, y, z)
local tyre = nodeNew()
nodeSetParent(tyre, node)
nodeSetMesh(tyre, meshCylinder(radius, width, 12), rubber)
nodeSetRotation(tyre, 0, 0, 90)
return node
end
-- The tank: a heavy hull, three road wheels a side.
local tank = nodeNew()
nodeSetMesh(tank, meshBox(3, 1, 5), armour)
nodeSetPosition(tank, -6, 1.2, 0)
bodyNew(tank, BODY_DYNAMIC, SHAPE_BOX, 3, 1, 5)
bodySetMass(tank, 8000)
vehicleNew(tank, VEHICLE_TANK)
for _, z in ipairs({ -1.8, 0, 1.8 }) do
vehicleAddWheel(tank, wheel(tank, -1.7, -0.4, z, 0.5, 0.4), 0.5, 0.4, 0.5)
vehicleAddWheel(tank, wheel(tank, 1.7, -0.4, z, 0.5, 0.4), 0.5, 0.4, 0.5)
end
vehicleSetEngine(tank, 1500, 4000, 800)
-- The motorcycle: a slim frame, one wheel each end, the rear driven.
local bike = nodeNew()
nodeSetMesh(bike, meshBox(0.3, 0.6, 1.6), chrome)
nodeSetPosition(bike, 4, 0.9, 0)
bodyNew(bike, BODY_DYNAMIC, SHAPE_BOX, 0.3, 0.6, 1.6)
bodySetMass(bike, 250)
vehicleNew(bike, VEHICLE_MOTORCYCLE)
vehicleAddWheel(bike, wheel(bike, 0, -0.3, -0.8, 0.35, 0.12), 0.35, 0.12, 0.3)
vehicleAddWheel(bike, wheel(bike, 0, -0.3, 0.8, 0.35, 0.12), 0.35, 0.12, 0.3)
vehicleSetEngine(bike, 150, 9000, 1200)
local sun = lightNew(LIGHT_DIRECTIONAL)
nodeSetPosition(sun, -5, 12, 6)
nodeLookAt(sun, 0, 0, -15)
lightSetIntensity(sun, 1.5)
lightSetShadow(sun, true)
local camera = nodeNew()
cameraSet(camera)
cameraSetPerspective(60, 0.1, 200)
function onOverlayUpdate()
local tx, ty, tz = nodeGetPosition(tank)
local bx, by, bz = nodeGetPosition(bike)
local t = frames / 60
frames = frames + 1
-- Tank: forward, then pivot, then on toward the slope. Bike: accelerate, then lean into a turn.
if tz > -12 and frames < 100 then
vehicleDrive(tank, 1, 0, 0, 0)
elseif frames < 130 then
vehicleDrive(tank, 0, 1, 0, 0)
else
vehicleDrive(tank, 1, 0, 0, 0)
end
if bz > -15 then
vehicleDrive(bike, 1, 0, 0, 0)
else
vehicleDrive(bike, 0.4, 0.35, 0, 0)
end
-- The camera watches the tank for the first two thirds, then chases the bike.
if frames < 125 then
nodeSetPosition(camera, tx + 8, ty + 5, tz + 10)
nodeLookAt(camera, tx, ty, tz)
else
nodeSetPosition(camera, bx + 6, by + 3, bz + 8)
nodeLookAt(camera, bx, by, bz)
end
overlayClear()
fontPrint(20, 20, string.format("Tank %.1f m/s bike %.1f m/s frame %d", vehicleGetSpeed(tank), vehicleGetSpeed(bike), frames))
if frames % 30 == 0 then
local _, ry = nodeGetRotation(tank)
local _, _, roll = nodeGetRotation(bike)
debugPrint(string.format("frame %d tank %.1f %.2f %.1f yaw %.0f speed %.1f | bike %.1f %.2f %.1f roll %.0f speed %.1f", frames, tx, ty, tz, ry, vehicleGetSpeed(tank), bx, by, bz, roll, vehicleGetSpeed(bike)))
end
if frames == 60 or frames == 120 or frames == 170 then
singeScreenshot()
end
if frames == 180 then
singeQuit()
end
end