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.

VirtualCamerasPlugin.ts 2.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import {AViewerPluginEventMap, AViewerPluginSync} from '../../viewer'
  2. import {IRenderTarget} from '../../rendering'
  3. import {ICamera} from '../../core'
  4. import {uiFolderContainer, uiToggle} from 'uiconfig.js'
  5. export interface VirtualCamerasPluginEventMap extends AViewerPluginEventMap {
  6. preRenderCamera: {camera: VirtualCamera}
  7. preBlitCamera: {camera: VirtualCamera, readBuffer: WebGLTexture}
  8. postRenderCamera: {camera: VirtualCamera}
  9. }
  10. export interface VirtualCamera {
  11. camera: ICamera
  12. target: IRenderTarget
  13. enabled: boolean
  14. }
  15. @uiFolderContainer('Virtual Cameras')
  16. export class VirtualCamerasPlugin extends AViewerPluginSync<VirtualCamerasPluginEventMap> {
  17. public static readonly PluginType = 'VirtualCamerasPlugin'
  18. @uiToggle()
  19. enabled = true
  20. toJSON: any = undefined // disable serialization
  21. constructor(enabled = true) {
  22. super()
  23. this.enabled = enabled
  24. }
  25. cameras: VirtualCamera[] = []
  26. protected _viewerListeners = {
  27. preRender: () => {
  28. if (this.isDisabled() || !this._viewer) return
  29. const viewer = this._viewer
  30. for (const v of this.cameras) {
  31. if (!v.enabled) continue
  32. const camera = v.camera
  33. try {
  34. this.dispatchEvent({type: 'preRenderCamera', camera: v})
  35. viewer.scene.renderCamera = camera
  36. viewer.renderManager.render(viewer.scene, false)
  37. const source = viewer.renderManager.composer.readBuffer.texture
  38. this.dispatchEvent({type: 'preBlitCamera', camera: v, readBuffer: source})
  39. viewer.renderManager.blit(v.target, {source})
  40. this.dispatchEvent({type: 'postRenderCamera', camera: v})
  41. } catch (e: any) {
  42. viewer.console.error(e)
  43. v.enabled = false
  44. if (viewer.debug) throw e
  45. }
  46. }
  47. },
  48. }
  49. addCamera(camera: ICamera, target?: IRenderTarget): VirtualCamera {
  50. if (!this._viewer) throw 'Plugin not added to viewer'
  51. target = target ?? this._viewer.renderManager.composerTarget.clone(true)
  52. target.name = camera.name + '_virtualCamTarget'
  53. const vCam: VirtualCamera = {camera, target, enabled: true}
  54. this.cameras.push(vCam)
  55. // todo: track for jitter in progressive or something else for jittering
  56. return vCam
  57. }
  58. }