Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(events)!: pointerevents manager and state #529

Merged
merged 19 commits into from
Apr 22, 2024

Conversation

garrlker
Copy link
Collaborator

@garrlker garrlker commented Jan 31, 2024

Events

  • onClick
  • onContextMenu (rightClick)
  • onDoubleClick
  • onWheel
  • onPointerDown
  • onPointerUp
  • onPointerLeave
  • onPointerMove
  • onPointerMissed

Event Details

  • ...DomEvent
  • ...Intersection
  • intersections: Intersection[]
  • object: Object3D
  • eventObject: Object3D
  • unprojectedPoint: Vector3
    • halfway done, need to clean up some math
  • ray: Ray
  • camera: Camera
  • sourceEvent: DomEvent
  • delta: number

Features

  • Event support for Primitives
  • Event Bubbling and Propagation
    • Raycast Propogation
    • Hierarchy Propogation
  • Events are emitted off of TresCanvas
  • Forced Raycasts
  • Duplicate Checks (no event handler called twice)

Chores

  • Getting up to date with the v4 branch
  • Documentation
  • Unit tests

Copy link

netlify bot commented Jan 31, 2024

Deploy Preview for tresjs-docs ready!

Name Link
🔨 Latest commit 580029d
🔍 Latest deploy log https://app.netlify.com/sites/tresjs-docs/deploys/65bc7351e16912000880f427
😎 Deploy Preview https://deploy-preview-529--tresjs-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@garrlker garrlker added the v4 label Jan 31, 2024
@garrlker garrlker self-assigned this Jan 31, 2024
@garrlker garrlker linked an issue Jan 31, 2024 that may be closed by this pull request
4 tasks
@garrlker garrlker linked an issue Jan 31, 2024 that may be closed by this pull request
5 tasks
Copy link
Contributor

@andretchen0 andretchen0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@garrlker

Looks like events are coming along! Great!

I'm not overly familiar with Tres internals, so this review is taking me a while. I'll have another look tomorrow, but I'll go ahead and submit what I've got so you can take a look when it's convenient.

