diff --git a/src/core/usePointer.js b/src/core/usePointer.js index 7b1f31f..21b251a 100644 --- a/src/core/usePointer.js +++ b/src/core/usePointer.js @@ -1,4 +1,4 @@ -import { Vector2, Vector3 } from 'three'; +import { InstancedMesh, Vector2, Vector3 } from 'three'; import useRaycaster from './useRaycaster'; export default function usePointer(options) { @@ -54,7 +54,7 @@ export default function usePointer(options) { position.x = x - rect.left; position.y = y - rect.top; positionN.x = (position.x / rect.width) * 2 - 1; - positionN.y = (position.y / rect.height) * 2 - 1; + positionN.y = -(position.y / rect.height) * 2 + 1; raycaster.updatePosition(positionN); }; @@ -67,21 +67,31 @@ export default function usePointer(options) { if (intersectObjects.length) { const intersects = raycaster.intersect(positionN, intersectObjects); const offObjects = [...intersectObjects]; + const iMeshes = []; intersects.forEach(intersect => { const { object } = intersect; const { component } = object; + + // only once for InstancedMesh + if (object instanceof InstancedMesh) { + if (iMeshes.indexOf(object) !== -1) return; + iMeshes.push(object); + } + if (!object.over) { object.over = true; if (component.onPointerOver) component.onPointerOver({ over: true, component, intersect }); if (component.onPointerEnter) component.onPointerEnter({ component, intersect }); } + if (component.onPointerMove) component.onPointerMove({ component, intersect }); + offObjects.splice(offObjects.indexOf(object), 1); }); offObjects.forEach(object => { const { component } = object; - if (object.over && component.onPointerOver) { + if (object.over) { object.over = false; if (component.onPointerOver) component.onPointerOver({ over: false, component }); if (component.onPointerLeave) component.onPointerLeave({ component }); diff --git a/src/meshes/InstancedMesh.js b/src/meshes/InstancedMesh.js index a5a0bca..538852c 100644 --- a/src/meshes/InstancedMesh.js +++ b/src/meshes/InstancedMesh.js @@ -1,6 +1,7 @@ import { InstancedMesh } from 'three'; -import Object3D from '../core/Object3D.js'; +import Object3D from '../core/Object3D'; import { bindProp } from '../tools'; +import { pointerProps } from './Mesh'; export default { extends: Object3D, @@ -8,6 +9,7 @@ export default { castShadow: Boolean, receiveShadow: Boolean, count: Number, + ...pointerProps, }, provide() { return { @@ -25,10 +27,21 @@ export default { methods: { initMesh() { this.mesh = new InstancedMesh(this.geometry, this.material, this.count); + this.mesh.component = this; bindProp(this, 'castShadow', this.mesh); bindProp(this, 'receiveShadow', this.mesh); + if (this.onPointerEnter || + this.onPointerOver || + this.onPointerMove || + this.onPointerLeave || + this.onPointerDown || + this.onPointerUp || + this.onClick) { + this.three.addIntersectObject(this.mesh); + } + this.initObject3D(this.mesh); }, setGeometry(geometry) { @@ -41,5 +54,10 @@ export default { if (this.mesh) this.mesh.material = material; }, }, + unmounted() { + if (this.mesh) { + this.three.removeIntersectObject(this.mesh); + } + }, __hmrId: 'InstancedMesh', }; diff --git a/src/meshes/Mesh.js b/src/meshes/Mesh.js index f1864ad..74eaf60 100644 --- a/src/meshes/Mesh.js +++ b/src/meshes/Mesh.js @@ -3,18 +3,23 @@ import { Mesh } from 'three'; import Object3D from '../core/Object3D.js'; import { bindProp } from '../tools'; +export const pointerProps = { + onPointerEnter: Function, + onPointerOver: Function, + onPointerMove: Function, + onPointerLeave: Function, + onPointerDown: Function, + onPointerUp: Function, + onClick: Function, +}; + export default { name: 'Mesh', extends: Object3D, props: { castShadow: Boolean, receiveShadow: Boolean, - onPointerEnter: Function, - onPointerOver: Function, - onPointerLeave: Function, - onPointerDown: Function, - onPointerUp: Function, - onClick: Function, + ...pointerProps, }, // can't use setup because it will not be used in sub components // setup() {}, @@ -36,6 +41,7 @@ export default { if (this.onPointerEnter || this.onPointerOver || + this.onPointerMove || this.onPointerLeave || this.onPointerDown || this.onPointerUp ||