Skip to content

Commit 034cb13

Browse files
committed
add headElement to schema, so non-6DOF model can apply when head is not the active camera e.g. spectator view
1 parent a6c21f6 commit 034cb13

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

‎docs/components/tracked-controls.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ so using idPrefix for Vive / OpenVR controllers is recommended.
3838
| id | Selects the controller from the Gamepad API using exact match. | |
3939
| idPrefix | Selects the controller from the Gamepad API using prefix match. | |
4040
| rotationOffset | Offset to add to model rotation. | 0 |
41+
| headElement | Head element for arm model if needed (if not active camera). | |
4142
| hand | Which hand to use, if arm model is needed. (left negates X) | right |
4243
| eyesToElbow | Arm model vector from eyes to elbow as user height ratio. | {x:0.175, y:-0.3, z:-0.03} |
4344
| forearm | Arm model vector for forearm as user height ratio. | {x:0, y:0, z:-0.175} |

‎src/components/tracked-controls.js‎

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module.exports.Component = registerComponent('tracked-controls', {
1919
idPrefix: {type: 'string', default: ''},
2020
rotationOffset: {default: 0},
2121
// Arm model parameters, to use when not 6DOF. (pose hasPosition false, no position)
22+
headElement: {type: 'selector'},
2223
hand: {type: 'string', default: 'right'},
2324
eyesToElbow: {default: {x: 0.175, y: -0.3, z: -0.03}}, // vector from eyes to elbow (divided by user height)
2425
forearm: {default: {x: 0, y: 0, z: -0.175}}, // vector from eyes to elbow (divided by user height)
@@ -50,6 +51,11 @@ module.exports.Component = registerComponent('tracked-controls', {
5051
this.updateButtons();
5152
},
5253

54+
/**
55+
* Return head element to use for non-6DOF arm model.
56+
*/
57+
getHeadElement: function () { return this.data.headElement || this.el.sceneEl.camera.el; },
58+
5359
/**
5460
* Handle update to `id` or `idPrefix.
5561
*/
@@ -82,9 +88,11 @@ module.exports.Component = registerComponent('tracked-controls', {
8288
var pose;
8389
var standingMatrix = this.standingMatrix;
8490
var vrDisplay = this.system.vrDisplay;
85-
var cameraEl = el.sceneEl.camera.el;
8691
var data = this.data;
87-
var userHeight = cameraEl.components.camera.data.userHeight || data.defaultUserHeight;
92+
var headEl = this.getHeadElement();
93+
var headObject3D = headEl.object3D;
94+
var headCamera = headEl.components.camera;
95+
var userHeight = (headCamera ? headCamera.data.userHeight : 0) || data.defaultUserHeight;
8896

8997
if (!controller) { return; }
9098

@@ -94,7 +102,7 @@ module.exports.Component = registerComponent('tracked-controls', {
94102
if (pose.orientation) {
95103
dolly.quaternion.fromArray(pose.orientation);
96104
} else {
97-
dolly.quaternion.copy(cameraEl.object3D.quaternion);
105+
dolly.quaternion.copy(headObject3D.quaternion);
98106
}
99107
if (pose.position) {
100108
dolly.position.fromArray(pose.position);
@@ -103,7 +111,7 @@ module.exports.Component = registerComponent('tracked-controls', {
103111
// Use controllerPosition and deltaControllerPosition to avoid creating yet more variables...
104112

105113
// Use camera position as head position.
106-
controllerPosition.copy(cameraEl.object3D.position);
114+
controllerPosition.copy(headObject3D.position);
107115
// Set offset for degenerate "arm model" to elbow.
108116
deltaControllerPosition.set(
109117
data.eyesToElbow.x * (data.hand === 'left' ? -1 : data.hand === 'right' ? 1 : 0),
@@ -112,7 +120,7 @@ module.exports.Component = registerComponent('tracked-controls', {
112120
// Scale offset by user height.
113121
deltaControllerPosition.multiplyScalar(userHeight);
114122
// Apply camera Y rotation (not X or Z, so you can look down at your hand).
115-
deltaControllerPosition.applyAxisAngle(cameraEl.object3D.up, cameraEl.object3D.rotation.y);
123+
deltaControllerPosition.applyAxisAngle(headObject3D.up, headObject3D.rotation.y);
116124
// Apply rotated offset to position.
117125
controllerPosition.add(deltaControllerPosition);
118126

@@ -124,7 +132,7 @@ module.exports.Component = registerComponent('tracked-controls', {
124132
if (pose.orientation) {
125133
controllerQuaternion.fromArray(pose.orientation);
126134
} else {
127-
controllerQuaternion.copy(cameraEl.object3D.quaternion);
135+
controllerQuaternion.copy(headObject3D.quaternion);
128136
}
129137
controllerEuler.setFromQuaternion(controllerQuaternion);
130138
controllerEuler.set(controllerEuler.x, controllerEuler.y, 0);

0 commit comments

Comments
 (0)