Просмотр исходного кода

Render target clone fix, add OldPluginType, other minor fixes.

master
Palash Bansal 2 лет назад
Родитель
Сommit
8f0efa6e76
Аккаунт пользователя с таким Email не найден

+ 2
- 1
src/assetmanager/gltf/GLTFViewerConfigExtension.ts Просмотреть файл



viewerConfig.resources = await viewer.loadConfigResources(viewerConfig.resources || {}, extraResources) viewerConfig.resources = await viewer.loadConfigResources(viewerConfig.resources || {}, extraResources)


if (resultScene) (resultScene as RootSceneImportResult).importedViewerConfig = viewerConfig
} }


if (resultScene) (resultScene as RootSceneImportResult).importedViewerConfig = viewerConfig

return viewerConfig return viewerConfig
} }



+ 28
- 4
src/core/ICamera.ts Просмотреть файл

export type TCameraControlsMode = '' | 'orbit' | 'deviceOrientation' | 'threeFirstPerson' | 'pointerLock' | string export type TCameraControlsMode = '' | 'orbit' | 'deviceOrientation' | 'threeFirstPerson' | 'pointerLock' | string


export interface ICameraUserData extends IObject3DUserData { export interface ICameraUserData extends IObject3DUserData {
autoNearFar?: boolean // default = true
minNearPlane?: number // default = 0.2
maxFarPlane?: number // default = 1000
autoLookAtTarget?: boolean // default = false, only for when controls and interactions are disabled
/**
* Automatically calculate near and far planes based on the scene bounding box.
*/
autoNearFar?: boolean
/**
* Minimum near plane distance. (when {@link autoNearFar} is true)
* Or the near plane distance when {@link autoNearFar} is false.
* @default 0.2
*/
minNearPlane?: number
/**
* Maximum far plane distance. (when {@link autoNearFar} is true)
* Or the far plane distance when {@link autoNearFar} is false.
* @default 1000
*/
maxFarPlane?: number
/**
* Automatically rotate camera to look at(lookAt) the target.
* Only for when controls and interactions are disabled.
* @default false
*/
autoLookAtTarget?: boolean

/**
* Disable jitter for this camera. (for {@link SSAAPlugin})
* @default false
*/
disableJitter?: boolean


__lastScale?: Vector3, __lastScale?: Vector3,
__isMainCamera?: boolean, __isMainCamera?: boolean,

+ 13
- 11
src/core/object/RootScene.ts Просмотреть файл

import {uiButton, uiColor, uiConfig, uiFolderContainer, uiImage, UiObjectConfig, uiSlider, uiToggle} from 'uiconfig.js' import {uiButton, uiColor, uiConfig, uiFolderContainer, uiImage, UiObjectConfig, uiSlider, uiToggle} from 'uiconfig.js'
import {IGeometry} from '../IGeometry' import {IGeometry} from '../IGeometry'


export type TCamera = ICamera

@uiFolderContainer('Root Scene') @uiFolderContainer('Root Scene')
export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements IScene<ISceneEvent, ISceneEventTypes> { export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements IScene<ISceneEvent, ISceneEventTypes> {
readonly isRootScene = true readonly isRootScene = true


// private _processors = new ObjectProcessorMap<'environment' | 'background'>() // private _processors = new ObjectProcessorMap<'environment' | 'background'>()
// private _sceneObjects: ISceneObject[] = [] // private _sceneObjects: ISceneObject[] = []
private _mainCamera: ICamera | null = null
private _mainCamera: TCamera | null = null
/** /**
* The root object where all imported objects are added. * The root object where all imported objects are added.
*/ */
/** /**
* The default camera in the scene * The default camera in the scene
*/ */
@uiConfig() @serialize() readonly defaultCamera: ICamera
@uiConfig() @serialize() readonly defaultCamera: TCamera


// private _environmentLight?: IEnvironmentLight // private _environmentLight?: IEnvironmentLight


// required just because we don't want activeCamera to be null. // required just because we don't want activeCamera to be null.
private _dummyCam = new PerspectiveCamera2('') as ICamera
private _dummyCam = new PerspectiveCamera2('') as TCamera


get mainCamera(): ICamera {
get mainCamera(): TCamera {
return this._mainCamera || this._dummyCam return this._mainCamera || this._dummyCam
} }
set mainCamera(camera: ICamera | undefined) {
set mainCamera(camera: TCamera | undefined) {
const cam = this.mainCamera const cam = this.mainCamera
if (!camera) camera = this.defaultCamera if (!camera) camera = this.defaultCamera
if (cam === camera) return if (cam === camera) return
this.setDirty() this.setDirty()
} }


private _renderCamera: ICamera | undefined
private _renderCamera: TCamera | undefined
get renderCamera() { get renderCamera() {
return this._renderCamera ?? this.mainCamera return this._renderCamera ?? this.mainCamera
} }
set renderCamera(camera: ICamera) {
set renderCamera(camera: TCamera) {
const cam = this._renderCamera const cam = this._renderCamera
this._renderCamera = camera this._renderCamera = camera
this.dispatchEvent({type: 'renderCameraChange', lastCamera: cam, camera}) this.dispatchEvent({type: 'renderCameraChange', lastCamera: cam, camera})
* @param camera * @param camera
* @param objectProcessor * @param objectProcessor
*/ */
constructor(camera: ICamera, objectProcessor?: IObjectProcessor) {
constructor(camera: TCamera, objectProcessor?: IObjectProcessor) {
super() super()
this.setDirty = this.setDirty.bind(this) this.setDirty = this.setDirty.bind(this)


* This is called automatically every time the camera is updated. * This is called automatically every time the camera is updated.
*/ */
refreshActiveCameraNearFar(): void { refreshActiveCameraNearFar(): void {
const camera = this.mainCamera as ICamera
const camera = this.mainCamera as TCamera
if (!camera) return if (!camera) return
if (!this.autoNearFarEnabled || camera.userData.autoNearFar === false) { if (!this.autoNearFarEnabled || camera.userData.autoNearFar === false) {
camera.near = camera.userData.minNearPlane ?? 0.5 camera.near = camera.userData.minNearPlane ?? 0.5
/** /**
* @deprecated * @deprecated
*/ */
get activeCamera(): ICamera {
get activeCamera(): TCamera {
console.error('activeCamera is deprecated. Use mainCamera instead.') console.error('activeCamera is deprecated. Use mainCamera instead.')
return this.mainCamera return this.mainCamera
} }
/** /**
* @deprecated * @deprecated
*/ */
set activeCamera(camera: ICamera | undefined) {
set activeCamera(camera: TCamera | undefined) {
console.error('activeCamera is deprecated. Use mainCamera instead.') console.error('activeCamera is deprecated. Use mainCamera instead.')
this.mainCamera = camera this.mainCamera = camera
} }

+ 22
- 2
src/rendering/RenderManager.ts Просмотреть файл

import { import {
BaseEvent, BaseEvent,
Color, Color,
ColorSpace,
FloatType, FloatType,
HalfFloatType, HalfFloatType,
IUniform, IUniform,
get composerTarget2(): IRenderTarget { get composerTarget2(): IRenderTarget {
return this._composer.renderTarget2 return this._composer.renderTarget2
} }

/**
* The size set in the three.js renderer.
* Final size is renderSize * renderScale
*/
get renderSize(): Vector2 { get renderSize(): Vector2 {
return this._renderSize return this._renderSize
} }
super(...ps) super(...ps)
this.uuid = generateUUID() this.uuid = generateUUID()
const ops = ps[ps.length - 1] as WebGLRenderTargetOptions const ops = ps[ps.length - 1] as WebGLRenderTargetOptions
const colorSpace = ops?.colorSpace
this._initTexture(colorSpace)
}

private _initTexture(colorSpace?: ColorSpace) {
if (Array.isArray(this.texture)) { if (Array.isArray(this.texture)) {
this.texture.forEach(t => { this.texture.forEach(t => {
if (ops.colorSpace !== undefined) t.colorSpace = ops.colorSpace
if (colorSpace !== undefined) t.colorSpace = colorSpace
t._target = this t._target = this
t.toJSON = () => { t.toJSON = () => {
console.warn('Multiple render target texture.toJSON not supported yet.') console.warn('Multiple render target texture.toJSON not supported yet.')
}) })
} else { } else {
this.texture._target = this this.texture._target = this
// if (colorSpace !== undefined) this.texture.colorSpace = colorSpace
this.texture.toJSON = () => ({ // todo use readRenderTargetPixels as data url or data buffer. this.texture.toJSON = () => ({ // todo use readRenderTargetPixels as data url or data buffer.
isRenderTargetTexture: true, isRenderTargetTexture: true,
}) // so that it doesn't get serialized }) // so that it doesn't get serialized
if (this.isTemporary) throw 'Cloning temporary render targets not supported' if (this.isTemporary) throw 'Cloning temporary render targets not supported'
if (Array.isArray(this.texture)) throw 'Cloning multiple render targets not supported' if (Array.isArray(this.texture)) throw 'Cloning multiple render targets not supported'
// Note: todo: webgl render target.clone messes up the texture, by not copying isRenderTargetTexture prop and maybe some other stuff. So its better to just create a new one // Note: todo: webgl render target.clone messes up the texture, by not copying isRenderTargetTexture prop and maybe some other stuff. So its better to just create a new one
const cloned = super.clone() as IRenderTarget
// const cloned = super.clone() as IRenderTarget
const cloned = new (this.constructor as Class<typeof this>)(this.renderManager)
cloned.copy(this)
cloned._initTexture((Array.isArray(this.texture) ? this.texture[0] : this.texture)?.colorSpace)
const tex = cloned.texture const tex = cloned.texture
if (Array.isArray(tex)) tex.forEach(t => t.isRenderTargetTexture = true) if (Array.isArray(tex)) tex.forEach(t => t.isRenderTargetTexture = true)
else tex.isRenderTargetTexture = true else tex.isRenderTargetTexture = true
return processNewTarget(cloned, this.sizeMultiplier || 1, trackTarget) return processNewTarget(cloned, this.sizeMultiplier || 1, trackTarget)
} }
copy(source: IRenderTarget|WebGLRenderTarget|WebGLMultipleRenderTargets): this {
super.copy(source as any)
return this
}

}(this, ...size, options) }(this, ...size, options)
} }



+ 3
- 1
src/rendering/RenderTarget.ts Просмотреть файл

UnsignedInt248Type, UnsignedInt248Type,
UnsignedIntType, UnsignedIntType,
UnsignedShortType, UnsignedShortType,
WebGLMultipleRenderTargets,
WebGLRenderTarget,
Wrapping, Wrapping,
} from 'three' } from 'three'
import {Vector4} from 'three/src/math/Vector4' import {Vector4} from 'three/src/math/Vector4'
targetKey?: string // for caching. targetKey?: string // for caching.
clone(trackTarget?: boolean): this clone(trackTarget?: boolean): this
setSize(width: number, height: number, depth?: number): void; setSize(width: number, height: number, depth?: number): void;
copy(source: IRenderTarget): this;
copy(source: IRenderTarget|WebGLRenderTarget|WebGLMultipleRenderTargets): this;
dispose(): void; dispose(): void;


scissor: Vector4; scissor: Vector4;

+ 5
- 4
src/three/utils/decorators.ts Просмотреть файл

set(newVal: any) { set(newVal: any) {
const {t, p} = getTarget(thisMat ? this : this.material) const {t, p} = getTarget(thisMat ? this : this.material)
if (processVal) newVal = processVal(newVal) if (processVal) newVal = processVal(newVal)
else if (typeof newVal === 'boolean') { // just in case
console.error('Boolean values are not supported for defines. Use @matDefineBool instead.')
newVal = newVal ? '1' : '0'
}
// boolean values are supported in material extender.
// else if (typeof newVal === 'boolean') { // just in case
// console.error('Boolean values are not supported for defines. Use @matDefineBool instead.')
// newVal = newVal ? '1' : '0'
// }
safeSetProperty(t, p, newVal, true) safeSetProperty(t, p, newVal, true)
if (newVal === undefined) delete t[p] if (newVal === undefined) delete t[p]
if (onChange && typeof onChange === 'function') { if (onChange && typeof onChange === 'function') {

+ 2
- 1
src/viewer/AViewerPlugin.ts Просмотреть файл

export abstract class AViewerPlugin<T extends string = string, TViewer extends ThreeViewer = ThreeViewer, IsSync extends boolean = boolean> extends EventDispatcher<Event, T|'serialize'|'deserialize'> implements IViewerPlugin<TViewer, IsSync> { export abstract class AViewerPlugin<T extends string = string, TViewer extends ThreeViewer = ThreeViewer, IsSync extends boolean = boolean> extends EventDispatcher<Event, T|'serialize'|'deserialize'> implements IViewerPlugin<TViewer, IsSync> {
declare ['constructor']: typeof AViewerPlugin declare ['constructor']: typeof AViewerPlugin
public static readonly PluginType: string = 'AViewerPlugin' public static readonly PluginType: string = 'AViewerPlugin'
public static readonly OldPluginType?: string
protected _dirty = false protected _dirty = false


uiConfig?: UiObjectConfig = undefined // todo: this should work when uncommented, remove all get uiConfig and do it properly uiConfig?: UiObjectConfig = undefined // todo: this should work when uncommented, remove all get uiConfig and do it properly
} }


fromJSON(data: ISerializedConfig, meta?: SerializationMetaType): this|null|Promise<this|null> { fromJSON(data: ISerializedConfig, meta?: SerializationMetaType): this|null|Promise<this|null> {
if (data.type !== this.constructor.PluginType)
if (data.type !== this.constructor.PluginType && data.type !== this.constructor.OldPluginType)
return null return null
ThreeSerialization.Deserialize(data, this, meta, true) ThreeSerialization.Deserialize(data, this, meta, true)
this.dispatchEvent({type: 'deserialize', data, meta}) this.dispatchEvent({type: 'deserialize', data, meta})

+ 1
- 0
src/viewer/IViewerPlugin.ts Просмотреть файл

// all classes must have this static property with a unique identifier value for this plugin // all classes must have this static property with a unique identifier value for this plugin
constructor: { constructor: {
PluginType: string PluginType: string
OldPluginType?: string // rename to type alias maybe
} }


// these plugins will be added automatically(with default settings), if they are not added yet. // these plugins will be added automatically(with default settings), if they are not added yet.

+ 8
- 1
src/viewer/ThreeViewer.ts Просмотреть файл

* Note: should be max (screen refresh rate / animation frame rate) like 60Hz / 30fps * Note: should be max (screen refresh rate / animation frame rate) like 60Hz / 30fps
* @type {number} * @type {number}
*/ */
public maxFramePerLoop = 1
maxFramePerLoop = 1
readonly debug: boolean readonly debug: boolean


/** /**
await this.removePlugin(this.plugins[type]) await this.removePlugin(this.plugins[type])
} }
this.plugins[type] = p this.plugins[type] = p
const oldType = p.constructor.OldPluginType
if (oldType && this.plugins[oldType]) this.console.error('Plugin type mismatch')
if (oldType) this.plugins[oldType] = p

await p.onAdded(this) await p.onAdded(this)
this.dispatchEvent({type: 'addPlugin', target: this, plugin: p}) this.dispatchEvent({type: 'addPlugin', target: this, plugin: p})
this.setDirty(p) this.setDirty(p)
this.removePluginSync(this.plugins[type]) this.removePluginSync(this.plugins[type])
} }
this.plugins[type] = p this.plugins[type] = p
const oldType = p.constructor.OldPluginType
if (oldType && this.plugins[oldType]) this.console.error('Plugin type mismatch')
if (oldType) this.plugins[oldType] = p
p.onAdded(this) p.onAdded(this)
this.dispatchEvent({type: 'addPlugin', target: this, plugin: p}) this.dispatchEvent({type: 'addPlugin', target: this, plugin: p})
this.setDirty(p) this.setDirty(p)

+ 1
- 1
src/viewer/version.ts Просмотреть файл

export const VERSION = '0.0.26'
export const VERSION = '0.0.27'

Загрузка…
Отмена
Сохранить