threepipe
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RootScene.ts 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. import {
  2. Color,
  3. EquirectangularReflectionMapping,
  4. EventListener,
  5. IUniform,
  6. Object3D,
  7. Scene,
  8. UVMapping,
  9. Vector3,
  10. } from 'three'
  11. import type {IObject3D, IObjectProcessor} from '../IObject'
  12. import {type ICamera} from '../ICamera'
  13. import {Box3B} from '../../three'
  14. import {AnyOptions, onChange2, onChange3, serialize} from 'ts-browser-helpers'
  15. import {PerspectiveCamera2} from '../camera/PerspectiveCamera2'
  16. import {ThreeSerialization} from '../../utils'
  17. import {ITexture} from '../ITexture'
  18. import {AddObjectOptions, IScene, ISceneEvent, ISceneEventTypes, ISceneSetDirtyOptions} from '../IScene'
  19. import {iObjectCommons} from './iObjectCommons'
  20. import {RootSceneImportResult} from '../../assetmanager'
  21. import {uiColor, uiConfig, uiFolderContainer, uiImage, UiObjectConfig, uiSlider, uiToggle} from 'uiconfig.js'
  22. @uiFolderContainer('Root Scene')
  23. export class RootScene extends Scene<ISceneEvent, ISceneEventTypes> implements IScene<ISceneEvent, ISceneEventTypes> {
  24. readonly isRootScene = true
  25. assetType = 'model' as const
  26. uiConfig!: UiObjectConfig
  27. // private _processors = new ObjectProcessorMap<'environment' | 'background'>()
  28. // private _sceneObjects: ISceneObject[] = []
  29. private _mainCamera: ICamera | null = null
  30. /**
  31. * The root object where all imported objects are added.
  32. */
  33. readonly modelRoot: IObject3D
  34. @uiColor<RootScene>('Background Color', (s)=>({
  35. onChange: ()=>s?.onBackgroundChange(),
  36. }))
  37. @serialize() @onChange2(RootScene.prototype.onBackgroundChange)
  38. backgroundColor: Color | null = null // read in three.js WebGLBackground
  39. @onChange2(RootScene.prototype.onBackgroundChange)
  40. @serialize() @uiImage('Background Image')
  41. background: null | Color | ITexture | 'environment' = null
  42. /**
  43. * The intensity for the environment light.
  44. */
  45. @serialize() @onChange3(RootScene.prototype.setDirty)
  46. @uiSlider('Background Intensity', [0, 10], 0.01)
  47. backgroundIntensity = 1
  48. @uiImage('Environment')
  49. @serialize() @onChange2(RootScene.prototype._onEnvironmentChange)
  50. environment: ITexture | null = null
  51. /**
  52. * The intensity for the environment light.
  53. */
  54. @uiSlider('Environment Intensity', [0, 10], 0.01)
  55. @serialize() @onChange3(RootScene.prototype.setDirty)
  56. envMapIntensity = 1
  57. /**
  58. * Fixed direction environment reflections irrespective of camera position.
  59. */
  60. @uiToggle('Fixed Env Direction')
  61. @serialize() @onChange3(RootScene.prototype.setDirty)
  62. fixedEnvMapDirection = false
  63. /**
  64. * The default camera in the scene
  65. */
  66. @uiConfig() @serialize() readonly defaultCamera: ICamera
  67. // private _environmentLight?: IEnvironmentLight
  68. // required just because we don't want activeCamera to be null.
  69. private _dummyCam = new PerspectiveCamera2('') as ICamera
  70. get mainCamera(): ICamera {
  71. return this._mainCamera || this._dummyCam
  72. }
  73. set mainCamera(camera: ICamera | undefined) {
  74. const cam = this.mainCamera
  75. if (!camera) camera = this.defaultCamera
  76. if (cam === camera) return
  77. if (cam) {
  78. cam.deactivateMain(undefined, true)
  79. cam.removeEventListener('cameraUpdate', this._mainCameraUpdate)
  80. }
  81. if (camera) {
  82. this._mainCamera = camera
  83. camera.addEventListener('cameraUpdate', this._mainCameraUpdate)
  84. camera.activateMain(undefined, true)
  85. } else {
  86. this._mainCamera = null
  87. }
  88. this.dispatchEvent({type: 'activeCameraChange', lastCamera: cam, camera}) // deprecated
  89. this.dispatchEvent({type: 'mainCameraChange', lastCamera: cam, camera})
  90. this.setDirty()
  91. }
  92. /**
  93. * Create a scene instance. This is done automatically in the {@link ThreeViewer} and must not be created separately.
  94. * @param camera
  95. * @param objectProcessor
  96. */
  97. constructor(camera: ICamera, objectProcessor?: IObjectProcessor) {
  98. super()
  99. this.setDirty = this.setDirty.bind(this)
  100. iObjectCommons.upgradeObject3D.call(this, undefined, objectProcessor)
  101. // this is called from parentDispatch since scene is a parent.
  102. this.addEventListener('materialUpdate', ()=>this.dispatchEvent({type: 'sceneMaterialUpdate'}))
  103. this.addEventListener('objectUpdate', this.refreshScene)
  104. this.addEventListener('geometryUpdate', this.refreshScene)
  105. this.addEventListener('geometryChanged', this.refreshScene)
  106. this.defaultCamera = camera
  107. this.modelRoot = new Object3D() as IObject3D
  108. this.modelRoot.userData.rootSceneModelRoot = true
  109. this.modelRoot.name = 'Scene' // for the UI
  110. // this.modelRoot.addEventListener('update', this.setDirty) // todo: where was this dispatched from/used ?
  111. // eslint-disable-next-line deprecation/deprecation
  112. this.add(this.modelRoot as any)
  113. // this.addSceneObject(this.modelRoot as any, {addToRoot: true, autoScale: false})
  114. // this.addSceneObject(this.defaultCamera, {addToRoot: true})
  115. // eslint-disable-next-line deprecation/deprecation
  116. this.add(this.defaultCamera)
  117. this.mainCamera = this.defaultCamera
  118. // this.boxHelper = new Box3Helper(this.getBounds())
  119. // this.boxHelper.userData.bboxVisible = false
  120. // this.boxHelper.visible = false
  121. // this.add(this.boxHelper)
  122. }
  123. /**
  124. * Add a widget (non-physical/interactive) object to the scene. like gizmos, ui components etc.
  125. * @param model
  126. * @param options
  127. */
  128. // addWidget(model: IWidget, options: AnyOptions = {}): void {
  129. // if (model.assetType !== 'widget') {
  130. // console.warn('Invalid asset type for ', model, ', adding anyway')
  131. // }
  132. // this.add(model.modelObject)
  133. //
  134. // // todo: dispatch event, add event listeners, etc
  135. // }
  136. /**
  137. * Add any processed object to the scene.
  138. * @param imported
  139. * @param options
  140. */
  141. addObject<T extends IObject3D|Object3D = IObject3D>(imported: T, options?: AddObjectOptions): T&IObject3D {
  142. if (options?.clearSceneObjects || options?.disposeSceneObjects) {
  143. this.clearSceneModels(options.disposeSceneObjects)
  144. }
  145. if (!imported) return imported
  146. if (!imported.isObject3D) {
  147. console.error('Invalid object, cannot add to scene.', imported)
  148. return imported as T&IObject3D
  149. }
  150. this._addObject3D(<IObject3D>imported, options)
  151. this.dispatchEvent({type: 'addSceneObject', object: <IObject3D>imported})
  152. return imported as T&IObject3D
  153. }
  154. /**
  155. Load model root scene exported to GLTF format. Used internally by {@link ThreeViewer.addSceneObject}.
  156. * @param obj
  157. * @param options
  158. */
  159. loadModelRoot(obj: RootSceneImportResult, options?: AddObjectOptions) {
  160. if (options?.clearSceneObjects || options?.disposeSceneObjects) {
  161. this.clearSceneModels(options.disposeSceneObjects)
  162. }
  163. if (!obj.userData?.rootSceneModelRoot) {
  164. console.error('Invalid model root scene object. Trying to add anyway.', obj)
  165. }
  166. if (obj.userData) {
  167. // todo deep merge all userdata?
  168. if (obj.userData.__importData)
  169. this.modelRoot.userData.__importData = {
  170. ...this.modelRoot.userData.__importData,
  171. ...obj.userData.__importData,
  172. }
  173. if (obj.userData.gltfAsset) {
  174. this.modelRoot.userData.__gltfAsset = { // todo: merge values?
  175. ...this.modelRoot.userData.__gltfAsset,
  176. ...obj.userData.gltfAsset,
  177. }
  178. }
  179. if (obj.userData.gltfExtras)
  180. this.modelRoot.userData.__gltfExtras = {
  181. ...this.modelRoot.userData.__gltfExtras,
  182. ...obj.userData.gltfExtras,
  183. }
  184. }
  185. if (obj.userData?.gltfAsset?.copyright) obj.children.forEach(c => !c.userData.license && (c.userData.license = obj.userData.gltfAsset?.copyright))
  186. if (obj.animations) {
  187. if (!this.modelRoot.animations) this.modelRoot.animations = []
  188. for (const animation of obj.animations) {
  189. if (this.modelRoot.animations.includes(animation)) continue
  190. this.modelRoot.animations.push(animation)
  191. }
  192. }
  193. return obj.children.map(c=>this.addObject(c, options))
  194. }
  195. private _addObject3D(model: IObject3D|null, {autoCenter = false, autoScale = false, autoScaleRadius = 2., addToRoot = false, license}: AddObjectOptions = {}): void {
  196. const obj = model
  197. if (!obj) {
  198. console.error('Invalid object, cannot add to scene.')
  199. return
  200. }
  201. // eslint-disable-next-line deprecation/deprecation
  202. if (addToRoot) this.add(obj)
  203. else this.modelRoot.add(obj)
  204. if (autoCenter && !obj.userData.isCentered) {
  205. obj.autoCenter?.()
  206. } else {
  207. obj.userData.isCentered = true // mark as centered, so that autoCenter is not called again when file is reloaded.
  208. }
  209. if (autoScale && !obj.userData.autoScaled) {
  210. obj.autoScale?.(obj.userData.autoScaleRadius || autoScaleRadius)
  211. } else {
  212. obj.userData.autoScaled = true // mark as auto-scaled, so that autoScale is not called again when file is reloaded.
  213. }
  214. if (license) obj.userData.license = [obj.userData.license, license].filter(v=>v).join(', ')
  215. this.setDirty({refreshScene: true})
  216. }
  217. clearSceneModels(dispose = false, setDirty = true): void {
  218. if (dispose) return this.disposeSceneModels(setDirty)
  219. this.modelRoot.clear()
  220. this.modelRoot.children = []
  221. setDirty && this.setDirty({refreshScene: true})
  222. }
  223. disposeSceneModels(setDirty = true) {
  224. [...this.modelRoot.children].forEach(child => child.dispose ? child.dispose() : child.removeFromParent())
  225. this.modelRoot.clear()
  226. if (setDirty) this.setDirty({refreshScene: true})
  227. }
  228. private _onEnvironmentChange() {
  229. // console.warn('environment changed')
  230. if (this.environment?.mapping === UVMapping) {
  231. this.environment.mapping = EquirectangularReflectionMapping // for PMREMGenerator
  232. this.environment.needsUpdate = true
  233. }
  234. this.dispatchEvent({type: 'environmentChanged', environment: this.environment})
  235. this.setDirty({refreshScene: true, geometryChanged: false})
  236. this.refreshUi?.()
  237. }
  238. onBackgroundChange() {
  239. this.dispatchEvent({type: 'backgroundChanged', background: this.background, backgroundColor: this.backgroundColor})
  240. this.setDirty({refreshScene: true, geometryChanged: false})
  241. this.refreshUi?.()
  242. }
  243. /**
  244. * @deprecated Use {@link addObject}
  245. */
  246. add(...object: Object3D[]): this {
  247. super.add(...object)
  248. // this._onSceneUpdate() // this is not needed, since it will be bubbled up from the object3d and we will get event objectUpdate
  249. return this
  250. }
  251. /**
  252. * Sets the backgroundColor property from a string, number or Color, and updates the scene.
  253. * @param color
  254. */
  255. setBackgroundColor(color: string | number | Color | null) {
  256. this.backgroundColor = color ? new Color(color) : null
  257. }
  258. /**
  259. * Mark the scene dirty, and force render in the next frame.
  260. * @param options - set `refreshScene` to true to mark that any object transformations have changed. It might trigger effects like frame fade depening on plugins.
  261. * @returns {this}
  262. */
  263. setDirty(options?: ISceneSetDirtyOptions): this {
  264. // todo: for onChange calls -> check options.key for specific key that's changed and use it to determine refreshScene
  265. if (options?.sceneUpdate) {
  266. console.warn('sceneUpdate is deprecated, use refreshScene instead.')
  267. options.refreshScene = true
  268. }
  269. if (options?.refreshScene) {
  270. this.refreshScene(options)
  271. } else {
  272. this.dispatchEvent({type: 'update'}) // todo remove
  273. iObjectCommons.setDirty.call(this, {...options, scene: this})
  274. } // this sets dirty in the viewer
  275. return this
  276. }
  277. private _mainCameraUpdate = () => {
  278. this.setDirty({refreshScene: false})
  279. this.refreshActiveCameraNearFar()
  280. this.dispatchEvent({type: 'mainCameraUpdate'})
  281. this.dispatchEvent({type: 'activeCameraUpdate'}) // deprecated
  282. }
  283. // cached values
  284. private _sceneBounds: Box3B = new Box3B
  285. private _sceneBoundingRadius = 0
  286. /**
  287. * For visualizing the scene bounds. API incomplete.
  288. * @type {Box3Helper}
  289. */
  290. // readonly boxHelper: Box3Helper
  291. refreshScene(event?: Partial<ISceneEvent> & ISceneSetDirtyOptions): this {
  292. if (event && event.type === 'objectUpdate' && event.object === this) return this // ignore self
  293. if (event?.sceneUpdate === false || event?.refreshScene === false) return this.setDirty(event) // so that it doesn't trigger frame fade, shadow refresh etc
  294. // console.warn(event)
  295. this.refreshActiveCameraNearFar()
  296. this._sceneBounds = this.getBounds(false, true)
  297. // this.boxHelper?.boxHelper?.copy?.(this._sceneBounds)
  298. this._sceneBoundingRadius = this._sceneBounds.getSize(new Vector3()).length() / 2.
  299. this.dispatchEvent({...event, type: 'sceneUpdate', hierarchyChanged: ['addedToParent', 'removedFromParent'].includes(event?.change || '')})
  300. iObjectCommons.setDirty.call(this, event)
  301. return this
  302. }
  303. refreshUi = iObjectCommons.refreshUi.bind(this)
  304. /**
  305. * Dispose the scene and clear all resources.
  306. * @warn Not fully implemented yet, just clears the scene.
  307. */
  308. dispose(): void {
  309. this.disposeSceneModels();
  310. [...this.children].forEach(child => child.dispose ? child.dispose() : child.removeFromParent())
  311. this.clear()
  312. // todo: dispose more stuff?
  313. this.environment?.dispose()
  314. if ((this.background as ITexture)?.isTexture) (this.background as ITexture)?.dispose?.()
  315. this.environment = null
  316. this.background = null
  317. return
  318. }
  319. /**
  320. * Returns the bounding box of the scene model root.
  321. * @param precise
  322. * @param ignoreInvisible
  323. * @returns {Box3B}
  324. */
  325. getBounds(precise = false, ignoreInvisible = true): Box3B {
  326. // See bboxVisible in userdata in Box3B
  327. return new Box3B().expandByObject(this, precise, ignoreInvisible)
  328. }
  329. /**
  330. * Refreshes the scene active camera near far values, based on the scene bounding box.
  331. * This is called automatically every time the camera is updated.
  332. */
  333. refreshActiveCameraNearFar(): void {
  334. const camera = this.mainCamera as ICamera
  335. if (!camera) return
  336. if (camera.userData.autoNearFar === false) {
  337. camera.near = camera.userData.minNearPlane ?? 0.2
  338. camera.far = camera.userData.maxFarPlane ?? 1000
  339. return
  340. }
  341. // todo check if this takes too much time with large scenes(when moving the camera and not animating), but we also need to support animations
  342. const bbox = this.getBounds(false) // todo: can we use this._sceneBounds or will it have some issue with animation?
  343. const pos = camera.getWorldPosition(new Vector3()).sub(bbox.getCenter(new Vector3()))
  344. const radius = 1.5 * bbox.getSize(new Vector3()).length() / 2.
  345. const dist = pos.length()
  346. const near = Math.max(camera.userData.minNearPlane ?? 0.2, dist - radius)
  347. const far = Math.min(Math.max(near + 1, dist + radius), camera.cameraObject.userData.maxFarPlane ?? 1000)
  348. camera.near = near
  349. camera.far = far
  350. // camera.near = 3
  351. // camera.far = 20
  352. }
  353. updateShaderProperties(material: {defines: Record<string, string|number|undefined>, uniforms: {[name: string]: IUniform}}): this {
  354. if (material.uniforms.sceneBoundingRadius) material.uniforms.sceneBoundingRadius.value = this._sceneBoundingRadius
  355. else console.warn('BaseRenderer: no uniform: frameCount')
  356. return this
  357. }
  358. /**
  359. * Serialize the scene properties
  360. * @param meta
  361. * @returns {any}
  362. */
  363. toJSON(meta?: any): any {
  364. const o = ThreeSerialization.Serialize(this, meta, true)
  365. // console.log(o)
  366. return o
  367. }
  368. /**
  369. * Deserialize the scene properties
  370. * @param json - object from {@link toJSON}
  371. * @param meta
  372. * @returns {this<TCamera>}
  373. */
  374. fromJSON(json: any, meta?: any): this {
  375. const env = json.environment
  376. if (env !== undefined) {
  377. this.environment = ThreeSerialization.Deserialize(env, this.environment, meta, false)
  378. delete json.environment
  379. }
  380. ThreeSerialization.Deserialize(json, this, meta, true)
  381. json.environment = env
  382. return this
  383. }
  384. addEventListener<T extends ISceneEventTypes>(type: T, listener: EventListener<ISceneEvent, T, this>): void {
  385. if (type === 'activeCameraChange') console.error('activeCameraChange is deprecated. Use mainCameraChange instead.')
  386. if (type === 'activeCameraUpdate') console.error('activeCameraUpdate is deprecated. Use mainCameraUpdate instead.')
  387. if (type === 'sceneMaterialUpdate') console.error('sceneMaterialUpdate is deprecated. Use materialUpdate instead.')
  388. if (type === 'update') console.error('update is deprecated. Use sceneUpdate instead.')
  389. super.addEventListener(type, listener)
  390. }
  391. // region inherited type fixes
  392. // re-declaring from IObject3D because: https://github.com/microsoft/TypeScript/issues/16936
  393. traverse: (callback: (object: IObject3D) => void) => void
  394. traverseVisible: (callback: (object: IObject3D) => void) => void
  395. traverseAncestors: (callback: (object: IObject3D) => void) => void
  396. getObjectById: <T extends IObject3D = IObject3D>(id: number) => T | undefined
  397. getObjectByName: <T extends IObject3D = IObject3D>(name: string) => T | undefined
  398. getObjectByProperty: <T extends IObject3D = IObject3D>(name: string, value: string) => T | undefined
  399. copy: (source: this, recursive?: boolean, ...args: any[]) => this
  400. clone: (recursive?: boolean) => this
  401. remove: (...object: IObject3D[]) => this
  402. dispatchEvent: (event: ISceneEvent) => void
  403. parent: null
  404. children: IObject3D[]
  405. // endregion
  406. // region deprecated
  407. // /**
  408. // * Set the scene environment map, this will be processed with PMREM automatically later.
  409. // * @param asset
  410. // * @returns {void}
  411. // */
  412. // public setEnvironment(asset: ITexture|null|undefined): void {
  413. // if (!asset) {
  414. // // eslint-disable-next-line deprecation/deprecation
  415. // this.environment = null
  416. // this._onEnvironmentChange()
  417. // return
  418. // }
  419. // if (!asset.isTexture) {
  420. // console.error('Unknown Environment type', asset)
  421. // return
  422. // }
  423. // if (asset.mapping === UVMapping) {
  424. // asset.mapping = EquirectangularReflectionMapping // for PMREMGenerator
  425. // asset.needsUpdate = true
  426. // }
  427. // // eslint-disable-next-line deprecation/deprecation
  428. // this.environment = asset
  429. // // eslint-disable-next-line deprecation/deprecation
  430. // // this.background = texture // for testing.
  431. // this._onEnvironmentChange()
  432. // }
  433. //
  434. // /**
  435. // * Get the current scene environment map
  436. // * @returns {ITexture<Texture>}
  437. // */
  438. // getEnvironment(): ITexture | null {
  439. // return this.environment || null
  440. // }
  441. /**
  442. * Find objects by name exact match in the complete hierarchy.
  443. * @deprecated Use {@link getObjectByName} instead.
  444. * @param name - name
  445. * @param parent - optional root node to start search from
  446. * @returns Array of found objects
  447. */
  448. public findObjectsByName(name: string, parent?: IObject3D): IObject3D[] {
  449. const o: IObject3D[] = [];
  450. (parent ?? this).traverse(object => {
  451. if (object.name === name) o.push(object)
  452. })
  453. return o
  454. }
  455. /**
  456. * @deprecated
  457. * Sets the camera pointing towards the object at a specific distance.
  458. * @param rootObject - The object to point at.
  459. * @param centerOffset - The distance offset from the object to point at.
  460. * @param targetOffset - The distance offset for the target from the center of object to point at.
  461. * @param options - Not used yet.
  462. */
  463. resetCamera(rootObject:Object3D|undefined = undefined, centerOffset = new Vector3(1, 1, 1), targetOffset = new Vector3(0, 0, 0)): void {
  464. if (this._mainCamera) {
  465. this.matrixWorldNeedsUpdate = true
  466. this.updateMatrixWorld(true)
  467. const bounds = rootObject ? new Box3B().expandByObject(rootObject, true, true) : this.getBounds(true)
  468. const center = bounds.getCenter(new Vector3())
  469. const radius = bounds.getSize(new Vector3()).length() * 0.5
  470. center.add(targetOffset.clone().multiplyScalar(radius))
  471. this._mainCamera.position = new Vector3( // todo: for nested cameras?
  472. center.x + centerOffset.x * radius,
  473. center.y + centerOffset.y * radius,
  474. center.z + centerOffset.z * radius,
  475. )
  476. this._mainCamera.target = center
  477. // this.scene.mainCamera.controls?.targetOffset.set(0, 0, 0)
  478. this.setDirty()
  479. }
  480. }
  481. /**
  482. * Minimum Camera near plane
  483. * @deprecated - use camera.userData.minNearPlane instead
  484. */
  485. get minNearDistance(): number {
  486. console.error('minNearDistance is deprecated. Use camera.userData.minNearPlane instead')
  487. return this.mainCamera.userData.minNearPlane ?? 0.02
  488. }
  489. /**
  490. * @deprecated - use camera.userData.minNearPlane instead
  491. */
  492. set minNearDistance(value: number) {
  493. console.error('minNearDistance is deprecated. Use camera.userData.minNearPlane instead')
  494. if (this.mainCamera)
  495. this.mainCamera.userData.minNearPlane = value
  496. }
  497. /**
  498. * @deprecated
  499. */
  500. get activeCamera(): ICamera {
  501. console.error('activeCamera is deprecated. Use mainCamera instead.')
  502. return this.mainCamera
  503. }
  504. /**
  505. * @deprecated
  506. */
  507. set activeCamera(camera: ICamera | undefined) {
  508. console.error('activeCamera is deprecated. Use mainCamera instead.')
  509. this.mainCamera = camera
  510. }
  511. /**
  512. * Get the threejs scene object
  513. * @deprecated
  514. */
  515. get modelObject(): this {
  516. return this as any
  517. }
  518. /**
  519. * @deprecated use {@link envMapIntensity} instead
  520. */
  521. get environmentIntensity(): number {
  522. return this.envMapIntensity
  523. }
  524. /**
  525. * @deprecated use {@link envMapIntensity} instead
  526. */
  527. set environmentIntensity(value: number) {
  528. this.envMapIntensity = value
  529. }
  530. /**
  531. * Add any processed scene object to the scene.
  532. * @deprecated renamed to {@link addObject}
  533. * @param imported
  534. * @param options
  535. */
  536. addSceneObject<T extends IObject3D|Object3D = IObject3D>(imported: T, options?: AddObjectOptions): T {
  537. return this.addObject(imported, options)
  538. }
  539. /**
  540. * Equivalent to setDirty({refreshScene: true}), dispatches 'sceneUpdate' event with the specified options.
  541. * @deprecated use refreshScene
  542. * @param options
  543. */
  544. updateScene(options?: AnyOptions): this {
  545. console.warn('updateScene is deprecated. Use refreshScene instead')
  546. return this.refreshScene(options || {})
  547. }
  548. /**
  549. * @deprecated renamed to {@link clearSceneModels}
  550. */
  551. removeSceneModels() {
  552. this.clearSceneModels()
  553. }
  554. // endregion
  555. }