Peter 1 år sedan
förälder
incheckning
395d8a9df3
32 ändrade filer med 7898 tillägg och 137 borttagningar
  1. 1 1
      docs/.vitepress/config/de.ts
  2. 1 1
      docs/.vitepress/config/en.ts
  3. 1 1
      docs/.vitepress/config/es.ts
  4. 1 1
      docs/.vitepress/config/fr.ts
  5. 1 1
      docs/.vitepress/config/nl.ts
  6. 1 1
      docs/.vitepress/config/zh.ts
  7. 1 1
      playground/vue/src/pages/events/Blocking.vue
  8. 1 1
      playground/vue/src/pages/events/Connect.vue
  9. 1 1
      playground/vue/src/pages/events/DeprecatedEventNames.vue
  10. 59 40
      playground/vue/src/pages/events/DynamicObjects.vue
  11. 1 1
      playground/vue/src/pages/events/EventModifiers.vue
  12. 2 2
      playground/vue/src/pages/events/Filter.vue
  13. 1 1
      playground/vue/src/pages/events/NoEvents.vue
  14. 1 1
      playground/vue/src/pages/events/OnCanvasLeave.vue
  15. 1 1
      playground/vue/src/pages/events/PointerCapture.vue
  16. 1 1
      playground/vue/src/pages/events/PointerEnterLeave.vue
  17. 2 4
      playground/vue/src/pages/events/PointerEnterLeaveOverOutComparison.vue
  18. 1 1
      playground/vue/src/pages/events/RemoveInteractivity.vue
  19. 1 1
      playground/vue/src/pages/events/StopPropagation.vue
  20. 1 1
      playground/vue/src/pages/events/TargetEnabled.vue
  21. 0 12
      playground/vue/src/pages/issues/732/ComponentWithInject.vue
  22. 0 13
      playground/vue/src/pages/issues/732/TheExperience.vue
  23. 25 25
      playground/vue/src/router/routes/events.ts
  24. 7757 2
      pnpm-lock.yaml
  25. 2 2
      src/components/TresCanvas.vue
  26. 0 1
      src/composables/useTresContextProvider/index.ts
  27. 9 8
      src/types/index.ts
  28. 2 2
      src/utils/createEventManager/createEventManager.test.ts
  29. 3 3
      src/utils/createEventManager/eventsRaycast.test.ts
  30. 18 4
      src/utils/createEventManager/eventsRaycast.ts
  31. 1 1
      src/utils/createEventManager/useEventsOptions.test.ts
  32. 1 1
      src/utils/createEventManager/useEventsOptions.ts

+ 1 - 1
docs/.vitepress/config/de.ts

@@ -98,7 +98,7 @@ export const deConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
           },
           {
             text: 'Nachbearbeitung',
-            link: 'https://post-processing.tresjs.org/'
+            link: 'https://post-processing.tresjs.org/',
           },
         ],
       },

+ 1 - 1
docs/.vitepress/config/en.ts

@@ -99,7 +99,7 @@ export const enConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
           },
           {
             text: 'Post-processing',
-            link: 'https://post-processing.tresjs.org/'
+            link: 'https://post-processing.tresjs.org/',
           },
         ],
       },

+ 1 - 1
docs/.vitepress/config/es.ts

@@ -99,7 +99,7 @@ export const esConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
           },
           {
             text: 'Post-procesamiento',
-            link: 'https://post-processing.tresjs.org/'
+            link: 'https://post-processing.tresjs.org/',
           },
         ],
       },

+ 1 - 1
docs/.vitepress/config/fr.ts

@@ -99,7 +99,7 @@ export const frConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
           },
           {
             text: 'Post-processing',
-            link: 'https://post-processing.tresjs.org/'
+            link: 'https://post-processing.tresjs.org/',
           },
         ],
       },

+ 1 - 1
docs/.vitepress/config/nl.ts

@@ -98,7 +98,7 @@ export const nlConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
           },
           {
             text: 'Nabewerking',
-            link: 'https://post-processing.tresjs.org/'
+            link: 'https://post-processing.tresjs.org/',
           },
         ],
       },

+ 1 - 1
docs/.vitepress/config/zh.ts

