threepipe
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

TransformControlsPlugin.ts 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import {uiButton, uiConfig, uiPanelContainer, uiToggle} from 'uiconfig.js'
  2. import {AViewerPluginSync, ThreeViewer} from '../../viewer'
  3. import {OrbitControls3, TransformControls2} from '../../three'
  4. import {PickingPlugin} from './PickingPlugin'
  5. import {onChange} from 'ts-browser-helpers'
  6. import {TransformControls} from '../../three/controls/TransformControls'
  7. import {UnlitLineMaterial, UnlitMaterial} from '../../core'
  8. @uiPanelContainer('Transform Controls')
  9. export class TransformControlsPlugin extends AViewerPluginSync<''> {
  10. public static readonly PluginType = 'TransformControlsPlugin'
  11. @uiToggle()
  12. @onChange(TransformControlsPlugin.prototype.setDirty)
  13. enabled = true
  14. private _pickingWidgetDisabled = false
  15. setDirty() {
  16. if (!this._viewer) return
  17. const picking = this._viewer.getPlugin(PickingPlugin)!
  18. const enabled = !this.isDisabled()
  19. if (enabled && picking.widgetEnabled) {
  20. picking.widgetEnabled = false
  21. this._pickingWidgetDisabled = true
  22. } else if (!enabled && this._pickingWidgetDisabled) {
  23. picking.widgetEnabled = true
  24. this._pickingWidgetDisabled = false
  25. }
  26. if (this.transformControls) {
  27. if (enabled && picking.getSelectedObject()) this.transformControls.attach(picking.getSelectedObject()!)
  28. else this.transformControls.detach()
  29. }
  30. this._viewer.setDirty()
  31. }
  32. constructor(enabled: boolean) {
  33. super()
  34. TransformControls.ObjectConstructors.MeshBasicMaterial = UnlitMaterial as any
  35. TransformControls.ObjectConstructors.LineBasicMaterial = UnlitLineMaterial as any
  36. this.enabled = enabled
  37. }
  38. toJSON: any = undefined
  39. dependencies = [PickingPlugin]
  40. @uiConfig()
  41. transformControls: TransformControls2 | undefined
  42. protected _isInteracting = false
  43. protected _viewerListeners = {
  44. postFrame: ()=>{
  45. if (!this.transformControls || !this._viewer) return
  46. // this._viewer.scene.mainCamera.setInteractions(!this._isInteracting, TransformControlsPlugin.PluginType)
  47. },
  48. }
  49. onAdded(viewer: ThreeViewer) {
  50. super.onAdded(viewer)
  51. this.setDirty()
  52. this.transformControls = new TransformControls2(viewer.scene.mainCamera, viewer.canvas)
  53. this._mainCameraChange = this._mainCameraChange.bind(this)
  54. viewer.scene.addEventListener('mainCameraChange', this._mainCameraChange)
  55. this.transformControls.addEventListener('dragging-changed', (event) => {
  56. if (!this?._viewer) return
  57. const controls = this._viewer.scene.mainCamera.controls
  58. if (typeof (controls as any)?.stopDamping === 'function' && controls?.enabled) (controls as OrbitControls3).stopDamping()
  59. this._viewer.scene.mainCamera.setInteractions(!event.value, TransformControlsPlugin.PluginType)
  60. // this._viewer.scene.mainCamera.autoNearFar = !event.value // todo: maintain state
  61. })
  62. this.transformControls.addEventListener('axis-changed', (event) => {
  63. if (!this?._viewer) return
  64. this._isInteracting = !!event.value
  65. const controls = this._viewer.scene.mainCamera.controls
  66. if (typeof (controls as any)?.stopDamping === 'function' && controls?.enabled) (controls as OrbitControls3).stopDamping()
  67. this._viewer.setDirty() // rerender for color change
  68. })
  69. viewer.scene.addObject(this.transformControls, {addToRoot: true})
  70. const picking = viewer.getPlugin(PickingPlugin)!
  71. picking.addEventListener('selectedObjectChanged', (event) => {
  72. if (!this.transformControls) return
  73. if (this.isDisabled()) {
  74. if (this.transformControls.object) this.transformControls.detach()
  75. return
  76. }
  77. event.object ? this.transformControls.attach(event.object) : this.transformControls.detach()
  78. })
  79. }
  80. onRemove(viewer: ThreeViewer) {
  81. viewer.scene.removeEventListener('mainCameraChange', this._mainCameraChange)
  82. if (this.transformControls) {
  83. this.transformControls.detach()
  84. viewer.scene.remove(this.transformControls)
  85. this.transformControls.dispose()
  86. }
  87. this.transformControls = undefined
  88. super.onRemove(viewer)
  89. }
  90. private _mainCameraChange = () => {
  91. if (!this.transformControls || !this._viewer) return
  92. this.transformControls.camera = this._viewer.scene.mainCamera
  93. }
  94. @uiButton('Center All Meshes')
  95. centerAllMeshes() {
  96. this._viewer?.scene.centerAllGeometries(true)
  97. }
  98. }