Tracked Device

Tracked Device provides the interface for the HMD and controller. All tracking functions are defined in this class.

List

Configure

setupConfig returns the TrackedDevice configured data before it’s connected. It provides the driver information to DeviceService.

@Override
public Config setupConfig() {
    int support = 0;
    Config configure = new Config();
    configure.analogType = new HashMap<Integer, Integer>();

    // setup ananlog type of input device
    configure.analogType.put(WVR.InputId_Alias1_Trigger, WVR.AnalogType_1D);
    configure.analogType.put(WVR.InputId_Alias1_Touchpad, WVR.AnalogType_2D);

    // setup ananlog / touch / button capability
    support |= 1 << WVR.InputId_Alias1_Trigger;
    support |= 1 << WVR.InputId_Alias1_Touchpad;
    configure.supportedAnalog = support;
    configure.supportedTouch = support;

    support |= 1 << WVR.InputId_Alias1_System;
    support |= 1 << WVR.InputId_Alias1_Menu;
    configure.supportedButton = support;

    return configure;
}

Pose

There are rotation and translation data types that need to be defined on Pose struct.

Pose List

Rotation

For rotation tracker data, define the orientation of the tracker and then represent it as a quaternion.

Pose pose = new Pose();
pose.rotation = new Quaternion();

//Design your tracker rotation. For every 10 degree angle
//rotation of your device tracker, it will be:

w = w + Math.PI/18;
x = x + Math.PI/18;
y = y + Math.PI/18;
z = z + Math.PI/18;

pose.rotation.w = w;
pose.rotation.x = x;
pose.rotation.y = y;
pose.rotation.z = z;

Translation

For positional tracker data, define the vector of the tracker and then represent it as a translation.

Pose pose = new Pose();
pose.translation = new Vector3();

//Design your tracker translation. If your device tracker
//translation is linear, it will be:

x = x + 0.001;
y = y + 0.001;
z = z + 0.001;

pose.translation.x = x;
pose.translation.y = y;
pose.translation.z = z;

AngularVelocity

For angular velocity in rad/s(radian per second), define the vector of the tracker and then represent it as an AngularVelocity.

The angular velocity of the pose is in the axis-angle representation. The direction is the angle of rotation and the magnitude is the angle around that axis in rad/s.

Pose Pose= new Pose();
Pose.angularVelocity= new Vector3();

//Design your tracker AngularVelocity. If your device tracker
//AngularVelocity is linear, it will be:

x = x + 0.001;
y = y + 0.001;
z = z + 0.001;

pose.angularVelocity.x = x;
pose.angularVelocity.y = y;
pose.angularVelocity.z = z;

updatePose() notifies the server that a tracked device’s pose has been updated.

// Vedor design function getVendorTrackingPose() to return pose data from vendor's tracking system
pose = getVendorTrackingPose(); // Includes rotation, translation and angular velocity
updatePose(pose, System.nanoTime());

Note

If the thread which is used to get pose data (from vendor’s tracking system) can not be the same as the thead which is used to call updatePose(). Please use synchronized method to protest pose data.

3 DoF or 6 DoF Scene Notification of an App

The function on6DofScene(boolean is6DoF) will be called (by Runtime system) to notify the device service of a changed scene in an app (from app side) when the scene of an app has been switched from 6DoF to 3DoF (or from 3DoF to 6 DoF).

This is just a notification from the app side. There is no need to do anything in the function on6DofScene().

Parameter:
is6DoF: boolean type, which specifies the scene of App is currently 3DoF or 6DoF.
  • true: The current app scene is switched to 6 DoF.
  • false: The current app scene is switched to 3 DoF.
@Override
public void on6DofScene(boolean is6DoF) {
    if (is6DoF) {
        Debug.Log("the scene is 6 DoF now");
    } else {
        Debug.Log("the scene is 3 DoF now");
    }
}

Current or Changed Tracking Mode Notification

The function onTrackingModeChanged(int mode) will be called (by Runtime system) to notify the device service of the current or changed tracking mode (from App side).