@@ -97,7 +97,7 @@ export const zhConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
           },
           {
             text: 'Post-processing',
-            link: 'https://post-processing.tresjs.org/'
+            link: 'https://post-processing.tresjs.org/',
           },
         ],
       },

+ 1 - 1
playground/vue/src/pages/events/Blocking.vue

@@ -1,9 +1,9 @@
 <!-- eslint-disable no-console -->
 <script setup lang="ts">
+import type { ThreeEvent } from '@tresjs/core'
 import { OrbitControls } from '@tresjs/cientos'
 import { TresCanvas } from '@tresjs/core'
 import { Vector3 } from 'three'
-import type { ThreeEvent } from '@tresjs/core'
 
 function onClick(ev: ThreeEvent<MouseEvent>) {
   ev.eventObject.material.color.set('red')

+ 1 - 1
playground/vue/src/pages/events/Connect.vue

@@ -1,9 +1,9 @@
 <!-- eslint-disable no-console -->
 <script setup lang="ts">
+import type { ThreeEvent, TresContext } from '@tresjs/core'
 import { OrbitControls } from '@tresjs/cientos'
 import { TresCanvas } from '@tresjs/core'
 import { BasicShadowMap, NoToneMapping, SRGBColorSpace } from 'three'
-import type { ThreeEvent, TresContext } from '@tresjs/core'
 
 const gl = {
   clearColor: '#202020',

+ 1 - 1
playground/vue/src/pages/events/DeprecatedEventNames.vue

@@ -1,8 +1,8 @@
 <!-- eslint-disable no-console -->
 <script setup lang="ts">
+import type { ThreeEvent } from '@tresjs/core'
 import { OrbitControls } from '@tresjs/cientos'
 import { TresCanvas } from '@tresjs/core'
-import type { ThreeEvent } from '@tresjs/core'
 import '@tresjs/leches/styles'
 
 function onClick(ev: ThreeEvent<MouseEvent>) {

+ 59 - 40
playground/vue/src/pages/events/DynamicObjects.vue

@@ -1,61 +1,80 @@
 <script setup lang="ts">
-import { Box, OrbitControls, Sphere, StatsGl } from '@tresjs/cientos'
+import { OrbitControls, Sphere } from '@tresjs/cientos'
 import { type ThreeEvent, TresCanvas } from '@tresjs/core'
-import { reactive } from 'vue'
-
-const hotspots = reactive([
-  {
-    position: [-2, 0, -2],
-  },
-  {
-    position: [0, 0, -2],
-  },
-  {
-    position: [2, 0, -2],
-  },
-])
-
-const addHotspot = () => {
-  const newHotspot = reactive({
-    position: [-2, 0, 0],
-  })
-  hotspots.push(newHotspot)
-}
+import { Mesh, MeshBasicMaterial, MeshNormalMaterial, TorusGeometry } from 'three'
 
-const removeHotspot = () => {
-  hotspots.pop()
-}
+const sphereCount = ref(1)
+
+const hoverMaterial = new MeshBasicMaterial({ color: 'white' })
+const sphereMaterial = new MeshNormalMaterial()
 
 const grow = (event: ThreeEvent<any>) => {
-  event.object.scale.set(1.5, 1.5, 1.5)
+  event.currentTarget.material = hoverMaterial
 }
 
 const shrink = (event: ThreeEvent<any>) => {
-  event.object.scale.set(1, 1, 1)
+  event.currentTarget.material = sphereMaterial
+}
+
+const torus = new Mesh(new TorusGeometry(0.2, 0.1), new MeshBasicMaterial({ color: 'red' }))
+const primitiveAOrB = ref('a')
+const msgs = ref<string[]>([])
+const isTestFinished = computed(() => msgs.value.length >= 2)
+const isTestPassed = computed(() => !msgs.value.some(msg => msg.startsWith('❌')))
+const primitiveAClick = () => {
+  if (primitiveAOrB.value === 'b') {
+    msgs.value.push('❌ old primitive event handler was called')
+  }
+  if (!isTestFinished.value) {
+    msgs.value.push('✅ primitiveA event handler was called')
+    primitiveAOrB.value = 'b'
+  }
+}
+const primitiveBPointerUp = () => {
+  if (primitiveAOrB.value === 'a') {
+    msgs.value.push('❌ old primitive event handler was called')
+  }
+  if (!isTestFinished.value) {
+    msgs.value.push('✅ primitiveB event handler was called')
+    primitiveAOrB.value = 'a'
+  }
 }
 </script>
 
 <template>
-  <TresCanvas>
-    <Suspense>
-      <StatsGl />
-    </Suspense>
+  <OverlayInfo>
+    <h1>Dynamic objects with events</h1>
+    <h2>Setup</h2>
+    <p>The torus is a <code>primitive :object</code>. Attaching the <code>:object</code> to a different <code>primitive</code> should not fire event handlers attached by the old primitive.</p>
+
+    <h2>Test</h2>
+    <p v-if="!isTestFinished"><strong>👉 Click on the red torus</strong></p>
+    <p v-else-if="isTestPassed">✅ Pass</p>
+    <p v-else>❌Fail</p>
+    <ul>
+      <li v-for="msg, i of msgs" :key="i" :style="{ color: (n - i) % 4 === 0 ? 'gray' : 'black' }">{{ msg }}</li>
+    </ul>
+
+    <h2>Test</h2>
+    <p>This test adds/removes objects with events to the scene in a <code>v-for</code>. When the pointer is over the object, it should be white. When the pointer is not over the object, it should have a "normal" material.</p>
+    <button @click="sphereCount++">Add a sphere</button>
+    <button @click="() => sphereCount = Math.max(0, sphereCount - 1)">Remove a sphere</button>
+  </OverlayInfo>
+  <TresCanvas clear-color="gray">
     <OrbitControls />
-    <TresPerspectiveCamera />
+    <TresPerspectiveCamera :position="[7, 7, 7]" :look-at="[0, 0, 0]" />
     <TresAmbientLight :args="['white', 0.5]" />
-    <Box :position="[0, 0, 0]" :scale="[1, 1, 1]" @click="addHotspot" @contextmenu="removeHotspot">
-      <TresMeshNormalMaterial />
-    </Box>
     <Sphere
-      v-for="(hotspot, index) in hotspots"
+      v-for="_, index in Array.from({ length: sphereCount })"
       :key="index"
-      :args="[0.5, 16, 16]"
-      :position="hotspot.position"
+      :scale="0.1"
+      :position="[Math.cos(index * 0.5) * (1 + index * 0.1), 0, Math.sin(index * 0.5) * (1 + index * 0.1)]"
+      :material="sphereMaterial"
       @click="console.log('click', index)"
       @pointerenter="grow"
       @pointerleave="shrink"
-    >
-      <TresMeshNormalMaterial />
-    </Sphere>
+    />
+    <primitive v-if="primitiveAOrB === 'a' && !isTestFinished" :object="torus" @click="primitiveAClick" />
+    <primitive v-if="primitiveAOrB === 'b' && !isTestFinished" :position-y="0.5" :object="torus" @pointerup="primitiveBPointerUp" />
   </TresCanvas>
 </template>

+ 1 - 1
playground/vue/src/pages/events/EventModifiers.vue

@@ -1,9 +1,9 @@
 <!-- eslint-disable no-console -->
 <script setup lang="ts">
+import type { ThreeEvent } from '@tresjs/core/types'
 import { Box, Cylinder, Sphere } from '@tresjs/cientos'
 import { TresCanvas } from '@tresjs/core'
 import { Color } from 'three'
-import type { ThreeEvent } from '@tresjs/core/types'
 
 const COLORS = 'red|orange|yellow|green|blue|purple'.split('|')
 

+ 2 - 2
playground/vue/src/pages/events/Filter.vue

@@ -1,10 +1,10 @@
 <!-- eslint-disable no-console -->
 <script setup lang="ts">
+import type { ThreeEvent, TresObject } from '@tresjs/core'
+import type { Intersection, Object3D } from 'three'
 import { OrbitControls } from '@tresjs/cientos'
 import { TresCanvas } from '@tresjs/core'
 import { BasicShadowMap, Color, NoToneMapping, SRGBColorSpace } from 'three'
-import type { ThreeEvent, TresObject } from '@tresjs/core'
-import type { Intersection, Object3D } from 'three'
 
 const gl = {
   clearColor: '#202020',

+ 1 - 1
playground/vue/src/pages/events/NoEvents.vue

@@ -1,9 +1,9 @@
 <!-- eslint-disable no-console -->
 <script setup lang="ts">
+import type { ThreeEvent } from '@tresjs/core'
 import { OrbitControls } from '@tresjs/cientos'
 import { TresCanvas } from '@tresjs/core'
 import { BasicShadowMap, Color, NoToneMapping, SRGBColorSpace } from 'three'
-import type { ThreeEvent } from '@tresjs/core'
 
 const gl = {
   clearColor: '#202020',

+ 1 - 1
playground/vue/src/pages/events/OnCanvasLeave.vue

@@ -1,7 +1,7 @@
 <script setup lang="ts">
+import type { ThreeEvent } from '@tresjs/core'
 import { TresCanvas } from '@tresjs/core'
 import { ref } from 'vue'
-import type { ThreeEvent } from '@tresjs/core'
 
 function over(ev: ThreeEvent<PointerEvent>) {
   ev.eventObject.material.color.set('#00F')

+ 1 - 1
playground/vue/src/pages/events/PointerCapture.vue

@@ -1,9 +1,9 @@
 <!-- eslint-disable no-console -->
 <script setup lang="ts">
+import type { ThreeEvent } from '@tresjs/core'
 import { OrbitControls } from '@tresjs/cientos'
 import { TresCanvas } from '@tresjs/core'
 import { MeshBasicMaterial, MeshPhongMaterial, Plane, Vector3 } from 'three'
-import type { ThreeEvent } from '@tresjs/core'
 
 const RADIUS = 20
 const COUNT = 250

+ 1 - 1
playground/vue/src/pages/events/PointerEnterLeave.vue

@@ -1,9 +1,9 @@
 <!-- eslint-disable no-console -->
 <script setup lang="ts">
+import type { ThreeEvent } from '@tresjs/core'
 import { Box, OrbitControls } from '@tresjs/cientos'
 import { TresCanvas } from '@tresjs/core'
 import { BasicShadowMap, BoxGeometry, MeshToonMaterial, NoToneMapping, SRGBColorSpace } from 'three'
-import type { ThreeEvent } from '@tresjs/core'
 import '@tresjs/leches/styles'
 
 const gl = {

+ 2 - 4
playground/vue/src/pages/events/PointerEnterLeaveOverOutComparison.vue

@@ -22,9 +22,7 @@ const tresNumLeave = ref(0)
 <template>
   <div class="container">
     <h1><code>pointer{enter,leave,over,out}</code></h1>
-    <h2>DOM vs. Tres pointer comparison</h2>
-    <p>Below, both setups have identical pointer events attached only to the gray elements.</p>
-    <p>Pointer events are counted when handled and are expected to yield the same counts for the same actions on both sides.</p>
+    <h2>Vue/DOM vs. Tres pointer comparison</h2>
 
     <div class="test-subject test-vue">
       <h2>DOM/Vue</h2>
@@ -47,7 +45,7 @@ const tresNumLeave = ref(0)
 
     <div class="test-subject">
       <h2>Tres (with <code>:blocking</code>)</h2>
-      <p>Event counts here should mirror Vue event counts</p>
+      <p>Event counts here should mirror Vue event counts for identical actions.</p>
       pointerover: {{ tresBlockingNumOver }}<br />
       pointerout: {{ tresBlockingNumOut }}<br />
       pointerenter: {{ tresBlockingNumEnter }}<br />

+ 1 - 1
playground/vue/src/pages/events/RemoveInteractivity.vue

@@ -1,8 +1,8 @@
 <script setup lang="ts">
+import type { ThreeEvent } from '@tresjs/core'
 import { OrbitControls } from '@tresjs/cientos'
 import { TresCanvas } from '@tresjs/core'
 import { ref } from 'vue'
-import type { ThreeEvent } from '@tresjs/core'
 
 function onClick(ev: ThreeEvent<MouseEvent>) {
   ev.eventObject.material.color.set('#008080')

+ 1 - 1
playground/vue/src/pages/events/StopPropagation.vue

@@ -1,8 +1,8 @@
 <!-- eslint-disable no-console -->
 <script setup lang="ts">
+import type { ThreeEvent } from '@tresjs/core'
 import { OrbitControls } from '@tresjs/cientos'
 import { TresCanvas } from '@tresjs/core'
-import type { ThreeEvent } from '@tresjs/core'
 import '@tresjs/leches/styles'
 
 const msgs0 = ref(['Mouse over cube'])

+ 1 - 1
playground/vue/src/pages/events/TargetEnabled.vue

@@ -1,7 +1,7 @@
 <script setup lang="ts">
+import type { ThreeEvent } from '@tresjs/core'
 import { OrbitControls } from '@tresjs/cientos'
 import { TresCanvas } from '@tresjs/core'
-import type { ThreeEvent } from '@tresjs/core'
 
 function onClick(ev: ThreeEvent<MouseEvent>) {
   ev.eventObject.material?.color.set('#008080')

+ 0 - 12
playground/vue/src/pages/issues/732/ComponentWithInject.vue

@@ -1,12 +0,0 @@
-<script setup lang="ts">
-import { inject } from 'vue'
-
-console.log(inject('test'))
-</script>
-
-<template>
-  <TresMesh>
-    <TresBoxGeometry :args="[1, 1, 1]" />
-    <TresMeshNormalMaterial />
-  </TresMesh>
-</template>

+ 0 - 13
playground/vue/src/pages/issues/732/TheExperience.vue

@@ -1,13 +0,0 @@
-<script setup lang="ts">
-import { TresCanvas } from '@tresjs/core'
-import { provide } from 'vue'
-import ComponentWithInject from './ComponentWithInject.vue'
-
-provide('test', '✅ Precedence is correct')
-</script>
-
-<template>
-  <TresCanvas>
-    <ComponentWithInject />
-  </TresCanvas>
-</template>

+ 25 - 25
playground/vue/src/router/routes/events.ts

@@ -4,31 +4,36 @@ export const eventsRoutes = [
     name: 'Events',
     component: () => import('../../pages/events/index.vue'),
   },
-  {
-    path: '/no-events',
-    name: 'No Events',
-    component: () => import('../../pages/events/NoEvents.vue'),
-  },
   {
     path: '/events/dynamic-objects',
     name: 'Dynamic Objects',
     component: () => import('../../pages/events/DynamicObjects.vue'),
   },
-  {
-    path: '/events/target-enabled',
-    name: 'DOM Target/Enabled',
-    component: () => import('../../pages/events/TargetEnabled.vue'),
-  },
   {
     path: '/events/pointer-enter-leave',
     name: 'Pointerenter/leave',
     component: () => import('../../pages/events/PointerEnterLeave.vue'),
   },
   {
-    path: '/events/pointer-over-out',
-    name: 'Pointerover/out comparison with Vue DOM',
+    path: '/events/pointer-enter-leave-over-out',
+    name: 'Pointer{enter,leave,over,out}',
     component: () => import('../../pages/events/PointerEnterLeaveOverOutComparison.vue'),
   },
+  {
+    path: '/events/blocking',
+    name: 'Blocking (solid objects)',
+    component: () => import('../../pages/events/Blocking.vue'),
+  },
+  {
+    path: '/events/event-modifiers',
+    name: 'Vue Event Modifiers',
+    component: () => import('../../pages/events/EventModifiers.vue'),
+  },
+  {
+    path: '/events/pointer-capture',
+    name: 'Pointer Capture',
+    component: () => import('../../pages/events/PointerCapture.vue'),
+  },
   {
     path: '/events/stop-propagation',
     name: 'StopPropagation',
@@ -55,23 +60,18 @@ export const eventsRoutes = [
     component: () => import('../../pages/events/Filter.vue'),
   },
   {
-    path: '/events/blocking',
-    name: 'Blocking (solid objects)',
-    component: () => import('../../pages/events/Blocking.vue'),
-  },
-  {
-    path: '/events/event-modifiers',
-    name: 'Vue Event Modifiers',
-    component: () => import('../../pages/events/EventModifiers.vue'),
-  },
-  {
-    path: '/events/pointer-capture',
-    name: 'Pointer Capture',
-    component: () => import('../../pages/events/PointerCapture.vue'),
+    path: '/events/target-enabled',
+    name: 'DOM Target/Enabled',
+    component: () => import('../../pages/events/TargetEnabled.vue'),
   },
   {
     path: '/events/deprecated-event-names',
     name: 'Deprecated Event Names',
     component: () => import('../../pages/events/DeprecatedEventNames.vue'),
   },
+  {
+    path: '/no-events',
+    name: 'No Events',
+    component: () => import('../../pages/events/NoEvents.vue'),
+  },
 ]

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 7757 - 2
pnpm-lock.yaml


+ 2 - 2
src/components/TresCanvas.vue

@@ -8,9 +8,10 @@ import type {
 import type { App, Ref } from 'vue'
 import type { RendererPresetsType } from '../composables/useRenderer/const'
 import type { TresCamera, TresObject, TresScene } from '../types/'
+import type { EventManagerProps } from '../utils/createEventManager/createEventManager'
 import { PerspectiveCamera, Scene } from 'three'
-import * as THREE from 'three'
 
+import * as THREE from 'three'
 import {
   createRenderer,
   defineComponent,
@@ -25,7 +26,6 @@ import {
   watch,
   watchEffect,
 } from 'vue'
-import type { EventManagerProps } from '../utils/createEventManager/createEventManager'
 import pkg from '../../package.json'
 import {
   type TresContext,

+ 0 - 1
src/composables/useTresContextProvider/index.ts

@@ -14,7 +14,6 @@ import { calculateMemoryUsage } from '../../utils/perf'
 import { useCamera } from '../useCamera'
 import { useRenderer } from '../useRenderer'
 import useSizes, { type SizesType } from '../useSizes'
-import { type TresEventManager, useTresEventManager } from '../useTresEventManager'
 import { useTresReady } from '../useTresReady'
 
 export interface InternalState {

+ 9 - 8
src/types/index.ts

@@ -75,14 +75,6 @@ export interface LocalState {
 export interface TresObject3D extends THREE.Object3D<THREE.Object3DEventMap> {
   geometry?: THREE.BufferGeometry & TresBaseObject
   material?: THREE.Material & TresBaseObject
-  // NOTE: Below are "fake" DOM Element methods that allow objects
-  // to communicate with Tres' `EventManager` about the pointer.
-  // Marked as optional to avoid interfering with existing types.
-  // TODO: Make non-optional?
-  // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/setPointerCapture
-  setPointerCapture?: (pointerId: number) => void
-  releasePointerCapture?: (pointerId: number) => void
-  hasPointerCapture?: (pointerId: number) => boolean
 }
 
 export type TresObject =
@@ -180,6 +172,15 @@ export interface EventHandlers {
   onWheel?: EventHandler<WheelEvent>
 }
 
+export interface PointerCaptureTarget {
+  // NOTE: Below are "fake" DOM Element methods that allow objects
+  // to communicate with Tres' `EventManager` about pointer capture.
+  // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/setPointerCapture
+  setPointerCapture: (pointerId: number) => void
+  releasePointerCapture: (pointerId: number) => void
+  hasPointerCapture: (pointerId: number) => boolean
+}
+
 interface MathRepresentation {
   set(...args: number[] | [THREE.ColorRepresentation]): any
 }

+ 2 - 2
src/utils/createEventManager/createEventManager.test.ts

@@ -1,11 +1,11 @@
+import type { TresContext } from '../../composables/useTresContextProvider'
+import type { CreateEventManagerProps } from './createEventManager'
 import { Scene } from 'three'
 import { beforeEach, describe, expect, it, vi } from 'vitest'
 import { shallowRef } from 'vue'
 import { nodeOps as getNodeOps } from './../../core/nodeOps'
 import { createEventManager } from './createEventManager'
 import { eventsNoop } from './eventsNoop'
-import type { TresContext } from '../../composables/useTresContextProvider'
-import type { CreateEventManagerProps } from './createEventManager'
 
 let t = mockTresInstance()
 let context = t.context

+ 3 - 3
src/utils/createEventManager/eventsRaycast.test.ts

@@ -1,10 +1,10 @@
+import type { TresContext } from 'src/composables/useTresContextProvider'
+import type { ThreeEvent, TresObject } from 'src/types'
+import type { Object3D } from 'three'
 import { BoxGeometry, MeshBasicMaterial, Scene, Vector3 } from 'three'
 import * as THREE from 'three'
 import { describe, expect, it, vi } from 'vitest'
 import { shallowRef } from 'vue'
-import type { TresContext } from 'src/composables/useTresContextProvider'
-import type { ThreeEvent, TresObject } from 'src/types'
-import type { Object3D } from 'three'
 import catalogue from '../../core/catalogue'
 import { nodeOps as getNodeOps } from '../../core/nodeOps'
 import { DOM_TO_THREE, type DomEventName, type ThreeEventName } from './const'

+ 18 - 4
src/utils/createEventManager/eventsRaycast.ts

@@ -1,12 +1,12 @@
-import { Raycaster, Vector2, Vector3 } from 'three'
 import type { Object3D, Intersection as ThreeIntersection } from 'three'
+import type { EventHandlers, IntersectionEvent, PointerCaptureTarget, Properties, ThreeEvent, TresCamera, TresInstance, TresObject } from '../../types'
+import type { CreateEventManagerProps } from './createEventManager'
+import { Raycaster, Vector2, Vector3 } from 'three'
 import { prepareTresInstance } from '..'
 import { isProd, type TresContext, useLogger } from '../../composables'
 import * as is from '../is'
 import { DOM_EVENT_NAMES, DOM_TO_PASSIVE, DOM_TO_THREE, type DomEventName, type DomEventTarget, POINTER_EVENT_NAMES, THREE_EVENT_NAMES } from './const'
 import { deprecatedEventsToNewEvents } from './deprecatedEvents'
-import type { EventHandlers, IntersectionEvent, Properties, ThreeEvent, TresCamera, TresInstance, TresObject } from '../../types'
-import type { CreateEventManagerProps } from './createEventManager'
 
 // NOTE:
 // This file consists of type definitions and functions
@@ -20,7 +20,7 @@ import type { CreateEventManagerProps } from './createEventManager'
 type RaycastEvent = MouseEvent | PointerEvent | WheelEvent
 type RaycastEventTarget = DomEventTarget
 type ThreeEventStub<DomEvent> = Omit<ThreeEvent<DomEvent>, 'eventObject' | 'object' | 'currentTarget' | 'target' | 'distance' | 'point'> & Partial<IntersectionEvent<DomEvent>>
-type Object3DWithEvents = Object3D & EventHandlers
+type Object3DWithEvents = Object3D & EventHandlers & PointerCaptureTarget
 
 function getInitialEvent() {
   // NOTE: Unit tests will without this check
@@ -331,6 +331,20 @@ function remove(instance: TresObject, config: Config) {
   // in `intersections`.
   handleIntersections(getLastEvent(config), intersections, config)
 
+  for (const instance of instanceAndDescendants) {
+    // NOTE: Remove all methods from the object.
+    // This is required for primitive objects, so that they
+    // don't keep events from a previous `<primitive />`
+    for (const threeEventName of THREE_EVENT_NAMES) {
+      delete (instance as Object3DWithEvents)[threeEventName]
+    }
+
+    // NOTE: Remove `PointerCaptureTarget` methods.
+    if ('setPointerCapture' in instance) { delete instance.setPointerCapture }
+    if ('releasePointerCapture' in instance) { delete instance.releasePointerCapture }
+    if ('hasPointerCapture' in instance) { delete instance.hasPointerCapture }
+  }
+
   // NOTE: Remove the remaining traces of the object and descendants
   config.priorHits.delete(instance as Object3D)
 

+ 1 - 1
src/utils/createEventManager/useEventsOptions.test.ts

@@ -1,6 +1,6 @@
+import type { TresContext } from 'src/composables/useTresContextProvider'
 import { describe, expect, it, vi } from 'vitest'
 import { computed, ref, shallowRef } from 'vue'
-import type { TresContext } from 'src/composables/useTresContextProvider'
 import { raycastProps } from '.'
 import { createEventManager } from './createEventManager'
 import { eventsRaycast } from './eventsRaycast'

+ 1 - 1
src/utils/createEventManager/useEventsOptions.ts

@@ -1,7 +1,7 @@
-import { toValue, watchEffect } from 'vue'
 import type { TresContext } from 'src/composables/useTresContextProvider'
 import type { EmitEventFn } from 'src/types'
 import type { MaybeRefOrGetter } from 'vue'
+import { toValue, watchEffect } from 'vue'
 import * as is from '../is'
 import { createEventManager, type EventManager, type EventManagerProps } from './createEventManager'
 import { eventsNoop } from './eventsNoop'

Vissa filer visades inte eftersom för många filer har ändrats