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

wip: core

This commit is contained in:
Kevin Levron 2021-04-19 19:37:11 +02:00
parent 98c892112a
commit 8adb685c56
4 changed files with 61 additions and 25 deletions

View File

@ -1,11 +1,7 @@
import { Camera } from 'three'
import { defineComponent, inject } from 'vue' import { defineComponent, inject } from 'vue'
import { ThreeInterface } from './useThree'
// import Object3D from './Object3D' // import Object3D from './Object3D'
interface ThreeInterface {
camera?: Camera
}
export default defineComponent({ export default defineComponent({
// TODO: eventually extend Object3D // TODO: eventually extend Object3D
// extends: Object3D, // extends: Object3D,

View File

@ -1,26 +1,40 @@
import { Object3D } from 'three' import { Object3D } from 'three'
import { defineComponent } from 'vue' import { defineComponent, inject, PropType } from 'vue'
import usePointer, { PointerIntersectCallbackType } from './usePointer' import usePointer, { IntersectObject, PointerInterface, PointerIntersectCallbackType } from './usePointer'
import { RendererInterface } from './Renderer'
import { ThreeInterface } from './useThree'
// eslint-disable-next-line @typescript-eslint/no-empty-function // eslint-disable-next-line @typescript-eslint/no-empty-function
const emptyCallBack: PointerIntersectCallbackType = () => {} const emptyCallBack: PointerIntersectCallbackType = () => {}
interface RaycasterSetupInterface {
renderer: RendererInterface
three: ThreeInterface
pointer?: PointerInterface
}
export default defineComponent({ export default defineComponent({
name: 'Raycaster', name: 'Raycaster',
inject: ['three', 'renderer'],
props: { props: {
onPointerEnter: { type: Function, default: emptyCallBack }, onPointerEnter: { type: Function as PropType<PointerIntersectCallbackType>, default: emptyCallBack },
onPointerOver: { type: Function, default: emptyCallBack }, onPointerOver: { type: Function as PropType<PointerIntersectCallbackType>, default: emptyCallBack },
onPointerMove: { type: Function, default: emptyCallBack }, onPointerMove: { type: Function as PropType<PointerIntersectCallbackType>, default: emptyCallBack },
onPointerLeave: { type: Function, default: emptyCallBack }, onPointerLeave: { type: Function as PropType<PointerIntersectCallbackType>, default: emptyCallBack },
onClick: { type: Function, default: emptyCallBack }, onClick: { type: Function as PropType<PointerIntersectCallbackType>, default: emptyCallBack },
intersectMode: { type: String, default: 'move' }, intersectMode: { type: String, default: 'move' },
}, },
setup(): RaycasterSetupInterface {
const renderer = inject('renderer') as RendererInterface
const three = inject('three') as ThreeInterface
return { renderer, three }
},
mounted() { mounted() {
this.renderer.onMounted(() => { this.renderer.onMounted(() => {
if (!this.three.camera) return
this.pointer = usePointer({ this.pointer = usePointer({
camera: this.three.camera, camera: this.three.camera,
domElement: this.three.renderer.domElement, domElement: this.renderer.canvas,
intersectObjects: this.getIntersectObjects(), intersectObjects: this.getIntersectObjects(),
onIntersectEnter: (<PointerIntersectCallbackType> this.onPointerEnter), onIntersectEnter: (<PointerIntersectCallbackType> this.onPointerEnter),
onIntersectOver: (<PointerIntersectCallbackType> this.onPointerOver), onIntersectOver: (<PointerIntersectCallbackType> this.onPointerOver),
@ -43,7 +57,11 @@ export default defineComponent({
}, },
methods: { methods: {
getIntersectObjects() { getIntersectObjects() {
return this.three.scene.children.filter((c: Object3D) => ['Mesh', 'InstancedMesh'].includes(c.type)) if (this.three.scene) {
const children = this.three.scene.children.filter((c: Object3D) => ['Mesh', 'InstancedMesh'].includes(c.type))
return children as IntersectObject[]
}
return []
}, },
}, },
render() { render() {

View File

@ -1,8 +1,8 @@
import { WebGLRenderer } from 'three' import { WebGLRenderer } from 'three'
import { defineComponent } from 'vue' import { defineComponent } from 'vue'
import useThree, { ThreeConfigInterface, ThreeInterface } from './useThree' import useThree, { SizeInterface, ThreeConfigInterface, ThreeInterface } from './useThree'
type CallbackType<T> = (e: T) => void type CallbackType<T> = (e?: T) => void
interface EventInterface<T> { interface EventInterface<T> {
renderer: T renderer: T
@ -12,19 +12,31 @@ interface RenderEventInterface<T> extends EventInterface<T> {
time: number time: number
} }
export interface RendererInterface { interface RendererSetupInterface {
canvas: HTMLCanvasElement canvas: HTMLCanvasElement
three: ThreeInterface three: ThreeInterface
renderer: WebGLRenderer renderer: WebGLRenderer
size: SizeInterface
renderFn(): void renderFn(): void
raf: boolean raf: boolean
onMountedCallbacks: CallbackType<EventInterface<this>>[] onMountedCallbacks: CallbackType<EventInterface<this>>[]
beforeRenderCallbacks: CallbackType<RenderEventInterface<this>>[] beforeRenderCallbacks: CallbackType<RenderEventInterface<this>>[]
afterRenderCallbacks: CallbackType<RenderEventInterface<this>>[] afterRenderCallbacks: CallbackType<RenderEventInterface<this>>[]
// pointerPosition?: Vector2
// pointerPositionN?: Vector2
// pointerPositionV3?: Vector3
} }
type MountedCallbackType = CallbackType<EventInterface<RendererInterface>> export interface RendererInterface extends RendererSetupInterface {
type RenderCallbackType = CallbackType<RenderEventInterface<RendererInterface>> onMounted(cb: CallbackType<EventInterface<this>>): void
onBeforeRender(cb: CallbackType<RenderEventInterface<this>>): void
offBeforeRender(cb: CallbackType<RenderEventInterface<this>>): void
onAfterRender(cb: CallbackType<RenderEventInterface<this>>): void
offAfterRender(cb: CallbackType<RenderEventInterface<this>>): void
}
// type MountedCallbackType = CallbackType<EventInterface<RendererSetupInterface>>
// type RenderCallbackType = CallbackType<RenderEventInterface<RendererSetupInterface>>
export default defineComponent({ export default defineComponent({
name: 'Renderer', name: 'Renderer',
@ -42,7 +54,7 @@ export default defineComponent({
onReady: Function, onReady: Function,
// onFrame: Function, // onFrame: Function,
}, },
setup(props): RendererInterface { setup(props): RendererSetupInterface {
const canvas = document.createElement('canvas') const canvas = document.createElement('canvas')
const config: ThreeConfigInterface = { const config: ThreeConfigInterface = {
canvas, canvas,
@ -69,6 +81,7 @@ export default defineComponent({
canvas, canvas,
three, three,
renderer: three.renderer, renderer: three.renderer,
size: three.size,
renderFn, renderFn,
raf: true, raf: true,
onMountedCallbacks, onMountedCallbacks,
@ -88,6 +101,13 @@ export default defineComponent({
if (this.three.init()) { if (this.three.init()) {
this.onReady?.(this) this.onReady?.(this)
// if (this.three.pointer) {
// this.pointerPosition = this.three.pointer.position
// this.pointerPositionN = this.three.pointer.positionN
// this.pointerPositionV3 = this.three.pointer.positionV3
// }
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

View File

@ -1,20 +1,22 @@
import { defineComponent, watch } from 'vue' import { defineComponent, inject, watch } from 'vue'
import { Scene, Color, Object3D } from 'three' import { Scene, Color, Object3D } from 'three'
import { ThreeInterface } from './useThree'
export default defineComponent({ export default defineComponent({
name: 'Scene', name: 'Scene',
inject: ['three'], // inject: ['three'],
props: { props: {
id: String, // id: String,
background: [String, Number], background: [String, Number],
}, },
setup(props) { setup(props) {
const three = inject('three') as ThreeInterface
const scene = new Scene() const scene = new Scene()
if (props.background) { if (props.background) {
scene.background = new Color(props.background) scene.background = new Color(props.background)
} }
watch(() => props.background, (value) => { if (scene.background instanceof Color && value) scene.background.set(value) }) watch(() => props.background, (value) => { if (scene.background instanceof Color && value) scene.background.set(value) })
return { scene } return { three, scene }
}, },
provide() { provide() {
return { return {