VR

There is a plugin winds3dvr adds VR feature to Awakening. winds3dvr use OpenVR sdk to supports VR, so any OpenVR compatible device can use in Awakening.
winds3dvr consisted of three files: winds3dvr.dll, winds3dvr.ini, winds3dvr.lua; the winds3dvr.ini is configuration file, you can edit it with notepad, and winds3dvr.lua provides script support. All these files (includes openvr_api.dll) can be found at Awakening's install folder.

To use the plugin, you should first copy these files to the same folder of WindsPlayer.exe (see Remark), then add below codes in your Scene Config File or  User Script File:

    lgLoadPackage(PACKAGE_VR)
    require 'winds3dvr'


Configuration file:

The winds3dvr.ini is a text file, you can edit to configure VR. Most of parameters in configuration file also can be changed by scripting. Here is the parameters list:

 Variable Name   Explain
 debug_mode Indicates whether turn on debug mode, should be 0 or 1.
 camera_offset The height offset of camera for vr rendering. Because HMD's position bases ground, so you need put camera to ground in scene to get right vr pictures; but normally camera will no locate on ground, e.g. the default player 's eye has a 160 height to ground, so you should set camera_offset to 160 to match HMD.
If absent, the default offset is 0.
 width_scale winds3dvr use device recommended resolution to render vr picture by default; but you can change resolution by width_scale & height_scale parameters, the value 100 means 100% scale. e.g. you can set it to 50, to use half resolution rendering, will effectively improve performance.
 height_scale see above.
 2dbuffer_width_scale All 2d elements will first render to a 2dbuffer, then stretchblt to the overlay plane. The 2dbuffer's resolution is:
