Procházet zdrojové kódy

Add dollyFov, add geometry.center2 with undo functionality, add pivotToBoundsCenter, pivotToPoint in IObject, add function getFittingDistance for camera, support function for target in GBufferRenderPass.

master
Palash Bansal před 1 rokem
rodič
revize
8282af67f0
Žádný účet není propojen s e-mailovou adresou tvůrce revize

+ 1
- 1
examples/unreal-bloom-pass/script.ts Zobrazit soubor

@@ -20,7 +20,7 @@ async function init() {
rgbm: false, // The pass from three.js doesn't support RGBM encoded render targets
zPrepass: false,
renderScale: 1,
maxHDRIntensity: 8,
maxHDRIntensity: 100,
dropzone: {
addOptions: {
disposeSceneObjects: true,

+ 1
- 0
package.json Zobrazit soubor

@@ -10,6 +10,7 @@
"exports": {
".": {
"import": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"require": "./dist/index.js"
},
"./dist/": {

+ 7
- 0
src/core/ICamera.ts Zobrazit soubor

@@ -33,6 +33,13 @@ export interface ICameraUserData extends IObject3DUserData {
* @default false
*/
autoLookAtTarget?: boolean
/**
* Automatically move the camera(dolly) based on the scene size when the field of view(fov) changes.
* Works when controls are enabled or autoLookAtTarget is true.
*
* Note - The camera must be added to RootScene for this to work
*/
dollyFov?: boolean

/**
* Disable jitter for this camera. (for {@link SSAAPlugin})

+ 15
- 1
src/core/IGeometry.ts Zobrazit soubor

@@ -18,7 +18,21 @@ export interface IGeometry<Attributes extends NormalOrGLBufferAttributes = Norma
refreshUi(): void;
uiConfig?: UiObjectConfig
appliedMeshes: Set<IObject3D>
center(offset?: Vector3, keepWorldPosition?: boolean): this

/**
* Centers the geometry.
* @param offset - returns the offset applied to the geometry
* @param keepWorldPosition - Updates the attached meshes, so that the world position of the geometry remains the same.
* @param setDirty
*/
center(offset?: Vector3, keepWorldPosition?: boolean, setDirty?: boolean): this

/**
* Same as center but returns a function to undo the centering
* @param offset
* @param keepWorldPosition
*/
center2(offset?: Vector3, keepWorldPosition?: boolean): ()=>void

// Note: for userData: add _ in front of for private use, which is preserved while cloning but not serialisation, and __ for private use, which is not preserved while cloning and serialisation
userData: IGeometryUserData

+ 24
- 1
src/core/IObject.ts Zobrazit soubor

@@ -1,6 +1,6 @@
import {IDisposable} from 'ts-browser-helpers'
import {IMaterial} from './IMaterial'
import {Event, Object3D} from 'three'
import {Event, Object3D, Vector3} from 'three'
import {ChangeEvent, IUiConfigContainer, UiObjectConfig} from 'uiconfig.js'
import {IGeometry, IGeometryEvent} from './IGeometry'
import {IImportResultUserData} from '../assetmanager'
@@ -202,6 +202,7 @@ export interface IObject3D<E extends Event = IObject3DEvent, ET = IObject3DEvent
userData: IObject3DUserData

/**
* Scales the object to fit the given radius.
*
* @param autoScaleRadius - optional (taken from userData.autoScaleRadius by default)
* @param isCentered - optional (taken from userData.isCentered by default)
@@ -211,12 +212,34 @@ export interface IObject3D<E extends Event = IObject3DEvent, ET = IObject3DEvent
autoScale?(autoScaleRadius?: number, isCentered?: boolean, setDirty?: boolean, undo?: boolean): this

/**
* Moves the bounding box center of the object to the center of the world
*
* @param setDirty - calls {@link setDirty} @default true
* @param undo - undo any previous autoCenter operation
*/
autoCenter?(setDirty?: boolean, undo?: boolean): this

/**
* Moves the object pivot to the center of the bounding box.
*
* The object will rotate around the new pivot.
*
* @param setDirty - calls {@link setDirty} @default true
* @returns undo function
*/
pivotToBoundsCenter?(setDirty?: boolean): () => void

/**
* Moves the object pivot to the given point
*
* The object will rotate around the new pivot.
*
* @param point - point to move the pivot to
* @param setDirty - calls {@link setDirty} @default true
* @returns undo function
*/
pivotToPoint?(point: Vector3, setDirty?: boolean): this

/**
* @deprecated use object directly
*/

+ 18
- 0
src/core/camera/PerspectiveCamera2.ts Zobrazit soubor

@@ -107,6 +107,7 @@ export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera {
*/
@bindToValue({obj: 'userData', onChange: 'setDirty'})
minNearPlane = 0.5

/**
* Maximum far clipping plane allowed. (Distance from camera)
* Used in RootScene when {@link autoNearFar} is true.
@@ -114,6 +115,15 @@ export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera {
@bindToValue({obj: 'userData', onChange: 'setDirty'})
maxFarPlane = 1000

/**
* Automatically move the camera(dolly) when the field of view(fov) changes.
* Works when controls are enabled or autoLookAtTarget is true.
*
* Note - this is not exact
*/
@bindToValue({obj: 'userData'})
dollyFov = false // bound to userData so that it's saved in the glb.

constructor(controlsMode?: TCameraControlsMode, domElement?: HTMLCanvasElement, autoAspect?: boolean, fov?: number, aspect?: number) {
super(fov, aspect)
this._canvas = domElement
@@ -409,6 +419,7 @@ export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera {
}

// endregion

// region utils/others

// for shader prop updater
@@ -427,6 +438,7 @@ export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera {
return this
}


dispose(): void {
this._disposeCameraControls()
// todo: anything else?
@@ -454,6 +466,11 @@ export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera {
label: 'Auto Near Far',
property: [this, 'autoNearFar'],
},
{
type: 'input',
label: 'Dolly FoV',
property: [this, 'dollyFov'],
},
()=>({ // because _controlsCtors can change
type: 'dropdown',
label: 'Controls Mode',
@@ -618,6 +635,7 @@ export class PerspectiveCamera2 extends PerspectiveCamera implements ICamera {
export class PerspectiveCamera0 extends PerspectiveCamera2 {
constructor(fov?: number, aspect?: number, near?: number, far?: number) {
super(undefined, undefined, undefined, fov, aspect || 1)
this.dollyFov = false
if (near || far) {
this.autoNearFar = false
if (near) {

+ 45
- 7
src/core/geometry/iGeometryCommons.ts Zobrazit soubor

@@ -3,6 +3,7 @@ import {IGeometry, IGeometrySetDirtyOptions} from '../IGeometry'
import {autoGPUInstanceMeshes, isInScene, toIndexedGeometry} from '../../three/utils'
import {BufferGeometry, Vector3} from 'three'
import {ThreeViewer} from '../../viewer'
import {IObject3D} from '../IObject'

export const iGeometryCommons = {
setDirty: function(this: IGeometry, options?: IGeometrySetDirtyOptions): void {
@@ -23,7 +24,7 @@ export const iGeometryCommons = {
},
upgradeGeometry: upgradeGeometry,
center: (superCenter: BufferGeometry['center']): IGeometry['center'] =>
function(this: IGeometry, offset?: Vector3, keepWorldPosition = false): IGeometry {
function(this: IGeometry, offset?: Vector3, keepWorldPosition = false, setDirty = true): IGeometry {
if (keepWorldPosition) {
offset = offset ? offset.clone() : new Vector3()
superCenter.call(this, offset)
@@ -32,14 +33,50 @@ export const iGeometryCommons = {
for (const m of meshes) {
m.updateMatrix()
m.position.copy(offset).applyMatrix4(m.matrix)
m.setDirty()
if (setDirty) m.setDirty()
}
} else {
superCenter.call(this, offset)
}
this.setDirty()
if (setDirty) this.setDirty()
return this
},
center2: function(this: IGeometry, offset?: Vector3, keepWorldPosition = false, setDirty = true): ()=>void {
const offset1 = offset ? offset : new Vector3()
if (keepWorldPosition) {
this.center(offset1, false, false)
const meshes = this.appliedMeshes
const positions = new WeakMap<IObject3D, Vector3>()
for (const m of meshes) {
m.updateMatrix()
positions.set(m, m.position.clone())
m.position.set(-offset1.x, -offset1.y, -offset1.z).applyMatrix4(m.matrix)
if (setDirty) m.setDirty()
}
if (setDirty) this.setDirty()
return ()=>{
// undo
for (const m of meshes) {
const pos = positions.get(m)
if (!pos) {
console.warn('GeometryCommons: No position found for mesh', m)
continue
}
m.position.copy(pos)
if (setDirty) m.setDirty()
}
if (setDirty) this.setDirty()
}
} else {
this.center(offset1, false, false)
if (setDirty) this.setDirty()
return ()=>{
// undo
this.translate(-offset1.x, -offset1.y, -offset1.z)
if (setDirty) this.setDirty()
}
}
},
makeUiConfig: function(this: IGeometry): UiObjectConfig {
if (this.uiConfig) return this.uiConfig
return {
@@ -59,16 +96,16 @@ export const iGeometryCommons = {
type: 'button',
label: 'Center Geometry',
value: async() => {
if (!await ThreeViewer.Dialog.confirm('This will move the objects based on the geometry center, do you want to continue?\nThis action cannot be undone.')) return
this.center()
if (!await ThreeViewer.Dialog.confirm('This will move the objects based on the geometry center, do you want to continue?')) return
return this.center2()
},
},
{
type: 'button',
label: 'Center Geometry (keep position)',
value: async() => {
if (!await ThreeViewer.Dialog.confirm('This will move the geometry center keeping the object position, do you want to continue?\nThis action cannot be undone.')) return
this.center(undefined, true)
if (!await ThreeViewer.Dialog.confirm('This will move the geometry center keeping the object position, do you want to continue?')) return
return this.center2(undefined, true)
},
},
{
@@ -174,6 +211,7 @@ function upgradeGeometry(this: IGeometry) {
this.dispose = iGeometryCommons.dispose(this.dispose)
this.center = iGeometryCommons.center(this.center)
this.clone = iGeometryCommons.clone(this.clone)
if (!this.center2) this.center2 = iGeometryCommons.center2

if (!this.setDirty) this.setDirty = iGeometryCommons.setDirty
if (!this.refreshUi) this.refreshUi = iGeometryCommons.refreshUi

+ 9
- 0
src/core/object/IObjectUi.ts Zobrazit soubor

@@ -154,6 +154,15 @@ export function makeIObject3DUiConfig(this: IObject3D, isMesh?:boolean): UiObjec
}
},
},
{
type: 'button',
label: 'Pivot to Node Center',
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: 'folder',
label: 'Rotate model',

+ 26
- 1
src/core/object/RootScene.ts Zobrazit soubor

@@ -21,6 +21,7 @@ import {iObjectCommons} from './iObjectCommons'
import {RootSceneImportResult} from '../../assetmanager'
import {uiButton, uiColor, uiConfig, uiFolderContainer, uiImage, UiObjectConfig, uiSlider, uiToggle} from 'uiconfig.js'
import {IGeometry} from '../IGeometry'
import {getFittingDistance} from '../../three/utils/camera'

export type TCamera = ICamera

@@ -287,7 +288,9 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I
centerAllGeometries(keepPosition = true, obj?: IObject3D) {
const geoms = new Set<IGeometry>()
;(obj ?? this.modelRoot).traverse((o) => o.geometry && geoms.add(o.geometry))
geoms.forEach(g => g.center(undefined, keepPosition))
const undos: (()=>void)[] = []
geoms.forEach(g => undos.push(g.center2(undefined, keepPosition)))
return ()=>undos.forEach(u=>u())
}

clearSceneModels(dispose = false, setDirty = true): void {
@@ -365,6 +368,7 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I
private _mainCameraUpdate = (e: any) => {
this.setDirty({refreshScene: false})
this.refreshActiveCameraNearFar()
if (e.key === 'fov') this.dollyActiveCameraFov()
this.dispatchEvent({...e, type: 'mainCameraUpdate'})
this.dispatchEvent({...e, type: 'activeCameraUpdate'}) // deprecated
}
@@ -384,6 +388,7 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I
if (event?.sceneUpdate === false || event?.refreshScene === false || event?.object?.isCamera) return this.setDirty(event) // so that it doesn't trigger frame fade, shadow refresh etc
// console.warn(event)
this.refreshActiveCameraNearFar()
// this.dollyActiveCameraFov()
this._sceneBounds = this.getBounds(false, true)
// this.boxHelper?.boxHelper?.copy?.(this._sceneBounds)
this._sceneBoundingRadius = this._sceneBounds.getSize(new Vector3()).length() / 2.
@@ -506,6 +511,26 @@ export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements I
// camera.far = 20
}

/**
* Refreshes the scene active camera near far values, based on the scene bounding box.
* This is called automatically every time the camera fov is updated.
*/
dollyActiveCameraFov(): void {
const camera = this.mainCamera as TCamera
if (!camera) return
if (!camera.userData.dollyFov) {
return
}

const bbox = this.getModelBounds(false, true, true)

// todo this is not exact because of 1.5, this needs to be calculated based on current position and last fov
const cameraZ = getFittingDistance(camera, bbox) * 1.5
const direction = new Vector3().subVectors(camera.target, camera.position).normalize()
camera.position.copy(direction.multiplyScalar(-cameraZ).add(camera.target))
camera.setDirty()
}

updateShaderProperties(material: {defines: Record<string, string|number|undefined>, uniforms: {[name: string]: IUniform}}): this {
if (material.uniforms.sceneBoundingRadius) material.uniforms.sceneBoundingRadius.value = this._sceneBoundingRadius
else console.warn('RootScene: no uniform: sceneBoundingRadius')

+ 53
- 1
src/core/object/iObjectCommons.ts Zobrazit soubor

@@ -1,4 +1,4 @@
import {Event, Mesh, Vector3} from 'three'
import {Event, Matrix4, Mesh, Vector3} from 'three'
import {IMaterial} from '../IMaterial'
import {objectHasOwn} from 'ts-browser-helpers'
import {IObject3D, IObject3DEvent, IObjectProcessor, IObjectSetDirtyOptions} from '../IObject'
@@ -39,6 +39,7 @@ export const iObjectCommons = {
if (setDirty) this.setDirty({change: 'autoCenter', undo})
return this
},

autoScale: function<T extends IObject3D>(this: T, autoScaleRadius?: number, isCentered?: boolean, setDirty = true, undo = false): T {
let scale = 1
if (undo) { // Note - undo only works for quick undo, not for multiple times
@@ -93,6 +94,55 @@ export const iObjectCommons = {
return this
},

pivotToBoundsCenter: function<T extends IObject3D>(this: T, setDirty = true): ()=>void {
const bb = new Box3B().expandByObject(this, true, true)
const center = bb.getCenter(new Vector3())
return iObjectCommons.pivotToPoint.call(this, center, setDirty)
},

pivotToPoint: function<T extends IObject3D>(this: T, point: Vector3, setDirty = true): ()=>void {
const worldCenter = new Vector3().copy(point)
const localCenter = new Vector3().copy(worldCenter)

const worldMatrixInv = new Matrix4().copy(this.matrixWorld).invert()
const m = this.parent?.matrixWorld
const parentWorldMatrixInv = new Matrix4()
if (m !== undefined)
parentWorldMatrixInv.copy(m).invert()

// Get the center with respect to the parent
worldCenter.applyMatrix4(parentWorldMatrixInv)
const lastPosition = this.position.clone()

// Apply the new position
this.position.copy(worldCenter)

// local center
localCenter.applyMatrix4(worldMatrixInv).negate()

// Shift the geometry
if (this.geometry) {
this.geometry.translate(localCenter.x, localCenter.y, localCenter.z)
}
// Add offsets
this.children.forEach((object)=> {
object.position.add(localCenter)
})
if (setDirty) this.setDirty({change: 'pivotToPoint', undo: false})

return ()=>{
// undo
this.position.copy(lastPosition)
if (this.geometry) {
this.geometry.translate(-localCenter.x, -localCenter.y, -localCenter.z)
}
this.children.forEach((object)=> {
object.position.sub(localCenter)
})
if (setDirty) this.setDirty({change: 'pivotToPoint', undo: true})
}
},

eventCallbacks: {
onAddedToParent: function(this: IObject3D, e: Event): void {
// added to some parent
@@ -401,6 +451,8 @@ function upgradeObject3D(this: IObject3D, parent?: IObject3D|undefined, objectPr
if (!this.refreshUi) this.refreshUi = iObjectCommons.refreshUi
if (!this.autoScale) this.autoScale = iObjectCommons.autoScale.bind(this)
if (!this.autoCenter) this.autoCenter = iObjectCommons.autoCenter.bind(this)
if (!this.pivotToBoundsCenter) this.pivotToBoundsCenter = iObjectCommons.pivotToBoundsCenter.bind(this)
if (!this.pivotToPoint) this.pivotToPoint = iObjectCommons.pivotToPoint.bind(this)

// fired from Object3D.js
this.addEventListener('added', iObjectCommons.eventCallbacks.onAddedToParent)

+ 3
- 16
src/plugins/animation/CameraViewPlugin.ts Zobrazit soubor

@@ -5,9 +5,10 @@ import {Box3B} from '../../three'
import {onChange, serialize, timeout} from 'ts-browser-helpers'
import {generateUiConfig, uiButton, uiDropdown, uiInput, UiObjectConfig, uiSlider, uiToggle} from 'uiconfig.js'
import {EasingFunctions, EasingFunctionType} from '../../utils'
import {CameraView, ICamera, ICameraView, PerspectiveCamera2} from '../../core'
import {CameraView, ICamera, ICameraView} from '../../core'
import {AnimationResult, PopmotionPlugin} from './PopmotionPlugin'
import {InteractionPromptPlugin} from '../interaction/InteractionPromptPlugin'
import {getFittingDistance} from '../../three/utils/camera'

export interface CameraViewPluginOptions{duration?: number, ease?: EasingFunctionType, interpolateMode?: 'spherical'|'linear'}

@@ -338,22 +339,8 @@ export class CameraViewPlugin extends AViewerPluginSync<'viewChange'|'startViewC
public async animateToFitObject(selected?: Object3D, distanceMultiplier = 1.5, duration = 1000, ease?: Easing|EasingFunctionType, distanceBounds = {min: 0.5, max: 50.0}) {
if (!this._viewer) return
const bbox = new Box3B().expandByObject(selected || this._viewer.scene.modelRoot, false, true)
const cameraZ = getFittingDistance(this._viewer.scene.mainCamera, bbox)
const center = bbox.getCenter(new Vector3()) // world position
const size = bbox.getSize(new Vector3())

const cam = this._viewer.scene.mainCamera
let cameraZ = 1
if (cam.isPerspectiveCamera && size.length() > 0.0001) {
const aspect = isFinite(cam.aspect) ? cam.aspect : 1
// get the max side of the bounding box (fits to width OR height as needed )
const fov = Math.max(1, (cam as PerspectiveCamera2).fov) * (Math.PI / 180)
const fovh = 2 * Math.atan(Math.tan(fov / 2) * aspect)
const dx = size.z / 2 + Math.abs(size.x / 2 / Math.tan(fovh / 2))
const dy = size.z / 2 + Math.abs(size.y / 2 / Math.tan(fov / 2))
cameraZ = Math.max(dx, dy)

}

await this.animateToTarget(Math.min(distanceBounds.max, Math.max(distanceBounds.min, cameraZ * distanceMultiplier)), center, duration, ease)
}


+ 1
- 1
src/plugins/interaction/TransformControlsPlugin.ts Zobrazit soubor

@@ -162,7 +162,7 @@ export class TransformControlsPlugin extends AViewerPluginSync<''> {

@uiButton('Center All Meshes')
centerAllMeshes() {
this._viewer?.scene.centerAllGeometries(true)
return this._viewer?.scene.centerAllGeometries(true)
}

}

+ 3
- 2
src/postprocessing/GBufferRenderPass.ts Zobrazit soubor

@@ -3,6 +3,7 @@ import {RenderPass} from 'three/examples/jsm/postprocessing/RenderPass.js'
import {IPassID, IPipelinePass} from './Pass'
import {ICamera, IMaterial, IRenderManager, IScene, IWebGLRenderer, PhysicalMaterial} from '../core'
import {uiFolderContainer, UiObjectConfig, uiToggle} from 'uiconfig.js'
import {getOrCall, ValOrFunc} from 'ts-browser-helpers'

@uiFolderContainer<GBufferRenderPass>((c)=>c.passId + ' Render Pass')
export class GBufferRenderPass<TP extends IPassID=IPassID, T extends WebGLMultipleRenderTargets | WebGLRenderTarget=WebGLMultipleRenderTargets | WebGLRenderTarget> extends RenderPass implements IPipelinePass<TP> { // todo: extend from jittered?
@@ -16,7 +17,7 @@ export class GBufferRenderPass<TP extends IPassID=IPassID, T extends WebGLMultip
after?: IPassID[]
required?: IPassID[]

constructor(public readonly passId: TP, public target: T, material: Material, clearColor: Color = new Color(1, 1, 1), clearAlpha = 1) {
constructor(public readonly passId: TP, public target: ValOrFunc<T>, material: Material, clearColor: Color = new Color(1, 1, 1), clearAlpha = 1) {
super(undefined, undefined, material, clearColor, clearAlpha)
}

@@ -74,7 +75,7 @@ export class GBufferRenderPass<TP extends IPassID=IPassID, T extends WebGLMultip
transparentRender: false,
transmissionRender: false,
mainRenderPass: false,
}, ()=> super.render(renderer, null, this.target, deltaTime as any, maskActive as any)) // here this.target is the write-buffer, variable writeBuffer is ignored
}, ()=> super.render(renderer, null, getOrCall(this.target), deltaTime as any, maskActive as any)) // here this.target is the write-buffer, variable writeBuffer is ignored

this._transparentMats.forEach(m => m.transparent = !m.transparent)
this._transparentMats.clear()

+ 23
- 0
src/three/utils/camera.ts Zobrazit soubor

@@ -0,0 +1,23 @@
import {Vector3} from 'three'
import {Box3B} from '../math/Box3B'
import {ICamera, PerspectiveCamera2} from '../../core'

/**
* Find distance of camera at which the camera's fov fits the given bounding box dimensions
* @param cam
* @param box
*/
export function getFittingDistance(cam: ICamera, box: Box3B): number {
const size = box.getSize(new Vector3())
let cameraZ = 1
if (cam.isPerspectiveCamera && size.length() > 0.0001) {
const aspect = isFinite(cam.aspect) ? cam.aspect : 1
// get the max side of the bounding box (fits to width OR height as needed )
const fov = Math.max(1, (cam as PerspectiveCamera2).fov) * (Math.PI / 180)
const fovh = 2 * Math.atan(Math.tan(fov / 2) * aspect)
const dx = size.z / 2 + Math.abs(size.x / 2 / Math.tan(fovh / 2))
const dy = size.z / 2 + Math.abs(size.y / 2 / Math.tan(fov / 2))
cameraZ = Math.max(dx, dy)
}
return cameraZ
}

+ 6
- 5
src/viewer/ThreeViewer.ts Zobrazit soubor

@@ -66,7 +66,6 @@ import {DropzonePlugin, DropzonePluginOptions} from '../plugins/interaction/Drop
// noinspection ES6PreferShortImport
import {TonemapPlugin} from '../plugins/postprocessing/TonemapPlugin'
import {VERSION} from './version'
import {Easing} from 'popmotion'
import {OrbitControls3} from '../three'

export interface IViewerEvent extends BaseEvent, Partial<IAnimationLoopEvent> {
@@ -126,8 +125,10 @@ export interface ThreeViewerOptions {
*/
rgbm?: boolean
/**
* Use rendered gbuffer as depth-prepass / z-prepass. (Requires DepthBufferPlugin/GBufferPlugin)
* todo: It will be disabled when there are any transparent/transmissive objects with render to depth buffer enabled.
* Use rendered gbuffer as depth-prepass / z-prepass. (Requires DepthBufferPlugin/GBufferPlugin).
* Set it to true if you only have opaque objects in the scene to get better performance.
*
* todo fix: It will be disabled when there are any transparent/transmissive objects with render to depth buffer enabled, see forceZPrepass
*/
zPrepass?: boolean
/**
@@ -183,7 +184,7 @@ export interface ThreeViewerOptions {
target?: Vector3,

}
// values above this might be clamped in post processing
maxHDRIntensity?: number

@@ -1320,7 +1321,7 @@ export class ThreeViewer extends EventDispatcher<IViewerEvent, IViewerEventTypes
// this.fromJSON(config, config.resources)
// }

public async fitToView(selected?: Object3D, distanceMultiplier = 1.5, duration?: number, ease?: Easing|EasingFunctionType) {
public async fitToView(selected?: Object3D, distanceMultiplier = 1.5, duration?: number, ease?: ((v: number) => number)|EasingFunctionType) {
const camViews = this.getPlugin<CameraViewPlugin>('CameraViews')
if (!camViews) {
this.console.error('ThreeViewer: CameraViewPlugin (CameraViews) is required for fitToView to work')

Načítá se…
Zrušit
Uložit