@pmndrs/pointer-events
Advanced tools
Comparing version 6.0.0 to 6.1.0
@@ -35,3 +35,2 @@ import { Quaternion, Vector2, Vector3 } from 'three'; | ||
target.copy(e.uv).multiplyScalar(2).addScalar(-1); | ||
target.y *= -1; | ||
return target; | ||
@@ -38,0 +37,0 @@ } |
@@ -35,3 +35,3 @@ import { Intersection as ThreeIntersection, Quaternion, Vector3 } from 'three'; | ||
*/ | ||
customSort?: (i1: ThreeIntersection, i2: ThreeIntersection) => number; | ||
customSort?: (i1: ThreeIntersection, pointerEventsOrder1: number | undefined, i2: ThreeIntersection, pointerEventsOrder2: number | undefined) => number; | ||
}; | ||
@@ -38,0 +38,0 @@ export * from './lines.js'; |
import { Line3, Matrix4, Plane, Quaternion, Ray, Raycaster, Vector3, } from 'three'; | ||
import { computeIntersectionWorldPlane, getDominantIntersection, traversePointerEventTargets } from './utils.js'; | ||
import { computeIntersectionWorldPlane, getDominantIntersectionIndex, traversePointerEventTargets } from './utils.js'; | ||
const raycaster = new Raycaster(); | ||
@@ -11,3 +11,4 @@ const invertedMatrixHelper = new Matrix4(); | ||
let intersection; | ||
traversePointerEventTargets(scene, pointerId, pointerType, pointerState, (object) => { | ||
let pointerEventsOrder; | ||
traversePointerEventTargets(scene, pointerId, pointerType, pointerState, (object, objectPointerEventsOrder) => { | ||
let prevAccLineLength = 0; | ||
@@ -40,3 +41,7 @@ const length = (intersection?.details.lineIndex ?? linePoints.length - 2) + 2; | ||
} | ||
intersection = getDominantIntersection(intersection, intersectsHelper, options); | ||
const index = getDominantIntersectionIndex(intersection, pointerEventsOrder, intersectsHelper, objectPointerEventsOrder, options); | ||
if (index != null) { | ||
intersection = intersectsHelper[index]; | ||
pointerEventsOrder = objectPointerEventsOrder; | ||
} | ||
intersectsHelper.length = 0; | ||
@@ -43,0 +48,0 @@ prevAccLineLength += lineLength; |
import { Matrix4, Plane, Ray, Raycaster, Vector3, } from 'three'; | ||
import { computeIntersectionWorldPlane, getDominantIntersection, traversePointerEventTargets } from './utils.js'; | ||
import { computeIntersectionWorldPlane, getDominantIntersectionIndex, traversePointerEventTargets } from './utils.js'; | ||
const raycaster = new Raycaster(); | ||
@@ -13,7 +13,12 @@ const directionHelper = new Vector3(); | ||
let intersection; | ||
let pointerEventsOrder; | ||
raycaster.ray.origin.copy(fromPosition); | ||
raycaster.ray.direction.copy(direction).applyQuaternion(fromQuaternion); | ||
traversePointerEventTargets(scene, pointerId, pointerType, pointerState, (object) => { | ||
traversePointerEventTargets(scene, pointerId, pointerType, pointerState, (object, objectPointerEventsOrder) => { | ||
object.raycast(raycaster, intersectsHelper); | ||
intersection = getDominantIntersection(intersection, intersectsHelper, options); | ||
const index = getDominantIntersectionIndex(intersection, pointerEventsOrder, intersectsHelper, objectPointerEventsOrder, options); | ||
if (index != null) { | ||
intersection = intersectsHelper[index]; | ||
pointerEventsOrder = objectPointerEventsOrder; | ||
} | ||
intersectsHelper.length = 0; | ||
@@ -59,7 +64,12 @@ }); | ||
let intersection; | ||
let pointerEventsOrder; | ||
raycaster.setFromCamera(coords, from); | ||
planeHelper.setFromNormalAndCoplanarPoint(from.getWorldDirection(directionHelper), raycaster.ray.origin); | ||
traversePointerEventTargets(scene, pointerId, pointerType, pointerState, (object) => { | ||
traversePointerEventTargets(scene, pointerId, pointerType, pointerState, (object, objectPointerEventsOrder) => { | ||
object.raycast(raycaster, intersectsHelper); | ||
intersection = getDominantIntersection(intersection, intersectsHelper, options); | ||
const index = getDominantIntersectionIndex(intersection, pointerEventsOrder, intersectsHelper, objectPointerEventsOrder, options); | ||
if (index != null) { | ||
intersection = intersectsHelper[index]; | ||
pointerEventsOrder = objectPointerEventsOrder; | ||
} | ||
intersectsHelper.length = 0; | ||
@@ -66,0 +76,0 @@ }); |
import { InstancedMesh, Matrix4, Mesh, Vector3, Sphere, Quaternion, Plane, } from 'three'; | ||
import { computeIntersectionWorldPlane, getDominantIntersection, traversePointerEventTargets } from './utils.js'; | ||
import { computeIntersectionWorldPlane, getDominantIntersectionIndex, traversePointerEventTargets } from './utils.js'; | ||
const collisionSphere = new Sphere(); | ||
@@ -10,7 +10,12 @@ const intersectsHelper = []; | ||
let intersection; | ||
let pointerEventsOrder; | ||
collisionSphere.center.copy(fromPosition); | ||
collisionSphere.radius = radius; | ||
traversePointerEventTargets(scene, pointerId, pointerType, pointerState, (object) => { | ||
traversePointerEventTargets(scene, pointerId, pointerType, pointerState, (object, objectPointerEventsOrder) => { | ||
intersectSphereWithObject(collisionSphere, object, intersectsHelper); | ||
intersection = getDominantIntersection(intersection, intersectsHelper, options); | ||
const index = getDominantIntersectionIndex(intersection, pointerEventsOrder, intersectsHelper, objectPointerEventsOrder, options); | ||
if (index != null) { | ||
intersection = intersectsHelper[index]; | ||
pointerEventsOrder = objectPointerEventsOrder; | ||
} | ||
intersectsHelper.length = 0; | ||
@@ -17,0 +22,0 @@ }); |
@@ -5,3 +5,6 @@ import { Plane, Intersection as ThreeIntersection, Object3D } from 'three'; | ||
export declare function computeIntersectionWorldPlane(target: Plane, intersection: Intersection, object: Object3D): boolean; | ||
export declare function traversePointerEventTargets(object: Object3D, pointerId: number, pointerType: string, pointerState: unknown, callback: (object: Object3D) => void, parentHasListener?: boolean, parentPointerEvents?: AllowedPointerEvents, parentPointerEventsType?: AllowedPointerEventsType): void; | ||
export declare function getDominantIntersection<T extends ThreeIntersection>(target: T | undefined, current: Array<T>, { customFilter, customSort: compare }?: IntersectionOptions): T | undefined; | ||
export declare function traversePointerEventTargets(object: Object3D, pointerId: number, pointerType: string, pointerState: unknown, callback: (object: Object3D, pointerEventsOrder: number | undefined) => void, parentHasListener?: boolean, parentPointerEvents?: AllowedPointerEvents, parentPointerEventsType?: AllowedPointerEventsType, parentPointerEventsOrder?: number): void; | ||
/** | ||
* @returns undefined if `i1` is the dominant intersection | ||
*/ | ||
export declare function getDominantIntersectionIndex<T extends ThreeIntersection>(i1: T | undefined, pointerEventsOrder1: number | undefined, i2: Array<T>, pointerEventsOrder2: number | undefined, { customFilter, customSort: compare }?: IntersectionOptions): number | undefined; |
@@ -42,27 +42,33 @@ import { hasObjectListeners } from '../utils.js'; | ||
} | ||
export function traversePointerEventTargets(object, pointerId, pointerType, pointerState, callback, parentHasListener = false, parentPointerEvents, parentPointerEventsType) { | ||
export function traversePointerEventTargets(object, pointerId, pointerType, pointerState, callback, parentHasListener = false, parentPointerEvents, parentPointerEventsType, parentPointerEventsOrder) { | ||
const hasListener = parentHasListener || hasObjectListeners(object); | ||
const allowedPointerEvents = object.pointerEvents ?? parentPointerEvents ?? 'listener'; | ||
const allowedPointerEventsType = object.pointerEventsType ?? parentPointerEventsType ?? 'all'; | ||
const isAllowed = isPointerEventsAllowed(hasListener, allowedPointerEvents, allowedPointerEventsType, pointerId, pointerType, pointerState); | ||
const pointerEvents = object.pointerEvents ?? parentPointerEvents; | ||
const pointerEventsType = object.pointerEventsType ?? parentPointerEventsType; | ||
const pointerEventsOrder = object.pointerEventsOrder ?? parentPointerEventsOrder; | ||
const isAllowed = isPointerEventsAllowed(hasListener, pointerEvents ?? 'listener', pointerEventsType ?? 'all', pointerId, pointerType, pointerState); | ||
if (isAllowed) { | ||
callback(object); | ||
callback(object, pointerEventsOrder); | ||
} | ||
const length = object.children.length; | ||
for (let i = 0; i < length; i++) { | ||
traversePointerEventTargets(object.children[i], pointerId, pointerType, pointerState, callback, hasListener, allowedPointerEvents, allowedPointerEventsType); | ||
traversePointerEventTargets(object.children[i], pointerId, pointerType, pointerState, callback, hasListener, pointerEvents, pointerEventsType, pointerEventsOrder); | ||
} | ||
} | ||
export function getDominantIntersection(target, current, { customFilter, customSort: compare = defaultSort } = {}) { | ||
const length = current.length; | ||
/** | ||
* @returns undefined if `i1` is the dominant intersection | ||
*/ | ||
export function getDominantIntersectionIndex(i1, pointerEventsOrder1, i2, pointerEventsOrder2, { customFilter, customSort: compare = defaultSort } = {}) { | ||
let index = undefined; | ||
const length = i2.length; | ||
for (let i = 0; i < length; i++) { | ||
const intersection = current[i]; | ||
const intersection = i2[i]; | ||
if (!(customFilter?.(intersection) ?? true)) { | ||
continue; | ||
} | ||
if (target == null || compare(target, intersection) > 0) { | ||
target = intersection; | ||
if (i1 == null || compare(i1, pointerEventsOrder1, intersection, pointerEventsOrder2) > 0) { | ||
i1 = intersection; | ||
index = i; | ||
} | ||
} | ||
return target; | ||
return index; | ||
} | ||
@@ -72,8 +78,6 @@ /** | ||
*/ | ||
function defaultSort(i1, i2) { | ||
const { pointerEventsOrder: o1 = 0 } = i1.object; | ||
const { pointerEventsOrder: o2 = 0 } = i2.object; | ||
if (o1 != o2) { | ||
function defaultSort(i1, pointerEventsOrder1 = 0, i2, pointerEventsOrder2 = 0) { | ||
if (pointerEventsOrder1 != pointerEventsOrder2) { | ||
//inverted order because order is sorted highest first | ||
return o2 - o1; | ||
return pointerEventsOrder2 - pointerEventsOrder1; | ||
} | ||
@@ -80,0 +84,0 @@ //i1 - i2 because negative values mean the sorting i1 before i2 is correct |
@@ -7,2 +7,3 @@ import { Object3D, Vector3 } from 'three'; | ||
* @default 0 | ||
* distance to intersection in local space | ||
*/ | ||
@@ -9,0 +10,0 @@ minDistance?: number; |
@@ -6,2 +6,3 @@ import { Quaternion, Vector3 } from 'three'; | ||
const NegZAxis = new Vector3(0, 0, -1); | ||
const vectorHelper = new Vector3(); | ||
export const defaultRayPointerOptions = { | ||
@@ -35,3 +36,4 @@ direction: NegZAxis, | ||
} | ||
if (intersection.distance < (options.minDistance ?? defaultRayPointerOptions.minDistance)) { | ||
const localDistance = intersection.distance * spaceObject.getWorldScale(vectorHelper).x; | ||
if (localDistance < (options.minDistance ?? defaultRayPointerOptions.minDistance)) { | ||
return undefined; | ||
@@ -38,0 +40,0 @@ } |
@@ -5,3 +5,3 @@ { | ||
"license": "SEE LICENSE IN LICENSE", | ||
"version": "6.0.0", | ||
"version": "6.1.0", | ||
"homepage": "https://github.com/pmndrs/xr", | ||
@@ -8,0 +8,0 @@ "author": "Bela Bohlender", |
70560
1609