Skip to content

Commit

Permalink
fix(WebXR): allow double selection with two controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
bourdaisj authored and finetjul committed Mar 22, 2024
1 parent fb2ee44 commit 60cc0f9
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import macro from 'vtk.js/Sources/macros';
import { mat4, quat, vec3, vec4 } from 'gl-matrix';
import vtkCompositeVRManipulator from 'vtk.js/Sources/Interaction/Manipulators/CompositeVRManipulator';
import vtkPicker from 'vtk.js/Sources/Rendering/Core/Picker';
import { vec3, vec4, mat4, quat } from 'gl-matrix';
import macro from 'vtk.js/Sources/macros';
import { States } from 'vtk.js/Sources/Rendering/Core/InteractorStyle/Constants';

// ----------------------------------------------------------------------------
// vtk3DControllerModelSelectorManipulator methods
Expand Down Expand Up @@ -93,21 +94,21 @@ function vtk3DControllerModelSelectorManipulator(publicAPI, model) {
prop.rotateQuaternion(propNewOrientation);
}

publicAPI.onButton3D = (
_interactorStyle,
renderer,
_state,
_device,
_input,
pressed,
targetPosition,
targetOrientation
) => {
function releasePickedProp() {
model.lastOrientation = null;
model.lastWorldPosition = null;

if (pickedProp) {
pickedProp.setDragable(true);
}

pickedProp = null;
}

publicAPI.onButton3D = (interactorStyle, renderer, state, eventData) => {
// If the button is not pressed, clear the state
if (!pressed) {
model.lastOrientation = null;
model.lastWorldPosition = null;
pickedProp = null;
if (!eventData.pressed) {
releasePickedProp();
return macro.VOID;
}

Expand Down Expand Up @@ -143,12 +144,13 @@ function vtk3DControllerModelSelectorManipulator(publicAPI, model) {
const props = picker.getActors();

// If we have picked props, store the first one.
if (props.length > 0) {
if (props.length > 0 && props[0].getNestedDragable()) {
pickedProp = props[0];

// prevent the prop from being dragged somewhere else
pickedProp.setDragable(false);
} else {
model.lastOrientation = null;
model.lastWorldPosition = null;
pickedProp = null;
releasePickedProp();
}

return macro.EVENT_ABORT;
Expand All @@ -161,7 +163,7 @@ function vtk3DControllerModelSelectorManipulator(publicAPI, model) {
publicAPI.onMove3D = (_interactorStyle, renderer, _state, eventData) => {
// If we are not interacting with any prop, we have nothing to do.
// Also check for dragable
if (pickedProp == null || !pickedProp.getNestedDragable()) {
if (state !== States.IS_CAMERA_POSE || pickedProp == null) {
return macro.VOID;
}

Expand Down
39 changes: 19 additions & 20 deletions Sources/Interaction/Style/InteractorStyleManipulator/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkInteractorStyleManipulator');

model.currentVRManipulators = new Map();
model.mouseManipulators = [];
model.keyboardManipulators = [];
model.vrManipulators = [];
Expand Down Expand Up @@ -289,26 +290,27 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
}

// Look for a matching 3D camera interactor.
model.currentManipulator = publicAPI.findVRManipulator(
const manipulator = publicAPI.findVRManipulator(
ed.device,
ed.input,
ed.pressed
);
if (model.currentManipulator) {
model.currentManipulator.onButton3D(
publicAPI,
ed.pokedRenderer,
model.state,
ed.device,
ed.input,
ed.pressed,
ed.targetPosition,
ed.targetOrientation
);

if (manipulator) {
// register the manipulator for this device
model.currentVRManipulators.set(ed.device, manipulator);

manipulator.onButton3D(publicAPI, ed.pokedRenderer, model.state, ed);

if (ed.pressed) {
publicAPI.startCameraPose();
} else {
publicAPI.endCameraPose();
model.currentVRManipulators.delete(ed.device);

// make sure we don't end camera pose if other VR manipulators are currently interacting
if (model.currentVRManipulators.size === 0) {
publicAPI.endCameraPose();
}
}
} else {
vtkDebugMacro('No manipulator found');
Expand All @@ -317,13 +319,10 @@ function vtkInteractorStyleManipulator(publicAPI, model) {

//-------------------------------------------------------------------------
publicAPI.handleMove3D = (ed) => {
if (model.currentManipulator && model.state === States.IS_CAMERA_POSE) {
model.currentManipulator.onMove3D(
publicAPI,
ed.pokedRenderer,
model.state,
ed
);
const manipulator = model.currentVRManipulators.get(ed.device);

if (manipulator && model.state === States.IS_CAMERA_POSE) {
manipulator.onMove3D(publicAPI, ed.pokedRenderer, model.state, ed);
}
};

Expand Down

0 comments on commit 60cc0f9

Please sign in to comment.