-- Physics debug drawing: physicsSetDebug draws the bodies, joints, contacts and velocities as -- lines over the scene (static shapes too, with DEBUG_STATIC); lineDraw draws the script's own -- ray cast for the frame, and navDraw the navigation mesh baked from the ground and the wall. local font = fontLoad("Singe/FreeSansBold.ttf", 28) local frames = 0 fontSelect(font) sceneEnable(true) sceneSetBackground(40, 45, 60) sceneSetAmbient(90, 90, 100) local grey = materialNew() materialSetColor(grey, 120, 120, 125) local wood = materialNew() materialSetColor(wood, 150, 100, 55) local ground = nodeNew() nodeSetMesh(ground, meshBox(24, 1, 24), grey) nodeSetPosition(ground, 0, -0.5, 0) bodyNew(ground, BODY_STATIC, SHAPE_BOX, 24, 1, 24) local wall = nodeNew() nodeSetMesh(wall, meshBox(1, 2, 8), grey) nodeSetPosition(wall, 2, 1, 0) bodyNew(wall, BODY_STATIC, SHAPE_BOX, 1, 2, 8) -- Crates and a ball dropped in a heap. for i = 1, 8 do local crate = nodeNew() nodeSetMesh(crate, meshBox(1, 1, 1), wood) nodeSetPosition(crate, -6 + i * 1.2, 3 + i * 1.3, -5 + (i % 3) * 2) nodeSetRotation(crate, i * 17, i * 31, 0) bodyNew(crate, BODY_DYNAMIC, SHAPE_BOX, 1, 1, 1) end local ball = nodeNew() nodeSetMesh(ball, meshSphere(0.6), wood) nodeSetPosition(ball, -4, 8, 4) bodyNew(ball, BODY_DYNAMIC, SHAPE_SPHERE, 0.6) -- A bar hinged to a fixed block, swinging. local post = nodeNew() nodeSetMesh(post, meshBox(0.4, 0.4, 0.4), grey) nodeSetPosition(post, 6, 6, -3) bodyNew(post, BODY_STATIC, SHAPE_BOX, 0.4, 0.4, 0.4) local bar = nodeNew() nodeSetMesh(bar, meshBox(0.3, 3, 0.3), wood) nodeSetPosition(bar, 7.7, 6, -3) nodeSetRotation(bar, 0, 0, 90) bodyNew(bar, BODY_DYNAMIC, SHAPE_BOX, 0.3, 3, 0.3) jointHinge(post, bar, 6, 6, -3, 0, 0, 1) -- A player capsule walking across. local player = nodeNew() nodeSetMesh(player, meshCylinder(0.4, 1.8), wood) nodeSetPosition(player, -9, 0.9, 6) playerNew(player, 0.4, 1.8) -- Everything walkable, for navDraw. local nav = navNew(0.4, 1.8, 45, 0.4) navAddNode(nav, ground) navAddNode(nav, wall) navBuild(nav) physicsSetDebug(DEBUG_ALL + DEBUG_STATIC) local sun = lightNew(LIGHT_DIRECTIONAL) nodeSetPosition(sun, 20, 30, 10) nodeLookAt(sun, 0, 0, 0) lightSetIntensity(sun, 2) lightSetShadow(sun, true) local camera = nodeNew() cameraSet(camera) cameraSetPerspective(55, 0.1, 200) local stops = { { 0, 9, 18, 0, 1, 0 }, -- The whole heap { -8, 4, 8, -3, 1, 0 }, -- Crates and the ball, close { 12, 6, 4, 6, 5, -3 }, -- The hinged bar { 0, 20, 1, 0, 0, 0 }, -- From above: the nav mesh around the wall } function onOverlayUpdate() local stop = stops[math.min(#stops, math.floor(frames / 45) + 1)] frames = frames + 1 nodeSetPosition(camera, stop[1], stop[2], stop[3]) nodeLookAt(camera, stop[4], stop[5], stop[6]) playerMove(player, 1.5, -0.6) -- A ray from above the heap straight down, drawn to whatever it hits. local hit, hx, hy, hz = physicsRaycast(-3, 12, -1, 0, -1, 0, 30) if hit then lineDraw(-3, 12, -1, hx, hy, hz, 255, 255, 0) end navDraw(nav) local x, y, z = nodeGetWorldPosition(player) overlayClear() fontPrint(20, 20, string.format("Physics debug, frame %d player at %.1f %.1f %.1f ray hit %s", frames, x, y, z, hit and "yes" or "no")) if frames == 40 or frames == 85 or frames == 130 or frames == 175 then singeScreenshot() debugPrint(string.format("frame %d player at %.2f %.2f %.2f hit %s", frames, x, y, z, tostring(hit))) end if frames == 180 then singeQuit() end end