Browse Source

UIConfig fixes, event additions/fixes, some types fixes

master
Palash Bansal 11 months ago
parent
commit
0e15d72ac3
No account linked to committer's email address

+ 12
- 0
src/core/IMaterial.ts View File

@@ -92,6 +92,16 @@ declare module 'three'{
bubbleToParent?: boolean
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*/
}
}

@@ -105,6 +115,8 @@ export interface IMaterialSetDirtyOptions extends ISetDirtyCommonOptions{
*/
needsUpdate?: boolean,

change?: string | keyof IMaterial

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

+ 9
- 10
src/core/IObject.ts View File

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

declare module 'three'{
export interface Object3DEventMap{
select: { // todo
select: { // todo remove?
ui?: boolean
focusCamera?: boolean
bubbleToParent?: boolean
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
} /* & IObjectSetDirtyOptions*/
@@ -47,13 +47,12 @@ export interface IObject3DEventMap extends Object3DEventMap{
materialUpdate: {
// object: IObject3D
material: IMaterial|IMaterial[]
}
} & IMaterialSetDirtyOptions
objectUpdate: {
object: IObject3D
change?: string
args?: any[]
bubbleToParent: boolean
}
} & Omit<IObjectSetDirtyOptions, 'bubbleToParent'>
textureUpdate: {
// object: IObject3D
// todo
@@ -75,7 +74,7 @@ export interface IObject3DEventMap extends Object3DEventMap{
geometry: IGeometry
// oldGeometry: IGeometry
bubbleToParent: boolean
}
} & IGeometrySetDirtyOptions
added: {
// object: IObject3D
// todo
@@ -100,7 +99,6 @@ export interface IObject3DEventMap extends Object3DEventMap{
camera?: ICamera | null
bubbleToParent: boolean
// object: IObject3D

}
cameraUpdate: {
ui?: boolean
@@ -108,7 +106,7 @@ export interface IObject3DEventMap extends Object3DEventMap{
// object: IObject3D
bubbleToParent: boolean
// todo
} & ICameraSetDirtyOptions
} & Omit<ICameraSetDirtyOptions, 'bubbleToParent'>
}
// Record<keyof IObject3DEventMap0, IObject3DEventMap0[keyof IObject3DEventMap0] & {
// // bubbleToParent?: boolean
@@ -304,6 +302,7 @@ export interface IObject3D<TE extends IObject3DEventMap = IObject3DEventMap> ext
isScene?: boolean
// isHelper?: boolean
isWidget?: boolean
isPoints?: boolean
readonly isObject3D: true

material?: IMaterial | IMaterial[]

+ 10
- 10
src/core/material/IMaterialUi.ts View File

@@ -97,7 +97,7 @@ export const iMaterialUI = {
{
type: 'checkbox',
property: [material, 'transparent'],
onChange: (ev)=>material.setDirty({uiChangeEvent: ev}),
onChange: (ev)=>material.setDirty({uiChangeEvent: ev, change: 'transparent'}),
},
{
type: 'dropdown',
@@ -119,17 +119,17 @@ export const iMaterialUI = {
{
type: 'checkbox',
property: [material, 'depthTest'],
onChange: (ev)=>material.setDirty({uiChangeEvent: ev}),
onChange: (ev)=>material.setDirty({uiChangeEvent: ev, change: 'depthTest'}),
},
{
type: 'checkbox',
property: [material, 'depthWrite'],
onChange: (ev)=>material.setDirty({uiChangeEvent: ev}),
onChange: (ev)=>material.setDirty({uiChangeEvent: ev, change: 'depthWrite'}),
},
{
type: 'checkbox',
property: [material, 'colorWrite'],
onChange: (ev)=>material.setDirty({uiChangeEvent: ev}),
onChange: (ev)=>material.setDirty({uiChangeEvent: ev, change: 'colorWrite'}),
},
{
type: 'slider',
@@ -270,7 +270,7 @@ export const iMaterialUI = {
setValue: (v: boolean)=>{
if (!v && !material.userData.renderToGBuffer) return
material.userData.renderToGBuffer = v
material.setDirty()
material.setDirty({change: 'userData', key: 'renderToGBuffer'})
},
},
{
@@ -281,7 +281,7 @@ export const iMaterialUI = {
setValue: (v: boolean)=>{
if (!v && !material.userData.renderToDepth) return
material.userData.renderToDepth = v
material.setDirty()
material.setDirty({change: 'userData', key: 'renderToDepth'})
},
},
material.isPhysicalMaterial ? {
@@ -291,7 +291,7 @@ export const iMaterialUI = {
getValue: ()=>material.userData.inverseAlphaMap === true,
setValue: (v: boolean)=>{
material.userData.inverseAlphaMap = v ? v : undefined
material.setDirty()
material.setDirty({change: 'userData', key: 'inverseAlphaMap'})
},
} : {},
],
@@ -382,7 +382,7 @@ export const iMaterialUI = {
setValue: (v: string)=>{
material.userData.envMapSlotKey = v
if (!v) delete material.userData.envMapSlotKey
material.setDirty()
material.setDirty({change: 'userData', key: 'envMapSlotKey'})
},
},
],
@@ -654,14 +654,14 @@ export const iMaterialUI = {
bounds: [0, 500],
label: 'Thickness0',
property: [material.iridescenceThicknessRange, '0'],
onChange: (ev)=>material.setDirty({uiChangeEvent: ev}),
onChange: (ev)=>material.setDirty({uiChangeEvent: ev, change: 'iridescenceThicknessRange', key: '0'}),
},
{
type: 'slider',
bounds: [0, 500],
label: 'Thickness1',
property: [material.iridescenceThicknessRange, '1'],
onChange: (ev)=>material.setDirty({uiChangeEvent: ev}),
onChange: (ev)=>material.setDirty({uiChangeEvent: ev, change: 'iridescenceThicknessRange', key: '1'}),
},
{
type: 'image',

+ 3
- 1
src/core/material/LegacyPhongMaterial.ts View File

@@ -171,8 +171,10 @@ export class LegacyPhongMaterial<TE extends IMaterialEventMap = IMaterialEventMa
expanded: true,
onChange: (ev)=>{
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.
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last})
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last, change: key})
},
children: [
...iMaterialUI.base(this),

+ 3
- 1
src/core/material/LineMaterial2.ts View File

@@ -134,8 +134,10 @@ export class LineMaterial2<TE extends IMaterialEventMap = IMaterialEventMap> ext
// 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.
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last})
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last, change: key})
},
children: [
...generateUiConfig(this) || [],

+ 3
- 1
src/core/material/ObjectShaderMaterial.ts View File

@@ -158,8 +158,10 @@ export class ObjectShaderMaterial<TE extends IMaterialEventMap = IMaterialEventM
expanded: true,
onChange: (ev)=>{
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.
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last})
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last, change: key})
},
children: [
...generateUiConfig(this),

+ 3
- 1
src/core/material/PhysicalMaterial.ts View File

@@ -133,8 +133,10 @@ export class PhysicalMaterial<TE extends IMaterialEventMap = IMaterialEventMap>
onChange: (ev)=>{
if (!ev.config || ev.config.onChange) return
// 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.
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last})
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last, change: key})
},
children: [
...iMaterialUI.base(this),

+ 3
- 1
src/core/material/UnlitLineMaterial.ts View File

@@ -161,8 +161,10 @@ export class UnlitLineMaterial<TE extends IMaterialEventMap = IMaterialEventMap>
expanded: true,
onChange: (ev)=>{
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.
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last})
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last, change: key})
},
children: [
{

+ 3
- 1
src/core/material/UnlitMaterial.ts View File

@@ -176,8 +176,10 @@ export class UnlitMaterial<TE extends IMaterialEventMap = IMaterialEventMap> ext
expanded: true,
onChange: (ev)=>{
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.
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last})
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last, change: key})
},
children: [
...iMaterialUI.base(this),

+ 2
- 2
src/core/material/iMaterialCommons.ts View File

@@ -80,7 +80,7 @@ export const iMaterialCommons = {
setDirty: function(this: IMaterial, options?: IMaterialSetDirtyOptions): void {
if (options?.needsUpdate !== false) this.needsUpdate = true
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'] =>
function(this: IMaterial, parameters: Material | (MaterialParameters & {type?: string})): IMaterial {
@@ -152,7 +152,7 @@ export const iMaterialCommons = {
superDispatchEvent.call(this, event)
const type = event.type
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}))
}

+ 25
- 2
src/core/object/IObjectUi.ts View File

@@ -69,7 +69,9 @@ export function makeIObject3DUiConfig(this: IObject3D, isMesh?:boolean): UiObjec
expanded: true,
onChange: (ev)=>{
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: [
{
@@ -104,7 +106,7 @@ export function makeIObject3DUiConfig(this: IObject3D, isMesh?:boolean): UiObjec
label: 'Name',
property: [this, 'name'],
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'})
},
},
{
@@ -183,12 +185,33 @@ export function makeIObject3DUiConfig(this: IObject3D, isMesh?:boolean): UiObjec
{
type: 'button',
label: 'Pivot to Node Center',
tags: ['context-menu', 'interaction'],
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?')
if (!res) return
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',
label: 'Delete Object',

+ 5
- 3
src/postprocessing/ScreenPass.ts View File

@@ -86,9 +86,11 @@ export class ScreenPass extends ExtendedShaderPass implements IPipelinePass<'scr
@uiToggle() clipBackground = false

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() {

Loading…
Cancel
Save