Skip to content

Commit

Permalink
add vive-tracker
Browse files Browse the repository at this point in the history
disable everGotGamepadEvent usage, seeing issues with latest Nightly

make sure vive-controls doesn't match tracker

bring in line with latest aframevr#2513

work around Nightly bug to get both controllers and trackers working at the same time

bring vive-tracker in line with aframevr#2513

fix tests

per separate discussion, use controllers list from system not getGamepadsByPrefix

bring in line with aframevr#2505

make sure that queryObject values are used even if falsy e.g. index 0

tracked-controls needs to know about hand to filter properly and find vive trackers, given current Nightly bug.  since empty string is always changed to default value (even when default is undefined), need to use 'none' to indicate empty-string hand

re-clone tracker tests from controls

use newly committed vive-tracker model

add rotation property, which applies if no rotationOffset and allows full 3DOF rotation

correct pose orientation for tracker to be what is generally expected of controllers

fix default vive-tracker rotation correction, per discussion

updateControllerModel for all tracked controls components; use fixed vive tracker model until published to CDN

use new tracker model from CDN

add rotation parameter

apply rotationOffset the old way, to avoid precision issues

add rotation offset test, with EPSILON

change sentinel hand value to avoid node test failure

zero pivot point

update tracked-controls hand docs per discussion on PR

fix duplicate play/pause presumably from botched merge
  • Loading branch information
machenmusik committed Jun 22, 2017
1 parent 386d6c9 commit 024cadd
Show file tree
Hide file tree
Showing 11 changed files with 543 additions and 23 deletions.
6 changes: 4 additions & 2 deletions docs/components/tracked-controls.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ so using idPrefix for Vive / OpenVR controllers is recommended.
| controller | Index of the controller in array returned by the Gamepad API. | 0 |
| id | Selects the controller from the Gamepad API using exact match. | |
| idPrefix | Selects the controller from the Gamepad API using prefix match. | |
| rotationOffset | Offset to add to model rotation. | 0 |
| rotation | Offset to add to model rotation. | |
| rotationOffset | Offset (around Z axis) to add to model rotation. | 0 |
| headElement | Head element for arm model if needed (if not active camera). | |
| hand | Which hand to use, if arm model is needed. (left negates X) | right |
| hand | Which hand to match (and use if arm model needed). | any-or-none |
| armModel | Whether to use arm model to simulate 3DOF controllers position. | true |

## Events

Expand Down
58 changes: 58 additions & 0 deletions docs/components/vive-tracker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
title: vive-tracker
type: components
layout: docs
parent_section: components
---

[trackedcontrols]: ./tracked-controls.md

The vive-tracker component interfaces with the HTC Vive Tracker. It
wraps the [tracked-controls component][trackedcontrols] while adding button
mappings, events, and a model.

## Example

```html
<a-box vive-tracker></a-box>

<a-box vive-tracker="index: 0"></a-entity>
<a-box vive-tracker="index: 1"></a-entity>
<a-box vive-tracker="index: 2"></a-entity>
```

## Value

| Property | Description | Default Value |
|----------------------|----------------------------------------------------|----------------------|
| buttonColor | Button colors when not pressed. | #FAFAFA (off-white) |
| buttonHighlightColor | Button colors when pressed and active. | #22D1EE (light blue) |
| index | The index of the tracker that will be tracked. | 0 |
| model | Whether the model is loaded. | true |
| rotationOffset | Offset to apply to model rotation. | 0 |

## Events

| Event Name | Description |
| ---------- | ----------- |
| gripdown | Grip button pressed. |
| gripup | Grip button released. |
| gripchanged | Grip button changed. |
| menudown | Menu button pressed. |
| menuup | Menu button released. |
| menuchanged | Menu button changed. |
| systemdown | System button pressed. |
| systemup | System button released. |
| systemchanged | System button changed. |
| trackpaddown | Trackpad pressed. |
| trackpadup | Trackpad released. |
| trackpadchanged | Trackpad button changed. |
| triggerdown | Trigger pressed. |
| triggerup | Trigger released. |
| triggerchanged | Trigger changed. |

## Assets

