1
0
mirror of https://github.com/troisjs/trois.git synced 2024-11-24 04:12:02 +08:00

wip: renderer

This commit is contained in:
Kevin Levron 2021-04-21 01:23:09 +02:00
parent 672c4f6ad2
commit d10c7d6a02

View File

@ -1,17 +1,50 @@
/* eslint-disable no-use-before-define */
import { WebGLRenderer } from 'three' import { WebGLRenderer } from 'three'
import { defineComponent } from 'vue' import { defineComponent, PropType } from 'vue'
import useThree, { SizeInterface, ThreeConfigInterface, ThreeInterface } from './useThree' import useThree, { SizeInterface, ThreeConfigInterface, ThreeInterface } from './useThree'
type CallbackType<T> = (e?: T) => void type CallbackType<T> = (event?: T) => void
interface EventInterface<T> { // type EventType = 'init' | 'mounted' | 'beforerender' | 'afterrender' | 'resize'
renderer: T
interface EventInterface {
type: 'init' | 'mounted'
renderer: RendererInterface
} }
interface RenderEventInterface<T> extends EventInterface<T> { interface RenderEventInterface {
type: 'beforerender' | 'afterrender'
renderer: RendererInterface
time: number time: number
} }
interface ResizeEventInterface {
type: 'resize'
renderer: RendererInterface
size: SizeInterface
}
type InitCallbackType = CallbackType<EventInterface>
type MountedCallbackType = CallbackType<EventInterface>
type RenderCallbackType = CallbackType<RenderEventInterface>
type ResizeCallbackType = CallbackType<ResizeEventInterface>
// interface EventMap {
// 'init': EventInterface;
// 'mounted': EventInterface;
// 'beforerender': RenderEventInterface;
// 'afterrender': RenderEventInterface;
// 'resize': ResizeEventInterface;
// }
interface EventCallbackMap {
'init': InitCallbackType;
'mounted': MountedCallbackType;
'beforerender': RenderCallbackType;
'afterrender': RenderCallbackType;
'resize': ResizeCallbackType;
}
interface RendererSetupInterface { interface RendererSetupInterface {
canvas: HTMLCanvasElement canvas: HTMLCanvasElement
three: ThreeInterface three: ThreeInterface
@ -19,20 +52,32 @@ interface RendererSetupInterface {
size: SizeInterface size: SizeInterface
renderFn(): void renderFn(): void
raf: boolean raf: boolean
onMountedCallbacks: CallbackType<EventInterface<this>>[]
beforeRenderCallbacks: CallbackType<RenderEventInterface<this>>[]
afterRenderCallbacks: CallbackType<RenderEventInterface<this>>[]
// pointerPosition?: Vector2 // pointerPosition?: Vector2
// pointerPositionN?: Vector2 // pointerPositionN?: Vector2
// pointerPositionV3?: Vector3 // pointerPositionV3?: Vector3
initCallbacks: InitCallbackType[]
mountedCallbacks: MountedCallbackType[]
beforeRenderCallbacks: RenderCallbackType[]
afterRenderCallbacks: RenderCallbackType[]
resizeCallbacks: ResizeCallbackType[]
} }
export interface RendererInterface extends RendererSetupInterface { export interface RendererInterface extends RendererSetupInterface {
onMounted(cb: CallbackType<EventInterface<this>>): void // onInit(cb: InitCallbackType): void
onBeforeRender(cb: CallbackType<RenderEventInterface<this>>): void // onMounted(cb: MountedCallbackType): void
offBeforeRender(cb: CallbackType<RenderEventInterface<this>>): void
onAfterRender(cb: CallbackType<RenderEventInterface<this>>): void // onBeforeRender(cb: RenderCallbackType): void
offAfterRender(cb: CallbackType<RenderEventInterface<this>>): void // offBeforeRender(cb: RenderCallbackType): void
// onAfterRender(cb: RenderCallbackType): void
// offAfterRender(cb: RenderCallbackType): void
// onResize(cb: ResizeCallbackType): void
// offResize(cb: ResizeCallbackType): void
addListener<T extends keyof EventCallbackMap>(t: T, cb: EventCallbackMap[T]): void
removeListener<T extends keyof EventCallbackMap>(t: T, cb: EventCallbackMap[T]): void
} }
export default defineComponent({ export default defineComponent({
@ -48,10 +93,15 @@ export default defineComponent({
width: String, width: String,
height: String, height: String,
xr: Boolean, xr: Boolean,
onReady: Function, onReady: Function as PropType<(r: RendererInterface) => void>,
// onFrame: Function,
}, },
setup(props): RendererSetupInterface { setup(props): RendererSetupInterface {
const initCallbacks: InitCallbackType[] = []
const mountedCallbacks: MountedCallbackType[] = []
const beforeRenderCallbacks: RenderCallbackType[] = []
const afterRenderCallbacks: RenderCallbackType[] = []
const resizeCallbacks: ResizeCallbackType[] = []
const canvas = document.createElement('canvas') const canvas = document.createElement('canvas')
const config: ThreeConfigInterface = { const config: ThreeConfigInterface = {
canvas, canvas,
@ -70,10 +120,6 @@ export default defineComponent({
const renderFn: {(): void} = () => {} const renderFn: {(): void} = () => {}
const onMountedCallbacks: {(): void}[] = []
const beforeRenderCallbacks: {(): void}[] = []
const afterRenderCallbacks: {(): void}[] = []
return { return {
canvas, canvas,
three, three,
@ -81,9 +127,11 @@ export default defineComponent({
size: three.size, size: three.size,
renderFn, renderFn,
raf: true, raf: true,
onMountedCallbacks, initCallbacks,
mountedCallbacks,
beforeRenderCallbacks, beforeRenderCallbacks,
afterRenderCallbacks, afterRenderCallbacks,
resizeCallbacks,
} }
}, },
provide() { provide() {
@ -97,18 +145,23 @@ export default defineComponent({
this.$el.parentNode.insertBefore(this.canvas, this.$el) this.$el.parentNode.insertBefore(this.canvas, this.$el)
if (this.three.init()) { if (this.three.init()) {
this.onReady?.(this)
// if (this.three.pointer) { // if (this.three.pointer) {
// this.pointerPosition = this.three.pointer.position // this.pointerPosition = this.three.pointer.position
// this.pointerPositionN = this.three.pointer.positionN // this.pointerPositionN = this.three.pointer.positionN
// this.pointerPositionV3 = this.three.pointer.positionV3 // this.pointerPositionV3 = this.three.pointer.positionV3
// } // }
this.three.config.onResize = (size) => {
this.resizeCallbacks.forEach(e => e({ type: 'resize', renderer: this, size }))
}
this.renderer.shadowMap.enabled = this.shadow this.renderer.shadowMap.enabled = this.shadow
this.renderFn = this.three.composer ? this.three.renderC : this.three.render this.renderFn = this.three.composer ? this.three.renderC : this.three.render
this.initCallbacks.forEach(e => e({ type: 'init', renderer: this }))
this.onReady?.(this as RendererInterface)
if (this.xr) { if (this.xr) {
this.renderer.xr.enabled = true this.renderer.xr.enabled = true
this.renderer.setAnimationLoop(this.render) this.renderer.setAnimationLoop(this.render)
@ -117,7 +170,7 @@ export default defineComponent({
} }
} }
this.onMountedCallbacks.forEach(c => c({ renderer: this })) this.mountedCallbacks.forEach(e => e({ type: 'mounted', renderer: this }))
}, },
beforeUnmount() { beforeUnmount() {
this.canvas.remove() this.canvas.remove()
@ -127,33 +180,57 @@ export default defineComponent({
this.three.dispose() this.three.dispose()
}, },
methods: { methods: {
onMounted(cb: {(): void}) { // onInit(cb: InitCallbackType) {
this.onMountedCallbacks.push(cb) // this.initCallbacks.push(cb)
// },
// onMounted(cb: MountedCallbackType) {
// this.mountedCallbacks.push(cb)
// },
// onBeforeRender(cb: RenderCallbackType) {
// this.beforeRenderCallbacks.push(cb)
// },
// offBeforeRender(cb: RenderCallbackType) {
// this.beforeRenderCallbacks = this.beforeRenderCallbacks.filter(e => e !== cb)
// },
// onAfterRender(cb: RenderCallbackType) {
// this.afterRenderCallbacks.push(cb)
// },
// offAfterRender(cb: RenderCallbackType) {
// this.afterRenderCallbacks = this.afterRenderCallbacks.filter(e => e !== cb)
// },
// onResize(cb: ResizeCallbackType) {
// this.resizeCallbacks.push(cb)
// },
// offResize(cb: ResizeCallbackType) {
// this.resizeCallbacks = this.resizeCallbacks.filter(e => e !== cb)
// },
addListener(type: string, cb: {(): void}) {
const callbacks = this.getCallbacks(type)
callbacks.push(cb)
}, },
onBeforeRender(cb: {(): void}) { removeListener(type: string, cb: {(): void}) {
this.beforeRenderCallbacks.push(cb) const callbacks = this.getCallbacks(type)
const index = callbacks.indexOf(cb)
if (index) callbacks.splice(index, 1)
}, },
offBeforeRender(cb: {(): void}) { getCallbacks(type: string) {
this.beforeRenderCallbacks = this.beforeRenderCallbacks.filter(c => c !== cb) if (type === 'init') {
}, return this.initCallbacks
onAfterRender(cb: {(): void}) { } else if (type === 'mounted') {
this.afterRenderCallbacks.push(cb) return this.mountedCallbacks
}, } else if (type === 'beforerender') {
offAfterRender(cb: {(): void}) { return this.beforeRenderCallbacks
this.afterRenderCallbacks = this.afterRenderCallbacks.filter(c => c !== cb) } else if (type === 'afterrender') {
}, return this.afterRenderCallbacks
onAfterResize(cb: {(): void}) { } else {
this.three.onAfterResize(cb) return this.resizeCallbacks
}, }
offAfterResize(cb: {(): void}) {
this.three.offAfterResize(cb)
}, },
render(time: number) { render(time: number) {
const cbParams = { time, renderer: this } this.beforeRenderCallbacks.forEach(e => e({ type: 'beforerender', renderer: this, time }))
this.beforeRenderCallbacks.forEach(cb => cb(cbParams))
// this.onFrame?.(cbParams) // this.onFrame?.(cbParams)
this.renderFn() this.renderFn()
this.afterRenderCallbacks.forEach(cb => cb(cbParams)) this.afterRenderCallbacks.forEach(e => e({ type: 'afterrender', renderer: this, time }))
}, },
renderLoop(time: number) { renderLoop(time: number) {
if (this.raf) requestAnimationFrame(this.renderLoop) if (this.raf) requestAnimationFrame(this.renderLoop)