If the device supports “Tracking Mode Change (6 DoF pose <-> 3 DoF pose)”, developer needs to do tracking disposal (see below) in this function when the device receives a current or changed tracking mode notification from the parameter mode.

  1. “New received tracking mode (ex. 3 DoF)” is not equal to “current recorded tracking mode (ex. 6 DoF)”:
    • Change the tracking (pose of device) system from 6 DoF to 3 DoF, or vice versa.
  2. “New received tracking mode (ex. 3 DoF)” is equal to “current recorded tracking mode (ex. 3 DoF)”:
    • Do nothing.
Parameter:
mode: integer type, which specifies the current/changed tracking mode is currently 3 DoF or 6 DoF.
  • WVR.TrackingMode.TrackingMode_3DoF: The current/changed tracking mode is 3 DoF
  • WVR.TrackingMode.TrackingMode_6DoF: The current/changed tracking mode is 6 DoF
// Variable mLastTrackMode is used to record the last Tracking Mode for onRecenter() and onTrackingModeChanged() of class TrackedDevice.
// mLastTrackMode should record default tracking mode in setupConfig().
private int mLastTrackMode = 0; // 0: 3 DoF, 1: 6 DoF

@Override
public void onTrackingModeChanged(int mode) {
    // return; // If device doesn't support Tracking Mode change, do nothing (directly return).

    switch (mode) {
        case WVR.TrackingMode.TrackingMode_3DoF: // receive current/changed tracking mode (3 DoF)
            if (mode != mLastTrackMode) { // switch device to 3 DoF tracking mode
                updateTrackingModeReady(false); // The status of Tracking Mode change is changing.
                // TODO: Change the tracking (pose of device) system from 6 DoF to 3 DoF.
                updateTrackingModeReady(true); // The status of Tracking Mode change is done.
            }
            mLastTrackMode = mode;
            break;
        case WVR.TrackingMode.TrackingMode_6DoF: // receive current/changed tracking mode (6 DoF)
            if (mode != mLastTrackMode) { // switch device to 6 DoF tracking mode
                updateTrackingModeReady(false); // The status of Tracking Mode change is changing.
                // TODO: Change the tracking (pose of device) system from 3 DoF to 6 DoF.
                updateTrackingModeReady(true); // The status of Tracking Mode change is done.
            }
            mLastTrackMode = mode;
            break;
    }
}
  • See “Tracking Mode” in VRDevice to learn how to set up the default Tracking Mode for the device (includes variable mLastTrackMode).
  • See “Tracking Mode Change Status Notification” to learn more about function updateTrackingModeReady().

Tracking Mode Change Status Notification

If the device supports “Tracking Mode Change (6 DoF pose <-> 3 DoF pose)”, the function updateTrackingModeReady(boolean isReady) is used to notify runtime system that the status of Tracking Mode change is changing or done.

Parameter:
isReady: boolean type, which specifies the status of Tracking Mode change.
  • true: Tracking Mode change is done.
  • false: Tracking Mode change is changing.

Button

When device services send the button data to AP, the following APIs need to be called in this order:

  1. setButtonTouch(true, ButtonId, System.nanoTime())
  2. setButtonPress(true, ButtonId, System.nanoTime())
  3. setButtonPress(false, ButtonId, System.nanoTime())
  4. setButtonTouch(false, ButtonId, System.nanoTime())

The parameter of buttonId is WVR_InputId.

Note

Whether the server is connected to the device service or not, the button data should always be sent to the server.

Wave VR 3.0.0 SDK auto key mapping

Wave VR 3.0.0 SDK supports auto key mapping. If an app requests buttons that the Device(Controller or HMD)do not support, auto key mapping will get the requested buttons for the app.

Example: The app requests WVR_InputId_Alias1_Menu but the device supports WVR_InputId_Alias1_Grip. Auto key mapping will help the app map WVR_InputId_Alias1_Grip to WVR_InputId_Alias1_Menu.

In the example above, the app will request the touch event of WVR_InputId_Alias1_Grip. If the Device didn’t send the touch state of WVR_InputId_Alias1_Menu, the SDK won’t be able to send the touch event. The app won’t get the WVR_InputId_Alias1_Menu touch state.

With the auto key mapping feature, the SDK needs the Device to send the touch state of the button. Device vendors need to follow these rules:
  1. Each button needs to set touch support in configure(TrackedDevice.Config.supportedTouch)
  2. Send the touch and press state in the order below.
  • Button touched -> Button pressed -> Button unpressed ->Button untouched

