threepipe
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

MeshOptSimplifyModifierPlugin.ts 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import {ThreeViewer} from '../../viewer'
  2. import {BufferAttribute, BufferGeometry} from 'three'
  3. import {IGeometry, iGeometryCommons} from '../../core'
  4. import {toIndexedGeometry} from '../../three'
  5. import {SimplifyModifierPlugin} from './SimplifyModifierPlugin'
  6. import {uiFolderContainer, uiNumber, uiToggle} from 'uiconfig.js'
  7. /**
  8. * Simplify modifier using [meshoptimizer](https://github.com/zeux/meshoptimizer) library.
  9. * Loads the library at runtime from a customisable cdn url.
  10. */
  11. @uiFolderContainer('Simplify Modifier (meshopt)')
  12. export class MeshOptSimplifyModifierPlugin extends SimplifyModifierPlugin {
  13. public static readonly PluginType = 'MeshOptSimplifyModifierPlugin'
  14. constructor(initialize = true) {
  15. super()
  16. // todo: check if compatible?
  17. if (initialize) this.initialize()
  18. }
  19. get initialized() {
  20. return !!window.MeshoptSimplifier
  21. }
  22. // static SIMPLIFIER_URL = 'https://cdn.jsdelivr.net/gh/zeux/meshoptimizer@master/js/meshopt_simplifier.module.js'
  23. static SIMPLIFIER_URL = 'https://unpkg.com/meshoptimizer@0.20.0/meshopt_simplifier.module.js'
  24. onAdded(viewer: ThreeViewer) {
  25. super.onAdded(viewer)
  26. }
  27. protected _initializing?: Promise<void> = undefined
  28. async initialize() {
  29. if (this.initialized) return
  30. if (this._initializing) return await this._initializing
  31. const s = document.createElement('script')
  32. s.type = 'module'
  33. const ev = Math.random().toString(36).substring(7)
  34. s.innerHTML = `
  35. import { MeshoptSimplifier } from '${MeshOptSimplifyModifierPlugin.SIMPLIFIER_URL}';
  36. MeshoptSimplifier.ready.then(() => {
  37. window.MeshoptSimplifier = MeshoptSimplifier;
  38. window.dispatchEvent(new CustomEvent('${ev}'))
  39. });
  40. `
  41. this._initializing = new Promise<void>((res) => {
  42. const l = () => {
  43. window.removeEventListener(ev, l)
  44. res() // todo timeout?
  45. }
  46. window.addEventListener(ev, l)
  47. document.head.appendChild(s) // todo remove later?
  48. // this._script = s
  49. })
  50. }
  51. @uiNumber()
  52. errorThreshold = 0.5
  53. @uiToggle()
  54. lockBorder = false
  55. protected _simplify(geometry: BufferGeometry, count: number): IGeometry {
  56. if (!this.initialized) throw new Error('MeshOptSimplifyModifierPlugin not initialized')
  57. if (!geometry.index) {
  58. geometry = toIndexedGeometry(geometry)
  59. } else {
  60. geometry = geometry.clone()
  61. }
  62. const srcIndexArray = geometry.index!.array
  63. const srcPositionArray = geometry.attributes.position.array
  64. const factor = count / geometry.attributes.position.count
  65. // console.log(factor)
  66. // const targetCount = count * 3
  67. const targetCount = 3 * Math.floor(factor * srcIndexArray.length / 3)
  68. // console.log('srcCount', srcIndexArray.length / 3, 'targetCount', targetCount / 3)
  69. // const errorThresh = 1e-2
  70. const [dstIndexArray, error] = window.MeshoptSimplifier.simplify(
  71. srcIndexArray,
  72. srcPositionArray,
  73. 3,
  74. targetCount,
  75. this.errorThreshold,
  76. this.lockBorder ? ['LockBorder'] : [],
  77. )
  78. console.log('srcCount', srcIndexArray.length / 3, 'destCount', dstIndexArray.length / 3)
  79. if (error) {
  80. console.error('Simplify error', error)
  81. // return geometry // todo
  82. }
  83. // (geometry.index!.array as Uint32Array).set(dstIndexArray)
  84. geometry.setIndex(new BufferAttribute(new Uint32Array(dstIndexArray), 1))
  85. // geometry.index!.needsUpdate = true
  86. // geometry.setDrawRange(0, dstIndexArray.length)
  87. return iGeometryCommons.upgradeGeometry.call(geometry.toNonIndexed())
  88. }
  89. }
  90. declare global{
  91. interface Window{
  92. MeshoptSimplifier?: any
  93. }
  94. }