Skip to content

Commit

Permalink
New Input Data Format for WebXR Data (#2)
Browse files Browse the repository at this point in the history
* Update Input to match format from client

* Add HDRP Sample

* Add Changelog and HDRP Sample

* Update to 0.2.0
  • Loading branch information
vmohan7 authored Jul 12, 2021
1 parent a7caf3d commit 782cb32
Show file tree
Hide file tree
Showing 255 changed files with 28,160 additions and 35 deletions.
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Changelog
All notable changes to com.unity.renderstreaming package will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [0.2.0] - 2021-07-12

### Changed

- VR Controller Data Input Format from client for WebXR data

### Added

- VR Controller Data for Axis input i.e. Trackpad and Joystick
- HDRP VR Render Streaming Sample

## [0.1.1] - 2021-07-04

### Added

- VR Broadcaster Script to Replace Remote Render Streaming default Broadcaster

### Fixed

- VR Broadcaster enables streaming to just one VR headset to avoid eavesdropping

## [0.1.0] - 2021-07-03

- Initial Release of Experimental VR Render Streaming
7 changes: 7 additions & 0 deletions CHANGELOG.md.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,23 @@ Limited testing and Proof of Concepts have been done with deploying a standalone
# GPU Recommendations

It is strongly recommended to utlize a NVIDIA GPU as these GPUs support Hardware Accelerated Encoding, which is a requirement for lower latency VR Streaming. You can check the fully compatability matrix on the [Unity WebRTC documentation](https://docs.unity3d.com/Packages/com.unity.webrtc@2.4/manual/index.html). If you are using a GPU that does not support Hardware Accelerated, you will need to uncheck this option on the **RenderStreaming** Gameobject and Component

# WebXR Input

Controller Input is captured via the [A-Frame Tracked-Controls component](https://aframe.io/docs/1.2.0/components/tracked-controls.html) and then sent over the data channel to the Unity SDK. This data protocol is adaopted from the Unity Broadcast system, which was also capable of sending Keyboard, Mouse, Touch, and Gamepad data back to Unity via the RemoteInput.cs script in Unity. As such, VR data is sent from the client to Unity as Data Array buffers, defined in bytes.

The first byte of the data Array Byffer refers to the input mode to determine how to parse the data as an id. The following IDs were reservered for Web Input by the Unity Render Streaming system.

- ID 0 = Keyboard
- ID 1 = Mouse
- ID 2 = MouseWheel
- ID 3 = Touch
- ID 4 = UI (legacy)
- ID 5 = Gamepad

ID 6 is what is used for all WebXR Input specific to VR. Within VR Input, we specify 3 different modes for sending data, which are:
- ID 0 = Positional and Rotational Data of the Headset and Hands
- ID 1 = Controller Button Data ( A , B , Trigger, Grip )
- ID 2 = Controller Axis Data (Joystick & Trackpad)

The Raw Data from the Client is passed to VRInputManager, who is responsible for transmitting events based on the data mode recieved. Controller Input is then parsed by the ControllerInputManager, which has events that can be subscribed to for VR Input.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "FusdeVR.Streaming",
"name": "FusedVR.Streaming",
"references": [
"GUID:40a5acf76f04c4c8ebb69605e4b0d5c7",
"GUID:f12aafacab75a87499e7e45c873ffab8"
Expand Down
File renamed without changes.
43 changes: 36 additions & 7 deletions Runtime/Scripts/ControllerInputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ public enum Button
Grip,
AButton,
BButton,
Joystick
Joystick,
Trackpad
}
#endregion

Expand All @@ -47,34 +48,62 @@ public enum Button
/// The class wrapper for the VRControllerData Unity Event
/// </summary>
[System.Serializable]
public class VRControllerData : UnityEvent<Hand, Button, bool, bool> {
public class VRButtonData : UnityEvent<Hand, Button, bool, bool> {

}

/// <summary>
/// The main controller input Unity Event. You may listen to this event via code or via the inspector just like any other Unity Event.
/// </summary>
public static VRControllerData VRControllerEvent;
public VRButtonData VRButtonEvent;

/// <summary>
/// The class wrapper for the VRControllerData Unity Event
/// </summary>
[System.Serializable]
public class VRAxisData : UnityEvent<Hand, Button, float, float> {

}

/// <summary>
/// The main controller input Unity Event. You may listen to this event via code or via the inspector just like any other Unity Event.
/// </summary>
public VRAxisData VRAxisEvent;
#endregion

#region Methods
// Start is called before the first frame update
void Start()
{
VRInputManager.ControllerDataEvent += ControllerEvents; //start listening
VRInputManager.ButtonDataEvent += ButtonEvents; //start listening
VRInputManager.AxisDataEvent += AxisEvents; //start listening
}

// OnDestroy is called when the game object is about to be destroyed in the scene
private void OnDestroy() {
VRInputManager.ControllerDataEvent -= ControllerEvents; //end listening
VRInputManager.ButtonDataEvent -= ButtonEvents; //end listening
VRInputManager.AxisDataEvent -= AxisEvents; //end listening
}

/// <summary>
/// Callback function for Raw Data from VRInputManager ControllerDataEvent
/// </summary>
void ControllerEvents(int handID, int buttonID, bool pressed, bool touched)
void ButtonEvents(VRInputManager.Source handID, int buttonID, bool pressed, bool touched)
{
VRControllerEvent.Invoke((Hand)handID, (Button)buttonID, pressed, touched); //invoke the Unity Event
VRButtonEvent?.Invoke((Hand)(handID -1), (Button)buttonID, pressed, touched); //invoke the Unity Event
}

/// <summary>
/// Callback function for Raw Data from VRInputManager ControllerDataEvent
/// </summary>
void AxisEvents(VRInputManager.Source handID, int buttonID, float x, float y) {
Button axisButton = (Button)((int)Button.Joystick + buttonID);

Debug.Log("My Button is " + axisButton);
Debug.Log("Axis is X : " + x);
Debug.Log("Axis is Y : " + y);

VRAxisEvent?.Invoke((Hand)(handID - 1), axisButton, x, y); //invoke the Unity Event
}
#endregion
}
Expand Down
75 changes: 49 additions & 26 deletions Runtime/Scripts/VRInputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ namespace FusedVR.VRStreaming
public class VRInputManager : InputChannelReceiverBase
{
#region Constants
/// <summary>
/// The Data Format that we are getting from the VR headset
/// </summary>
public enum VRDataType {
PosRot,
Button,
Axis
}

/// <summary>
/// Data Source for positional / rotational VR Data i.e. Head Left Hand or Right Hand
/// </summary>
Expand All @@ -33,17 +42,9 @@ public enum Source {
}

/// <summary>
/// This is the ID for getting Controller Input Data from the client
/// </summary>
public const int VR_CONTROLLER_ID = 5;

/// <summary>
/// The Base ID for Recieving Positional / Rotational Data from the client
/// BASEID + 0 = Head
/// BASEID + 1 = Left Hand
/// BASEID + 2 = Right Hand
/// The Base ID for Recieving VR Data from the Web client
/// </summary>
public const int VR_BASE_ID = 6;
public const int VR_DEVICE_ID = 6;
#endregion

#region Events
Expand All @@ -61,10 +62,17 @@ public class VRPoseData : UnityEvent<Source, Vector3, Vector3> {
public VRPoseData VRPoseEvent;

/// <summary>
/// C# Event responsible for sending Controller Data that is recieved from the client
/// C# Event responsible for sending Controller Button Data that is recieved from the client
/// </summary>
public delegate void OnControllerDataRecieved(int handID, int buttonID, bool pressed, bool touched);
public static OnControllerDataRecieved ControllerDataEvent;
public delegate void OnButtonDataRecieved(Source handID, int buttonID, bool pressed, bool touched);
public static OnButtonDataRecieved ButtonDataEvent;


/// <summary>
/// C# Event responsible for sending Controller Axis Data that is recieved from the client
/// </summary>
public delegate void OnAxisDataRecieved(Source handID, int buttonID, float xaxis, float yaxis);
public static OnAxisDataRecieved AxisDataEvent;
#endregion

#region Methods
Expand All @@ -83,22 +91,37 @@ public void SendData(string msg)
/// </summary>
protected override void OnMessage(byte[] bytes)
{
int index = bytes[0];

if (index == VR_CONTROLLER_ID)
{ //VR Controller Data
ControllerDataEvent?.Invoke(bytes[1], bytes[2], BitConverter.ToBoolean(bytes, 3), BitConverter.ToBoolean(bytes, 4));
}
if (bytes[0] == VR_DEVICE_ID) //VR Device Data
{
int data_type = bytes[1]; //get input data source
switch ( (VRDataType) data_type) {
case VRDataType.PosRot:
Source device_type = (Source) bytes[2]; //get source
Vector3 pos = new Vector3(BitConverter.ToSingle(bytes, 3),
BitConverter.ToSingle(bytes, 11), BitConverter.ToSingle(bytes, 19));

if (index >= VR_BASE_ID)
{ //VR data
Vector3 pos = new Vector3(BitConverter.ToSingle(bytes, 1),
BitConverter.ToSingle(bytes, 9), BitConverter.ToSingle(bytes, 17));
Vector3 rot = new Vector3(Mathf.Rad2Deg * BitConverter.ToSingle(bytes, 27),
Mathf.Rad2Deg * BitConverter.ToSingle(bytes, 35), Mathf.Rad2Deg * BitConverter.ToSingle(bytes, 43));
VRPoseEvent.Invoke(device_type, pos, rot);
break;
case VRDataType.Button:
ButtonDataEvent?.Invoke((Source) bytes[2], bytes[3], BitConverter.ToBoolean(bytes, 4),
BitConverter.ToBoolean(bytes, 5));
break;
case VRDataType.Axis:
if ( BitConverter.ToBoolean(bytes, 3) || BitConverter.ToBoolean(bytes, 12) ) { //if trackpad changed
AxisDataEvent?.Invoke((Source)bytes[2], 1, BitConverter.ToSingle(bytes, 4),
BitConverter.ToSingle(bytes, 13));
}

Vector3 rot = new Vector3(Mathf.Rad2Deg * BitConverter.ToSingle(bytes, 25),
Mathf.Rad2Deg * BitConverter.ToSingle(bytes, 33), Mathf.Rad2Deg * BitConverter.ToSingle(bytes, 41));
if (BitConverter.ToBoolean(bytes, 21) || BitConverter.ToBoolean(bytes, 30)) { //if joystick changed
AxisDataEvent?.Invoke((Source)bytes[2], 0, BitConverter.ToSingle(bytes, 22),
BitConverter.ToSingle(bytes, 31));
}

VRPoseEvent.Invoke((Source)(index - VR_BASE_ID), pos, rot);
break;
}

}
}
#endregion
Expand Down
19 changes: 19 additions & 0 deletions Samples~/HDRPVR/Editor/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using UnityEngine;
using UnityEditor;
using UnityEditor.PackageManager;

[InitializeOnLoad]
public class Startup {

//Only Load Once
private static bool loaded = false;

//On Startup Load the HD Render Pipeline
static Startup() {
if (!loaded) {
Debug.Log("Loading High Definiton Render Pipeline Package from Startup script...");
Client.Add("com.unity.render-pipelines.high-definition");
loaded = true;
}
}
}
11 changes: 11 additions & 0 deletions Samples~/HDRPVR/Editor/Startup.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Samples~/HDRPVR/ExampleAssets.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Samples~/HDRPVR/ExampleAssets/Materials.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 782cb32

Please sign in to comment.