Przeglądaj źródła

refactor: streamline useRenderer and integrate render state management

Tino Koch 2 miesięcy temu
rodzic
commit
c89a4ffa99

+ 0 - 1
src/composables/index.ts

@@ -6,7 +6,6 @@ export * from './useGraph'
 export * from './useLoader'
 export * from './useLoader'
 export * from './useLoop'
 export * from './useLoop'
 export * from './useRaycaster'
 export * from './useRaycaster'
-export * from './useRenderer/'
 export * from './useRenderLoop'
 export * from './useRenderLoop'
 export * from './useSeek'
 export * from './useSeek'
 export * from './useTexture'
 export * from './useTexture'

+ 34 - 5
src/composables/useRenderer/index.ts

@@ -1,22 +1,32 @@
 import type { TresCanvasProps } from 'src/components/TresCanvas.vue'
 import type { TresCanvasProps } from 'src/components/TresCanvas.vue'
 import { createRenderer } from 'src/core/createRenderer'
 import { createRenderer } from 'src/core/createRenderer'
-import type { TresRendererSetupContext } from '../../composables'
 import { WebGLRenderer } from 'three'
 import { WebGLRenderer } from 'three'
 import { setupWebGLRenderer } from 'src/core/setupRenderer'
 import { setupWebGLRenderer } from 'src/core/setupRenderer'
 import { onUnmounted } from 'vue'
 import { onUnmounted } from 'vue'
