Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix XR's near interaction's selection mesh positioning #15993

Merged
merged 2 commits into from
Dec 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions packages/dev/core/src/XR/features/WebXRNearInteraction.ts
Original file line number Diff line number Diff line change
@@ -142,6 +142,8 @@ export interface IWebXRNearInteractionOptions {
motionControllerTouchMaterialSnippetUrl?: string;
}

const _tmpVectors = [new Vector3(), new Vector3(), new Vector3(), new Vector3()];

/**
* A module that will enable near interaction near interaction for hands and motion controllers of XR Input Sources
*/
@@ -245,6 +247,11 @@ export class WebXRNearInteraction extends WebXRAbstractFeature {
*/
public selectionMeshPickedColor: Color3 = new Color3(0.3, 0.3, 1.0);

/**
* If set to true, the selection mesh will always be hidden. Otherwise it will be shown only when needed
*/
public alwaysHideSelectionMesh: boolean = false;

/**
* constructs a new background remover module
* @param _xrSessionManager the session manager for this module
@@ -590,7 +597,7 @@ export class WebXRNearInteraction extends WebXRAbstractFeature {
if (controllerData.pick && controllerData.pick.pickedPoint && controllerData.pick.hit) {
controllerData.meshUnderPointer = controllerData.pick.pickedMesh;
controllerData.pickedPointVisualCue.position.copyFrom(controllerData.pick.pickedPoint);
controllerData.pickedPointVisualCue.isVisible = true;
controllerData.pickedPointVisualCue.isVisible = !this.alwaysHideSelectionMesh;

if (this._farInteractionFeature && this._farInteractionFeature.attached) {
this._farInteractionFeature._setPointerSelectionDisabledByPointerId(controllerData.id, true);
@@ -703,7 +710,7 @@ export class WebXRNearInteraction extends WebXRAbstractFeature {
this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);
controllerData.downTriggered = false;
controllerData.grabInteraction = false;
controllerData.pickedPointVisualCue.isVisible = true;
controllerData.pickedPointVisualCue.isVisible = !this.alwaysHideSelectionMesh;
}
} else {
if (pressed && !this._options.enableNearInteractionOnAllControllers && !this._options.disableSwitchOnClick) {
@@ -764,7 +771,7 @@ export class WebXRNearInteraction extends WebXRAbstractFeature {
) {
this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);
controllerData.grabInteraction = false;
controllerData.pickedPointVisualCue.isVisible = true;
controllerData.pickedPointVisualCue.isVisible = !this.alwaysHideSelectionMesh;
controllerData.downTriggered = false;
}
};
@@ -994,9 +1001,12 @@ export class WebXRNearInteraction extends WebXRAbstractFeature {
return pi;
}

const result = TmpVectors.Vector3[0];
const tmpVec = TmpVectors.Vector3[1];
const tmpRay = new Ray(Vector3.Zero(), Vector3.Zero(), 1);
const result = _tmpVectors[0];
const tmpVec = _tmpVectors[1];
_tmpVectors[2].setAll(0);
_tmpVectors[3].setAll(0);

const tmpRay = new Ray(_tmpVectors[2], _tmpVectors[3], 1);

let distance = +Infinity;
let tmp, tmpDistanceSphereToCenter, tmpDistanceSurfaceToCenter, intersectionInfo;
@@ -1015,8 +1025,8 @@ export class WebXRNearInteraction extends WebXRAbstractFeature {
tmp = Vector3.Distance(tmpVec, sphere.center);

// Check for finger inside of mesh
tmpDistanceSurfaceToCenter = Vector3.Distance(tmpVec, mesh.getAbsolutePosition());
tmpDistanceSphereToCenter = Vector3.Distance(sphere.center, mesh.getAbsolutePosition());
tmpDistanceSurfaceToCenter = Vector3.DistanceSquared(tmpVec, mesh.getAbsolutePosition());
tmpDistanceSphereToCenter = Vector3.DistanceSquared(sphere.center, mesh.getAbsolutePosition());
if (tmpDistanceSphereToCenter !== -1 && tmpDistanceSurfaceToCenter !== -1 && tmpDistanceSurfaceToCenter > tmpDistanceSphereToCenter) {
tmp = 0;
tmpVec.copyFrom(sphere.center);