Przeglądaj źródła

isDisabled refactor and enabled fixes

master
Palash Bansal 2 lat temu
rodzic
commit
add88b1c77
No account linked to committer's email address

+ 8
- 8
src/plugins/animation/CameraViewPlugin.ts Wyświetl plik



@uiButton('Reset To First View') @uiButton('Reset To First View')
public async resetToFirstView(duration = 100) { public async resetToFirstView(duration = 100) {
if (!this.enabled) return
if (this.isDisabled()) return
this._currentView = undefined this._currentView = undefined
await this.animateToView(0, duration) await this.animateToView(0, duration)
await timeout(2) await timeout(2)


@uiButton('Add Current View') @uiButton('Add Current View')
async addCurrentView() { async addCurrentView() {
if (!this.enabled) return
if (this.isDisabled()) return
const camera = this._viewer?.scene.mainCamera const camera = this._viewer?.scene.mainCamera
if (!camera) return if (!camera) return
const view = this.getView(camera) const view = this.getView(camera)


@uiButton('Animate All Views') @uiButton('Animate All Views')
async animateAllViews() { async animateAllViews() {
if (!this.enabled) return
if (this.isDisabled()) return
if (this.viewLooping || this._cameraViews.length < 2) return if (this.viewLooping || this._cameraViews.length < 2) return
while (this._viewQueue.length > 0) this._viewQueue.pop() while (this._viewQueue.length > 0) this._viewQueue.pop()
this._viewQueue.push(...this._cameraViews) this._viewQueue.push(...this._cameraViews)
if (this._animationLooping) return if (this._animationLooping) return
this._animationLooping = true this._animationLooping = true
while (this.viewLooping || !this._infiniteLooping) { while (this.viewLooping || !this._infiniteLooping) {
if (!this.enabled) break
if (this.isDisabled()) break
if (this._cameraViews.length < 1) break if (this._cameraViews.length < 1) break
if (this._viewQueue.length === 0) { if (this._viewQueue.length === 0) {
if (this._infiniteLooping) this._viewQueue.push(...this._cameraViews) if (this._infiniteLooping) this._viewQueue.push(...this._cameraViews)
// * For slight rotation of camera when seekOnScroll is enabled // * For slight rotation of camera when seekOnScroll is enabled
// */ // */
// private _pointerMove(ev: PointerEvent) { // private _pointerMove(ev: PointerEvent) {
// if (!this.enabled) return
// if (this.isDisabled()) return
// if (!this._animating && this.seekOnScroll) { // if (!this._animating && this.seekOnScroll) {
// const cam = this._viewer?.scene.mainCamera // const cam = this._viewer?.scene.mainCamera
// if (!cam) return // if (!cam) return
// private _scrollAnimationState = 0 // private _scrollAnimationState = 0
// scrollAnimationDamping = 0.1 // scrollAnimationDamping = 0.1
// private _wheel(ev: any | WheelEvent) { // private _wheel(ev: any | WheelEvent) {
// if (!this.enabled) return
// if (this.isDisabled()) return
// if (this.seekOnScroll && !this._animating) { // if (this.seekOnScroll && !this._animating) {
// // if (ev.deltaY > 0) this.focusNext(false) // // if (ev.deltaY > 0) this.focusNext(false)
// // else this.focusPrevious(false) // // else this.focusPrevious(false)
// todo: same code used in PopmotionPlugin, merge somehow // todo: same code used in PopmotionPlugin, merge somehow
// private _postFrame() { // private _postFrame() {
// if (!this._viewer) return // if (!this._viewer) return
// if (!this.enabled || !this._animating) {
// if (this.isDisabled() || !this._animating) {
// this._lastFrameTime = 0 // this._lastFrameTime = 0
// if (this._fadeDisabled) { // if (this._fadeDisabled) {
// this._viewer.getPluginByType<FrameFadePlugin>('FrameFade')?.enable(CameraViewPlugin.PluginType) // this._viewer.getPluginByType<FrameFadePlugin>('FrameFade')?.enable(CameraViewPlugin.PluginType)


// @uiButton('Record All Views') // @uiButton('Record All Views')
// public async recordAllViews(onStart?: ()=>void, downloadOnEnd = true) { // public async recordAllViews(onStart?: ()=>void, downloadOnEnd = true) {
// if (!this.enabled) return
// if (this.isDisabled()) return
// const recorder = this._viewer?.getPluginByType<CanvasRecorderPlugin>('CanvasRecorder') // const recorder = this._viewer?.getPluginByType<CanvasRecorderPlugin>('CanvasRecorder')
// if (!recorder || !recorder.enabled) return // if (!recorder || !recorder.enabled) return
// if (this._cameraViews.length < 1) return // if (this._cameraViews.length < 1) return

+ 7
- 7
src/plugins/animation/GLTFAnimationPlugin.ts Wyświetl plik

* @param animations - play specific animations, otherwise play all animations. Note: the promise returned (if this is set) from this will resolve before time if the animations was ever paused, or converged mode is on in recorder. * @param animations - play specific animations, otherwise play all animations. Note: the promise returned (if this is set) from this will resolve before time if the animations was ever paused, or converged mode is on in recorder.
*/ */
async playAnimation(resetOnEnd = false, animations?: AnimationAction[]): Promise<void> { async playAnimation(resetOnEnd = false, animations?: AnimationAction[]): Promise<void> {
if (!this.enabled) return
if (this.isDisabled()) return
let wasPlaying = false let wasPlaying = false
if (this._animationState === 'playing') { if (this._animationState === 'playing') {
this.stopAnimation(false) // stop and play again. reset is done below. this.stopAnimation(false) // stop and play again. reset is done below.
this._lastAnimId = '' this._lastAnimId = ''


if (this._viewer && this._fadeDisabled) { if (this._viewer && this._fadeDisabled) {
this._viewer.getPlugin<FrameFadePlugin>('FrameFade')?.enable(GLTFAnimationPlugin.PluginType)
this._viewer.getPlugin<FrameFadePlugin>('FrameFade')?.enable(this)
this._fadeDisabled = false this._fadeDisabled = false
} }


const pageScrollAnimate = this.animateOnPageScroll // && this._animationState === 'paused' const pageScrollAnimate = this.animateOnPageScroll // && this._animationState === 'paused'
const dragAnimate = this.animateOnDrag // && this._animationState === 'paused' const dragAnimate = this.animateOnDrag // && this._animationState === 'paused'


if (!this.enabled || this.animations.length < 1 || this._animationState !== 'playing' && !scrollAnimate && !dragAnimate && !pageScrollAnimate) {
if (this.isDisabled() || this.animations.length < 1 || this._animationState !== 'playing' && !scrollAnimate && !dragAnimate && !pageScrollAnimate) {
this._lastFrameTime = 0 this._lastFrameTime = 0
// console.log('not anim') // console.log('not anim')
if (this._fadeDisabled) { if (this._fadeDisabled) {
this._viewer.getPlugin<FrameFadePlugin>('FrameFade')?.enable(GLTFAnimationPlugin.PluginType)
this._viewer.getPlugin<FrameFadePlugin>('FrameFade')?.enable(this)
this._fadeDisabled = false this._fadeDisabled = false
} }
return return
} }


private _scroll() { private _scroll() {
if (!this.enabled) return
if (this.isDisabled()) return
this._pageScrollAnimationState = this.pageScrollTime - this.animationTime this._pageScrollAnimationState = this.pageScrollTime - this.animationTime
} }


private _wheel({deltaY}: any | WheelEvent) { private _wheel({deltaY}: any | WheelEvent) {
if (!this.enabled) return
if (this.isDisabled()) return
if (Math.abs(deltaY) > 0.001) if (Math.abs(deltaY) > 0.001)
this._scrollAnimationState = -1. * Math.sign(deltaY) this._scrollAnimationState = -1. * Math.sign(deltaY)
} }


private _drag(ev: any) { private _drag(ev: any) {
if (!this.enabled || !this._viewer) return
if (this.isDisabled() || !this._viewer) return
this._dragAnimationState = this.dragAxis === 'x' ? this._dragAnimationState = this.dragAxis === 'x' ?
ev.delta.x * this._viewer.canvas.width / 4 : ev.delta.x * this._viewer.canvas.width / 4 :
ev.delta.y * this._viewer.canvas.height / 4 ev.delta.y * this._viewer.canvas.height / 4

+ 3
- 3
src/plugins/animation/PopmotionPlugin.ts Wyświetl plik

// Same code used in CameraViewPlugin // Same code used in CameraViewPlugin
private _postFrame = ()=>{ private _postFrame = ()=>{
if (!this._viewer) return if (!this._viewer) return
if (!this.enabled || Object.keys(this.animations).length < 1) {
if (this.isDisabled() || Object.keys(this.animations).length < 1) {
this._lastFrameTime = 0 this._lastFrameTime = 0
// console.log('not anim') // console.log('not anim')
if (this._fadeDisabled) { if (this._fadeDisabled) {
this._viewer.getPlugin<FrameFadePlugin>('FrameFade')?.enable(PopmotionPlugin.PluginType)
this._viewer.getPlugin<FrameFadePlugin>('FrameFade')?.enable(this)
this._fadeDisabled = false this._fadeDisabled = false
} }
return return
if (!this._fadeDisabled && this.disableFrameFade) { if (!this._fadeDisabled && this.disableFrameFade) {
const ff = this._viewer.getPlugin<FrameFadePlugin>('FrameFade') const ff = this._viewer.getPlugin<FrameFadePlugin>('FrameFade')
if (ff) { if (ff) {
ff.disable(PopmotionPlugin.PluginType)
ff.disable(this)
this._fadeDisabled = true this._fadeDisabled = true
} }
} }

+ 9
- 14
src/plugins/base/PipelinePassPlugin.ts Wyświetl plik

import {IPassID, IPipelinePass} from '../../postprocessing' import {IPassID, IPipelinePass} from '../../postprocessing'
import {AViewerPluginSync, ISerializedConfig, ThreeViewer} from '../../viewer' import {AViewerPluginSync, ISerializedConfig, ThreeViewer} from '../../viewer'
import {serialize, wrapThisFunction} from 'ts-browser-helpers'
import {onChange, serialize, wrapThisFunction} from 'ts-browser-helpers'
import {SerializationMetaType} from '../../utils' import {SerializationMetaType} from '../../utils'
import {uiConfig, uiToggle} from 'uiconfig.js' import {uiConfig, uiToggle} from 'uiconfig.js'




@serialize() @serialize()
@uiToggle('Enabled') @uiToggle('Enabled')
get enabled(): boolean {
return this._pass?.enabled || this._enabledTemp
}

set enabled(value: boolean) {
if (this._pass) this._pass.enabled = value
this._enabledTemp = value
this.setDirty()
}
@onChange(PipelinePassPlugin.prototype.setDirty)
enabled = true


@uiConfig() @uiConfig()
@serialize('pass') @serialize('pass')
/** /**
* This function is called every frame before composer render, if this pass is being used in the pipeline * This function is called every frame before composer render, if this pass is being used in the pipeline
* @param _ * @param _
* @protected
*/ */
protected _beforeRender(): boolean {return this._pass?.enabled && this.enabled || false}
private _enabledTemp = true // to save enabled state when pass is not yet created
protected _beforeRender(): boolean {
if (!this._pass) return false
this._pass.enabled = !this.isDisabled()
return this._pass.enabled
}


constructor() { constructor() {
super() super()
this._pass.onDirty?.push(viewer.setDirty) this._pass.onDirty?.push(viewer.setDirty)
this._pass.beforeRender = wrapThisFunction(this._beforeRender, this._pass.beforeRender) this._pass.beforeRender = wrapThisFunction(this._beforeRender, this._pass.beforeRender)
viewer.renderManager.registerPass(this._pass) viewer.renderManager.registerPass(this._pass)
this.enabled = this._enabledTemp
} }


onRemove(viewer: TViewer): void { onRemove(viewer: TViewer): void {
} }


setDirty() { setDirty() {
if (this._pass) this._pass.enabled = !this.isDisabled()
this._viewer?.setDirty() this._viewer?.setDirty()
this.uiConfig?.uiRefresh?.(true, 'postFrame', 100) // adding delay for a few frames, so render target(if any can update) this.uiConfig?.uiRefresh?.(true, 'postFrame', 100) // adding delay for a few frames, so render target(if any can update)
} }

+ 14
- 13
src/plugins/extras/HDRiGroundPlugin.ts Wyświetl plik

static readonly PluginType = 'HDRiGroundPlugin' static readonly PluginType = 'HDRiGroundPlugin'


@serialize() @serialize()
@onChange(HDRiGroundPlugin.prototype._paramsChanged)
@onChange(HDRiGroundPlugin.prototype.setDirty)
@uiToggle('Enabled') @uiToggle('Enabled')
enabled = false enabled = false


@serialize() @serialize()
@onChange(HDRiGroundPlugin.prototype._paramsChanged)
@onChange(HDRiGroundPlugin.prototype.setDirty)
@uiSlider('World Radius', [1, 1000], 0.01) @uiSlider('World Radius', [1, 1000], 0.01)
worldRadius = 100 worldRadius = 100


@serialize() @serialize()
@onChange(HDRiGroundPlugin.prototype._paramsChanged)
@onChange(HDRiGroundPlugin.prototype.setDirty)
@uiSlider('Tripod height', [0, 50], 0.01) @uiSlider('Tripod height', [0, 50], 0.01)
tripodHeight = 10 tripodHeight = 10


@serialize() @serialize()
@onChange(HDRiGroundPlugin.prototype._paramsChanged)
@onChange(HDRiGroundPlugin.prototype.setDirty)
@uiVector('Origin Position', undefined, 0.001, (t: HDRiGroundPlugin)=>({ @uiVector('Origin Position', undefined, 0.001, (t: HDRiGroundPlugin)=>({
onChange: t._paramsChanged, // this is for x, y, z values.
onChange: t.setDirty, // this is for x, y, z values.
})) }))
originPosition = new Vector3(0, 0, 0) originPosition = new Vector3(0, 0, 0)


@serialize() @serialize()
@onChange(HDRiGroundPlugin.prototype._paramsChanged)
@onChange(HDRiGroundPlugin.prototype.setDirty)
promptOnBackgroundMismatch = true promptOnBackgroundMismatch = true


// todo // todo
// * Automatically set the origin position based on the ground position in GroundPlugin // * Automatically set the origin position based on the ground position in GroundPlugin
// */ // */
// @serialize() // @serialize()
// @onChange(HDRiGroundPlugin.prototype._paramsChanged)
// @onChange(HDRiGroundPlugin.prototype.setDirty)
// @uiToggle('Auto Ground Position') // @uiToggle('Auto Ground Position')
// autoGroundPosition = false // autoGroundPosition = false


constructor(enabled = false, promptOnBackgroundMismatch = true) { constructor(enabled = false, promptOnBackgroundMismatch = true) {
super() super()
this._paramsChanged = this._paramsChanged.bind(this)
this.setDirty = this.setDirty.bind(this)
this.enabled = enabled this.enabled = enabled
this.promptOnBackgroundMismatch = promptOnBackgroundMismatch this.promptOnBackgroundMismatch = promptOnBackgroundMismatch


this.addEventListener('deserialize', this._paramsChanged)
this.addEventListener('deserialize', this.setDirty)
} }


private _paramsChanged() {
setDirty() {
if (!this._viewer) return if (!this._viewer) return
const bg = this._viewer.scene.background const bg = this._viewer.scene.background
if (this.enabled && bg !== this._viewer.scene.environment && bg !== 'environment') { if (this.enabled && bg !== this._viewer.scene.environment && bg !== 'environment') {
unif.worldRadius.value = this.worldRadius unif.worldRadius.value = this.worldRadius
unif.originPosition.value.copy(this.originPosition) unif.originPosition.value.copy(this.originPosition)
if (cubeMat) { if (cubeMat) {
if (!this.enabled && cubeMat.defines.HDRi_GROUND_PROJ)
if (this.isDisabled() && cubeMat.defines.HDRi_GROUND_PROJ)
delete cubeMat.defines.HDRi_GROUND_PROJ delete cubeMat.defines.HDRi_GROUND_PROJ
else if (this.enabled)
else if (!this.isDisabled())
cubeMat.defines.HDRi_GROUND_PROJ = '1' cubeMat.defines.HDRi_GROUND_PROJ = '1'
cubeMat.needsUpdate = true cubeMat.needsUpdate = true
} }
`) `)
} }


viewer.scene.addEventListener('environmentChanged', this._paramsChanged)
viewer.scene.addEventListener('environmentChanged', this.setDirty)
} }



} }

+ 2
- 2
src/plugins/interaction/DropzonePlugin.ts Wyświetl plik

*/ */
@uiButton('Select files') @uiButton('Select files')
public promptForFile(): void { public promptForFile(): void {
if (!this.enabled) return
if (this.isDisabled()) return
this.allowedExtensions = this._allowedExtensions this.allowedExtensions = this._allowedExtensions
this._inputEl?.click() this._inputEl?.click()
} }


private async _onFileDrop({files, nativeEvent}: {files: Map<string, File>, nativeEvent: DragEvent}) { private async _onFileDrop({files, nativeEvent}: {files: Map<string, File>, nativeEvent: DragEvent}) {
if (!files) return if (!files) return
if (!this.enabled) return
if (this.isDisabled()) return
const viewer = this._viewer const viewer = this._viewer
if (!viewer) return if (!viewer) return
if (this._allowedExtensions !== undefined) { if (this._allowedExtensions !== undefined) {

+ 5
- 5
src/plugins/interaction/EditorViewWidgetPlugin.ts Wyświetl plik

public static readonly PluginType = 'EditorViewWidgetPlugin' public static readonly PluginType = 'EditorViewWidgetPlugin'


@uiToggle() @uiToggle()
@onChange(EditorViewWidgetPlugin.prototype._enableChange)
@onChange(EditorViewWidgetPlugin.prototype.setDirty)
enabled = true enabled = true


protected _enableChange() {
setDirty() {
if (!this._viewer || !this.widget) return if (!this._viewer || !this.widget) return
this.widget.domContainer.style.display = this.enabled ? 'block' : 'none'
this.widget.domContainer.style.display = !this.isDisabled() ? 'block' : 'none'
} }


constructor(public readonly placement: DomPlacement = 'top-left', public readonly size = 128) { constructor(public readonly placement: DomPlacement = 'top-left', public readonly size = 128) {
protected _needsRender = false protected _needsRender = false
protected _viewerListeners = { protected _viewerListeners = {
postRender: (_: IViewerEvent)=>{ postRender: (_: IViewerEvent)=>{
if (!this._viewer || !this.widget || !this.enabled) return
if (!this._viewer || !this.widget || this.isDisabled()) return
this._needsRender = true this._needsRender = true
}, },
postFrame: (_: IViewerEvent)=>{ postFrame: (_: IViewerEvent)=>{
if (!this._viewer || !this.widget || !this.enabled || !this._needsRender) return
if (!this._viewer || !this.widget || this.isDisabled() || !this._needsRender) return
this.widget.update() this.widget.update()
this.widget.render() this.widget.render()
if (this.widget.animating) this._viewer.scene.mainCamera.setDirty() if (this.widget.animating) this._viewer.scene.mainCamera.setDirty()

+ 11
- 14
src/plugins/interaction/PickingPlugin.ts Wyświetl plik



export class PickingPlugin extends AViewerPluginSync<'selectedObjectChanged'|'hoverObjectChanged'|'hitObject'> { export class PickingPlugin extends AViewerPluginSync<'selectedObjectChanged'|'hoverObjectChanged'|'hitObject'> {
@serialize() @serialize()
@onChange(PickingPlugin.prototype._enableChange)
@onChange(PickingPlugin.prototype.setDirty)
enabled = true enabled = true


private _enableChange() {
if (!this._viewer) return
if (!this.enabled) this.setSelectedObject(undefined) // todo
}

get picker(): ObjectPicker|undefined { get picker(): ObjectPicker|undefined {
return this._picker return this._picker
} }
this.uiConfig?.uiRefresh?.(true) this.uiConfig?.uiRefresh?.(true)
} }


public setDirty() {
this._viewer?.setDirty()
setDirty() {
if (!this._viewer) return
if (this.isDisabled()) this.setSelectedObject(undefined) // todo
this._viewer.setDirty()
} }
constructor(selection: Class<SelectionWidget>|undefined = BoxSelectionWidget, pickUi = true, autoFocus = false) { constructor(selection: Class<SelectionWidget>|undefined = BoxSelectionWidget, pickUi = true, autoFocus = false) {
super() super()
} }


getSelectedObject<T extends IObject3D = IObject3D>(): T|undefined { getSelectedObject<T extends IObject3D = IObject3D>(): T|undefined {
if (!this.enabled) return
if (this.isDisabled()) return
return this._picker?.selectedObject as T || undefined return this._picker?.selectedObject as T || undefined
} }


setSelectedObject(object: IObject3D|undefined, focusCamera = false) { // todo: listen to object dispose setSelectedObject(object: IObject3D|undefined, focusCamera = false) { // todo: listen to object dispose
if (!this.enabled) return
if (this.isDisabled()) return
if (!this._picker) return if (!this._picker) return
const t = this.autoFocus const t = this.autoFocus
this.autoFocus = false this.autoFocus = false


onAdded(viewer: ThreeViewer): void { onAdded(viewer: ThreeViewer): void {
super.onAdded(viewer) super.onAdded(viewer)
this._enableChange()
this.setDirty()
this._picker = new ObjectPicker(viewer.scene.modelRoot, viewer.canvas, viewer.scene.mainCamera, (obj)=>{ this._picker = new ObjectPicker(viewer.scene.modelRoot, viewer.canvas, viewer.scene.mainCamera, (obj)=>{
const hasMat = obj.material const hasMat = obj.material
if (!hasMat) return false if (!hasMat) return false


const frameFade = this._viewer.getPlugin(FrameFadePlugin) const frameFade = this._viewer.getPlugin(FrameFadePlugin)
if (frameFade) { if (frameFade) {
if (selected) frameFade.disable(PickingPlugin.PluginType)
else frameFade.enable(PickingPlugin.PluginType)
if (selected) frameFade.disable(this)
else frameFade.enable(this)
} }


this._viewer.scene.autoNearFarEnabled = !selected // for widgets etc, this can be removed when they are rendered in a separate pass this._viewer.scene.autoNearFarEnabled = !selected // for widgets etc, this can be removed when they are rendered in a separate pass


private _onObjectHit = (e: any)=>{ private _onObjectHit = (e: any)=>{
if (!this._viewer) return if (!this._viewer) return
if (!this.enabled) {
if (this.isDisabled()) {
e.intersects.selectedObject = null e.intersects.selectedObject = null
return return
} }

+ 17
- 7
src/plugins/interaction/TransformControlsPlugin.ts Wyświetl plik

import {OrbitControls3, TransformControls2} from '../../three' import {OrbitControls3, TransformControls2} from '../../three'
import {PickingPlugin} from './PickingPlugin' import {PickingPlugin} from './PickingPlugin'
import {onChange} from 'ts-browser-helpers' import {onChange} from 'ts-browser-helpers'
import {TransformControls} from '../../three/controls/TransformControls'
import {UnlitLineMaterial, UnlitMaterial} from '../../core'


@uiPanelContainer('Transform Controls') @uiPanelContainer('Transform Controls')
export class TransformControlsPlugin extends AViewerPluginSync<''> { export class TransformControlsPlugin extends AViewerPluginSync<''> {
public static readonly PluginType = 'TransformControlsPlugin' public static readonly PluginType = 'TransformControlsPlugin'


@uiToggle() @uiToggle()
@onChange(TransformControlsPlugin.prototype._enableChange)
@onChange(TransformControlsPlugin.prototype.setDirty)
enabled = true enabled = true


private _pickingWidgetDisabled = false private _pickingWidgetDisabled = false
private _enableChange() {
setDirty() {
if (!this._viewer) return if (!this._viewer) return
const picking = this._viewer.getPlugin(PickingPlugin)! const picking = this._viewer.getPlugin(PickingPlugin)!
if (this.enabled && picking.widgetEnabled) {
const enabled = !this.isDisabled()
if (enabled && picking.widgetEnabled) {
picking.widgetEnabled = false picking.widgetEnabled = false
this._pickingWidgetDisabled = true this._pickingWidgetDisabled = true
} else if (!this.enabled && this._pickingWidgetDisabled) {
} else if (!enabled && this._pickingWidgetDisabled) {
picking.widgetEnabled = true picking.widgetEnabled = true
this._pickingWidgetDisabled = false this._pickingWidgetDisabled = false
} }
if (this.transformControls) { if (this.transformControls) {
if (this.enabled && picking.getSelectedObject()) this.transformControls.attach(picking.getSelectedObject()!)
if (enabled && picking.getSelectedObject()) this.transformControls.attach(picking.getSelectedObject()!)
else this.transformControls.detach() else this.transformControls.detach()
} }
this._viewer.setDirty()
}

constructor() {
super()
TransformControls.ObjectConstructors.MeshBasicMaterial = UnlitMaterial as any
TransformControls.ObjectConstructors.LineBasicMaterial = UnlitLineMaterial as any
} }


toJSON: any = undefined toJSON: any = undefined


onAdded(viewer: ThreeViewer) { onAdded(viewer: ThreeViewer) {
super.onAdded(viewer) super.onAdded(viewer)
this._enableChange()
this.setDirty()
this.transformControls = new TransformControls2(viewer.scene.mainCamera, viewer.canvas) this.transformControls = new TransformControls2(viewer.scene.mainCamera, viewer.canvas)
this._mainCameraChange = this._mainCameraChange.bind(this) this._mainCameraChange = this._mainCameraChange.bind(this)
viewer.scene.addEventListener('mainCameraChange', this._mainCameraChange) viewer.scene.addEventListener('mainCameraChange', this._mainCameraChange)
const picking = viewer.getPlugin(PickingPlugin)! const picking = viewer.getPlugin(PickingPlugin)!
picking.addEventListener('selectedObjectChanged', (event) => { picking.addEventListener('selectedObjectChanged', (event) => {
if (!this.transformControls) return if (!this.transformControls) return
if (!this.enabled) {
if (this.isDisabled()) {
if (this.transformControls.object) this.transformControls.detach() if (this.transformControls.object) this.transformControls.detach()
return return
} }

+ 4
- 4
src/plugins/material/ClearcoatTintPlugin.ts Wyświetl plik

// private _multiplyPass?: MultiplyPass // private _multiplyPass?: MultiplyPass
readonly materialExtension: MaterialExtension = { readonly materialExtension: MaterialExtension = {
parsFragmentSnippet: (_, material: PhysicalMaterial)=>{ parsFragmentSnippet: (_, material: PhysicalMaterial)=>{
if (!this.enabled || !material?.userData._clearcoatTint?.enableTint || !(material.clearcoat > 0)) return ''
if (this.isDisabled() || !material?.userData._clearcoatTint?.enableTint || !(material.clearcoat > 0)) return ''
return glsl` return glsl`
uniform vec3 ccTintColor; uniform vec3 ccTintColor;
uniform float ccThickness; uniform float ccThickness;
` `
}, },
shaderExtender: (shader, material: PhysicalMaterial) => { shaderExtender: (shader, material: PhysicalMaterial) => {
if (!this.enabled || !material?.userData._clearcoatTint?.enableTint || !(material.clearcoat > 0)) return
if (this.isDisabled() || !material?.userData._clearcoatTint?.enableTint || !(material.clearcoat > 0)) return


// Note: clearcoat only considers specular, not diffuse // Note: clearcoat only considers specular, not diffuse




updateMaterialDefines({ updateMaterialDefines({
// ...this._defines, // ...this._defines,
['CLEARCOAT_TINT_ENABLED']: +this.enabled,
['CLEARCOAT_TINT_ENABLED']: +!this.isDisabled(),
}, material) }, material)
}, },
extraUniforms: { extraUniforms: {
...this._uniforms, ...this._uniforms,
}, },
computeCacheKey: (material1: PhysicalMaterial) => { computeCacheKey: (material1: PhysicalMaterial) => {
return (this.enabled ? '1' : '0') + (material1.userData._clearcoatTint?.enableTint ? '1' : '0') + (material1.clearcoat > 0 ? '1' : '0')
return (this.isDisabled() ? '0' : '1') + (material1.userData._clearcoatTint?.enableTint ? '1' : '0') + (material1.clearcoat > 0 ? '1' : '0')
}, },
isCompatible: (material1: PhysicalMaterial) => { isCompatible: (material1: PhysicalMaterial) => {
return material1.isPhysicalMaterial return material1.isPhysicalMaterial

+ 2
- 2
src/plugins/material/CustomBumpMapPlugin.ts Wyświetl plik



readonly materialExtension: MaterialExtension = { readonly materialExtension: MaterialExtension = {
parsFragmentSnippet: (_, material: PhysicalMaterial)=>{ parsFragmentSnippet: (_, material: PhysicalMaterial)=>{
if (!this.enabled || !material?.userData._hasCustomBump) return ''
if (this.isDisabled() || !material?.userData._hasCustomBump) return ''
return CustomBumpMapPluginShader return CustomBumpMapPluginShader
}, },
shaderExtender: (shader, material: PhysicalMaterial) => { shaderExtender: (shader, material: PhysicalMaterial) => {
if (!this.enabled || !material?.userData._hasCustomBump) return
if (this.isDisabled() || !material?.userData._hasCustomBump) return
const customBumpMap = material.userData._customBumpMap const customBumpMap = material.userData._customBumpMap
if (!customBumpMap) return if (!customBumpMap) return



+ 4
- 4
src/plugins/material/NoiseBumpMaterialPlugin.ts Wyświetl plik



readonly materialExtension: MaterialExtension = { readonly materialExtension: MaterialExtension = {
parsFragmentSnippet: (_, material: PhysicalMaterial)=>{ parsFragmentSnippet: (_, material: PhysicalMaterial)=>{
if (!this.enabled || !material?.userData._noiseBumpMat?.hasBump) return ''
if (this.isDisabled() || !material?.userData._noiseBumpMat?.hasBump) return ''
return NoiseBumpMaterialPluginPars return NoiseBumpMaterialPluginPars
}, },
shaderExtender: (shader, material: PhysicalMaterial) => { shaderExtender: (shader, material: PhysicalMaterial) => {
if (!this.enabled || !material?.userData._noiseBumpMat?.hasBump) return
if (this.isDisabled() || !material?.userData._noiseBumpMat?.hasBump) return
shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#glMarker beforeAccumulation', NoiseBumpMaterialPluginPatch, {prepend: true}) shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#glMarker beforeAccumulation', NoiseBumpMaterialPluginPatch, {prepend: true})
;(shader as any).defines.USE_UV = '' ;(shader as any).defines.USE_UV = ''
;(shader as any).extensionDerivatives = true ;(shader as any).extensionDerivatives = true


updateMaterialDefines({ updateMaterialDefines({
// ...this._defines, // ...this._defines,
['NOISE_BUMP_MATERIAL_ENABLED']: +this.enabled,
['NOISE_BUMP_MATERIAL_ENABLED']: +!this.isDisabled(),
}, material) }, material)
}, },
extraUniforms: { extraUniforms: {
...this._uniforms, ...this._uniforms,
}, },
computeCacheKey: (material1: PhysicalMaterial) => { computeCacheKey: (material1: PhysicalMaterial) => {
return (this.enabled ? '1' : '0') + (material1.userData._noiseBumpMat?.hasBump ? '1' : '0')
return (this.isDisabled() ? '0' : '1') + (material1.userData._noiseBumpMat?.hasBump ? '1' : '0')
}, },
isCompatible: (material1: PhysicalMaterial) => material1.isPhysicalMaterial, isCompatible: (material1: PhysicalMaterial) => material1.isPhysicalMaterial,
getUiConfig: material => { getUiConfig: material => {

+ 4
- 21
src/plugins/pipeline/FrameFadePlugin.ts Wyświetl plik

this.stopTransition = this.stopTransition.bind(this) this.stopTransition = this.stopTransition.bind(this)
this._fadeCam = this._fadeCam.bind(this) this._fadeCam = this._fadeCam.bind(this)
this._fadeMat = this._fadeMat.bind(this) this._fadeMat = this._fadeMat.bind(this)
this.isDisabled = ((sup)=>()=>!this._pointerEnabled || sup())(this.isDisabled)
} }


public async startTransition(duration: number) { // duration in ms public async startTransition(duration: number) { // duration in ms


} }



private _disabledBy: string[] = []

disable(name: string) {
if (!this._disabledBy.includes(name)) {
this._disabledBy.push(name)
}
}
enable(name: string) {
const i = this._disabledBy.indexOf(name)
if (i >= 0) {
this._disabledBy.splice(i, 1)
}
}
isDisabled() {
return !this._pointerEnabled || this._disabledBy.length > 0 || !this.enabled
}

setDirty() { setDirty() {
if (!this.enabled) return
if (this.isDisabled()) return
this._viewer?.setDirty() this._viewer?.setDirty()
} }


get dirty() { get dirty() {
return this.enabled && !!this._pass && this._pass.fadeTimeState > 0
return !this.isDisabled() && !!this._pass && this._pass.fadeTimeState > 0
} }


set dirty(_: boolean) { set dirty(_: boolean) {


get canFrameFade() { get canFrameFade() {
return this._target && this._pointerEnabled && return this._target && this._pointerEnabled &&
this.enabled && this.dirty && this._pass &&
this.dirty && this._pass &&
this._pass.fadeTimeState > 0.001 && this._pass.fadeTimeState > 0.001 &&
this._viewer && this._viewer.scene.renderCamera === this._viewer.scene.mainCamera this._viewer && this._viewer.scene.renderCamera === this._viewer.scene.mainCamera
} }

+ 4
- 3
src/plugins/postprocessing/AScreenPassExtensionPlugin.ts Wyświetl plik

import {AViewerPlugin, AViewerPluginSync, ThreeViewer} from '../../viewer'
import {type AViewerPlugin, AViewerPluginSync} from '../../viewer/AViewerPlugin'
import type {ThreeViewer} from '../../viewer'
import {MaterialExtension} from '../../materials' import {MaterialExtension} from '../../materials'
import {Shader, Vector4, WebGLRenderer} from 'three' import {Shader, Vector4, WebGLRenderer} from 'three'
import {IMaterial} from '../../core' import {IMaterial} from '../../core'
protected _shaderPatch = '' protected _shaderPatch = ''


shaderExtender(shader: Shader, _: IMaterial, _1: WebGLRenderer): void { shaderExtender(shader: Shader, _: IMaterial, _1: WebGLRenderer): void {
if (!this.enabled) return
if (this.isDisabled()) return


shader.fragmentShader = shaderReplaceString( shader.fragmentShader = shaderReplaceString(
shader.fragmentShader, shader.fragmentShader,
return this.uiConfig return this.uiConfig
} }


computeCacheKey = (_: IMaterial) => this.enabled ? '1' : '0'
computeCacheKey = (_: IMaterial) => this.isDisabled() ? '0' : '1'


isCompatible(_: IMaterial): boolean { isCompatible(_: IMaterial): boolean {
return true // (material as MeshStandardMaterial2).isMeshStandardMaterial2 return true // (material as MeshStandardMaterial2).isMeshStandardMaterial2

+ 1
- 1
src/plugins/postprocessing/ChromaticAberrationPlugin.ts Wyświetl plik

priority = -50 priority = -50


parsFragmentSnippet = () => { parsFragmentSnippet = () => {
if (!this.enabled) return ''
if (this.isDisabled()) return ''


return glsl` return glsl`
uniform float aberrationIntensity; uniform float aberrationIntensity;

+ 1
- 1
src/plugins/postprocessing/FilmicGrainPlugin.ts Wyświetl plik

priority = -50 priority = -50


parsFragmentSnippet = () => { parsFragmentSnippet = () => {
if (!this.enabled) return ''
if (this.isDisabled()) return ''


return glsl` return glsl`
uniform float grainIntensity; uniform float grainIntensity;

+ 2
- 2
src/plugins/postprocessing/TonemapPlugin.ts Wyświetl plik

priority = -100 priority = -100


parsFragmentSnippet = () => { parsFragmentSnippet = () => {
if (!this.enabled) return ''
if (this.isDisabled()) return ''


return glsl` return glsl`
uniform float toneMappingContrast; uniform float toneMappingContrast;
private _rendererState: any = {} private _rendererState: any = {}


onObjectRender(_: Object3D, material: IMaterial, renderer: WebGLRenderer): void { onObjectRender(_: Object3D, material: IMaterial, renderer: WebGLRenderer): void {
if (!this.enabled) return
if (this.isDisabled()) return
const {toneMapping, toneMappingExposure} = renderer const {toneMapping, toneMappingExposure} = renderer
this._rendererState.toneMapping = toneMapping this._rendererState.toneMapping = toneMapping
this._rendererState.toneMappingExposure = toneMappingExposure this._rendererState.toneMappingExposure = toneMappingExposure

+ 1
- 1
src/plugins/postprocessing/VignettePlugin.ts Wyświetl plik

priority = -50 priority = -50


parsFragmentSnippet = () => { parsFragmentSnippet = () => {
if (!this.enabled) return ''
if (this.isDisabled()) return ''


return glsl` return glsl`
uniform float power; uniform float power;

+ 1
- 1
src/plugins/rendering/VirtualCamerasPlugin.ts Wyświetl plik



protected _viewerListeners = { protected _viewerListeners = {
preRender: () => { preRender: () => {
if (!this.enabled || !this._viewer) return
if (this.isDisabled() || !this._viewer) return
const viewer = this._viewer const viewer = this._viewer
for (const v of this.cameras) { for (const v of this.cameras) {
if (!v.enabled) continue if (!v.enabled) continue

+ 6
- 2
src/plugins/ui/GeometryUVPreviewPlugin.ts Wyświetl plik

import {AViewerPluginSync, ThreeViewer} from '../../viewer' import {AViewerPluginSync, ThreeViewer} from '../../viewer'
import {createDiv, createStyles, getOrCall, onChange, ValOrFunc} from 'ts-browser-helpers' import {createDiv, createStyles, getOrCall, onChange, ValOrFunc} from 'ts-browser-helpers'
import styles from './GeometryUVPreviewPlugin.css'
import styles from './GeometryUVPreviewPlugin.css?inline'
import {CustomContextMenu} from '../../utils' import {CustomContextMenu} from '../../utils'
import {uiFolderContainer, uiToggle} from 'uiconfig.js' import {uiFolderContainer, uiToggle} from 'uiconfig.js'
import {IGeometry} from '../../core' import {IGeometry} from '../../core'
return return
} }
if (!this.mainDiv.parentElement) this._viewer.container?.appendChild(this.mainDiv) if (!this.mainDiv.parentElement) this._viewer.container?.appendChild(this.mainDiv)
this.mainDiv.style.display = this.enabled ? 'flex' : 'none'
this.mainDiv.style.display = !this.isDisabled() ? 'flex' : 'none'
this.mainDiv.style.zIndex = parseInt(this._viewer.canvas.style.zIndex || '0') + 1 + '' this.mainDiv.style.zIndex = parseInt(this._viewer.canvas.style.zIndex || '0') + 1 + ''
this._viewer?.setDirty() this._viewer?.setDirty()
} }


setDirty() { // for enable/disable functions
this.refreshUi()
}

dispose() { dispose() {
for (const target of this.targetBlocks) { for (const target of this.targetBlocks) {
this.removeGeometry(target.target) this.removeGeometry(target.target)

+ 6
- 2
src/plugins/ui/RenderTargetPreviewPlugin.ts Wyświetl plik

import {IRenderTarget} from '../../rendering' import {IRenderTarget} from '../../rendering'
import {createDiv, createStyles, getOrCall, onChange, ValOrFunc} from 'ts-browser-helpers' import {createDiv, createStyles, getOrCall, onChange, ValOrFunc} from 'ts-browser-helpers'
import {SRGBColorSpace, Vector4, WebGLRenderTarget} from 'three' import {SRGBColorSpace, Vector4, WebGLRenderTarget} from 'three'
import styles from './RenderTargetPreviewPlugin.css'
import styles from './RenderTargetPreviewPlugin.css?inline'
import {CustomContextMenu} from '../../utils' import {CustomContextMenu} from '../../utils'
import {uiFolderContainer, uiToggle} from 'uiconfig.js' import {uiFolderContainer, uiToggle} from 'uiconfig.js'


return return
} }
if (!this.mainDiv.parentElement) this._viewer.container?.appendChild(this.mainDiv) if (!this.mainDiv.parentElement) this._viewer.container?.appendChild(this.mainDiv)
this.mainDiv.style.display = this.enabled ? 'flex' : 'none'
this.mainDiv.style.display = !this.isDisabled() ? 'flex' : 'none'
this.mainDiv.style.zIndex = parseInt(this._viewer.canvas.style.zIndex || '0') + 1 + '' this.mainDiv.style.zIndex = parseInt(this._viewer.canvas.style.zIndex || '0') + 1 + ''
this._viewer?.setDirty() this._viewer?.setDirty()
} }


setDirty() { // for enable/disable functions
this.refreshUi()
}

dispose() { dispose() {
for (const target of this.targetBlocks) { for (const target of this.targetBlocks) {
this.removeTarget(target.target) this.removeTarget(target.target)

+ 16
- 0
src/viewer/AViewerPlugin.ts Wyświetl plik

return e return e
} }


private _disabledBy = new Set<any>()
disable = (key: any) => {
const size = this._disabledBy.size
this._disabledBy.add(key)
if (this.setDirty && size !== this._disabledBy.size) this.setDirty()
}
enable = (key: any) => {
const size = this._disabledBy.size
this._disabledBy.delete(key)
if (this.setDirty && size !== this._disabledBy.size) this.setDirty()
}
isDisabled = () => {
return this._disabledBy.size > 0 || !this.enabled
}

setDirty?(...args: any[]): any


// todo: move to ThreeViewer // todo: move to ThreeViewer
// storeState(prefix?: string, storage?: Storage, data?: any): void { // storeState(prefix?: string, storage?: Storage, data?: any): void {

Ładowanie…
Anuluj
Zapisz