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

GLTFLoader2.ts 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import {GLTF, GLTFLoader, GLTFLoaderPlugin, GLTFParser} from 'three/examples/jsm/loaders/GLTFLoader.js'
  2. import {LoadingManager, Object3D} from 'three'
  3. import {AnyOptions, safeSetProperty} from 'ts-browser-helpers'
  4. import {ThreeViewer} from '../../viewer/ThreeViewer'
  5. import {generateUUID} from '../../three/utils/misc'
  6. import {GLTFViewerConfigExtension} from '../gltf/GLTFViewerConfigExtension'
  7. import {GLTFMaterialExtrasExtension} from '../gltf/GLTFMaterialExtrasExtension'
  8. import {GLTFObject3DExtrasExtension} from '../gltf/GLTFObject3DExtrasExtension'
  9. import {GLTFLightExtrasExtension} from '../gltf/GLTFLightExtrasExtension'
  10. import {GLTFMaterialsBumpMapExtension} from '../gltf/GLTFMaterialsBumpMapExtension'
  11. import {GLTFMaterialsLightMapExtension} from '../gltf/GLTFMaterialsLightMapExtension'
  12. import {GLTFMaterialsDisplacementMapExtension} from '../gltf/GLTFMaterialsDisplacementMapExtension'
  13. import {GLTFMaterialsAlphaMapExtension} from '../gltf/GLTFMaterialsAlphaMapExtension'
  14. import {RootSceneImportResult} from '../IAssetImporter'
  15. import {ILoader} from '../IImporter'
  16. export class GLTFLoader2 extends GLTFLoader implements ILoader<GLTF, Object3D|undefined> {
  17. isGLTFLoader2 = true
  18. constructor(manager: LoadingManager) {
  19. super(manager)
  20. }
  21. static ImportExtensions: ((parser: GLTFParser) => GLTFLoaderPlugin)[] = [
  22. GLTFObject3DExtrasExtension.Import,
  23. GLTFLightExtrasExtension.Import,
  24. GLTFMaterialsBumpMapExtension.Import,
  25. GLTFMaterialsDisplacementMapExtension.Import,
  26. GLTFMaterialsLightMapExtension.Import,
  27. GLTFMaterialsAlphaMapExtension.Import,
  28. ]
  29. transform(res: GLTF, _: AnyOptions): Object3D|undefined {
  30. // todo: support loading of multiple scenes?
  31. const scene: RootSceneImportResult|undefined = res ? res.scene || !!res.scenes && res.scenes.length > 0 && res.scenes[0] : undefined as any
  32. if (!scene) return undefined
  33. if (res.animations.length > 0) scene.animations = res.animations
  34. scene.traverse((node: Object3D) => {
  35. if (node.userData.gltfUUID) { // saved in GLTFExporter2
  36. safeSetProperty(node, 'uuid', node.userData.gltfUUID, true, true)
  37. delete node.userData.gltfUUID // have issue with cloning if we don't dispose.
  38. }
  39. })
  40. if (!scene.userData) scene.userData = {}
  41. if (res.userData) scene.userData.gltfExtras = res.userData // todo: put back in gltf in GLTFExporter2
  42. if (res.cameras) res.cameras.forEach(c => !c.parent && scene.add(c))
  43. if (res.asset) scene.userData.gltfAsset = res.asset // todo: put back in gltf in GLTFExporter2
  44. return scene
  45. }
  46. register(callback: (parser: GLTFParser) => GLTFLoaderPlugin): this {
  47. return super.register(callback) as this
  48. }
  49. setup(viewer: ThreeViewer, extraExtensions: ((parser: GLTFParser) => GLTFLoaderPlugin)[]): this {
  50. this.register(GLTFMaterialExtrasExtension.Import(viewer.loadConfigResources))
  51. for (const ext of extraExtensions) this.register(ext)
  52. for (const ext of GLTFLoader2.ImportExtensions) this.register(ext)
  53. // Note: this should be last
  54. this.register(this.gltfViewerParser(viewer))
  55. return this
  56. }
  57. // loads the viewer config and handles loading the draco loader for extension
  58. gltfViewerParser = (viewer: ThreeViewer): (p: GLTFParser)=>GLTFLoaderPlugin => {
  59. return (parser: GLTFParser) => {
  60. const tempPathDrc = generateUUID() + '.drc'
  61. const tempPathKtx2 = generateUUID() + '.ktx2'
  62. const needsDrc = parser.json?.extensionsRequired?.includes?.('KHR_draco_mesh_compression')
  63. if (needsDrc) {
  64. const drc = viewer.assetManager.importer.registerFile(tempPathDrc)
  65. drc && this.setDRACOLoader(drc as any) // todo: check class?
  66. }
  67. const needsMeshOpt = parser.json?.extensionsUsed?.includes?.('EXT_meshopt_compression')
  68. if (needsMeshOpt) {
  69. if ((window as any).MeshoptDecoder) { // added by the plugin or by the user
  70. this.setMeshoptDecoder((window as any).MeshoptDecoder)
  71. parser.options.meshoptDecoder = (window as any).MeshoptDecoder as any
  72. } else {
  73. console.error('Add GLTFMeshOptPlugin to viewer to enable EXT_meshopt_compression decode')
  74. }
  75. }
  76. const needsBasisU = parser.json?.extensionsUsed?.includes?.('KHR_texture_basisu')
  77. if (needsBasisU) {
  78. const ktx2 = viewer.assetManager.importer.registerFile(tempPathKtx2)
  79. if (ktx2) {
  80. this.setKTX2Loader(ktx2 as any) // todo: check class?
  81. parser.options.ktx2Loader = ktx2 as any
  82. }
  83. }
  84. return {name: 'GLTF2_HELPER_PLUGIN', afterRoot: async(result: GLTF) => {
  85. if (needsDrc) viewer.assetManager.importer.unregisterFile(tempPathDrc)
  86. if (needsBasisU) viewer.assetManager.importer.unregisterFile(tempPathKtx2)
  87. await GLTFViewerConfigExtension.ImportViewerConfig(parser, viewer, result.scenes || [result.scene])
  88. }}
  89. }
  90. }
  91. }