-
-
Notifications
You must be signed in to change notification settings - Fork 97
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
Conversation
✅ Deploy Preview for tresjs-docs ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
@@ -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) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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](https://private-user-images.githubusercontent.com/20469369/301699743-5476e9d2-50eb-499e-9939-988e7a3f3965.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ4Njc4NjUsIm5iZiI6MTcyNDg2NzU2NSwicGF0aCI6Ii8yMDQ2OTM2OS8zMDE2OTk3NDMtNTQ3NmU5ZDItNTBlYi00OTllLTk5MzktOTg4ZTdhM2YzOTY1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODI4VDE3NTI0NVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTdiNWVmMmJkOTk1NjgxYzEzYjYyOTQwN2U0N2Y4MjNjZjdhNTljYTI0MTU1ODMxYjc3ZTk3ODBiNzJiZTFlMzkmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.gul2YmmiddtQC4uvS1mlxnU2u0dfKqX70tDJvT3NvGU)
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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!
977c470
to
580029d
Compare
… to work while multiple TresCanvas' are being used
…moving intersects into a ref that is updated on pointer-move
@garrlker Regarding the store, I would suggest adding it to the |
As an aside, is there any interest in using something like Pinia for the store/ ContextR3F uses their own reactive Pinia-like store (zustand) for similar purposes. |
Meta
@alvarosabu , that answers this question from @garrlker 's source, right?
|
Here's the R3F approach in a nutshell:
https://docs.pmnd.rs/react-three-fiber/api/events That seems like a good approach to me. |
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. |
Hey @garrlker I just updated the branch to latest v4, everything smooth,I'm also gonna take over docs
Regarding:
We can iterate in a follow up task after |
@garrlker Doing testing of each event I realise that the 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? |
Tested with primitives. Works! Great! 👍 |
@andretchen0 that was my next test, thanks for taking care of it 💚 |
No problem. 😉 Just to be clear, I tested events added on the 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>
|
…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
…es into 515-pointer-eventmanager-state
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 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 |
There was a problem hiding this 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.
* 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 <alvaro.saburido@gmail.com> * 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 <17991193+Tinoooo@users.noreply.github.com> * Update docs/api/composables.md Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com> * Update docs/api/composables.md Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com> * Update docs/api/composables.md Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com> * Update docs/api/composables.md Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com> * Update docs/api/composables.md Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com> * Update docs/api/composables.md Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com> * chore: refactor subscribers to `priorityEventHooks` * Update docs/api/composables.md Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com> * 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 <17991193+Tinoooo@users.noreply.github.com> * Update docs/api/composables.md Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com> * 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 <17991193+Tinoooo@users.noreply.github.com> * 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 <petermoldovia@yahoo.ca> Co-authored-by: Garrett Walker <garbwalk@gmail.com> Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com> Co-authored-by: Jaime Torrealba <solucionesinformaticasjtc@gmail.com> Co-authored-by: Jaime A Torrealba C <63722373+JaimeTorrealba@users.noreply.github.com>
Events
Event Details
Features
TresCanvas
Chores