singe/testScripts/scene22.singe

110 lines
4 KiB
Text

-- Vehicles: a car built from primitives (a box chassis with a dynamic body, four wheel nodes) on a
-- track with a ramp, crates and a wall, driven by a scripted route: pull away, jump the ramp, brake,
-- turn, and reverse into the crates. The camera chases.
local font = fontLoad("Singe/FreeSansBold.ttf", 28)
local frames = 0
local turned = false
local reversed = false
fontSelect(font)
discPlay()
sceneEnable(true)
sceneSetBackground(0, 0, 0, 0)
sceneSetAmbient(70, 70, 80)
local asphalt = materialNew()
materialSetColor(asphalt, 70, 70, 75)
materialSetRoughness(asphalt, 0.95)
local paint = materialNew()
materialSetColor(paint, 200, 40, 40)
materialSetMetallic(paint, 0.5)
materialSetRoughness(paint, 0.3)
local rubber = materialNew()
materialSetColor(rubber, 30, 30, 30)
local wood = materialNew()
materialSetColor(wood, 150, 100, 50)
local function block(x, y, z, w, h, d, material, rz)
local node = nodeNew()
nodeSetMesh(node, meshBox(w, h, d), material)
nodeSetPosition(node, x, y, z)
if rz then nodeSetRotation(node, rz, 0, 0) end
bodyNew(node, BODY_STATIC, SHAPE_BOX, w, h, d)
return node
end
-- The track runs along -Z (the car's nose). A long floor, a ramp, a landing, crates and a wall.
block(0, -0.1, -60, 40, 0.2, 200, asphalt)
block(0, 0.45, -18, 6, 0.2, 5, asphalt, 12)
block(0, 0.9, -23.4, 6, 0.2, 6, asphalt)
for i = 0, 5 do
local crate = nodeNew()
nodeSetMesh(crate, meshBox(0.6, 0.6, 0.6), wood)
nodeSetPosition(crate, -3 + (i % 3) * 0.65, 0.3 + math.floor(i / 3) * 0.62, -36)
bodyNew(crate, BODY_DYNAMIC, SHAPE_BOX, 0.6, 0.6, 0.6)
bodySetMass(crate, 4)
end
block(8, 1, -30, 0.3, 2, 12, asphalt)
-- The car: chassis 1.8 x 0.5 x 4.0, wheels as children whose X axis is the axle.
local car = nodeNew()
nodeSetMesh(car, meshBox(1.8, 0.5, 4.0), paint)
nodeSetPosition(car, 0, 0.9, 0)
bodyNew(car, BODY_DYNAMIC, SHAPE_BOX, 1.8, 0.5, 4.0)
bodySetMass(car, 1500)
vehicleNew(car, VEHICLE_CAR)
local wheels = {}
for i, p in ipairs({ { -0.95, -0.2, -1.4 }, { 0.95, -0.2, -1.4 }, { -0.95, -0.2, 1.4 }, { 0.95, -0.2, 1.4 } }) do
local wheel = nodeNew()
nodeSetParent(wheel, car)
nodeSetPosition(wheel, p[1], p[2], p[3])
local tyre = nodeNew()
nodeSetParent(tyre, wheel)
nodeSetMesh(tyre, meshCylinder(0.35, 0.25, 16), rubber)
nodeSetRotation(tyre, 0, 0, 90)
wheels[i] = vehicleAddWheel(car, wheel, 0.35, 0.25, 0.4)
end
vehicleSetEngine(car, 600, 6500, 1000)
vehicleSetAntiRoll(car, 800)
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 cx, cy, cz = nodeGetPosition(car)
local t = frames / 60
frames = frames + 1
-- Route by distance, since physics runs on the clock: floor it over the ramp, then brake and
-- steer, then reverse toward the crates, then stop.
if cz > -30 and not turned then
vehicleDrive(car, 1, 0, 0, 0)
elseif not turned then
vehicleDrive(car, 0, 0.7, 0.6, 0)
if vehicleGetSpeed(car) < 2 then turned = true end
elseif not reversed then
vehicleDrive(car, -1, 0, 0, 0)
if vehicleGetSpeed(car) < -6 then reversed = true end
else
vehicleDrive(car, 0, 0, 1, 1)
end
nodeSetPosition(camera, cx + 3, cy + 3, cz + 9)
nodeLookAt(camera, cx, cy, cz - 3)
overlayClear()
fontPrint(20, 20, string.format("Car, frame %d speed %.1f m/s gear %d rpm %.0f", frames, vehicleGetSpeed(car), vehicleGetGear(car), vehicleGetRpm(car)))
if frames % 30 == 0 then
debugPrint(string.format("frame %d car %.1f %.2f %.1f speed %.1f gear %d rpm %.0f ground %s %s %s %s slip %.2f", frames, cx, cy, cz, vehicleGetSpeed(car), vehicleGetGear(car), vehicleGetRpm(car), tostring(vehicleIsWheelOnGround(car, 0)), tostring(vehicleIsWheelOnGround(car, 1)), tostring(vehicleIsWheelOnGround(car, 2)), tostring(vehicleIsWheelOnGround(car, 3)), vehicleGetWheelSlip(car, 2)))
end
if frames == 60 or frames == 120 or frames == 170 then
singeScreenshot()
end
if frames == 180 then
singeQuit()
end
end