vr_rendering_resolution_width * 2dbuffer_width_scale / 100
vr_rendering_resolution_width * 2dbuffer_height_scale / 100
Lower 2d buffer resolution make 2d elements looks bigger.
The default width scale is 100.
 2dbuffer_height_scale See above, the default height scale  is 75.
 fov_scale winds3dvr use device recommended field of view to render vr picture by default; but you can change it by this parameter, the value 100 means 100% scale. (normally no need to change fov)
 copy_to_host Indicates whether copy vr picture to host (WindsPlayer's window):
0: no copy 1: copy left eye's picture 2: copy right eye's picture
you can use DoConsoleCommand('r_host_render 0') script code to turn off host rendering to improve performance.
 near_clip The near clipping plane for vr rendering. The value normally should same as setting in Miscellaneous Options
 far_clip The far clipping plane for vr rendering
 unit_scale The OpenVR sdk treat 1 length unit as 1 meter, but 1 unit means 1 centimeter in Awakening, so set this parameter to 100 normally. If absent, the default value is 100.
 overlay_show
Indicates whether draw overlay content in vr rendering, should be 0 or 1, default is 0.
When turn on overlay drawing, all overlay elements ( text2d, image2d, etc. )  in scene will be draw in a plane in front of eyes.
 overlay_height The half height of overlay plane, default is 75; the half width of overlay plane is fixed to 100.
 overlay_depth The depth of overlay plane, default is 100; depth means the distance to eyes.
 overlay_alpha The opacity of overlay plane, default is 255.
The value range (0 ~ 255) means cutout mode, the area outside of 2d elements will leave blank.
The value range (256 ~ 511) means fill mode, first clear plane use scene background color, then draw 2d elements.

 

Scripting:

winds3dvr provides script api let you control vr:

 Class Name   Explain
 winds3dvr  winds3dvr
 controller  tracked controller
 device  tracked device
 pose  pose of tracking device

Global Variables:

 Variable Name   Explain
 winds3dvr winds3dvr
 ControllerA controller instance, pre-generated by winds3dvr_new_controller(1)
 ControllerB controller instance, pre-generated by winds3dvr_new_controller(2)
 finalcameraLeft the camera used for vr rendering, combined by scene camera and HMD & left eye pose
 finalcameraRight the camera used for vr rendering, combined by scene camera and HMD & right eye pose
 finalcamera the camera averaged from finalcameraLeft & finalcameraRight ( if not in VR mode, the finalcamera same with scene camera but delay one frame )

Functions:

 Function Name Parameter Return   Explain
 winds3dvr_new_controller number idxCtrl controller generate a controller instance, the parameter idxCtrl is controller index (1 based)
 mouse_message_by_ray controller ctrl, ray ray,
number winWidth, winHeight
None generate mouse message by ray, see Remark3.

 

 Callback Function Parameter Return   Explain
 onControllerButtonPress number deviceID, buttonID None if you define this function, winds3dvr will call it when a controller button be pressed.
 onControllerButtonUnpress number deviceID, buttonID None if you define this function, winds3dvr will call it when a controller button  unpressed.
 onControllerButtonTouch number deviceID, buttonID None if you define this function, winds3dvr will call it when a controller button  be touched.
 onControllerButtonUntouch number deviceID, buttonID None if you define this function, winds3dvr will call it when a controller button  untouched.
       
 _onVREvent number eventType, deviceID, eventAgeSeconds,
dword pdata
None if you define this function, winds3dvr will call it when  a vr event occur. the parameter pdata is a pointer to event data.
see Remark2.

 

Remark:  To use plugin, you also need ensure lg.dll & User.cfg locate with WindsPlayer.exe and  add a line to User.cfg: iniLogicModule = "lg.dll"

Remark2:  The eventType defined by below code:

--------- VR Event Type --------
VREvent =
{
None = 0,

TrackedDeviceActivated = 100,
TrackedDeviceDeactivated = 101,
TrackedDeviceUpdated = 102,
TrackedDeviceUserInteractionStarted = 103,
TrackedDeviceUserInteractionEnded = 104,
IpdChanged = 105,
EnterStandbyMode = 106,
LeaveStandbyMode = 107,
TrackedDeviceRoleChanged = 108,
WatchdogWakeUpRequested = 109,
LensDistortionChanged = 110,
PropertyChanged = 111,

ButtonPress = 200, -- data is controller
ButtonUnpress = 201, -- data is controller
ButtonTouch = 202, -- data is controller
ButtonUntouch = 203, -- data is controller

MouseMove = 300, -- data is mouse
MouseButtonDown = 301, -- data is mouse
MouseButtonUp = 302, -- data is mouse
FocusEnter = 303, -- data is overlay
FocusLeave = 304, -- data is overlay
Scroll = 305, -- data is mouse
TouchPadMove = 306, -- data is mouse
OverlayFocusChanged = 307, -- data is overlay, global event

InputFocusCaptured = 400, -- data is process DEPRECATED
InputFocusReleased = 401, -- data is process DEPRECATED
SceneFocusLost = 402, -- data is process
SceneFocusGained = 403, -- data is process
SceneApplicationChanged = 404, -- data is process - The App actually drawing the scene changed (usually to or from the compositor)
SceneFocusChanged = 405, -- data is process - New app got access to draw the scene
InputFocusChanged = 406, -- data is process
SceneApplicationSecondaryRenderingStarted = 407, -- data is process

HideRenderModels = 410, -- Sent to the scene application to request hiding render models temporarily
ShowRenderModels = 411, -- Sent to the scene application to request restoring render model visibility

OverlayShown = 500,
OverlayHidden = 501,
DashboardActivated = 502,
DashboardDeactivated = 503,
DashboardThumbSelected = 504, -- Sent to the overlay manager - data is overlay
DashboardRequested = 505, -- Sent to the overlay manager - data is overlay
ResetDashboard = 506, -- Send to the overlay manager
RenderToast = 507, -- Send to the dashboard to render a toast - data is the notification ID
ImageLoaded = 508, -- Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading
ShowKeyboard = 509, -- Sent to keyboard renderer in the dashboard to invoke it
HideKeyboard = 510, -- Sent to keyboard renderer in the dashboard to hide it
OverlayGamepadFocusGained = 511, -- Sent to an overlay when IVROverlay::SetFocusOverlay is called on it
OverlayGamepadFocusLost = 512, -- Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else
OverlaySharedTextureChanged = 513,
DashboardGuideButtonDown = 514,
DashboardGuideButtonUp = 515,
ScreenshotTriggered = 516, -- Screenshot button combo was pressed, Dashboard should request a screenshot
ImageFailed = 517, -- Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load
DashboardOverlayCreated = 518,

-- Screenshot API
RequestScreenshot = 520, -- Sent by vrclient application to compositor to take a screenshot
ScreenshotTaken = 521, -- Sent by compositor to the application that the screenshot has been taken
ScreenshotFailed = 522, -- Sent by compositor to the application that the screenshot failed to be taken
SubmitScreenshotToDashboard = 523, -- Sent by compositor to the dashboard that a completed screenshot was submitted
ScreenshotProgressToDashboard = 524, -- Sent by compositor to the dashboard that a completed screenshot was submitted

PrimaryDashboardDeviceChanged = 525,

Notification_Shown = 600,
Notification_Hidden = 601,
Notification_BeginInteraction = 602,
Notification_Destroyed = 603,

Quit = 700, -- data is process
ProcessQuit = 701, -- data is process
QuitAborted_UserPrompt = 702, -- data is process
QuitAcknowledged = 703, -- data is process
DriverRequestedQuit = 704, -- The driver has requested that SteamVR shut down

ChaperoneDataHasChanged = 800,
ChaperoneUniverseHasChanged = 801,
ChaperoneTempDataHasChanged = 802,
ChaperoneSettingsHaveChanged = 803,
SeatedZeroPoseReset = 804,

AudioSettingsHaveChanged = 820,

BackgroundSettingHasChanged = 850,
CameraSettingsHaveChanged = 851,
ReprojectionSettingHasChanged = 852,
ModelSkinSettingsHaveChanged = 853,
EnvironmentSettingsHaveChanged = 854,
PowerSettingsHaveChanged = 855,
EnableHomeAppSettingsHaveChanged = 856,

StatusUpdate = 900,

MCImageUpdated = 1000,

FirmwareUpdateStarted = 1100,
FirmwareUpdateFinished = 1101,

KeyboardClosed = 1200,
KeyboardCharInput = 1201,
KeyboardDone = 1202, -- Sent when DONE button clicked on keyboard

ApplicationTransitionStarted = 1300,
ApplicationTransitionAborted = 1301,
ApplicationTransitionNewAppStarted = 1302,
ApplicationListUpdated = 1303,
ApplicationMimeTypeLoad = 1304,
ApplicationTransitionNewAppLaunchComplete = 1305,
ProcessConnected = 1306,
ProcessDisconnected = 1307,

Compositor_MirrorWindowShown = 1400,
Compositor_MirrorWindowHidden = 1401,
Compositor_ChaperoneBoundsShown = 1410,
Compositor_ChaperoneBoundsHidden = 1411,

TrackedCamera_StartVideoStream = 1500,
TrackedCamera_StopVideoStream = 1501,
TrackedCamera_PauseVideoStream = 1502,
TrackedCamera_ResumeVideoStream = 1503,
TrackedCamera_EditingSurface = 1550,

PerformanceTest_EnableCapture = 1600,
PerformanceTest_DisableCapture = 1601,
PerformanceTest_FidelityLevel = 1602,

MessageOverlay_Closed = 1650,

-- Vendors are free to expose private events in this reserved region
VendorSpecific_Reserved_Start = 10000,
VendorSpecific_Reserved_End = 19999,
}

Remark3: You can use controller & ray to simulate mouse operation. The function check intersection between ray & overlay plane, calculate mousex & mousey by intersection point and parameter winWidth &               winHeight, and check controller's trigger button for mouse down / up; typical usage is:
                        mouse_message_by_ray( ControllerA, ray.new( ControllerA.getPosition(), ControllerA.getFront() ), winwidth, winheight )
                        -- call this function in FrameMove(), winwidth,winheight is window size; but if you use dxui plugin, should let winwidth, winheight = winds3dvr.get_2dbuffer_resolution()

Remark4: If water rendering looks uncomfortable in vr mode, try set the console variable r_oblique_clip to 1