Gear VR template: /gear_vr.lua — code sample - Stingray Lua API Reference

Gear VR template: /gear_vr.lua — code sample

Code

require 'core/appkit/lua/class'

GearVRSystem = Appkit.class(GearVRSystem)

local Application = stingray.Application
local Viewport    = stingray.Viewport
local World       = stingray.World
local Unit        = stingray.Unit
local Matrix4x4   = stingray.Matrix4x4
local Camera      = stingray.Camera
local GearVR      = stingray.GearVR

function GearVRSystem.exists()
    return GearVR ~= nil
end

function GearVRSystem:init(world)
    if not GearVR then return end

    self._world          = world
    self._enabled        = false
    self._is_initialized = false
end

function GearVRSystem:initialize(near, far, left_rt, right_rt)
    if not GearVR then return end
    if not self then return end

    -- Intialize VR system
    self._is_initialized = GearVR.initialize()

    -- Bail if there was an error on initialization
    if not self._is_initialized then return end

    -- Fetch GearVR information
    self._hmd_info       = GearVR.hmd_info()
    self._left_eye_info  = GearVR.eye_info(GearVR.EYE_LEFT)
    self._right_eye_info = GearVR.eye_info(GearVR.EYE_RIGHT)

    -- Create left, right and blit cameras
    self._left_camera_unit  = World.spawn_unit(self._world, "core/units/camera")
    self._right_camera_unit = World.spawn_unit(self._world, "core/units/camera")
    self._blit_camera_unit  = World.spawn_unit(self._world, "core/units/camera")
    self._left_camera       = Unit.camera(self._left_camera_unit , "camera")
    self._right_camera      = Unit.camera(self._right_camera_unit, "camera")
    self._blit_camera       = Unit.camera(self._blit_camera_unit  , "camera")

    -- Create left, right and blit viewports
    self._viewport_left  = Application.create_viewport(self._world, "vr_left" )
    self._viewport_right = Application.create_viewport(self._world, "vr_right")

    -- Setup performance options
    GearVR.set_mobile_options{
            reduced_latency = true,
            correct_chromatic_aberration = false,
            --minimum_vsyncs = 2,
            --extra_latency_mode = GearVR.EXTRA_LATENCY_ON,
            cpu_level = 3,
            gpu_level = 3,
    }

    -- Setup GearVR
    GearVR.setup_hmd(
        left_rt,
        right_rt,
        self._left_eye_info.default_fov_left_tan,
        self._left_eye_info.default_fov_right_tan,
        self._left_eye_info.default_fov_down_tan,
        self._left_eye_info.default_fov_up_tan,
        self._right_eye_info.default_fov_left_tan,
        self._right_eye_info.default_fov_right_tan,
        self._right_eye_info.default_fov_down_tan,
        self._right_eye_info.default_fov_up_tan
        )

    -- Initialize cameras
    Camera.set_projection_type(self._left_camera , Camera.PERSPECTIVE)
    Camera.set_projection_type(self._right_camera, Camera.PERSPECTIVE)

    Camera.set_near_range(self._left_camera , near)
    Camera.set_near_range(self._right_camera, near)
    Camera.set_far_range (self._left_camera , far )
    Camera.set_far_range (self._right_camera, far )

    Camera.set_frustum_half_angles(
        self._left_camera,
        self._left_eye_info.default_fov_left_tan,
        self._left_eye_info.default_fov_right_tan,
        self._left_eye_info.default_fov_down_tan,
        self._left_eye_info.default_fov_up_tan
        )

    Camera.set_frustum_half_angles(
        self._right_camera,
        self._right_eye_info.default_fov_left_tan,
        self._right_eye_info.default_fov_right_tan,
        self._right_eye_info.default_fov_down_tan,
        self._right_eye_info.default_fov_up_tan
        )

    GearVR.link_node_to_tracker(
        self._left_camera_unit,
        Unit.node(self._left_camera_unit, "rp_root"),
        GearVR.LINK_HMD,
        GearVR.EYE_LEFT,
        self._world
        )

    GearVR.link_node_to_tracker(
        self._right_camera_unit,
        Unit.node(self._right_camera_unit, "rp_root"),
        GearVR.LINK_HMD,
        GearVR.EYE_RIGHT,
        self._world
        )