+import type { RenderState, TresContext } from '../useTresContextProvider'
+import type { EmitEventFn } from 'types'
+
+export type TresRendererSetupContext = Pick< // TODO make this public
+  TresContext,
+  'sizes' | 'scene' | 'camera' | 'canvas' | 'invalidate' | 'advance' | 'loop'
+>
 
 
 export async function useRenderer({
 export async function useRenderer({
-  contextParts: ctx,
+  emit,
   options,
   options,
+  renderState, // TODO think about embedding this in this composable
+  contextParts,
 }: {
 }: {
-  contextParts: TresRendererSetupContext
+  emit: EmitEventFn
   options: TresCanvasProps
   options: TresCanvasProps
+  renderState: RenderState
+  contextParts: TresRendererSetupContext
 }) {
 }) {
-  const renderer = await createRenderer(ctx, options)
+  const renderer = await createRenderer(contextParts, options)
 
 
   // For now we only support WebGLRenderer. If the user wants to use their own renderer, it is their responsibility to handle the disposal and stuff like that.
   // For now we only support WebGLRenderer. If the user wants to use their own renderer, it is their responsibility to handle the disposal and stuff like that.
   if (renderer instanceof WebGLRenderer) {
   if (renderer instanceof WebGLRenderer) {
-    setupWebGLRenderer(renderer, options, ctx) // TODO use contents directly
+    setupWebGLRenderer(renderer, options, contextParts) // TODO use contents directly
 
 
     onUnmounted(() => {
     onUnmounted(() => {
       renderer.dispose()
       renderer.dispose()
@@ -24,5 +34,24 @@ export async function useRenderer({
     })
     })
   }
   }
 
 
+  const { camera, scene } = contextParts
+
+  contextParts.loop.register(() => {
+    if (camera.value && renderState.frames.value > 0) {
+      renderer.render(scene.value, camera.value)
+      emit('render', renderer)
+    }
+
+    // Reset priority
+    renderState.priority.value = 0
+
+    if (renderState.mode.value === 'always') {
+      renderState.frames.value = 1
+    }
+    else {
+      renderState.frames.value = Math.max(0, renderState.frames.value - 1)
+    }
+  }, 'render')
+
   return renderer
   return renderer
 }
 }

+ 12 - 34
src/composables/useTresContextProvider/index.ts

@@ -84,11 +84,6 @@ export interface TresContext {
   deregisterBlockingObjectAtPointerEventHandler?: (object: TresObject) => void
   deregisterBlockingObjectAtPointerEventHandler?: (object: TresObject) => void
 }
 }
 
 
-export type TresRendererSetupContext = Pick<
-  TresContext,
-  'sizes' | 'scene' | 'camera' | 'canvas' | 'invalidate' | 'advance'
->
-
 export async function useTresContextProvider({
 export async function useTresContextProvider({
   scene,
   scene,
   canvas,
   canvas,
@@ -113,30 +108,29 @@ export async function useTresContextProvider({
     setCameraActive,
     setCameraActive,
   } = useCamera({ sizes, scene })
   } = useCamera({ sizes, scene })
 
 
-  // Render state
-
-  const render: RenderState = {
+  const renderState: RenderState = { // TODO rename // TODO make separate
     mode: ref(rendererOptions.renderMode || 'always') as Ref<'always' | 'on-demand' | 'manual'>,
     mode: ref(rendererOptions.renderMode || 'always') as Ref<'always' | 'on-demand' | 'manual'>,
     priority: ref(0),
     priority: ref(0),
     frames: ref(0),
     frames: ref(0),
-    maxFrames: 60,
-    canBeInvalidated: computed(() => render.mode.value === 'on-demand' && render.frames.value === 0),
+    maxFrames: 60, // TODO add issue for prop
+    canBeInvalidated: computed(() => renderState.mode.value === 'on-demand' && renderState.frames.value === 0),
   }
   }
 
 
   function invalidate(frames = 1) {
   function invalidate(frames = 1) {
     // Increase the frame count, ensuring not to exceed a maximum if desired
     // Increase the frame count, ensuring not to exceed a maximum if desired
     if (rendererOptions.renderMode === 'on-demand') {
     if (rendererOptions.renderMode === 'on-demand') {
-      render.frames.value = Math.min(render.maxFrames, render.frames.value + frames)
+      renderState.frames.value = Math.min(renderState.maxFrames, renderState.frames.value + frames)
     }
     }
   }
   }
 
 
   function advance() {
   function advance() {
     if (rendererOptions.renderMode === 'manual') {
     if (rendererOptions.renderMode === 'manual') {
-      render.frames.value = 1
+      renderState.frames.value = 1
     }
     }
   }
   }
 
 
-  // Renderer
+  const loop = createRenderLoop()
+
   const renderer = await useRenderer({
   const renderer = await useRenderer({
     contextParts: {
     contextParts: {
       sizes,
       sizes,
@@ -145,8 +139,11 @@ export async function useTresContextProvider({
       canvas,
       canvas,
       advance,
       advance,
       invalidate,
       invalidate,
+      loop,
     },
     },
     options: rendererOptions,
     options: rendererOptions,
+    emit,
+    renderState,
   })
   })
 
 
   const ctx: TresContext = {
   const ctx: TresContext = {
@@ -170,13 +167,13 @@ export async function useTresContextProvider({
         accumulator: [],
         accumulator: [],
       },
       },
     },
     },
-    render,
+    render: renderState,
     advance,
     advance,
     invalidate,
     invalidate,
     registerCamera,
     registerCamera,
     setCameraActive,
     setCameraActive,
     deregisterCamera,
     deregisterCamera,
-    loop: createRenderLoop(),
+    loop,
   }
   }
 
 
   provide('useTres', ctx)
   provide('useTres', ctx)
@@ -186,25 +183,6 @@ export async function useTresContextProvider({
     root: ctx,
     root: ctx,
   }
   }
 
 
-  // The loop
-
-  ctx.loop.register(() => {
-    if (ctx.renderer.value && camera.value && render.frames.value > 0) {
-      ctx.renderer.value.render(scene, camera.value)
-      emit('render', ctx.renderer.value)
-    }
-
-    // Reset priority
-    render.priority.value = 0
-
-    if (render.mode.value === 'always') {
-      render.frames.value = 1
-    }
-    else {
-      render.frames.value = Math.max(0, render.frames.value - 1)
-    }
-  }, 'render')
-
   const { on: onTresReady, cancel: cancelTresReady } = useTresReady(ctx)!
   const { on: onTresReady, cancel: cancelTresReady } = useTresReady(ctx)!
 
 
   ctx.loop.setReady(false)
   ctx.loop.setReady(false)

+ 1 - 1
src/core/createRenderer.ts

@@ -1,5 +1,5 @@
 import { WebGLRenderer } from 'three'
 import { WebGLRenderer } from 'three'
-import type { TresRendererSetupContext } from '../composables'
+import type { TresRendererSetupContext } from '../composables/useRenderer'
 import type { TresRenderer } from '../types'
 import type { TresRenderer } from '../types'
 import type { TresCanvasProps } from '../components/TresCanvas.vue'
 import type { TresCanvasProps } from '../components/TresCanvas.vue'
 import { toValue } from 'vue'
 import { toValue } from 'vue'