Button List

Recenter

Recenter means reseting 3 DoF/6 DoF pose (zero orientation) of device.

Recenter would be trigggered in App side if user
  • has been pressing home button on controller for 1 second. (recenter controller)
  • re-wears HMD. (recenter HMD)

These two conditions (given above) to trigger recenter function were defined in HTC OEM Service. (The other manufacturer can self-define different conditions to trigger recenter function in customized OEM Service.)

There are two kinds of recenter definition for device:

  1. Supports hardware (HW) recenter
    • Set up “Hardware Recenter Support” for device. See Hardware Recenter Supported/Unsupported in VRDevice for more information.
    • The function onRecenter() will be called (by event mechanism) in device service when recenter behavior is trigger in the app.
    • Implement the hardware recenter procedure in the function onRecenter(). See the following code.
// Variable mLastTrackMode is used to record the last Tracking Mode for onRecenter() and onTrackingModeChanged() of class TrackedDevice.
// mLastTrackMode should record default tracking mode in setupConfig().
private int mLastTrackMode = 0; // 0: 3 DoF, 1: 6 DoF

private boolean HwRecenter() {
    if (mLastTrackMode == 0) { // 3 DoF tracking mode
        // TODO: implement HW recenter of 3 DoF device.
    } else if (mLastTrackMode == 1) { // 6 DoF tracking mode
        // TODO: implement HW recenter of 6 DoF device.
    }
    return true; // HW Recente succeeded
    // return false; // HW Recente failed
}

@Override
public void onRecenter() {
    Debug.Log("Recenter behavior has been triggered. Execute HW recenter.");

    boolean result = HwRecenter(); // TODO: implement HW recenter of 3 DoF/6 DoF device.

    boolean is3Dof = false;
    if (mLastTrackMode == 0) { // 3 DoF tracking mode
        is3Dof = true;
    } else if (mLastTrackMode == 1) { // 6 DoF tracking mode
        is3Dof = false;
    }
    updateRecenterResult(result, is3Dof); // Notify runtime system of result of HW recenter
}

See Tracking Mode in VRDevice to learn more about mLastTrackMode in the above code.

See “Result of Hardware Recenter Notification” to learn more about updateRecenterResult() in the above code.

  1. Supports software (SW) recenter
    • Set up “Hardware Recenter Unsupported” for device. See Hardware Recenter Supported/Unsupported in VRDevice for more information.
    • Developer do not need to do any operation in the device service. HTC VR Runtime system will handle “zero” orientation for software recenter.
    • For the following cases, consider useing the software recenter for developer’s controller.
      • Devices of VR kits that support independent HW recenter of controller. This needs HTC VR Runtime system to make the yaw angle of the controller align with the yaw angle of the HMD.
      • Developer doesn’t use the same (manufacturer’s) tracking reference solution in both HMD and controller.
    • If “containsRecenter” is set as “false” (SW recenter supported) in the function setupConfig of the HMD device service, call the fucntion clearSoftwareRecenterTransform when the HMD screen turns off in the HMD device service (for SDK v3.2.0 and later only).
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            Debug.Log("HmdDevice, got ACTION_SCREEN_OFF intent");
            clearSoftwareRecenterTransform();
        }
}

Virtual D-Pad on Touchpad

If the device supports touchpad, “virtual D-pad” would be implemented on the touchpad by default to make up for not having physical D-pad on the controller.

Configuration of a virtual D-pad

_images/VirtualDPadButton.png
  • See WVR_InputId enum type in Types in wvr.h.
  • See Virtual/Physical D-Pad Button in Controller to learn know how to disable the default virtual D-pad for the controller.

Analog

The analog is divided into two components: trigger and touchpad. updateAnalog() is used to transmit the trigger or touchpad data.

Determine the value for the axis.

PointF axis = new PointF();

When the button WVR.InputId_Alias1_Trigger is pressed, only the axis.x analog value (between 0~1) will change.

updateAnalog(WVR.InputId_Alias1_Trigger, axis, System.nanoTime());

When the button WVR.InputId_Alias1_Touchpad is touched, the axis.x and axis.y analog values will both change. The axis.x value when there are horizontal swipes should be between -1~1. The axis.y value when there are vertical swipes should be between -1~1.

