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: 516 localstate for custom renderer node instances instead of userdata #522

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7ad2e31
feat: conditional rendering
alvarosabu Jan 5, 2024
5d72244
chore: remove subscribe system
alvarosabu Jan 5, 2024
b2cfa4a
feat: on-demand automatic invalidation with prop changes
alvarosabu Jan 5, 2024
97921a5
feat: invalidate once first when is `renderMode !== 'always'`
alvarosabu Jan 5, 2024
d5efdf4
docs: performance page, on-demand rendering
alvarosabu Jan 5, 2024
a0d5344
chore: fix windowsize issue
alvarosabu Jan 6, 2024
ecec472
chore(lint): fix maximum line length issues
alvarosabu Jan 6, 2024
fccc50d
feat: invalidate on-demand on window resize
alvarosabu Jan 6, 2024
82e9264
feat: add advance method for manual mode
alvarosabu Jan 7, 2024
2ae5624
feat: fix manual first render with advance
alvarosabu Jan 7, 2024
42cefab
docs: performance manual mode
alvarosabu Jan 7, 2024
331ee15
docs: add badge with version
alvarosabu Jan 7, 2024
628a38f
Merge branch 'v4' into feature/140-on-demand-rendering
alvarosabu Jan 19, 2024
f196a38
chore: correct typos and PR suggestions
alvarosabu Jan 22, 2024
6426856
chore: tell dont ask fix
alvarosabu Jan 22, 2024
8b648a7
feat: render state instead of internal
alvarosabu Jan 22, 2024
1f9ce8d
feat: add __tres local state to nodeOps instances
alvarosabu Jan 22, 2024
9228092
feat: add context to root on instances localstate
alvarosabu Jan 23, 2024
f9897be
fix: render mode type
alvarosabu Jan 23, 2024
5bd10da
feat: camera registration ops from node local state ctx
alvarosabu Jan 23, 2024
a839320
feat: event handling registration from localState of nodes
alvarosabu Jan 23, 2024
fbdaa13
feature: disposable flag on node localstate
alvarosabu Jan 23, 2024
b52d1f0
feat: remove userData from types
alvarosabu Jan 23, 2024
e6a510b
chore: remove unused import
alvarosabu Jan 23, 2024
aaa4d32
fix(test): fake localstate `.__tres` on tests
alvarosabu Jan 24, 2024
d1f1c83
fix(types): fix nodeOps instances localstate type
alvarosabu Jan 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions playground/src/components/TheExperience.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ watchEffect(() => {
:rotation="[-Math.PI / 2, 0, Math.PI / 2]"
name="floor"
receive-shadow
@click="wireframe = !wireframe"
>
<TresPlaneGeometry :args="[20, 20, 20]" />
<TresMeshToonMaterial
Expand Down
2 changes: 1 addition & 1 deletion src/components/TresCanvas.vue
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ onMounted(() => {
emit,
})

usePointerEventHandler({ scene: scene.value, contextParts: context.value })
usePointerEventHandler(context.value)

const { registerCamera, camera, cameras, deregisterCamera } = context.value

Expand Down
3 changes: 0 additions & 3 deletions src/composables/useCamera/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ export const useCamera = ({ sizes, scene }: Pick<TresContext, 'sizes'> & { scene
}
})

scene.userData.tres__registerCamera = registerCamera
scene.userData.tres__deregisterCamera = deregisterCamera

onUnmounted(() => {
cameras.value = []
})
Expand Down
24 changes: 10 additions & 14 deletions src/composables/usePointerEventHandler/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Intersection, Object3D, Object3DEventMap } from 'three'
import type { TresScene } from 'src/types'
import { computed, reactive, ref } from 'vue'
import { uniqueBy } from '../../utils'
import { useRaycaster } from '../useRaycaster'
Expand All @@ -17,11 +16,7 @@ export interface EventProps {
}

