threepipe
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

GeometryGeneratorPlugin.ts 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import {AViewerPluginSync, BufferGeometry2, IGeometry, Mesh, PhysicalMaterial, ThreeViewer} from 'threepipe'
  2. import {TorusGeometryGenerator} from './primitives/TorusGeometryGenerator'
  3. import {CircleGeometryGenerator} from './primitives/CircleGeometryGenerator'
  4. import {BoxGeometryGenerator} from './primitives/BoxGeometryGenerator'
  5. import {SphereGeometryGenerator} from './primitives/SphereGeometryGenerator'
  6. import {PlaneGeometryGenerator} from './primitives/PlaneGeometryGenerator'
  7. import {CylinderGeometryGenerator} from './primitives/CylinderGeometryGenerator'
  8. import {GeometryGenerator, updateUi} from './AGeometryGenerator'
  9. /**
  10. * GeometryGeneratorPlugin
  11. *
  12. * Geometry generator plugin to create updatable parametric objects/geometries.
  13. * Includes support for several primitive types from three.js
  14. */
  15. export class GeometryGeneratorPlugin extends AViewerPluginSync<''> {
  16. public static readonly PluginType = 'GeometryGeneratorPlugin'
  17. enabled = true
  18. toJSON: any = undefined
  19. generators: Record<string, GeometryGenerator> = {
  20. plane: new PlaneGeometryGenerator('plane'),
  21. sphere: new SphereGeometryGenerator('sphere'),
  22. box: new BoxGeometryGenerator('box'),
  23. circle: new CircleGeometryGenerator('circle'),
  24. torus: new TorusGeometryGenerator('torus'),
  25. cylinder: new CylinderGeometryGenerator('cylinder'),
  26. }
  27. generateObject(type: string, params?: any) {
  28. const generator = this.generators[type]
  29. if (!generator) throw new Error('Unknown generator type: ' + type)
  30. const obj = new Mesh(new BufferGeometry2(), new PhysicalMaterial())
  31. generator.generate(obj.geometry, params)
  32. obj.name = type
  33. obj.geometry.name = 'Generated ' + type
  34. return obj
  35. }
  36. generateGeometry(type: string, params: any, geometry?: IGeometry) {
  37. const generator = this.generators[type]
  38. if (!generator) throw new Error('Unknown generator type: ' + type)
  39. const g = generator.generate(geometry, params)
  40. g.name = 'Generated ' + type
  41. return g
  42. }
  43. updateGeometry(geometry: IGeometry, params: any) {
  44. if (!geometry.userData.generationParams?.type) throw new Error('Geometry is not generated')
  45. const generator = this.generators[geometry.userData.generationParams.type]
  46. if (!generator) throw new Error('Unknown generator type: ' + geometry.userData.generationParams.type)
  47. generator.generate(geometry, params)
  48. }
  49. onAdded(v: ThreeViewer) {
  50. super.onAdded(v)
  51. v.scene.addEventListener('sceneUpdate', this._sceneUpdate)
  52. }
  53. protected _sceneUpdate = (e: any)=>{
  54. if (e.hierarchyChanged) {
  55. const obj = e.object || this._viewer?.scene.modelRoot
  56. console.log(obj)
  57. if (obj) {
  58. obj.traverse((o: any)=>{
  59. const type = o.geometry?.userData?.generationParams?.type
  60. if (!type) return
  61. updateUi(o.geometry, ()=>{
  62. const gen = this.generators[type]
  63. return gen?.createUiConfig ? gen.createUiConfig(o.geometry) ?? [] : []
  64. })
  65. })
  66. }
  67. }
  68. }
  69. uiConfig = {
  70. type: 'folder',
  71. label: 'Generate Geometry',
  72. children:
  73. [()=>Object.keys(this.generators).map((v) => ({
  74. type: 'button',
  75. label: 'Generate ' + v,
  76. value: async() => {
  77. const obj = this.generateObject(v)
  78. obj.name = v
  79. this._viewer?.scene.addObject(obj)
  80. },
  81. }))],
  82. }
  83. }