Skip to content

Commit 98a4a9f

Browse files
zjm-metameta-codesync[bot]
authored andcommitted
feat(core) Add support of detachOnGrab in DistanceGrabbable component.
Summary: Support detachOnGrab in DistanceGrabbable component to allow detaching the object from its parents when grabbed. Reviewed By: felixtrz Differential Revision: D89236264 fbshipit-source-id: ca1d8915ceefc2a8b1cd4a01ac5ad5931cf11af3
1 parent 7166ff4 commit 98a4a9f

File tree

4 files changed

+40
-21
lines changed

4 files changed

+40
-21
lines changed

examples/grab/metaspatial/Composition/Main.scene

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ entities:
4747
tag: Environment
4848
- components:
4949
com.iwsdk.components.DistanceGrabbable:
50-
translate: false
51-
movementMode: 3
5250
scale: false
51+
movementMode: 3
52+
translate: false
5353
com.iwsdk.components.Interactable:
5454
{}
5555
com.meta.components.Animatable:
@@ -81,15 +81,16 @@ entities:
8181
tag: earth
8282
- components:
8383
com.iwsdk.components.DistanceGrabbable:
84-
targetPositionOffset:
85-
- 0.100000001
86-
- 0
87-
- 0
84+
detachOnGrab: true
8885
targetQuaternionOffset:
8986
- 0
9087
- 120
9188
- 0
9289
- 1
90+
targetPositionOffset:
91+
- 0.100000001
92+
- 0
93+
- 0
9394
com.iwsdk.components.Interactable:
9495
{}
9596
com.meta.components.Animatable:
@@ -206,7 +207,8 @@ entities:
206207
tag: pin3
207208
- components:
208209
com.iwsdk.components.DistanceGrabbable:
209-
{}
210+
movementMode: 0
211+
detachOnGrab: true
210212
com.iwsdk.components.Interactable:
211213
{}
212214
com.meta.components.Animatable:
@@ -272,16 +274,16 @@ entities:
272274
tag: opera_house
273275
- components:
274276
com.iwsdk.components.DistanceGrabbable:
275-
targetPositionOffset:
276-
- 0
277-
- 0.300000012
278-
- 0
279-
moveSpeedFactor: 0.5
280277
targetQuaternionOffset:
281278
- 12
282279
- 0
283280
- 0
284281
- 1
282+
moveSpeedFactor: 0.5
283+
targetPositionOffset:
284+
- 0
285+
- 0.300000012
286+
- 0
285287
com.iwsdk.components.Interactable:
286288
{}
287289
com.meta.components.Animatable:

packages/core/src/grab/distance-grabbable.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ export const DistanceGrabbable = createComponent(
110110
},
111111
/** A boolean value to set whether the object snap back to its original position and rotation. */
112112
returnToOrigin: { type: Types.Boolean, default: false },
113+
/** A boolean value to set whether the object will be detached from its parent and attach to the scene/Level root when grabbed. */
114+
detachOnGrab: { type: Types.Boolean, default: false },
113115
/** Object movement and rotation speed factor for the MoveTowardsTarget movement mode with a scale from 0 to 1. */
114116
moveSpeedFactor: { type: Types.Float32, default: 0.1 },
115117
/** Target position offset relative to the input source for MoveTowardsTarget mode in [x, y, z]. */

packages/core/src/grab/grab-system.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { DistanceGrabbable } from './distance-grabbable.js';
1818
import { DistanceGrabHandle, MovementMode, Handle } from './handles.js';
1919
import { OneHandGrabbable } from './one-hand-grabbable.js';
2020
import { TwoHandsGrabbable } from './two-hands-grabbable.js';
21+
import { LevelTag } from '../level/index.js';
2122

2223
/**
2324
* Manages interactive object grabbing and manipulation for VR/AR experiences.
@@ -241,6 +242,9 @@ export class GrabSystem extends createSystem(
241242
const object = entity.object3D;
242243
if (!(object instanceof Object3D)) return;
243244
const obj = object as Object3D<PointerEventsMap & Object3DEventMap>;
245+
const rootEntity = entity.hasComponent(LevelTag)
246+
? this.world.activeLevel.value
247+
: this.world.sceneEntity;
244248
const rotateMax = entity.getVectorView(DistanceGrabbable, 'rotateMax');
245249
const rotateMin = entity.getVectorView(DistanceGrabbable, 'rotateMin');
246250
const translateMax = entity.getVectorView(
@@ -257,6 +261,9 @@ export class GrabSystem extends createSystem(
257261
const returnToOrigin = Boolean(
258262
entity.getValue(DistanceGrabbable, 'returnToOrigin'),
259263
);
264+
const detachOnGrab = Boolean(
265+
entity.getValue(DistanceGrabbable, 'detachOnGrab'),
266+
);
260267
const targetPosOffset = entity.getVectorView(
261268
DistanceGrabbable,
262269
'targetPositionOffset',
@@ -297,6 +304,7 @@ export class GrabSystem extends createSystem(
297304
});
298305
const handle = new DistanceGrabHandle(
299306
obj,
307+
rootEntity.object3D!,
300308
opts,
301309
movementMode!,
302310
returnToOrigin,
@@ -308,6 +316,7 @@ export class GrabSystem extends createSystem(
308316
targetQuatOffset[2],
309317
targetQuatOffset[3],
310318
),
319+
detachOnGrab,
311320
);
312321
handle.bind(obj);
313322
obj.pointerEventsType = { deny: 'grab' };

packages/core/src/grab/handles.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,14 @@ export class DistanceGrabHandle<T> extends HandleStore<T> {
4343

4444
constructor(
4545
readonly target_: Object3D | { current?: Object3D | null },
46+
readonly sceneRoot_: Object3D,
4647
public readonly getOptions: () => HandleOptions<T> = () => ({}),
4748
public readonly movementMode: string,
48-
public readonly returnToOrigin: Boolean,
49+
public readonly returnToOrigin: boolean,
4950
public readonly moveSpeedFactor: number = 0.1,
5051
public readonly targetPosOffset: Vector3 = new Vector3(0, 0, 0),
5152
public readonly targetQuatOffset: Quaternion = new Quaternion(0, 0, 0, 1),
53+
public readonly detachOnGrab: boolean,
5254
) {
5355
super(target_, getOptions);
5456

@@ -60,14 +62,6 @@ export class DistanceGrabHandle<T> extends HandleStore<T> {
6062
}
6163

6264
update(time: number) {
63-
if (
64-
this.movementMode === MovementMode.RotateAtSource ||
65-
this.movementMode === MovementMode.MoveFromTarget
66-
) {
67-
super.update(time);
68-
return;
69-
}
70-
7165
const target = this.getTarget();
7266

7367
if (
@@ -82,6 +76,18 @@ export class DistanceGrabHandle<T> extends HandleStore<T> {
8276
return;
8377
}
8478

79+
if (this.detachOnGrab && target.parent != this.sceneRoot_) {
80+
this.sceneRoot_.attach(target);
81+
}
82+
83+
if (
84+
this.movementMode === MovementMode.RotateAtSource ||
85+
this.movementMode === MovementMode.MoveFromTarget
86+
) {
87+
super.update(time);
88+
return;
89+
}
90+
8591
const pointerAmount = this.inputState.size;
8692
target.getWorldPosition(DistanceGrabHandle._posHelper);
8793
target.getWorldQuaternion(DistanceGrabHandle._quatHelper);

0 commit comments

Comments
 (0)