1
0
mirror of https://github.com/troisjs/trois.git synced 2024-11-24 12:22:03 +08:00
trois/src/core/Object3D.ts

121 lines
3.5 KiB
TypeScript
Raw Normal View History

2021-04-21 07:10:48 +08:00
import { Object3D, Scene } from 'three'
2021-04-25 03:45:57 +08:00
import { ComponentPublicInstance, defineComponent, PropType, watch } from 'vue'
2021-04-16 07:56:52 +08:00
import { bindProp } from '../tools'
2021-04-25 03:45:57 +08:00
import { RendererInjectionKey, RendererInterface } from './Renderer'
import { SceneInjectionKey } from './Scene'
2021-04-16 07:56:52 +08:00
2021-04-21 22:04:20 +08:00
export interface Object3DSetupInterface {
2021-04-25 03:45:57 +08:00
renderer?: RendererInterface
scene?: Scene
2021-04-19 04:27:53 +08:00
o3d?: Object3D
parent?: ComponentPublicInstance
}
2021-04-20 23:50:06 +08:00
export interface Object3DInterface extends Object3DSetupInterface {
addToParent(o?: Object3D): boolean
removeFromParent(o?: Object3D): boolean
add(o: Object3D): void
remove(o: Object3D): void
}
2021-04-25 03:45:57 +08:00
// export function object3DSetup(): Object3DSetupInterface {
// const renderer = inject(RendererInjectionKey)
// const scene = inject(SceneInjectionKey)
// return { scene, renderer }
// }
2021-04-21 22:04:20 +08:00
2021-04-24 05:29:56 +08:00
export interface Vector2PropInterface {
x?: number
y?: number
}
export interface Vector3PropInterface extends Vector2PropInterface {
z?: number
}
export interface EulerPropInterface extends Vector3PropInterface {
order?: 'XYZ' | 'YZX' | 'ZXY' | 'XZY' | 'YXZ' | 'ZYX'
}
2021-04-16 07:56:52 +08:00
export default defineComponent({
name: 'Object3D',
2021-04-25 03:45:57 +08:00
// inject for sub components
inject: {
renderer: RendererInjectionKey as symbol,
scene: SceneInjectionKey as symbol,
},
2021-04-16 07:56:52 +08:00
emits: ['created', 'ready'],
props: {
2021-04-24 05:29:56 +08:00
position: { type: Object as PropType<Vector3PropInterface>, default: () => ({ x: 0, y: 0, z: 0 }) },
rotation: { type: Object as PropType<EulerPropInterface>, default: () => ({ x: 0, y: 0, z: 0 }) },
scale: { type: Object as PropType<Vector3PropInterface>, default: () => ({ x: 1, y: 1, z: 1, order: 'XYZ' }) },
lookAt: { type: Object as PropType<Vector3PropInterface>, default: null },
2021-04-16 07:56:52 +08:00
autoRemove: { type: Boolean, default: true },
userData: { type: Object, default: () => ({}) },
},
2021-04-25 03:45:57 +08:00
setup(): Object3DSetupInterface {
// return object3DSetup()
return {}
2021-04-19 04:27:53 +08:00
},
2021-04-25 03:45:57 +08:00
created() {
if (!this.renderer) {
console.error('Missing parent Renderer')
}
if (!this.scene) {
console.error('Missing parent Scene')
}
2021-04-24 05:29:56 +08:00
},
2021-04-16 07:56:52 +08:00
unmounted() {
if (this.autoRemove) this.removeFromParent()
},
methods: {
initObject3D(o3d: Object3D) {
this.o3d = o3d
2021-04-19 04:27:53 +08:00
this.$emit('created', o3d)
bindProp(this, 'position', o3d)
bindProp(this, 'rotation', o3d)
bindProp(this, 'scale', o3d)
2021-04-19 07:28:09 +08:00
bindProp(this, 'userData', o3d.userData)
2021-04-16 07:56:52 +08:00
2021-04-24 05:29:56 +08:00
if (this.lookAt) o3d.lookAt(this.lookAt.x ?? 0, this.lookAt.y, this.lookAt.z)
watch(() => this.lookAt, (v) => { o3d.lookAt(v.x ?? 0, v.y, v.z) }, { deep: true })
2021-04-16 07:56:52 +08:00
2021-04-19 04:27:53 +08:00
this.parent = this.getParent()
2021-04-16 07:56:52 +08:00
if (this.addToParent()) this.$emit('ready', this)
else console.error('Missing parent (Scene, Group...)')
},
2021-04-19 04:27:53 +08:00
getParent(): undefined | ComponentPublicInstance {
2021-04-16 07:56:52 +08:00
let parent = this.$parent
while (parent) {
2021-04-19 04:27:53 +08:00
if ((parent as any).add) return parent
2021-04-16 07:56:52 +08:00
parent = parent.$parent
}
2021-04-19 04:27:53 +08:00
return undefined
2021-04-16 07:56:52 +08:00
},
2021-04-19 04:27:53 +08:00
addToParent(o?: Object3D) {
2021-04-16 07:56:52 +08:00
const o3d = o || this.o3d
2021-04-19 04:27:53 +08:00
if (this.parent) {
(this.parent as any).add(o3d)
2021-04-16 07:56:52 +08:00
return true
}
return false
},
2021-04-19 04:27:53 +08:00
removeFromParent(o?: Object3D) {
2021-04-16 07:56:52 +08:00
const o3d = o || this.o3d
2021-04-19 04:27:53 +08:00
if (this.parent) {
(this.parent as any).remove(o3d)
2021-04-16 07:56:52 +08:00
return true
}
return false
},
2021-04-19 04:27:53 +08:00
add(o: Object3D) { this.o3d?.add(o) },
remove(o: Object3D) { this.o3d?.remove(o) },
2021-04-16 07:56:52 +08:00
},
render() {
return this.$slots.default ? this.$slots.default() : []
},
__hmrId: 'Object3D',
})