Skip to content

Commit

Permalink
Added hide button for the hand controller.
Browse files Browse the repository at this point in the history
Summary:
Added the hide button to hide hand controller signal from the polyfill. Also added some improvements/bug fixes to the initial commit for controller hiding button:
* Added a hidden panel on top of the controller card when the hide button is clicked. This behavior follows the same practice as the `Polyfill` button.
* Changed the `_controllerMeshesVisible` into `_controllerMeshesHide` in #87 of `immersive-web-emulator/src/devtool/js/
emulatedDevice.js` which is a boolean array controlled only by the `toggleControllerVisibility` function. This fixes the bug of setting up a wrong initial value for ControllerVisibility.
  * (i.e. if the hand mode was selected when the emulator launches, both controller meshes would have the visibility set as `false`, then no controller mesh would show up the 1st time user switch the mode to the controller)
* Removed the transform control visibility when the controller/hand is hidden. This follows the same behavior as our user object hidden logic.

Reviewed By: felixtrz

Differential Revision: D54216588

fbshipit-source-id: 143ef338c9cdacfc254d51d55480ec6efd4a83a6
  • Loading branch information
zjm-meta authored and facebook-github-bot committed Feb 27, 2024
1 parent d5b5dbe commit 7abf503
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 27 deletions.
36 changes: 30 additions & 6 deletions polyfill/EmulatedXRDevice.js
Original file line number Diff line number Diff line change
Expand Up @@ -858,16 +858,22 @@ export default class EmulatedXRDevice extends XRDevice {
gamepad.axes[axisIndex] = value;
}

_updateInputVisibility(controllerIndex, visible) {
if (controllerIndex >= this.gamepads.length) {
throw new Error('ControllerIndex ' + controllerIndex + ' is greater than the gamepads.length ' + this.gamepads.length);
_updateControllerInputVisibility(controllerIndex, visible) {
if (controllerIndex >= this.gamepadInputSources.length) {
throw new Error('ControllerIndex ' + controllerIndex + ' is greater than the gamepadInputSources.length ' + this.gamepadInputSources.length);
}
const gamepad = this.gamepads[controllerIndex];
gamepad.active = visible;
const inputSourceImpl = this.gamepadInputSources[controllerIndex];
inputSourceImpl.active = visible;
}

_updateHandInputVisibility(handIndex, visible) {
if (handIndex >= this.handInputSources.length) {
throw new Error('HandIndex ' + handIndex + ' is greater than the handInputSources.length ' + this.handInputSources.length);
}
const inputSourceImpl = this.handInputSources[handIndex];
inputSourceImpl.active = visible;
}

_initializeControllers(config) {
const hasController = config.controllers !== undefined;
const controllerNum = hasController ? config.controllers.length : 0;
Expand Down Expand Up @@ -993,7 +999,7 @@ export default class EmulatedXRDevice extends XRDevice {
switch (objectName) {
case 'right-controller':
case 'left-controller':
this._updateInputVisibility(
this._updateControllerInputVisibility(
objectName === 'right-controller' ? 0 : 1, // @TODO: remove magic number
visible,
);
Expand Down Expand Up @@ -1067,6 +1073,24 @@ export default class EmulatedXRDevice extends XRDevice {
this.handPoseData[handedness].poseId = poseId;
});

window.addEventListener(
POLYFILL_ACTIONS.HAND_VISIBILITY_CHANGE,
(event) => {
const handedness = event.detail.handedness;
const visible = event.detail.visible;

switch (handedness) {
case 'right':
case 'left':
this._updateHandInputVisibility(
handedness === 'right' ? 0 : 1, // @TODO: remove magic number
visible,
);
break;
}
},
);

window.addEventListener(POLYFILL_ACTIONS.PINCH_VALUE_CHANGE, (event) => {
const handedness = event.detail.handedness;
const pinchValue = event.detail.value;
Expand Down
2 changes: 2 additions & 0 deletions src/devtool/js/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const EMULATOR_ACTIONS = {
EXCLUDE_POLYFILL: 'ea-exclude-polyfill',
INPUT_MODE_CHANGE: 'ea-input-mode-change',
HAND_POSE_CHANGE: 'ea-hand-pose-change',
HAND_VISIBILITY_CHANGE: 'ea-hand-visibility-change',
PINCH_VALUE_CHANGE: 'ea-pinch-value-change',
USER_OBJECTS_CHANGE: 'ea-user-objects-change',
};
Expand All @@ -43,6 +44,7 @@ export const POLYFILL_ACTIONS = {
ROOM_DIMENSION_CHANGE: 'pa-room-dimension-change',
INPUT_MODE_CHANGE: 'pa-input-mode-change',
HAND_POSE_CHANGE: 'pa-hand-pose-change',
HAND_VISIBILITY_CHANGE: 'pa-hand-visibility-change',
PINCH_VALUE_CHANGE: 'pa-pinch-value-change',
USER_OBJECTS_CHANGE: 'pa-user-objects-change',
};
Expand Down
28 changes: 16 additions & 12 deletions src/devtool/js/emulatedDevice.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ export default class EmulatedDevice extends EventEmitter {
this._camera.lookAt(new THREE.Vector3(0, 1.6, 0));

this._controllerMeshes = {};
this._controllerMeshesVisible = {};
this._controllerMeshesHidden = {};
this._handMeshes = {};
this._handMeshesHidden = {};

this._labelContainer = document.createElement('div');

Expand Down Expand Up @@ -83,7 +84,7 @@ export default class EmulatedDevice extends EventEmitter {
if (CONTROLLER_STRINGS[deviceKey]) {
this._controllerMeshes[deviceKey] = mesh;
mesh.visible = EmulatorSettings.instance.inputMode === 'controllers';
this._controllerMeshesVisible[deviceKey] = mesh.visible;
this._controllerMeshesHidden[deviceKey] = false;
}
this.render();
});
Expand All @@ -99,6 +100,7 @@ export default class EmulatedDevice extends EventEmitter {
node.add(mesh);
this._handMeshes[deviceKey] = mesh;
mesh.visible = EmulatorSettings.instance.inputMode === 'hands';
this._handMeshesHidden[deviceKey] = false;
this.render();
});
}
Expand Down Expand Up @@ -205,7 +207,6 @@ export default class EmulatedDevice extends EventEmitter {
controls.attach(object);
controls.enabled = false;
controls.visible = false;
controls.hidden = false;
controls.addEventListener(
'mouseDown',
() => (this._orbitControls.enabled = false),
Expand Down Expand Up @@ -445,11 +446,11 @@ export default class EmulatedDevice extends EventEmitter {
});
}
const controls = this._transformControls[deviceKey];
if (!controls.enabled && !controls.hidden) {
if (!controls.enabled) {
controls.enabled = true;
controls.visible = true;
controls.setMode('translate');
} else if (controls.getMode() === 'translate' && !controls.hidden) {
} else if (controls.getMode() === 'translate') {
controls.setMode('rotate');
} else {
controls.enabled = false;
Expand All @@ -459,11 +460,12 @@ export default class EmulatedDevice extends EventEmitter {
}

toggleControllerVisibility(deviceKey, visible) {
this._controllerMeshesVisible[deviceKey] = visible;
const controls = this._transformControls[deviceKey];
controls.visible = visible;
controls.enabled = visible;
controls.hidden = !visible;
this._controllerMeshesHidden[deviceKey] = !visible;
this.render();
}

toggleHandVisibility(deviceKey, visible) {
this._handMeshesHidden[deviceKey] = !visible;
this.render();
}

Expand Down Expand Up @@ -493,12 +495,14 @@ export default class EmulatedDevice extends EventEmitter {

render() {
Object.entries(this._handMeshes).forEach(([deviceKey, mesh]) => {
mesh.visible = EmulatorSettings.instance.inputMode === 'hands';
mesh.visible =
EmulatorSettings.instance.inputMode === 'hands' &&
!this._handMeshesHidden[deviceKey];
});
Object.entries(this._controllerMeshes).forEach(([deviceKey, mesh]) => {
mesh.visible =
EmulatorSettings.instance.inputMode === 'controllers' &&
this._controllerMeshesVisible[deviceKey];
!this._controllerMeshesHidden[deviceKey];
});
const parent = this.canvas.parentElement;
if (!parent) return;
Expand Down
7 changes: 7 additions & 0 deletions src/devtool/js/messenger.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ export const toggleControllerVisibility = (deviceKey, visible) => {
});
};

export const toggleHandVisibility = (deviceId, visible) => {
executeAction(EMULATOR_ACTIONS.HAND_VISIBILITY_CHANGE, {
handedness: HAND_STRINGS[deviceId].handedness,
visible,
});
};

export const reloadInspectedTab = () => {
executeAction(EMULATOR_ACTIONS.EXCLUDE_POLYFILL);
};
Expand Down
2 changes: 1 addition & 1 deletion src/devtool/jsx/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export default function App({ device }) {
style={{ display: inputMode === 'hands' ? 'flex' : 'none' }}
>
{[DEVICE.INPUT_LEFT, DEVICE.INPUT_RIGHT].map((deviceKey) => (
<HandPanel key={deviceKey} deviceKey={deviceKey} />
<HandPanel key={deviceKey} deviceKey={deviceKey} device={device} />
))}
</div>
</div>
Expand Down
10 changes: 10 additions & 0 deletions src/devtool/jsx/controllers.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,20 @@ export default function ControllerPanel({ deviceKey, device }) {
className="btn special-button"
type="button"
onClick={(event) => toggleDeviceVisibility(event)}
style={{ zIndex: 11, position: 'relative' }}
>
Hide
</button>
</div>
<div
style={{
backgroundColor: 'rgba(0,0,0,0.5)',
zIndex: 10,
position: 'absolute',
height: (showController ? 0 : 100) + '%',
width: '100%',
}}
></div>
<div className="card-body">
<div className="row">
<div className="col-4 d-flex align-items-center">
Expand Down
48 changes: 40 additions & 8 deletions src/devtool/jsx/hands.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,24 @@
*/

import { EmulatorSettings, emulatorStates } from '../js/emulatorStates';
import { changeHandPose, updatePinchValue } from '../js/messenger';
import {
changeHandPose,
updatePinchValue,
toggleHandVisibility,
} from '../js/messenger';

import { HAND_STRINGS } from '../js/constants';
import React from 'react';
import { createAnalogPressFunction } from './controllers.jsx';

export default function HandPanel({ deviceKey }) {
export default function HandPanel({ deviceKey, device }) {
const strings = HAND_STRINGS[deviceKey];
const pressRef = React.createRef();
const rangeRef = React.createRef();
const poseSelectRef = React.createRef();

const [showHand, setShowHand] = React.useState(true);

function onHandPoseChange() {
EmulatorSettings.instance.handPoses[strings.name] =
poseSelectRef.current.value;
Expand All @@ -30,6 +36,13 @@ export default function HandPanel({ deviceKey }) {
updatePinchValue(deviceKey);
}

function toggleDeviceVisibility(event) {
setShowHand(!showHand); // React state only applies to the next rendering frame
device.toggleHandVisibility(deviceKey, !showHand);
toggleHandVisibility(deviceKey, !showHand);
event.target.classList.toggle('button-pressed', showHand);
}

const onPressAnalog = createAnalogPressFunction(
pressRef,
rangeRef,
Expand All @@ -42,13 +55,32 @@ export default function HandPanel({ deviceKey }) {
<div className="col">
<div className="component-container">
<div className="card controller-card hand-card">
<div className="card-header">
<img
src={`./assets/images/${strings.name}.png`}
className="control-icon"
/>
<span className="control-label">{strings.displayName}</span>
<div className="card-header d-flex justify-content-between align-items-center">
<div className="title">
<img
src={`./assets/images/${strings.name}.png`}
className="control-icon"
/>
<span className="control-label">{strings.displayName}</span>
</div>
<button
className="btn special-button"
type="button"
onClick={(event) => toggleDeviceVisibility(event)}
style={{ zIndex: 11, position: 'relative' }}
>
Hide
</button>
</div>
<div
style={{
backgroundColor: 'rgba(0,0,0,0.5)',
zIndex: 10,
position: 'absolute',
height: (showHand ? 0 : 100) + '%',
width: '100%',
}}
></div>
<div className="card-body">
<div className="row">
<div className="col-4 d-flex align-items-center">
Expand Down
7 changes: 7 additions & 0 deletions src/extension/content-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ const connection = {
});
break;

case EMULATOR_ACTIONS.HAND_VISIBILITY_CHANGE:
triggerPolyfillAction(POLYFILL_ACTIONS.HAND_VISIBILITY_CHANGE, {
handedness: message.handedness,
visible: message.visible,
});
break;

case EMULATOR_ACTIONS.PINCH_VALUE_CHANGE:
triggerPolyfillAction(POLYFILL_ACTIONS.PINCH_VALUE_CHANGE, {
handedness: message.handedness,
Expand Down

0 comments on commit 7abf503

Please sign in to comment.