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

Merge branch 'master' into vanruesc/postprocessing

This commit is contained in:
Kevin Levron 2021-05-03 23:14:28 +02:00
commit ec6a9db7fc
6 changed files with 52 additions and 39 deletions

View File

@ -1,6 +1,6 @@
import { Object3D, Scene } from 'three' import { Object3D, Scene } from 'three'
import { ComponentPublicInstance, defineComponent, PropType, watch } from 'vue' import { ComponentPublicInstance, defineComponent, PropType, watch } from 'vue'
import { bindProp } from '../tools' import { bindOptions, bindProp } from '../tools'
import { RendererInjectionKey, RendererInterface } from './Renderer' import { RendererInjectionKey, RendererInterface } from './Renderer'
import { SceneInjectionKey } from './Scene' import { SceneInjectionKey } from './Scene'
@ -54,7 +54,9 @@ export default defineComponent({
lookAt: { type: Object as PropType<Vector3PropInterface>, default: null }, lookAt: { type: Object as PropType<Vector3PropInterface>, default: null },
userData: { type: Object, default: () => ({}) }, userData: { type: Object, default: () => ({}) },
visible: { type: Boolean, default: true }, visible: { type: Boolean, default: true },
autoRemove: { type: Boolean, default: true }, props: { type: Object, default: () => ({}) },
disableAdd: { type: Boolean, default: false },
disableRemove: { type: Boolean, default: false },
}, },
setup(): Object3DSetupInterface { setup(): Object3DSetupInterface {
// return object3DSetup() // return object3DSetup()
@ -69,26 +71,30 @@ export default defineComponent({
} }
}, },
unmounted() { unmounted() {
if (this.autoRemove) this.removeFromParent() if (!this.disableRemove) this.removeFromParent()
}, },
methods: { methods: {
initObject3D(o3d: Object3D) { initObject3D(o3d: Object3D) {
this.o3d = o3d this.o3d = o3d
this.$emit('created', o3d)
bindProp(this, 'position', o3d) bindProp(this, 'position', o3d)
bindProp(this, 'rotation', o3d) bindProp(this, 'rotation', o3d)
bindProp(this, 'scale', o3d) bindProp(this, 'scale', o3d)
bindProp(this, 'userData', o3d.userData) bindProp(this, 'userData', o3d.userData)
bindProp(this, 'visible', o3d) bindProp(this, 'visible', o3d)
bindOptions(o3d, this.props)
this.$emit('created', o3d)
if (this.lookAt) o3d.lookAt(this.lookAt.x ?? 0, this.lookAt.y, this.lookAt.z) 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 }) watch(() => this.lookAt, (v) => { o3d.lookAt(v.x ?? 0, v.y, v.z) }, { deep: true })
this.parent = this.getParent() this.parent = this.getParent()
if (!this.disableAdd) {
if (this.addToParent()) this.$emit('ready', this) if (this.addToParent()) this.$emit('ready', this)
else console.error('Missing parent (Scene, Group...)') else console.error('Missing parent (Scene, Group...)')
}
}, },
getParent(): undefined | ComponentPublicInstance { getParent(): undefined | ComponentPublicInstance {
let parent = this.$parent let parent = this.$parent

View File

@ -2,7 +2,7 @@
import { Camera, NoToneMapping, PCFShadowMap, Scene, WebGLRenderer } from 'three' import { Camera, NoToneMapping, PCFShadowMap, Scene, WebGLRenderer } from 'three'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer' import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'
import { ComponentPublicInstance, defineComponent, InjectionKey, PropType } from 'vue' import { ComponentPublicInstance, defineComponent, InjectionKey, PropType } from 'vue'
import { bindProp } from '../tools' import { bindOptions } from '../tools'
import { PointerPublicConfigInterface } from './usePointer' import { PointerPublicConfigInterface } from './usePointer'
import useThree, { SizeInterface, ThreeConfigInterface, ThreeInterface } from './useThree' import useThree, { SizeInterface, ThreeConfigInterface, ThreeInterface } from './useThree'
@ -107,11 +107,10 @@ export default defineComponent({
pointer: { type: [Boolean, Object] as PropType<boolean | PointerPublicConfigInterface>, default: false }, pointer: { type: [Boolean, Object] as PropType<boolean | PointerPublicConfigInterface>, default: false },
resize: { type: [Boolean, String] as PropType<boolean | string>, default: false }, resize: { type: [Boolean, String] as PropType<boolean | string>, default: false },
shadow: Boolean, shadow: Boolean,
shadowType: { type: Number, default: PCFShadowMap },
toneMapping: { type: Number, default: NoToneMapping },
width: String, width: String,
height: String, height: String,
xr: Boolean, xr: Boolean,
props: { type: Object, default: () => ({}) },
onReady: Function as PropType<(r: RendererInterface) => void>, onReady: Function as PropType<(r: RendererInterface) => void>,
onClick: Function as PropType<(this: HTMLCanvasElement, ev: MouseEvent) => any>, onClick: Function as PropType<(this: HTMLCanvasElement, ev: MouseEvent) => any>,
}, },
@ -137,7 +136,7 @@ export default defineComponent({
if (props.height) config.height = parseInt(props.height) if (props.height) config.height = parseInt(props.height)
const three = useThree(config) const three = useThree(config)
bindProp(props, 'toneMapping', three.renderer) bindOptions(three.renderer, props.props)
const renderFn: {(): void} = () => {} const renderFn: {(): void} = () => {}

View File

@ -1,17 +1,17 @@
import { defineComponent, PropType, watch } from 'vue' import { defineComponent, PropType, watch } from 'vue'
import { CubeReflectionMapping, CubeTextureLoader, RGBFormat } from 'three' import { CubeReflectionMapping, CubeTextureLoader } from 'three'
import Texture from './Texture' import Texture from './Texture'
export default defineComponent({ export default defineComponent({
extends: Texture, extends: Texture,
props: { props: {
name: { type: String, default: 'envMap' },
path: { type: String, required: true }, path: { type: String, required: true },
urls: { urls: {
type: Array as PropType<string[]>, type: Array as PropType<string[]>,
default: () => ['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg'], default: () => ['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg'],
}, },
// format: { type: Number, default: RGBFormat }, props: { type: Object, default: () => ({ mapping: CubeReflectionMapping }) },
mapping: { type: Number, default: CubeReflectionMapping },
}, },
created() { created() {
watch(() => this.path, this.refreshTexture) watch(() => this.path, this.refreshTexture)

View File

@ -1,6 +1,7 @@
import { ComponentPublicInstance, defineComponent, InjectionKey, PropType, watch } from 'vue' import { ComponentPublicInstance, defineComponent, InjectionKey, PropType, watch } from 'vue'
import { FrontSide, Material, NormalBlending, Texture } from 'three' import { FrontSide, Material, NormalBlending, Texture } from 'three'
import { MeshInjectionKey, MeshInterface } from '../meshes/Mesh' import { MeshInjectionKey, MeshInterface } from '../meshes/Mesh'
import { bindOptions } from '../tools'
export interface MaterialSetupInterface { export interface MaterialSetupInterface {
mesh?: MeshInterface mesh?: MeshInterface
@ -33,6 +34,7 @@ export default defineComponent({
side: { type: Number, default: FrontSide }, side: { type: Number, default: FrontSide },
transparent: Boolean, transparent: Boolean,
vertexColors: Boolean, vertexColors: Boolean,
props: { type: Object, default: () => ({}) },
}, },
setup(): MaterialSetupInterface { setup(): MaterialSetupInterface {
return {} return {}
@ -50,6 +52,7 @@ export default defineComponent({
if (this.createMaterial) { if (this.createMaterial) {
this.material = this.createMaterial() this.material = this.createMaterial()
bindOptions(this.material, this.props)
this.mesh.setMaterial(this.material) this.mesh.setMaterial(this.material)
this.addWatchers() this.addWatchers()
} }

View File

@ -1,8 +1,7 @@
import { defineComponent, PropType, watch } from 'vue' import { defineComponent, PropType, watch } from 'vue'
import { ClampToEdgeWrapping, LinearEncoding, LinearFilter, LinearMipmapLinearFilter, ShaderMaterial, Texture, TextureLoader, UVMapping } from 'three' import { ShaderMaterial, Texture, TextureLoader } from 'three'
import { bindProp } from '../tools' import { bindOptions } from '../tools'
import { MaterialInjectionKey, MaterialInterface } from './Material' import { MaterialInjectionKey, MaterialInterface } from './Material'
import { Vector2PropInterface } from '../core/Object3D'
export interface TexureInterface { export interface TexureInterface {
material?: MaterialInterface material?: MaterialInterface
@ -20,16 +19,7 @@ export default defineComponent({
onLoad: Function as PropType<(t: Texture) => void>, onLoad: Function as PropType<(t: Texture) => void>,
onProgress: Function as PropType<(e: ProgressEvent) => void>, onProgress: Function as PropType<(e: ProgressEvent) => void>,
onError: Function as PropType<(e: ErrorEvent) => void>, onError: Function as PropType<(e: ErrorEvent) => void>,
encoding: { type: Number, default: LinearEncoding }, props: { type: Object, default: () => ({}) },
// format: { type: Number, default: RGBAFormat },
mapping: { type: Number, default: UVMapping },
wrapS: { type: Number, default: ClampToEdgeWrapping },
wrapT: { type: Number, default: ClampToEdgeWrapping },
magFilter: { type: Number, default: LinearFilter },
minFilter: { type: Number, default: LinearMipmapLinearFilter },
repeat: { type: Object as PropType<Vector2PropInterface>, default: () => ({ x: 1, y: 1 }) },
rotation: { type: Number, default: 0 },
center: { type: Object as PropType<Vector2PropInterface>, default: () => ({ x: 0, y: 0 }) },
}, },
setup(): TexureInterface { setup(): TexureInterface {
return {} return {}
@ -45,21 +35,23 @@ export default defineComponent({
methods: { methods: {
createTexture() { createTexture() {
if (!this.src) return undefined if (!this.src) return undefined
const texture = new TextureLoader().load(this.src, this.onLoaded, this.onProgress, this.onError) return new TextureLoader().load(this.src, this.onLoaded, this.onProgress, this.onError)
// use format ? TextureLoader will automatically set format to THREE.RGBFormat for JPG images.
const wathProps = ['encoding', 'mapping', 'wrapS', 'wrapT', 'magFilter', 'minFilter', 'repeat', 'rotation', 'center']
wathProps.forEach(prop => { bindProp(this, prop, texture) })
return texture
}, },
refreshTexture() { initTexture() {
this.texture = this.createTexture() if (!this.texture) return
bindOptions(this.texture, this.props)
if (!this.material) return
if (this.texture && this.material) {
this.material.setTexture(this.texture, this.name) this.material.setTexture(this.texture, this.name)
if (this.material.material instanceof ShaderMaterial && this.uniform) { if (this.material.material instanceof ShaderMaterial && this.uniform) {
(this.material as any).uniforms[this.uniform] = { value: this.texture } (this.material as any).uniforms[this.uniform] = { value: this.texture }
} }
} },
refreshTexture() {
this.texture?.dispose()
this.texture = this.createTexture()
this.initTexture()
}, },
onLoaded(t: Texture) { onLoaded(t: Texture) {
this.onLoad?.(t) this.onLoad?.(t)

View File

@ -1,5 +1,18 @@
import { toRef, watch } from 'vue' import { toRef, watch } from 'vue'
export function applyOptions(dst: any, options: Record<string, unknown>): void {
if (options instanceof Object) {
Object.entries(options).forEach(([key, value]) => {
dst[key] = value
})
}
}
export function bindOptions(dst: any, options: Record<string, unknown>): void {
applyOptions(dst, options)
watch(() => options, (value) => { applyOptions(dst, value) }, { deep: true })
}
export function setFromProp(o: Record<string, unknown>, prop: Record<string, unknown>): void { export function setFromProp(o: Record<string, unknown>, prop: Record<string, unknown>): void {
if (prop instanceof Object) { if (prop instanceof Object) {
Object.entries(prop).forEach(([key, value]) => { Object.entries(prop).forEach(([key, value]) => {