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:
commit
ec6a9db7fc
@ -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
|
||||||
|
@ -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} = () => {}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
13
src/tools.ts
13
src/tools.ts
@ -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]) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user