Kaynağa Gözat

UIConfig fixes, event additions/fixes, some types fixes

master
Palash Bansal 11 ay önce
ebeveyn
işleme
0e15d72ac3
No account linked to committer's email address

+ 12
- 0
src/core/IMaterial.ts Dosyayı Görüntüle

bubbleToParent?: boolean bubbleToParent?: boolean
uiChangeEvent?: ChangeEvent uiChangeEvent?: ChangeEvent
} }
select: { // todo remove?
ui?: boolean
// focusCamera?: boolean // todo ?
bubbleToObject?: boolean
bubbleToParent?: boolean
material: IMaterial
value?: /* IObject3D | */ IMaterial | null // todo is this required?

source?: string // who is triggering the event. so that recursive events can be prevented
} /* & IObjectSetDirtyOptions*/
} }
} }


*/ */
needsUpdate?: boolean, needsUpdate?: boolean,


change?: string | keyof IMaterial

[key: string]: any [key: string]: any
} }
export interface IMaterialUserData extends IImportResultUserData{ export interface IMaterialUserData extends IImportResultUserData{

+ 9
- 10
src/core/IObject.ts Dosyayı Görüntüle

import {IMaterial, IMaterialEventMap} from './IMaterial'
import {IMaterial, IMaterialEventMap, IMaterialSetDirtyOptions} from './IMaterial'
import {Box3, EventListener2, Object3D, Object3DEventMap, Sphere, Vector3} from 'three' import {Box3, EventListener2, Object3D, Object3DEventMap, Sphere, Vector3} from 'three'
import {ChangeEvent, IUiConfigContainer, UiObjectConfig} from 'uiconfig.js' import {ChangeEvent, IUiConfigContainer, UiObjectConfig} from 'uiconfig.js'
import {IGeometry, IGeometryEventMap} from './IGeometry'
import {IGeometry, IGeometryEventMap, IGeometrySetDirtyOptions} from './IGeometry'
import {IImportResultUserData} from '../assetmanager' import {IImportResultUserData} from '../assetmanager'
import {GLTF} from 'three/examples/jsm/loaders/GLTFLoader.js' import {GLTF} from 'three/examples/jsm/loaders/GLTFLoader.js'
import {ICamera, type ICameraSetDirtyOptions} from './ICamera' import {ICamera, type ICameraSetDirtyOptions} from './ICamera'


declare module 'three'{ declare module 'three'{
export interface Object3DEventMap{ export interface Object3DEventMap{
select: { // todo
select: { // todo remove?
ui?: boolean ui?: boolean
focusCamera?: boolean focusCamera?: boolean
bubbleToParent?: boolean bubbleToParent?: boolean
object: IObject3D object: IObject3D
value?: IObject3D /* | Material*/ // todo is this required?
value?: IObject3D|null /* | Material*/ // todo is this required?


source?: string // who is triggering the event. so that recursive events can be prevented source?: string // who is triggering the event. so that recursive events can be prevented
} /* & IObjectSetDirtyOptions*/ } /* & IObjectSetDirtyOptions*/
materialUpdate: { materialUpdate: {
// object: IObject3D // object: IObject3D
material: IMaterial|IMaterial[] material: IMaterial|IMaterial[]
}
} & IMaterialSetDirtyOptions
objectUpdate: { objectUpdate: {
object: IObject3D object: IObject3D
change?: string
args?: any[] args?: any[]
bubbleToParent: boolean bubbleToParent: boolean
}
} & Omit<IObjectSetDirtyOptions, 'bubbleToParent'>
textureUpdate: { textureUpdate: {
// object: IObject3D // object: IObject3D
// todo // todo
geometry: IGeometry geometry: IGeometry
// oldGeometry: IGeometry // oldGeometry: IGeometry
bubbleToParent: boolean bubbleToParent: boolean
}
} & IGeometrySetDirtyOptions
added: { added: {
// object: IObject3D // object: IObject3D
// todo // todo
camera?: ICamera | null camera?: ICamera | null
bubbleToParent: boolean bubbleToParent: boolean
// object: IObject3D // object: IObject3D

} }
cameraUpdate: { cameraUpdate: {
ui?: boolean ui?: boolean
// object: IObject3D // object: IObject3D
bubbleToParent: boolean bubbleToParent: boolean
// todo // todo
} & ICameraSetDirtyOptions
} & Omit<ICameraSetDirtyOptions, 'bubbleToParent'>
} }
// Record<keyof IObject3DEventMap0, IObject3DEventMap0[keyof IObject3DEventMap0] & { // Record<keyof IObject3DEventMap0, IObject3DEventMap0[keyof IObject3DEventMap0] & {
// // bubbleToParent?: boolean // // bubbleToParent?: boolean
isScene?: boolean isScene?: boolean
// isHelper?: boolean // isHelper?: boolean
isWidget?: boolean isWidget?: boolean
isPoints?: boolean
readonly isObject3D: true readonly isObject3D: true


material?: IMaterial | IMaterial[] material?: IMaterial | IMaterial[]

+ 10
- 10
src/core/material/IMaterialUi.ts Dosyayı Görüntüle

{ {
type: 'checkbox', type: 'checkbox',
property: [material, 'transparent'], property: [material, 'transparent'],
onChange: (ev)=>material.setDirty({uiChangeEvent: ev}),
onChange: (ev)=>material.setDirty({uiChangeEvent: ev, change: 'transparent'}),
}, },
{ {
type: 'dropdown', type: 'dropdown',
{ {
type: 'checkbox', type: 'checkbox',
property: [material, 'depthTest'], property: [material, 'depthTest'],
onChange: (ev)=>material.setDirty({uiChangeEvent: ev}),
onChange: (ev)=>material.setDirty({uiChangeEvent: ev, change: 'depthTest'}),
}, },
{ {
type: 'checkbox', type: 'checkbox',
property: [material, 'depthWrite'], property: [material, 'depthWrite'],
onChange: (ev)=>material.setDirty({uiChangeEvent: ev}),
onChange: (ev)=>material.setDirty({uiChangeEvent: ev, change: 'depthWrite'}),
}, },
{ {
type: 'checkbox', type: 'checkbox',
property: [material, 'colorWrite'], property: [material, 'colorWrite'],
onChange: (ev)=>material.setDirty({uiChangeEvent: ev}),
onChange: (ev)=>material.setDirty({uiChangeEvent: ev, change: 'colorWrite'}),
}, },
{ {
type: 'slider', type: 'slider',
setValue: (v: boolean)=>{ setValue: (v: boolean)=>{
if (!v && !material.userData.renderToGBuffer) return if (!v && !material.userData.renderToGBuffer) return
material.userData.renderToGBuffer = v material.userData.renderToGBuffer = v
material.setDirty()
material.setDirty({change: 'userData', key: 'renderToGBuffer'})
}, },
}, },
{ {
setValue: (v: boolean)=>{ setValue: (v: boolean)=>{
if (!v && !material.userData.renderToDepth) return if (!v && !material.userData.renderToDepth) return
material.userData.renderToDepth = v material.userData.renderToDepth = v
material.setDirty()
material.setDirty({change: 'userData', key: 'renderToDepth'})
}, },
}, },
material.isPhysicalMaterial ? { material.isPhysicalMaterial ? {
getValue: ()=>material.userData.inverseAlphaMap === true, getValue: ()=>material.userData.inverseAlphaMap === true,
setValue: (v: boolean)=>{ setValue: (v: boolean)=>{
material.userData.inverseAlphaMap = v ? v : undefined material.userData.inverseAlphaMap = v ? v : undefined
material.setDirty()
material.setDirty({change: 'userData', key: 'inverseAlphaMap'})
}, },
} : {}, } : {},
], ],
setValue: (v: string)=>{ setValue: (v: string)=>{
material.userData.envMapSlotKey = v material.userData.envMapSlotKey = v
if (!v) delete material.userData.envMapSlotKey if (!v) delete material.userData.envMapSlotKey
material.setDirty()
material.setDirty({change: 'userData', key: 'envMapSlotKey'})
}, },
}, },
], ],
bounds: [0, 500], bounds: [0, 500],
label: 'Thickness0', label: 'Thickness0',
property: [material.iridescenceThicknessRange, '0'], property: [material.iridescenceThicknessRange, '0'],
onChange: (ev)=>material.setDirty({uiChangeEvent: ev}),
onChange: (ev)=>material.setDirty({uiChangeEvent: ev, change: 'iridescenceThicknessRange', key: '0'}),
}, },
{ {
type: 'slider', type: 'slider',
bounds: [0, 500], bounds: [0, 500],
label: 'Thickness1', label: 'Thickness1',
property: [material.iridescenceThicknessRange, '1'], property: [material.iridescenceThicknessRange, '1'],
onChange: (ev)=>material.setDirty({uiChangeEvent: ev}),
onChange: (ev)=>material.setDirty({uiChangeEvent: ev, change: 'iridescenceThicknessRange', key: '1'}),
}, },
{ {
type: 'image', type: 'image',

+ 3
- 1
src/core/material/LegacyPhongMaterial.ts Dosyayı Görüntüle

expanded: true, expanded: true,
onChange: (ev)=>{ onChange: (ev)=>{
if (!ev.config || ev.config.onChange) return if (!ev.config || ev.config.onChange) return
let key = Array.isArray(ev.config.property) ? ev.config.property[1] : ev.config.property
key = typeof key === 'string' ? key : undefined
// todo set needsUpdate true only for properties that require it like maps. // todo set needsUpdate true only for properties that require it like maps.
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last})
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last, change: key})
}, },
children: [ children: [
...iMaterialUI.base(this), ...iMaterialUI.base(this),

+ 3
- 1
src/core/material/LineMaterial2.ts Dosyayı Görüntüle

// m.computeLineDistances() // m.computeLineDistances()
// } // }
// }) // })
let key = Array.isArray(ev.config.property) ? ev.config.property[1] : ev.config.property
key = typeof key === 'string' ? key : undefined
// todo set needsUpdate true only for properties that require it like maps. // todo set needsUpdate true only for properties that require it like maps.
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last})
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last, change: key})
}, },
children: [ children: [
...generateUiConfig(this) || [], ...generateUiConfig(this) || [],

+ 3
- 1
src/core/material/ObjectShaderMaterial.ts Dosyayı Görüntüle

expanded: true, expanded: true,
onChange: (ev)=>{ onChange: (ev)=>{
if (!ev.config || ev.config.onChange) return if (!ev.config || ev.config.onChange) return
let key = Array.isArray(ev.config.property) ? ev.config.property[1] : ev.config.property
key = typeof key === 'string' ? key : undefined
// todo set needsUpdate true only for properties that require it like maps. // todo set needsUpdate true only for properties that require it like maps.
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last})
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last, change: key})
}, },
children: [ children: [
...generateUiConfig(this), ...generateUiConfig(this),

+ 3
- 1
src/core/material/PhysicalMaterial.ts Dosyayı Görüntüle

onChange: (ev)=>{ onChange: (ev)=>{
if (!ev.config || ev.config.onChange) return if (!ev.config || ev.config.onChange) return
// todo frameFade // todo frameFade
let key = Array.isArray(ev.config.property) ? ev.config.property[1] : ev.config.property
key = typeof key === 'string' ? key : undefined
// todo set needsUpdate true only for properties that require it like maps. // todo set needsUpdate true only for properties that require it like maps.
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last})
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last, change: key})
}, },
children: [ children: [
...iMaterialUI.base(this), ...iMaterialUI.base(this),

+ 3
- 1
src/core/material/UnlitLineMaterial.ts Dosyayı Görüntüle

expanded: true, expanded: true,
onChange: (ev)=>{ onChange: (ev)=>{
if (!ev.config || ev.config.onChange) return if (!ev.config || ev.config.onChange) return
let key = Array.isArray(ev.config.property) ? ev.config.property[1] : ev.config.property
key = typeof key === 'string' ? key : undefined
// todo set needsUpdate true only for properties that require it like maps. // todo set needsUpdate true only for properties that require it like maps.
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last})
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last, change: key})
}, },
children: [ children: [
{ {

+ 3
- 1
src/core/material/UnlitMaterial.ts Dosyayı Görüntüle

expanded: true, expanded: true,
onChange: (ev)=>{ onChange: (ev)=>{
if (!ev.config || ev.config.onChange) return if (!ev.config || ev.config.onChange) return
let key = Array.isArray(ev.config.property) ? ev.config.property[1] : ev.config.property
key = typeof key === 'string' ? key : undefined
// todo set needsUpdate true only for properties that require it like maps. // todo set needsUpdate true only for properties that require it like maps.
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last})
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last, change: key})
}, },
children: [ children: [
...iMaterialUI.base(this), ...iMaterialUI.base(this),

+ 2
- 2
src/core/material/iMaterialCommons.ts Dosyayı Görüntüle

setDirty: function(this: IMaterial, options?: IMaterialSetDirtyOptions): void { setDirty: function(this: IMaterial, options?: IMaterialSetDirtyOptions): void {
if (options?.needsUpdate !== false) this.needsUpdate = true if (options?.needsUpdate !== false) this.needsUpdate = true
this.dispatchEvent({bubbleToObject: true, bubbleToParent: true, ...options, type: 'materialUpdate'}) // this sets sceneUpdate in root scene this.dispatchEvent({bubbleToObject: true, bubbleToParent: true, ...options, type: 'materialUpdate'}) // this sets sceneUpdate in root scene
if (options?.last !== false) this.uiConfig?.uiRefresh?.(true, 'postFrame', 1)
if (options?.last !== false && options?.refreshUi !== false) this.uiConfig?.uiRefresh?.(true, 'postFrame', 1)
}, },
setValues: (superSetValues: Material['setValues']): IMaterial['setValues'] => setValues: (superSetValues: Material['setValues']): IMaterial['setValues'] =>
function(this: IMaterial, parameters: Material | (MaterialParameters & {type?: string})): IMaterial { function(this: IMaterial, parameters: Material | (MaterialParameters & {type?: string})): IMaterial {
superDispatchEvent.call(this, event) superDispatchEvent.call(this, event)
const type = event.type const type = event.type
if ((event as IMaterialEventMap['materialUpdate']).bubbleToObject && ( if ((event as IMaterialEventMap['materialUpdate']).bubbleToObject && (
type === 'beforeDeserialize' || type === 'materialUpdate' || type === 'textureUpdate' // todo - add more events
type === 'beforeDeserialize' || type === 'materialUpdate' || type === 'textureUpdate' || type === 'select' // todo - add more events
)) { )) {
this.appliedMeshes.forEach(m => m.dispatchEvent({...event, material: this, type})) this.appliedMeshes.forEach(m => m.dispatchEvent({...event, material: this, type}))
} }

+ 25
- 2
src/core/object/IObjectUi.ts Dosyayı Görüntüle

expanded: true, expanded: true,
onChange: (ev)=>{ onChange: (ev)=>{
if (!ev.config || ev.config.onChange) return if (!ev.config || ev.config.onChange) return
this.setDirty({uiChangeEvent: ev, refreshScene: false, refreshUi: true})
let key = Array.isArray(ev.config.property) ? ev.config.property[1] : ev.config.property
key = typeof key === 'string' ? key : undefined
this.setDirty({uiChangeEvent: ev, refreshScene: false, refreshUi: !!ev.last, change: key})
}, },
children: [ children: [
{ {
label: 'Name', label: 'Name',
property: [this, 'name'], property: [this, 'name'],
onChange: (e)=>{ onChange: (e)=>{
if (e.last) this.setDirty?.({uiChangeEvent: e, refreshScene: true, frameFade: false, refreshUi: true})
if (e.last) this.setDirty?.({uiChangeEvent: e, refreshScene: true, frameFade: false, refreshUi: true, change: 'name'})
}, },
}, },
{ {
{ {
type: 'button', type: 'button',
label: 'Pivot to Node Center', label: 'Pivot to Node Center',
tags: ['context-menu', 'interaction'],
value: async()=>{ value: async()=>{
const res = await ThreeViewer.Dialog.confirm('Pivot to Center: Adjust the pivot to bounding box center. The object will rotate around the new pivot, are you sure you want to proceed?') const res = await ThreeViewer.Dialog.confirm('Pivot to Center: Adjust the pivot to bounding box center. The object will rotate around the new pivot, are you sure you want to proceed?')
if (!res) return if (!res) return
return this.pivotToBoundsCenter?.(true) // return value is the undo function return this.pivotToBoundsCenter?.(true) // return value is the undo function
}, },
}, },
{
type: 'button',
label: 'Duplicate Object',
tags: ['context-menu'],
value: async()=>{
const parent = this.parent
const clone = this.clone(true) as IObject3D
clone.name = this.name + ' (copy)'
return {
action: ()=>{
if (parent && !clone.parent)
parent.add(clone) // todo same index?
},
undo: ()=>{
if (clone.parent === parent)
clone.removeFromParent()
},
}
},
},
{ {
type: 'button', type: 'button',
label: 'Delete Object', label: 'Delete Object',

+ 5
- 3
src/postprocessing/ScreenPass.ts Dosyayı Görüntüle

@uiToggle() clipBackground = false @uiToggle() clipBackground = false


beforeRender(_: IScene, _1: ICamera, renderManager: ViewerRenderManager) { beforeRender(_: IScene, _1: ICamera, renderManager: ViewerRenderManager) {
this.material.uniforms.tTransparent.value = renderManager.renderPass.preserveTransparentTarget ? renderManager.renderPass.transparentTarget?.texture || null : null
this.material.defines.HAS_TRANSPARENT_TARGET = this.material.uniforms.tTransparent.value ? 1 : undefined
if (!this.material.defines.HAS_TRANSPARENT_TARGET) delete this.material.defines.HAS_TRANSPARENT_TARGET
if (this.material.uniforms.tTransparent) {
this.material.uniforms.tTransparent.value = renderManager.renderPass.preserveTransparentTarget ? renderManager.renderPass.transparentTarget?.texture || null : null
this.material.defines.HAS_TRANSPARENT_TARGET = this.material.uniforms.tTransparent.value ? 1 : undefined
if (!this.material.defines.HAS_TRANSPARENT_TARGET) delete this.material.defines.HAS_TRANSPARENT_TARGET
}
} }


setDirty() { setDirty() {

Loading…
İptal
Kaydet