110 lines
4 KiB
Text
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
|