playground/src/pages/raycaster/Propogation.vue Outdated Show resolved Hide resolved
@@ -43,10 +48,10 @@ export const useRaycaster = (

raycaster.value.setFromCamera(new Vector2(x, y), camera.value)

return raycaster.value.intersectObjects(objects.value, false)
return raycaster.value.intersectObjects(objects.value, true)
Copy link
Contributor

@andretchen0 andretchen0 Jan 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, this will test against all children of the scene and recurse down through all children.

If that's right, is that worth optimizing in this PR? Or ever?


For context, it looks like R3F does some optimization to keep some eventless objects from being tested for intersections.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, this currently tests against all children of the scene recursively.

I'm not against optimizing the events in this PR, but overall our CPU usage is somehow lower on my system than the main

The reason we need to include the entire scene in the intersectObjects() is because of the event propagation.
Children that do not have events are still the starting point for parents that do.

There are a few optimizations I've thought of since starting this

  • Only include node's with events and their direct descendants in the hit test. Being a custom renderer gives us this flexibility to do this on scene insertion. The original solution used a similar idea to only include node's having events and blocking-objects
  • Add the .self event modifier so a node will only listen to their own events. That let's us exclude any children of that node without events from the hit test as well
  • Add a no-events attribute that remove that object and possibly it's children from the hit test as well.
  • I think we're calling intersectObjects() way more than needed via the getIntersects() call. Realistically that should only need to be called on pointer-move, than any other event just grab the intersect results from there. Though I'm still not sure that are actually doing a hit test on every single event. Need to debug it more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!

It sounds like there's plenty to think about and discuss with the others. I don't want to keep these events out of Tres. So maybe we open another PR when this PR is merged.

Only include node's with events and their direct descendants in the hit test. Being a custom renderer gives us this flexibility to do this on scene insertion.

Yeah, something like that is what I had in mind as well. We'd have to watch event updates as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After talking with @alvarosabu and @Tinoooo it looks like we have enough time before the V4 release for me to take a stab at optimizing this some more

I was able to confirm intersectObjects is being called multiple times per frame (and even per event).
I've simplified it's usage. I'm seeing about half the cpu % in my test scenes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could add a flag to the localstate __tres of the instances marking if we expect it to have events to optimize the traversing of the scene. See recently merged #522

Meshes and groups:

instance.__tres.events = true

Dunno, materials and geometries:

instance.__tres.events = false

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh good idea. The localstate __tres will be very helpful

Thank you for calling it out!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the EventManager onto Tres's Context

Let me know if that was what you had in mind

	new file:   playground/src/pages/raycaster/Propogation.vue
	  * Started work on interactive Event Propogation playground example
	modified:   src/components/TresCanvas.vue
	  * Import and use `useEventStore`
	  * defineEmits for all expected pointer events so we may emit propogated events off of the canvasa
	modified:   src/composables/index.ts
	new file:   src/composables/useEventStore/index.ts
	  * Started work on an event store. I'm not sure this counts as a store just yet
	  * Wired up majority of pointer events
	  * Added event propogation
	  * Does not require using userData scene props or nodeOps for registering objects to scene
	modified:   src/composables/useRaycaster/index.ts
	  * Added new event listeners to power newly supported pointer events. We now check whole scene/children when calling intersectObjects.
	  * Created new EventHooks for new events
	  * Added `forceUpdate` function that allows for pointer-move events to work without mouth movement (good for when camera is moving but mouse is not)

	modified:   src/core/nodeOps.ts
	  * Added supported events to array so they don't get received as props
	  * (temporarily) unhook current pointer event solution to iterate on useEventStore
	modified:   src/utils/index.ts
	  * Added Camel-to-kebab case util
let parent = object.parent
while(parent !== null && !stopPropagating) {
executeEventListeners(parent[eventName], intersection, event)
parent = parent.parent
Copy link
Contributor

@andretchen0 andretchen0 Feb 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One click should probably cause no more than one call to a given click handler.

For a given click, etc., a particular click handler shouldn't be called more than once, it seems to me. I think the way it works currently will be confusing in "real" world scenarios.

Currently

This shows the result of a single click with the current bubbling setup:

Screenshot 2024-02-02 at 02 42 39

The console shows that the box at the top of the pyramid gets its click handler called 4 times.

"Realer" world

The above doesn't seem wrong to me, but I was trying to think about it as a Tres user and I think it breaks down in "realer" world cases.

Here's a simple example: buy a bicycle.

<Bicycle @click="buy">
  <Frame>
    <Wheel />
    <Wheel />
  </Frame>
</Bicycle>

Positioning the canvas at a certain angle, you could click both wheels and the frame, and you'll buy 3 bicycles instead of 1.

R3F removes duplicates

I checked out R3F. They remove duplicates.

Here's a StackBlitz with a simple setup like your playground.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch!

I will be sure to add duplicate checks somehow

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest changes include duplicate checks and it's working pretty well

Thanks for catching that!

@garrlker garrlker force-pushed the 515-pointer-eventmanager-state branch from 977c470 to 580029d Compare February 2, 2024 04:45
@garrlker garrlker changed the base branch from main to v4 February 2, 2024 04:51
… to work while multiple TresCanvas' are being used
…moving intersects into a ref that is updated on pointer-move
@alvarosabu
Copy link
Member

@garrlker Regarding the store, I would suggest adding it to the TresContext directly instead of creating a separate store, that way is available on all instances via localState

@alvarosabu alvarosabu mentioned this pull request Feb 7, 2024
Closed
13 tasks
@alvarosabu alvarosabu mentioned this pull request Feb 20, 2024
5 tasks
@andretchen0
Copy link
Contributor

andretchen0 commented Mar 9, 2024

@alvarosabu

Regarding the store

As an aside, is there any interest in using something like Pinia for the store/context? Probably after v4?

Context

R3F uses their own reactive Pinia-like store (zustand) for similar purposes.

@andretchen0
Copy link
Contributor

andretchen0 commented Mar 9, 2024

Meta

@garrlker Regarding the store, I would suggest adding it to the TresContext directly instead of creating a separate store, that way is available on all instances via localState

@alvarosabu , that answers this question from @garrlker 's source, right?

// QUESTION: Maybe I should move the useEventStore logic into usePointerEventHandler? I seem to have created a similar pattern
// usePointerEventHandler({ scene: scene.value, contextParts: context.value })

playground/src/pages/raycaster/Propagation.vue Outdated Show resolved Hide resolved
src/composables/useEventStore/index.ts Outdated Show resolved Hide resolved
@andretchen0
Copy link
Contributor

wdyt @garrlker , @andretchen0 do you see any other property that could be important for the end user?

Here's the R3F approach in a nutshell:

Events contain the browser event as well as the three.js event data (object, point, distance, etc).

https://docs.pmnd.rs/react-three-fiber/api/events

That seems like a good approach to me.

@garrlker
Copy link
Collaborator Author

Great catch!

ngl I've never liked how verbose R3F events can be, mostly because I like to log the whole events in my console when debugging. But that's more personal preference 😅

I've started working on adding more properties to the event details object.

Also, I've added my personal todo list to the PR so it's easier to see what's been implemented. If you think anythings missing feel free to add more.

@alvarosabu
Copy link
Member

alvarosabu commented Mar 20, 2024

Hey @garrlker I just updated the branch to latest v4, everything smooth,I'm also gonna take over docs

  • Getting up to date with the v4 branch
  • Documentation

Regarding:

I'm going to push the perf optimization work into a new issue for later so it won't hold this up. The perf is still better than before so I don't think it's high priority.

We can iterate in a follow up task after v4

@alvarosabu
Copy link
Member

@garrlker Doing testing of each event I realise that the pointer-missed returns an empty array

Screenshot 2024-03-22 at 10 33 48

I checked it on R3F and you get an event object similar to the other events with the type of event that you missed. Could we have a similar behavior?

@andretchen0
Copy link
Contributor

Tested with primitives. Works! Great! 👍

@alvarosabu
Copy link
Member

@andretchen0 that was my next test, thanks for taking care of it 💚

@andretchen0
Copy link
Contributor

andretchen0 commented Mar 22, 2024

@andretchen0 that was my next test, thanks for taking care of it 💚

No problem. 😉

Just to be clear, I tested events added on the <primitive />, not added to the THREE.Mesh in <script setup>, for example.

Fwiw, here's the Vue file I set up if that's handy for anyone for double-checking primitives or my write-up.
<script setup lang="ts">
import type { ThreeEvent } from '@tresjs/core'
import { TresCanvas } from '@tresjs/core'
import { BasicShadowMap, SRGBColorSpace, NoToneMapping, BoxGeometry, MeshToonMaterial, Mesh, MathUtils } from 'three'
import { TresLeches, useControls } from '@tresjs/leches'
import { OrbitControls } from '@tresjs/cientos'
import '@tresjs/leches/styles'

const gl = {
  clearColor: '#202020',
  shadows: true,
  alpha: false,
  shadowMapType: BasicShadowMap,
  outputColorSpace: SRGBColorSpace,
  toneMapping: NoToneMapping,
}

const { stopPropagation } = useControls({
  stopPropagation: false,
})

function onClick(ev: ThreeEvent<MouseEvent>) {
  console.log('click', ev)
  if (stopPropagation.value) ev.stopPropagation()
  ev.object.material.color.set('#008080')
}

function onDoubleClick(ev: ThreeEvent<MouseEvent>) {
  console.log('double-click', ev)
  if (stopPropagation.value) ev.stopPropagation()
  ev.object.material.color.set('#FFD700')
}

function onPointerEnter(ev: ThreeEvent<MouseEvent>) {
  if (stopPropagation.value) ev.stopPropagation()
  ev.object.material.color.set('#CCFF03')
}

function onPointerLeave(ev: ThreeEvent<MouseEvent>) {
  if (stopPropagation.value) ev.stopPropagation()
  /*  ev.object.material.color.set('#efefef') */
}

function onPointerMove(ev: ThreeEvent<MouseEvent>) {
  if (stopPropagation.value) ev.stopPropagation()
}

function onContextMenu(ev: ThreeEvent<MouseEvent>) {
  console.log('context-menu', ev)
  if (stopPropagation.value) ev.stopPropagation()
  ev.object.material.color.set('#FF4500')
}

function onPointerMissed(ev: ThreeEvent<MouseEvent>) {
  console.log('pointer-missed', ev)
  if (stopPropagation.value) ev.stopPropagation()
}

const SIDE = 3
const COUNT = SIDE * SIDE * SIDE
const SPREAD = 6
const [LO, HI] = [-SPREAD * 0.5, SPREAD * 0.5]
const lerp = MathUtils.lerp

const geo = new BoxGeometry()
const objs = new Array(COUNT).fill(0).map((_, i) => {
  const mesh = new Mesh(geo, new MeshToonMaterial({ color: '#efefef' }))
  mesh.position.set(
    lerp(LO, HI, (i % SIDE) / (SIDE - 1)), 
    lerp(LO, HI, (Math.floor(i / SIDE) % SIDE) / (SIDE - 1)),
    lerp(LO, HI, Math.floor(i / (SIDE * SIDE)) / (SIDE - 1)),
  )
  return mesh
})
</script>

<template>
  <TresLeches />
  <TresCanvas
    window-size
    v-bind="gl"
  >
    <TresPerspectiveCamera :position="[10, 10, 10]" />
    <OrbitControls />
    <primitive
      v-for="obj, i in objs"
      :key="i"
      :object="obj"
      @click="onClick"
      @double-click="onDoubleClick"
      @pointer-enter="onPointerEnter"
      @pointer-leave="onPointerLeave"
      @pointer-move="onPointerMove"
      @context-menu="onContextMenu"
      @pointer-missed="onPointerMissed"
    />
    <TresDirectionalLight :intensity="1" />
    <TresAmbientLight :intensity="1" />
  </TresCanvas>
</template>

@alvarosabu alvarosabu added feature p3-significant High-priority enhancement (priority) breaking-change and removed enhancement labels Mar 28, 2024
…aterial color. Add ability to force event system updates even when mouse hasn't moved. Enhance pointer-enter/leave events. Update types

  Box.vue
    * Added pointer-missed handler
    * set the materials flash color using the object coming off of the event instead of a ref
  UseRaycaster
    * Flesh out event details to include
      * all mouse event properties
      * intersections
      * tres camera
      * camera raycaster
      * source event
      * mouse position delta
      * stopPropagating stub
      * and unprojectedPoint (this needs work, cant get the math to work)
  UseTresContextProvider
    * Add TresEventManager type to TresContext
  useTresEventManager
    * Add forceUpdate method to allow apps to force an event system update even when the mouse hasnt moved
    * Add pointerMissed event
    * Properly implement pointer-enter/pointer-leave events
      * Before now, pointer-enter | leave were only called on first object in intersection, now we execute the events for all entered/left objects
    * Use stopPropagating property included on event object
@garrlker
Copy link
Collaborator Author

Hey everyone, I've pushed up my latest. This includes a few fixes from the previous comments and some other features

Most notably it includes a much more detailed events object for all events, including the pointer-missed event.

Besides that it also includes the ability to force a raycast(events fire even when mouse isn't moving) and I fixed a major oversight I came across in the pointer-enter/leave events

This should be good for more testing

@alvarosabu alvarosabu marked this pull request as ready for review April 16, 2024 15:07
Copy link
Member

@alvarosabu alvarosabu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing work @garrlker 👏🏻 we can finally merge it.

@alvarosabu alvarosabu merged commit b536ab1 into v4 Apr 22, 2024
3 checks passed
@alvarosabu alvarosabu deleted the 515-pointer-eventmanager-state branch April 22, 2024 17:38
alvarosabu added a commit that referenced this pull request May 30, 2024
* feat: 474 vue chrome devtools plugin (#479)

* feat: vue chrome devtools

* feat: editable scenes from devtools

* chore(lint): fix lint errors

* feat: highlight material

* chore(lint): fix

* chore: release v4.0.0-next.0

* feat: update to three `v160` and vue `v3.4` (#488)

* fix(types): added `Object3DEventMap` to `Object3D` generics for point event handling (#491)

* feat: 140 on demand rendering (#497)

* feat: conditional rendering

* chore: remove subscribe system

* feat: on-demand automatic invalidation with prop changes

* feat: invalidate once first when is `renderMode !== 'always'`

* docs: performance page, on-demand rendering

* chore: fix windowsize issue

* chore(lint): fix maximum line length issues

* feat: invalidate on-demand on window resize

* feat: add advance method for manual mode

* feat: fix manual first render with advance

* docs: performance manual mode

* docs: add badge with version

* chore: correct typos and PR suggestions

* chore: tell dont ask fix

* feat: render state instead of internal

* feat: remove default camera warning (#499)

* feat: remove annoying defautl camera warning

* chore: remove logWarning

* feat: 492 set tone mapping default to acesfilmictonemapping (#498)

* feat: set ACESFilmicToneMapping as default toneMapping

* chore: usage of nullish coealescing operator instead of ternaries

* feat: 516 localstate for custom renderer node instances instead of userdata (#522)

* feat: conditional rendering

* chore: remove subscribe system

* feat: on-demand automatic invalidation with prop changes

* feat: invalidate once first when is `renderMode !== 'always'`

* docs: performance page, on-demand rendering

* chore: fix windowsize issue

* chore(lint): fix maximum line length issues

* feat: invalidate on-demand on window resize

* feat: add advance method for manual mode

* feat: fix manual first render with advance

* docs: performance manual mode

* docs: add badge with version

* chore: correct typos and PR suggestions

* chore: tell dont ask fix

* feat: render state instead of internal

* feat: add __tres local state to nodeOps instances

* feat: add context to root on instances localstate

* feat: camera registration ops from node local state ctx

* feat: event handling registration from localState of nodes

* feature: disposable flag on node localstate

* feat: remove userData from types

* chore: remove unused import

* fix(test): fake localstate `.__tres` on tests

* fix(types): fix nodeOps instances localstate type

* fix: camera aspect

* Update orthographic camera aspect when screen size updates
* Give user a "manual" flag to keep Tres from updating camera

* feat: 503 conditional rendering of primitives (#514)

* feat(nodeOps): switch instance logic for reactive `object` prop

* chore: playground primitives with models

* chore: fix linter

* chore: fix tests and linters, primitive object is now reactive

* chore: refactor instance swaping logic to overwrite set and copy properties

* chore: tests

* chore: remove console.log

* chore: remove unused import watch

* feat: add primitive conditional to patch object prop

* fix: `nodeOps` is now a function (#579)

* fix: `nodeOps` is now a function

* chore(test): updated tests for `nodeOps`

* chore: next package json version

* chore: release v4.0.0-next.1

* fix: refactor nodeOps to return methods at the end of the function (#602)

* fix: refactor nodeOps to return methods at the end of the function

* chore: fix lint

* chore: internal playground organisation (#601)

* chore: new internal playground org and testing pages

* chore: fix lint

* chore: better styling of playground landing page

* chore: lint

* chore: deps update

* chore: internal primitive model test playground

* chore: fix lint

* chore: release v4.0.0-next.2

* chore: misc routes

* fix: do not change pierced props case (#608)

* chore: lint fix

* chore: problem with package version

* chore: fix lint

* chore: rebuild pnpm-lock

* test(nodeOps): clean up tests

* test(nodeOps): organize tests

* test: add coverage plugin

* test: add coverage to package.json script

* test(nodeOps): improve test coverage

* feat: devtools renderer improvements (#614)

* feat: renderer programs when selecting scene on devtools

* feat: renderer.info

* chore: fix lint

* docs: devtools update

* chore: fix lint issues

* feat(events)!: pointerevents manager and state (#529)

* new file:   playground/src/components/Box.vue
	new file:   playground/src/pages/raycaster/Propogation.vue
	  * Started work on interactive Event Propogation playground example
	modified:   src/components/TresCanvas.vue
	  * Import and use `useEventStore`
	  * defineEmits for all expected pointer events so we may emit propogated events off of the canvasa
	modified:   src/composables/index.ts
	new file:   src/composables/useEventStore/index.ts
	  * Started work on an event store. I'm not sure this counts as a store just yet
	  * Wired up majority of pointer events
	  * Added event propogation
	  * Does not require using userData scene props or nodeOps for registering objects to scene
	modified:   src/composables/useRaycaster/index.ts
	  * Added new event listeners to power newly supported pointer events. We now check whole scene/children when calling intersectObjects.
	  * Created new EventHooks for new events
	  * Added `forceUpdate` function that allows for pointer-move events to work without mouth movement (good for when camera is moving but mouse is not)

	modified:   src/core/nodeOps.ts
	  * Added supported events to array so they don't get received as props
	  * (temporarily) unhook current pointer event solution to iterate on useEventStore
	modified:   src/utils/index.ts
	  * Added Camel-to-kebab case util

* Support multiple event listeners, add support for .stop event modifier

* Set stopProgation variable to false by default, whoops

* fix typo

* fix: remove `createGlobalState` from `useEventStore`, allowing events to work while multiple TresCanvas' are being used

* fix(perf): remove extraneous intersectObjects/getIntersects calls by moving intersects into a ref that is updated on pointer-move

* chore(lint): fix lint issues

* feat: enhance events manager to include duplicates checking, pointer-missed support, and forced updating

Per file changelog:
	modified:   playground/src/components/Box.vue
	  * Added a pointer-missed handler for testing
	modified:   playground/src/pages/TheBasic.vue
	  * uses forceUpdate from EventManager to fire events even when the mouse hasn't moved
	modified:   playground/src/pages/raycaster/Propagation.vue
	  * Didn't mean to undo the lint changes, adds a pointer-missed event on the canvas 		for extra testing
	modified:   src/components/TresCanvas.vue
	  * Adds `pointer-missed` as possible event for canvas emits
	modified:   src/composables/index.ts
	  * Update export
	deleted:    src/composables/useEventStore/index.ts
	  * Rename `useEventStore` to `useTresEventManager`
	modified:   src/composables/useRaycaster/index.ts
	  * Check for empty intersects on hit test, wire up pointerMissed events eventHook
	  * Fix forceUpdate to call onPointerMove instead of triggering an EventHook
	modified:   src/composables/useTresContextProvider/index.ts
	  * Add TresEventManager type
	new file:   src/composables/useTresEventManager/index.ts
	  * add onPointerMissed
	  * create (de)registerPointerMissedObj methods so we can track objects in the scene listening to this event
	  * Note: These are passed to nodeOps via TresContext
	  * Implement duplicates checking for eventPropogation
	modified:   src/core/nodeOps.ts
	  * register/deregister pointerMissed objects

* chore: lint

* docs: new event docs

* chore: fix lint

* feat: enhance event object details and use in Box example to change material color. Add ability to force event system updates even when mouse hasn't moved. Enhance pointer-enter/leave events. Update types

  Box.vue
    * Added pointer-missed handler
    * set the materials flash color using the object coming off of the event instead of a ref
  UseRaycaster
    * Flesh out event details to include
      * all mouse event properties
      * intersections
      * tres camera
      * camera raycaster
      * source event
      * mouse position delta
      * stopPropagating stub
      * and unprojectedPoint (this needs work, cant get the math to work)
  UseTresContextProvider
    * Add TresEventManager type to TresContext
  useTresEventManager
    * Add forceUpdate method to allow apps to force an event system update even when the mouse hasnt moved
    * Add pointerMissed event
    * Properly implement pointer-enter/pointer-leave events
      * Before now, pointer-enter | leave were only called on first object in intersection, now we execute the events for all entered/left objects
    * Use stopPropagating property included on event object

* chore: lint

* chore: fix lint issues

---------

Co-authored-by: alvarosabu <[email protected]>

* feat: 499 better memory management (#606)

* chore: memory management playground

* feat: recursively free cpu and gpu memory allocation on remove

* chore: clumsy attempt to dispose on unmount

* chore: lint fix

* feat: remove scene root on disposal

* chore: fix lint

* docs: added disposal guide on `performance` docs

* chore: fix lint

* chore: type issues (#663)

* fix: fix some internal types

* chore: fix linters

* fix: typescript issues on event manager

* chore: release v4.0.0-rc.0

* fix: make on* callbacks settable (#672)

* fix: make on- callbacks settable

* test: test setting not calling

* feat: 633 use loop  (#673)

* feat: createRenderLoop unique to context

* feat: onLoop returns current state

* feat: ensuring callback excecution with index order

* feat: take control of render loop logic

* docs: updated composable docs

* feat: change error to deprecation warning towards v5

* chore: add link to new composable docs on deprecation warning

* chore: remove depcreation warning of existing useRenderLoop

* feat: `useFrame` and `useRender` instead of `onLoop`

* chore: fix lint

* feat: applied useFrame to directives

* chore: fix lint

* feat: `useUpdate` instead of `useFrame` and useRender pausing.

* chore: testing fbo

* feat: reserve index 1 for late-updates

* chore: fix lint

* feat: useLoop composable for the win

* chore: change onLoop name for register

* chore: unit tests for loop

* chore: change order for registration to make index optional

* chore: fix lint

* feat: pauseRender and resumeRender

* docs: useLoop guide

* docs: updated basic animations recipe to `useLoop`

* docs: correct pause render methods on docs

* Update docs/api/composables.md

Co-authored-by: Tino Koch <[email protected]>

* Update docs/api/composables.md

Co-authored-by: Tino Koch <[email protected]>

* Update docs/api/composables.md

Co-authored-by: Tino Koch <[email protected]>

* Update docs/api/composables.md

Co-authored-by: Tino Koch <[email protected]>

* Update docs/api/composables.md

Co-authored-by: Tino Koch <[email protected]>

* Update docs/api/composables.md

Co-authored-by: Tino Koch <[email protected]>

* Update docs/api/composables.md

Co-authored-by: Tino Koch <[email protected]>

* chore: refactor subscribers to `priorityEventHooks`

* Update docs/api/composables.md

Co-authored-by: Tino Koch <[email protected]>

* feat: just return `off` on the loop registration methods

* docs: update docs to add `off` unregister callback method

* feat: remove `v-rotate`

* docs: added context warning for `v-always-look-at`

* Update docs/api/composables.md

Co-authored-by: Tino Koch <[email protected]>

* Update docs/api/composables.md

Co-authored-by: Tino Koch <[email protected]>

* chore: remove leftover of isntance.provide

* chore: remove subscribers from context

* chore: abstract `wrapCallback`  and move render loop register to `useRender`

* chore: fix lint

* chore: testing off

* Revert "chore: abstract `wrapCallback`  and move render loop register to `useRender`"

This reverts commit 24cec65.

* chore: return bound `off` method and use createPriorityEvent for render with defaultFn fallback

* feat: deprecate and remove `vAlwaysLookAt` and `vRotate`

BREAKING_CHANGE: Directives `vAlwaysLookAt` and `vRotate` due incompatibility with new `useLoop` and the refactor of the render loop logic.

* feat: set context to loop to avoid wrapping the callbacks

* feat: dispose render hook before taking over

---------

Co-authored-by: Tino Koch <[email protected]>

* chore(playground): adding missing import and removing the directives that were deprecated

* chore(playground): use new composable on animations

* fix(utils): reorder object disposal to avoid issue with Helper `dispose` methods (#683)

* chore: updated deps

* chore: release v4.0.0-rc.1

* fix: manual rendering blank (#685)

* fix: increate time to advance on manual mode

* chore: correct playground

* fix: 686 useloop callback state missing controls (#687)

* fix(loop): take plain snapshots of ctx

* fix: types for useloop

* chore: lint

* docs: add RectAreaLightHelper to vLightHelper docs

* chore(deps): update deps 24-0-2024

* chore: release v4.0.0-rc.2

* fix: start loop if user calls useRenderLoop (#695)

* docs: change motivation

* chore(deps): last update before release

---------

Co-authored-by: Peter <[email protected]>
Co-authored-by: Garrett Walker <[email protected]>
Co-authored-by: Tino Koch <[email protected]>
Co-authored-by: Jaime Torrealba <[email protected]>
Co-authored-by: Jaime A Torrealba C <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-change feature p3-significant High-priority enhancement (priority) v4
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

<TresSprite @click="() => console.log('')" /> throws error on pointer interaction Pointer EventManager state
4 participants