export const usePointerEventHandler = (
{ scene, contextParts }:
{
scene: TresScene
contextParts: Pick<TresContext, 'renderer' | 'camera' | 'raycaster'>
},
ctx: TresContext,
) => {
const objectsWithEventListeners = reactive({
click: new Map<Object3D<Object3DEventMap>, CallbackFn>(),
Expand Down Expand Up @@ -54,13 +49,6 @@ export const usePointerEventHandler = (
if (onPointerLeave) objectsWithEventListeners.pointerLeave.set(object, onPointerLeave)
}

// to make the registerObject available in the custom renderer (nodeOps), it is attached to the scene
scene.userData.tres__registerAtPointerEventHandler = registerObject
scene.userData.tres__deregisterAtPointerEventHandler = deregisterObject

scene.userData.tres__registerBlockingObjectAtPointerEventHandler = registerBlockingObject
scene.userData.tres__deregisterBlockingObjectAtPointerEventHandler = deregisterBlockingObject

const objectsToWatch = computed(() =>
uniqueBy(
[
Expand All @@ -73,7 +61,13 @@ export const usePointerEventHandler = (
),
)

const { onClick, onPointerMove } = useRaycaster(objectsToWatch, contextParts)
// Temporaly add the methods to the context, this should be handled later by the EventManager state on the context https://github.com/Tresjs/tres/issues/515
ctx.registerObjectAtPointerEventHandler = registerObject
ctx.deregisterObjectAtPointerEventHandler = deregisterObject
ctx.registerBlockingObjectAtPointerEventHandler = registerBlockingObject
ctx.deregisterBlockingObjectAtPointerEventHandler = deregisterBlockingObject

const { onClick, onPointerMove } = useRaycaster(objectsToWatch, ctx)

onClick(({ intersects, event }) => {
if (intersects.length) objectsWithEventListeners.click.get(intersects[0].object)?.(intersects[0], event)
Expand Down Expand Up @@ -101,5 +95,7 @@ export const usePointerEventHandler = (
return {
registerObject,
deregisterObject,
registerBlockingObject,
deregisterBlockingObject,
}
}
10 changes: 5 additions & 5 deletions src/composables/useRaycaster/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ interface PointerClickEventPayload {

export const useRaycaster = (
objects: Ref<THREE.Object3D[]>,
{ renderer, camera, raycaster }: Pick<TresContext, 'renderer' | 'camera' | 'raycaster'>,
ctx: TresContext,
Tinoooo marked this conversation as resolved.
Show resolved Hide resolved
) => {
// having a separate computed makes useElementBounding work
const canvas = computed(() => renderer.value.domElement as HTMLCanvasElement)
const canvas = computed(() => ctx.renderer.value.domElement as HTMLCanvasElement)

const { x, y } = usePointer({ target: canvas })

Expand All @@ -39,11 +39,11 @@ export const useRaycaster = (
}

const getIntersectsByRelativePointerPosition = ({ x, y }: { x: number; y: number }) => {
if (!camera.value) return
if (!ctx.camera.value) return

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

return raycaster.value.intersectObjects(objects.value, false)
return ctx.raycaster.value.intersectObjects(objects.value, false)
}

const getIntersects = (event?: PointerEvent | MouseEvent) => {
Expand Down
26 changes: 19 additions & 7 deletions src/composables/useTresContextProvider/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { toValue, useElementSize, useFps, useMemory, useRafFn, useWindowSize, refDebounced } from '@vueuse/core'
import { inject, provide, readonly, shallowRef, computed, ref, onUnmounted, watchEffect } from 'vue'
import type { Camera, EventDispatcher, Scene, WebGLRenderer } from 'three'
import type { Camera, EventDispatcher, Object3D, WebGLRenderer } from 'three'
import { Raycaster } from 'three'
import type { ComputedRef, DeepReadonly, MaybeRef, MaybeRefOrGetter, Ref, ShallowRef } from 'vue'
import { calculateMemoryUsage } from '../../utils/perf'
Expand All @@ -9,6 +9,8 @@ import type { UseRendererOptions } from '../useRenderer'
import { useRenderer } from '../useRenderer'
import { extend } from '../../core/catalogue'
import { useLogger } from '../useLogger'
import type { TresScene } from '../../types'
import type { EventProps } from '../usePointerEventHandler'

export interface InternalState {
priority: Ref<number>
Expand Down Expand Up @@ -43,7 +45,7 @@ export interface PerformanceState {
}

export interface TresContext {
scene: ShallowRef<Scene>
scene: ShallowRef<TresScene>
sizes: { height: Ref<number>; width: Ref<number>; aspectRatio: ComputedRef<number> }
extend: (objects: any) => void
camera: ComputedRef<Camera | undefined>
Expand All @@ -61,9 +63,17 @@ export interface TresContext {
* Advance one frame when renderMode === 'manual'
*/
advance: () => void
// Camera
registerCamera: (camera: Camera) => void
setCameraActive: (cameraOrUuid: Camera | string) => void
deregisterCamera: (camera: Camera) => void
// Events
// Temporaly add the methods to the context, this should be handled later by the EventManager state on the context https://github.com/Tresjs/tres/issues/515
// When thats done maybe we can short the names of the methods since the parent will give the context.
registerObjectAtPointerEventHandler: (object: Object3D & EventProps) => void
deregisterObjectAtPointerEventHandler: (object: Object3D) => void
registerBlockingObjectAtPointerEventHandler: (object: Object3D) => void
deregisterBlockingObjectAtPointerEventHandler: (object: Object3D) => void
}

export function useTresContextProvider({
Expand All @@ -74,7 +84,7 @@ export function useTresContextProvider({
rendererOptions,
emit,
}: {
scene: Scene
scene: TresScene
canvas: MaybeRef<HTMLCanvasElement>
windowSize: MaybeRefOrGetter<boolean>
disableRender: MaybeRefOrGetter<boolean>
Expand Down Expand Up @@ -109,7 +119,7 @@ export function useTresContextProvider({
width: computed(() => debouncedReactiveSize.value.width),
aspectRatio,
}
const localScene = shallowRef<Scene>(scene)
const localScene = shallowRef<TresScene>(scene)
const {
camera,
cameras,
Expand All @@ -121,7 +131,7 @@ export function useTresContextProvider({
// Render state

const render: RenderState = {
mode: ref<'always' | 'on-demand' | 'manual'>(rendererOptions.renderMode || 'always'),
mode: ref(rendererOptions.renderMode || 'always') as Ref<'always' | 'on-demand' | 'manual'>,
priority: ref(0),
frames: ref(0),
maxFrames: 60,
Expand Down Expand Up @@ -189,8 +199,10 @@ export function useTresContextProvider({

provide('useTres', ctx)

// Add context to scene.userData
ctx.scene.value.userData.tres__context = ctx
// Add context to scene local state
ctx.scene.value.__tres = {
root: ctx,
}

// Performance
const updateInterval = 100 // Update interval in milliseconds
Expand Down
Loading
Loading