require "lua/camera" local wd = wd or nil local pw = pw or nil local rw = rw or nil local sg = sg or nil local camera = camera or nil local physics_debug = physics_debug or false local graphics_debug = graphics_debug or false local fpscamera = fpscamera or nil local move = false function init() -- Set the title of the main window Window.set_title("01-physics") Device.enable_resource_autoload(true) -- Create World wd = Device.create_world() pw = World.physics_world(wd) rw = World.render_world(wd) sg = World.scene_graph(wd) -- Spawn camera camera_unit = World.spawn_unit(wd, "core/units/camera") local camera_tr = SceneGraph.transform_instances(sg, camera_unit) SceneGraph.set_local_position(sg, camera_tr, Vector3(0, 1.5, -20)) camera = World.camera(wd, camera_unit) World.set_camera_viewport_metrics(wd, camera, 0, 0, 1000, 625) -- Spawn light World.spawn_unit(wd, "core/units/light", Vector3(-25, 25, -25)) -- Spawn skydome skydome = World.spawn_unit(wd, "skydome") local skydome_transform = SceneGraph.transform_instances(sg, skydome) SceneGraph.set_local_scale(sg, skydome_transform, Vector3(500, 500, 500)) -- Spawn ground World.spawn_unit(wd, "plane", Vector3(0, 0, 0)) -- Load test level World.load_level(wd, "test", Vector3(0, 0.1, 0)) -- Spawn additional stuff World.spawn_unit(wd, "ramp", Vector3(0, 0, 25), Quaternion.look(Vector3(1, 0, 0))) -- Debug stuff PhysicsWorld.enable_debug_drawing(pw, physics_debug) RenderWorld.enable_debug_drawing(rw, graphics_debug) -- Spawn FPS camera fpscamera = FPSCamera(wd, camera_unit) end function update(dt) -- Update wd World.update(wd, dt) -- Stop the engine when the 'ESC' key is released if Keyboard.released(Keyboard.button_id("escape")) then Device.quit() end if Keyboard.released(Keyboard.button_id("z")) then physics_debug = not physics_debug PhysicsWorld.enable_debug_drawing(pw, physics_debug) end if Keyboard.released(Keyboard.button_id("x")) then graphics_debug = not graphics_debug RenderWorld.enable_debug_drawing(rw, graphics_debug) end -- Spawn a sphere when left mouse button is pressed if Mouse.pressed(Mouse.button_id("left")) then local camera_transform = SceneGraph.transform_instances(sg, camera_unit) local pos = SceneGraph.local_position(sg, camera_transform) local dir = Matrix4x4.z(SceneGraph.local_pose(sg, camera_transform)) local u1 = World.spawn_unit(wd, "sphere", pos) Vector3.normalize(dir) local a1 = PhysicsWorld.actor_instances(pw, u1) PhysicsWorld.add_actor_impulse(pw, a1, dir * 500.0) end -- Perform a raycast when middle mouse button is pressed if Mouse.pressed(Mouse.button_id("middle")) then local camera_transform = SceneGraph.transform_instances(sg, camera_unit) local pos = SceneGraph.local_position(sg, camera_transform) local dir = Matrix4x4.z(SceneGraph.local_pose(sg, camera_transform)) local hits = PhysicsWorld.raycast(pw, pos, dir, 100, "closest") if #hits > 0 then PhysicsWorld.add_actor_impulse(pw, hits[1], dir * 400.0) end end -- Update camera local delta = Vector3.zero() if Mouse.pressed(Mouse.button_id("right")) then move = true end if Mouse.released(Mouse.button_id("right")) then move = false end if move then delta = Mouse.axis(Mouse.axis_id("cursor_delta")) end fpscamera:update(-delta.x, -delta.y) end function render(dt) local win_w, win_h = Device.resolution() World.set_camera_aspect(wd, camera, win_w/win_h) World.set_camera_viewport_metrics(wd, camera, 0, 0, win_w, win_h) Device.render_world(wd, fpscamera:camera()) end function shutdown() Device.destroy_world(wd) end