Skip to content

Commit 6195c75

Browse files
committed
projectRays option for handle
1 parent febdc17 commit 6195c75

File tree

6 files changed

+35
-25
lines changed

6 files changed

+35
-25
lines changed

docs/handles/handle-component.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ Allows disabling automatic binding of the event listeners to the provided handle
5353
**apply**
5454
The `apply` function is used to apply a state modification that originates from a user interaction to the state. This property allows overriding the default apply function, giving the developer complete control over how modifications affect the state. For instance, instead of applying the modification directly, the developer can apply it to their own state management solution. The state management solution can then apply the modification to the handle target.
5555

56+
**projectRays**
57+
Allows to configure whether rays from input devices should be projected onto the interaction space (3D plane or 3D Line).
58+
5659
**alwaysUpdate**
5760
In situations where the handle target is placed inside a constantly changing group, the `alwaysUpdate` flag ensures that the handle target's transformation is updated every frame to reflect the current state of the handle.
5861

packages/handle/src/computations/one-pointer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export function computeOnePointerHandleTransformState(
6565
//matrixHelper2 = initialPointerToTargetParentOffset
6666

6767
projectOntoSpace(
68+
options.projectRays,
6869
spaceHelper,
6970
pointerData.initialPointerWorldPoint,
7071
pointerData.pointerWorldOrigin,

packages/handle/src/computations/translate-as.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,28 @@ export function computeTranslateAsHandleTransformState(
7272

7373
//compute initial delta between point and target projected on space
7474
deltaHelper1.setFromMatrixPosition(matrixHelper)
75-
projectOntoSpace(space, pointerData.initialPointerWorldPoint, pointerData.pointerWorldOrigin, deltaHelper1, undefined)
75+
projectOntoSpace(
76+
options.projectRays,
77+
space,
78+
pointerData.initialPointerWorldPoint,
79+
pointerData.pointerWorldOrigin,
80+
deltaHelper1,
81+
undefined,
82+
)
7683
deltaHelper1.negate().add(pointerData.initialPointerWorldPoint)
7784

7885
//compute current delta between point and target projected on space
7986
deltaHelper2.setFromMatrixPosition(targetWorldMatrix)
80-
projectOntoSpace(space, pointerData.initialPointerWorldPoint, pointerData.pointerWorldOrigin, deltaHelper2, undefined)
8187
projectOntoSpace(
88+
options.projectRays,
89+
space,
90+
pointerData.initialPointerWorldPoint,
91+
pointerData.pointerWorldOrigin,
92+
deltaHelper2,
93+
undefined,
94+
)
95+
projectOntoSpace(
96+
options.projectRays,
8297
space,
8398
pointerData.initialPointerWorldPoint,
8499
pointerData.pointerWorldOrigin,

packages/handle/src/computations/two-pointer.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,15 @@ export function computeTwoPointerHandleTransformState(
6969
addSpaceFromTransformOptions(space, qHelper1, storeData.initialTargetRotation, options.scale ?? true, 'scale')
7070
//project pointers into that space
7171
projectOntoSpace(
72+
options.projectRays,
7273
space,
7374
pointer1Data.initialPointerWorldPoint,
7475
pointer1Data.pointerWorldOrigin,
7576
vectorHelper1.copy(pointer1Data.pointerWorldPoint),
7677
pointer1Data.pointerWorldDirection,
7778
)
7879
projectOntoSpace(
80+
options.projectRays,
7981
space,
8082
pointer2Data.initialPointerWorldPoint,
8183
pointer2Data.pointerWorldOrigin,

packages/handle/src/computations/utils.ts

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,16 @@ function applyTransformOptionsToAxis(
210210
}
211211

212212
export function projectOntoSpace(
213+
projectRays: boolean = true,
213214
space: Array<Vector3>,
214215
initialWorldPoint: Vector3,
215216
worldPointerOrigin: Vector3,
216217
worldPoint: Vector3,
217218
worldDirection: Vector3 | undefined,
218219
): void {
220+
if (!projectRays) {
221+
return
222+
}
219223
switch (space.length) {
220224
case 0:
221225
case 3:
@@ -382,9 +386,6 @@ const planeHelper = new Plane()
382386
const normalHelper = new Vector3()
383387
const vectorHelper = new Vector3()
384388

385-
const _3Degree = (3 / 180) * Math.PI
386-
const _6Degree = (6 / 180) * Math.PI
387-
388389
function projectOntoPlane(
389390
_axis1: Vector3,
390391
_axis2: Vector3,
@@ -396,9 +397,7 @@ function projectOntoPlane(
396397
normalHelper.crossVectors(_axis1, _axis2).normalize()
397398
planeHelper.setFromNormalAndCoplanarPoint(normalHelper, initialWorldPoint)
398399

399-
const angleDifference = worldDirection == null ? 0 : Math.abs(normalHelper.dot(worldDirection))
400-
401-
if (worldDirection == null || angleDifference < _3Degree) {
400+
if (worldDirection == null) {
402401
//project point onto plane
403402
planeHelper.projectPoint(worldPoint, worldPoint)
404403
return
@@ -415,14 +414,6 @@ function projectOntoPlane(
415414

416415
vectorHelper.copy(worldPoint)
417416
worldPoint.copy(worldPointerOrigin).addScaledVector(worldDirection, distanceAlongDirection)
418-
419-
if (angleDifference < _6Degree) {
420-
//angleDifference is between 3° and 6°
421-
//factor = 1 means that we want 100% from worldPoint and 0 from project point
422-
const factor = (angleDifference - _3Degree) / _3Degree
423-
planeHelper.projectPoint(vectorHelper, vectorHelper)
424-
worldPoint.multiplyScalar(factor).addScaledVector(vectorHelper, 1 - factor)
425-
}
426417
}
427418

428419
/**
@@ -435,8 +426,7 @@ export function projectOntoAxis(
435426
worldPoint: Vector3,
436427
worldDirection: Vector3 | undefined,
437428
): void {
438-
const angleDifference = worldDirection == null ? 0 : 1 - Math.abs(axis.dot(worldDirection))
439-
if (worldDirection == null || angleDifference < _3Degree) {
429+
if (worldDirection == null) {
440430
projectPointOntoAxis(worldPoint, initialWorldPoint, axis)
441431
return
442432
}
@@ -461,13 +451,6 @@ export function projectOntoAxis(
461451
vectorHelper.copy(worldPoint)
462452
// 4. Calculate the nearest point on the first line
463453
worldPoint.copy(initialWorldPoint).addScaledVector(axis, t)
464-
if (angleDifference < _6Degree) {
465-
//angleDifference is between 3° and 6°
466-
//factor = 1 means that we want 100% from worldPoint and 0 from project point
467-
const factor = (angleDifference - _3Degree) / _3Degree
468-
projectPointOntoAxis(vectorHelper, initialWorldPoint, axis)
469-
worldPoint.multiplyScalar(factor).addScaledVector(vectorHelper, 1 - factor)
470-
}
471454
}
472455

473456
export function projectPointOntoAxis(target: Vector3, axisOrigin: Vector3, axisNormal: Vector3) {

packages/handle/src/store.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ export type HandleOptions<T> = {
4141
* @default true
4242
*/
4343
rotate?: HandleTransformOptions
44+
/**
45+
* allows to configure whether rays from input devices should be projected onto the interaction space (3D plane or 3D Line).
46+
* @default true
47+
*/
48+
projectRays?: boolean
4449
/**
4550
* @default true
4651
*/
@@ -129,6 +134,7 @@ export class HandleStore<T>
129134
}
130135
const pointerWorldDirection = getWorldDirection(event, vectorHelper) ? vectorHelper.clone() : undefined
131136

137+
event.intersection.details.type
132138
this.inputState.set(event.pointerId, {
133139
pointerWorldDirection,
134140
pointerWorldPoint: event.point,

0 commit comments

Comments
 (0)