----------------------------------------------------------------------------------- -- This implementation uses the default SimpleProject and the Project extensions are -- used to extend the SimpleProject behavior. -- This is the global table name used by Appkit Basic project to extend behavior Project = Project or {} require 'script/lua/flow_callbacks' require 'vr_oculus/script/lua/oculus_vr_flow_callbacks' Project.level_names = { floorplan = "content/levels/vr_learning" } require 'core/appkit/lua/simple_project' SimpleProject = SimpleProject or {} -- Oculus device require 'vr_oculus/script/lua/oculus_vr' OculusVRSystem = OculusVRSystem or {} -- Oculus input mapper require 'vr_oculus/script/lua/oculus_input_mapper' OculusInputMapper = OculusInputMapper or {} local vr_system = nil local vr_input_mapper = nil local vr_player_height = 1.778 local vr_eye_height = 1.675 -- Can provide a config for the basic project, or it will use a default if not. SimpleProject.config = { standalone_init_level_name = Project.level_names.floorplan, camera_unit = "core/appkit/units/camera/camera", camera_index = 1, shading_environment = nil, -- Will override levels that have env set in editor. create_free_cam_player = false, -- Project will provide its own player. exit_standalone_with_esc_key = true -- Loading screen disabled until 2D gui VR is fully supported. -- loading_screen_materials = {"core/appkit/materials/loading_screen"}, -- loading_screen_start_package = "loading_screen", -- loading_screen_end_package = "main", -- loading_screen_shading_env = "core/stingray_renderer/environments/midday/midday" -- Controls the shading environment used by default by the loading screen. } -- check to see if there are player starts in the level, if not return world 0 local function get_player_start_pose() local player_starts = stingray.World.units_by_resource(SimpleProject.world, "tools/player_start") if #player_starts > 0 then local index = stingray.Math.random(1, #player_starts) local pose = stingray.Unit.world_pose(player_starts[index], 1) local scale = stingray.Unit.local_scale(player_starts[index], 1) stingray.Matrix4x4.set_scale(pose, scale) return pose else return stingray.Matrix4x4.identity() end end -- return a new quaternion containing only euler z-axis rotation local function get_rotation_z(rotation) local _, _, euler_z = stingray.Quaternion.to_euler_angles_xyz(rotation) return stingray.Quaternion(stingray.Vector3.up(), math.rad(euler_z)) end -- This optional function is called by SimpleProject after level, world and player is loaded -- but before lua trigger level loaded node is activated. function Project.on_level_load_pre_flow() -- Spawn the player for all non-menu levels. -- level_name will be nil if this -- is an unsaved Test Level. local level_name = SimpleProject.level_name local managed_world = Appkit.managed_world; -- Create and setup an Oculus device for project local managed_world = Appkit.managed_world vr_system = OculusVRSystem(managed_world.world) Project.vr_system = vr_system OculusVRSystem.initialize(vr_system, 0.01, 1000.0, "vr_target", "vr_hud") OculusVRSystem.enable(vr_system) vr_input_mapper = OculusInputMapper(vr_system) local view_position = Appkit.get_editor_view_position() or stingray.Vector3(10, 1, vr_player_height) local view_rotation = Appkit.get_editor_view_rotation() or stingray.Quaternion.identity() local view_scale = stingray.Vector3(1,1,1) -- If an Oculus profile is found use it's data to initialize local values local vr_profile = OculusVRSystem.profile(vr_system) if vr_profile then vr_player_height = vr_profile.player_height vr_eye_height = vr_profile.eye_height end -- Fixes Oculus tracking origin vr_player_height = vr_player_height / 2 vr_eye_height = vr_eye_height / 2 Project.vr_eye_height = vr_eye_height if OculusVRSystem.is_enabled(vr_system) then if LEVEL_EDITOR_TEST then OculusVRSystem.set_tracking_space(vr_system, stingray.Matrix4x4.from_quaternion_position(get_rotation_z(view_rotation), view_position, view_scale)) else local player_start_pose = get_player_start_pose() local player_start_position = stingray.Matrix4x4.transform(player_start_pose, stingray.Vector3(0, 0, vr_player_height)) stingray.Matrix4x4.set_translation(player_start_pose, player_start_position) OculusVRSystem.set_tracking_space(vr_system, stingray.Matrix4x4.translation(player_start_pose), stingray.Matrix4x4.rotation(player_start_pose), stingray.Matrix4x4.scale(player_start_pose)) end else if not LEVEL_EDITOR_TEST then local player_start_pose = get_player_start_pose() local player_start_position = stingray.Matrix4x4.transform(player_start_pose, stingray.Vector3(0, 0, vr_player_height)) stingray.Matrix4x4.set_translation(player_start_pose, player_start_position) view_position = stingray.Matrix4x4.translation(player_start_pose) view_rotation = stingray.Matrix4x4.rotation(player_start_pose) end local Player = require 'script/lua/player' Player.set_default_character_eye_height(vr_eye_height) Player.spawn_player(SimpleProject.level, view_position, view_rotation, vr_input_mapper) end end function Project.on_level_shutdown_post_flow() end -- Optional function called by SimpleProject after world update (we will probably want to split to pre/post appkit calls) function Project.update(dt) if not vr_system then return end -- Update Oculus tracking space pose local managed_world = Appkit.managed_world; -- Update input OculusInputMapper.update(vr_input_mapper, dt) if not OculusVRSystem.is_enabled(vr_system) then return end -- Press 'r' key to recenter Oculus pose if stingray.Keyboard.pressed(stingray.Keyboard.button_id('r')) then OculusVRSystem.recenter(vr_system) end -- Update the Wwise Listener to include the Oculus device pose if stingray.Wwise then local eye_poses = OculusInputMapper.get_eye_poses(vr_input_mapper) stingray.WwiseWorld.set_listener( stingray.Wwise.wwise_world(managed_world.world), stingray.Wwise.LISTENER_0, eye_poses.left_eye ) end end -- Optional function called by SimpleProject *before* appkit/level/player/world shutdown function Project.shutdown() OculusVRSystem.shutdown(vr_system) end function Project.render() if OculusVRSystem.is_enabled(vr_system) then local managed_world = Appkit.managed_world OculusVRSystem.render(vr_system, managed_world.shading_env) return true -- Override the regular SimpleProject rendering with VR rendering end end return Project