- [Controller OBJ](https://cdn.aframe.io/controllers/vive/vr_controller_vive.obj)
- [Controller MTL](https://cdn.aframe.io/controllers/vive/vr_controller_vive.mtl)

4 changes: 4 additions & 0 deletions src/components/daydream-controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ module.exports.Component = registerComponent('daydream-controls', {
var el = this.el;
var data = this.data;
el.setAttribute('tracked-controls', {idPrefix: GAMEPAD_ID_PREFIX, hand: data.hand, rotationOffset: data.rotationOffset, armModel: data.armModel});
this.updateControllerModel();
},

updateControllerModel: function () {
if (!this.data.model) { return; }
this.el.setAttribute('obj-model', {
obj: DAYDREAM_CONTROLLER_MODEL_OBJ_URL,
Expand Down
4 changes: 4 additions & 0 deletions src/components/gearvr-controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ module.exports.Component = registerComponent('gearvr-controls', {
var el = this.el;
var data = this.data;
el.setAttribute('tracked-controls', {idPrefix: GAMEPAD_ID_PREFIX, rotationOffset: data.rotationOffset, armModel: data.armModel});
this.updateControllerModel();
},

updateControllerModel: function () {
if (!this.data.model) { return; }
this.el.setAttribute('obj-model', {
obj: GEARVR_CONTROLLER_MODEL_OBJ_URL,
Expand Down
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ require('./text');
require('./tracked-controls');
require('./visible');
require('./vive-controls');
require('./vive-tracker');
require('./wasd-controls');

require('./scene/canvas');
Expand Down
30 changes: 26 additions & 4 deletions src/components/tracked-controls.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var registerComponent = require('../core/component').registerComponent;
var THREE = require('../lib/three');
var DEG2RAD = require('../lib/three').Math.DEG2RAD;
var DEFAULT_USER_HEIGHT = require('../constants').DEFAULT_USER_HEIGHT;

var DEFAULT_HANDEDNESS = require('../constants').DEFAULT_HANDEDNESS;
Expand All @@ -18,9 +19,11 @@ var FOREARM = {x: 0, y: 0, z: -0.175}; // vector from eyes to elbow (divided by
module.exports.Component = registerComponent('tracked-controls', {
schema: {
controller: {default: 0},
hand: {type: 'string', default: 'any-or-none'},
id: {type: 'string', default: ''},
idPrefix: {type: 'string', default: ''},
rotationOffset: {default: 0},
rotation: {type: 'vec3'},
// Arm model parameters, to use when not 6DOF. (pose hasPosition false, no position)
armModel: {default: true},
headElement: {type: 'selector'}
Expand All @@ -30,6 +33,8 @@ module.exports.Component = registerComponent('tracked-controls', {
this.axis = [0, 0, 0];
this.buttonStates = {};

this.rotationOffset = new THREE.Quaternion();

this.dolly = new THREE.Object3D();
this.controllerEuler = new THREE.Euler();
this.controllerEuler.order = 'YXZ';
Expand All @@ -42,6 +47,14 @@ module.exports.Component = registerComponent('tracked-controls', {
this.updateGamepad();
},

update: function (oldData) {
var data = this.data;
if (data.rotation === oldData.rotation) { return; }

this.controllerEuler.set(DEG2RAD * data.rotation.x, DEG2RAD * data.rotation.y, DEG2RAD * data.rotation.z);
this.rotationOffset.setFromEuler(this.controllerEuler);
},

tick: function (time, delta) {
var mesh = this.el.getObject3D('mesh');
// Update mesh animations.
Expand Down Expand Up @@ -70,9 +83,15 @@ module.exports.Component = registerComponent('tracked-controls', {
var matchingControllers;

// Hand IDs: 0 is right, 1 is left.
matchingControllers = controllers.filter(function hasIdOrPrefix (controller) {
if (data.idPrefix) { return controller.id.indexOf(data.idPrefix) === 0; }
return controller.id === data.id;
matchingControllers = controllers.filter(function hasIdOrPrefixAndHand (controller) {
if (data.idPrefix) {
if (controller.id.indexOf(data.idPrefix) !== 0) { return false; }
} else {
if (controller.id !== data.id) { return false; }
}

if (data.hand === 'any-or-none') { return true; }
return (controller.hand === undefined ? DEFAULT_HANDEDNESS : controller.hand) === (data.hand === 'none' ? '' : data.hand);
});

this.controller = matchingControllers[data.controller];
Expand Down Expand Up @@ -129,6 +148,7 @@ module.exports.Component = registerComponent('tracked-controls', {
var controller = this.controller;
var controllerEuler = this.controllerEuler;
var controllerPosition = this.controllerPosition;
var controllerQuaternion = this.controllerQuaternion;
var currentPosition;
var deltaControllerPosition = this.deltaControllerPosition;
var dolly = this.dolly;
Expand Down Expand Up @@ -175,7 +195,9 @@ module.exports.Component = registerComponent('tracked-controls', {
}

// Decompose.
controllerEuler.setFromRotationMatrix(dolly.matrix);
controllerQuaternion.setFromRotationMatrix(dolly.matrix);
controllerQuaternion.multiply(this.rotationOffset);
controllerEuler.setFromQuaternion(controllerQuaternion);
controllerPosition.setFromMatrixPosition(dolly.matrix);

// Apply rotation (as absolute, with rotation offset).
Expand Down
19 changes: 8 additions & 11 deletions src/components/vive-controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,31 +103,28 @@ module.exports.Component = registerComponent('vive-controls', {
el.removeEventListener('axismove', this.onAxisMoved);
},

/**
* Once OpenVR returns correct hand data in supporting browsers, we can use hand property.
* var isPresent = this.checkControllerPresentAndSetup(this.el.sceneEl, GAMEPAD_ID_PREFIX,
{ hand: data.hand });
* Until then, use hardcoded index.
*/
checkIfControllerPresent: function () {
var data = this.data;
var controllerIndex = data.hand === 'right' ? 0 : data.hand === 'left' ? 1 : 2;
this.checkControllerPresentAndSetup(this, GAMEPAD_ID_PREFIX, {index: controllerIndex});
// Once OpenVR / SteamVR return correct hand data in the supporting browsers, we can use hand property.
this.checkControllerPresentAndSetup(this, GAMEPAD_ID_PREFIX, { hand: data.hand });
},

injectTrackedControls: function () {
var el = this.el;
var data = this.data;

// If we have an OpenVR Gamepad, use the fixed mapping.
// Use the supplied controller index.
el.setAttribute('tracked-controls', {
idPrefix: GAMEPAD_ID_PREFIX,
// Hand IDs: 0 = right, 1 = left, 2 = anything else.
controller: data.hand === 'right' ? 0 : data.hand === 'left' ? 1 : 2,
hand: data.hand,
rotationOffset: data.rotationOffset
});

// Load model.
this.updateControllerModel();
},

updateControllerModel: function () {
if (!this.data.model) { return; }
this.el.setAttribute('obj-model', {
obj: VIVE_CONTROLLER_MODEL_OBJ_URL,
Expand Down
Loading

0 comments on commit 024cadd

Please sign in to comment.