updateAnalog(WVR.InputId_Alias1_Touchpad, axis, System.nanoTime());

Note

Before calling the updateAnalog() function, it must call setButtonTouch(true, ButtonId, System.nanoTime()) to inform the app that the device is starting to transmit analog data. When the device finishes transmitting analog data, call setButtonTouch(false, ButtonId, System.nanoTime()).

Note

Check the analogId capability inside updateAnalog(int analogId, PointF axis, long nanoTime). If the config inside TrackedDevice.Config.supportedAnalog and analogType for the buttonId has been set up, the function will work.

Swipe Motions on Touchpad

If the device supports a touchpad, the function “swipe motions on touchpad” is implemented by default in the device service.

There are four types of swipe motions:

  1. Left-to-Right
    • If Left-to-Right swipe motion has been triggered successfully, app developer can receive the event WVR_EventType_LeftToRightSwipe.
  2. Right-to-Left
    • If Right-to-Left swipe motion has been triggered successfully, app developer can receive the event WVR_EventType_RightToLeftSwipe.
  3. Down-to-Up
    • If Down-to-Up swipe motion has been triggered successfully, app developer can receive the event WVR_EventType_DownToUpSwipe.
  4. Up-to-Down
    • If Up-to-Down swipe motion has been triggered successfully, app developer can receive the event WVR_EventType_UpToDownSwipe.
  • See Touchpad in Controller to learn how to set up “touchpad supported” for the device.
  • If there is an implementation for swipe motion, disable the virtual D-pad via the configure value “disableVirtualDpad” and send the swipe event by the implementation. See Virtual/Physical D-Pad in Controller to learn how to disable “virtual D-pad supported” for the device.
  • See WaveVR_SystemEvent

Adjust the thresholds to trigger Swipe Events

There are three adjustable thresholds and a two-dimention component input ID for swipe motion settings. A swipe motion must meet the criteria to send a valid swipe event.

It is optional to setup minSwipeLength and maxSwipePoint. If the number of swipe points is bigger than the quantity of maxSwipePoint. DeviceService will not send a swipe event.

Likewise, if a swipe length is shorter than the minSwipeLength, DeviceService will not send a swipe event.

For the thumbstick, edgeTriggerArea is used to indicate the area which triggers a swipe event. If edgeTriggerArea = 0.7f, |Analog X| > 0.7f or |Analog Y| > 0.7f a swipe event will be triggered

supportVirDpadSwipeInputId is used to determine which two-dimension component is activated if there are more than one two-dimension components on the VR device.

Each of the parameters below has a default value.

supportVirDpadSwipeInputId: integer type, determine which two-dimension component is activated if there are more than one two-dimension component on the VR device.

minSwipeLength: float type, optional, indicates the minimum swipe length to trigger swipe events.

maxSwipePoint: integer type, optional, indicates the maximum analog points when triggering swipe events.

edgeTriggerArea: float type, optional, indicate the area which triggers a swipe event(for the thumbstick only).

For the thumbstick swipe event to be accurate, the origin (0, 0) must be the first point of a thumbstick analog record of a swipe event. If it is not, set the origin(0, 0) to be the first point everytime when the thumbstick analog is recorded.

Result of Hardware Recenter Notification

The function updateRecenterResult(boolean recenter_result, boolean is_3Dof) is used to notify the runtime system of the hardware (HW) recenter result of a 3 DoF/6 DoF device (3 DoF/6 DoF Tracking Mode) from the device service side.

The function updateRecenterResult(boolean recenter_result) is only for 6 DoF devices.

Call this function after a hardware recenter procedure of a 3 DoF/6 DoF device in the function onRecenter() of the class TrackedDevice.

Parameter:
recenter_result: boolean type, which specifies the result of the HW recenter procedure.
  • true: HW recenter successful
  • false: HW recenter failed
is_3Dof: boolean type, which specifies the current Tracking Mode (3 DoF/6 DoF) of device.
  • true: The device supports 3 DoF Tracking Mode.
  • false: The device supports 6 DoF Tracking Mode.
  • See “Tracking Mode” in VRDevice to learn more about tracking mode.
  • See “Recenter” to learn more about the hardware recenter procedure in onRecenter().