end

--[[
    Enable VR rendering
]]--
function GearVRSystem:enable()
    if not GearVR then return end
    if not self or not self._is_initialized then return end

    self._enabled = true
    GearVR.enable(self._enabled);
    Application.set_render_setting("vr_enabled", "true")
end

--[[
    Disable VR rendering
--]]
function GearVRSystem:disable()
    if not GearVR then return end
    if not self or not self._is_initialized then return end

    self._enabled = false
    GearVR.enable(self._enabled);
    Application.set_render_setting("vr_enabled", "false")
end

--[[
    Returns if VR rendering currently enabled
]]--
function GearVRSystem:is_enabled()
    if not GearVR then return end
    if not self or not self._is_initialized then return false end

    return self._enabled
end

--[[
    Returns VR render buffer size
]]--
function GearVRSystem:vr_back_buffer_size()
    if not GearVR then return nil end
    if not self or not self._is_initialized then return nil end

    return Application.back_buffer_size()
end

--[[
    Shutdown VR system
--]]
function GearVRSystem:shutdown()
    if not GearVR then return end
    if not self or not self._is_initialized then return end

    GearVRSystem.disable(self)
    GearVR.shutdown()

    World.destroy_unit(self._world, self._left_camera_unit)
    World.destroy_unit(self._world, self._right_camera_unit)
    World.destroy_unit(self._world, self._blit_camera_unit)

    Application.destroy_viewport(self._world, self._viewport_left)
    Application.destroy_viewport(self._world, self._viewport_right)

    self._is_initialized = false
end

--[[
    Returns the current GearVR profile values specified in meters such as:
        - profile.player_height
        - profile.eye_height
        - profile.ipd
        - profile.eye_to_neck_x
        - profile.eye_to_neck_y
--]]
function GearVRSystem:profile()
    if not GearVR then return end
    if not self or not self._is_initialized then return nil end

    return GearVR.profile()
end

--[[
    Returns the current HMD info values such as:
        - hmd_info.product_name
        - hmd_info.manufacturer
        - hmd_info.resolution_w
        - hmd_info.resolution_h
        - hmd_info.refresh_rate
--]]
function GearVRSystem:hmd_info()
    if not GearVR then return end
    if not self or not self._is_initialized then return nil end

    return self._hmd_info;
end

--[[
    Recenters the GearVR pose
]]--
function GearVRSystem:recenter()
    if not GearVR then return end
    if not self or not self._is_initialized then return end

    GearVR.recenter()
end

--[[
    Returns HMD forward vector and local eye poses
]]--
function GearVRSystem:hmd_local_pose()
    if not GearVR then return nil end
    if not self or not self._is_initialized then return nil end

    head, left, right = GearVR.hmd_local_pose()
    return {
        forward   = Matrix4x4.forward(head),
        left_eye  = left,
        right_eye = right
    }
end

--[[
    Returns HMD forward vector and world eye poses
--]]
function GearVRSystem:hmd_world_pose()
    if not GearVR then return nil end
    if not self or not self._is_initialized then return nil end

    head, left, right = GearVR.hmd_world_pose()
    return {
        forward   = Matrix4x4.forward(head),
        left_eye  = left,
        right_eye = right
    }
end


--[[
    Sets tracking space pose
--]]
function GearVRSystem:set_tracking_space_pose(pose)
    if not GearVR then return end
    if not self or not self._is_initialized then return end

    GearVR.set_tracking_space_pose(pose)
end

--[[
    Render in VR mode
]]--
function GearVRSystem:render(shading_environment)
    if not GearVR then return end
    if not self or not self._enabled then return end

    -- Render world for left and right cameras
    Application.render_world(self._world, self._left_camera, self._viewport_left, shading_environment)
    Application.render_world(self._world, self._right_camera, self._viewport_right, shading_environment)
end

return GearVRSystem