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.

KTX2LoadPlugin.ts 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import {ThreeViewer} from '../../viewer'
  2. import {GLTFWriter2, ILoader, Importer, ImportResultExtras} from '../../assetmanager'
  3. import {KTX2Loader} from 'three/examples/jsm/loaders/KTX2Loader.js'
  4. import {CompressedTexture} from 'three'
  5. import {serializeTextureInExtras} from '../../utils'
  6. import {ITexture, upgradeTexture} from '../../core'
  7. import {BaseImporterPlugin} from '../base/BaseImporterPlugin'
  8. /**
  9. * Adds support for loading Compressed Textures of format `.ktx2`, `image/ktx2` files and data uris.
  10. * @category Plugins
  11. */
  12. export class KTX2LoadPlugin extends BaseImporterPlugin {
  13. public static readonly PluginType = 'KTX2LoadPlugin'
  14. protected _importer = new Importer(KTX2Loader2, ['ktx2'], ['image/ktx2'], false)
  15. public static TRANSCODER_LIBRARY_PATH = 'https://cdn.jsdelivr.net/gh/BinomialLLC/basis_universal@1.16.4/webgl/transcoder/build/'
  16. onAdded(viewer: ThreeViewer) {
  17. this._importer.onCtor = (l: KTX2Loader2) => l
  18. .setTranscoderPath(KTX2LoadPlugin.TRANSCODER_LIBRARY_PATH)
  19. .detectSupport(viewer.renderManager.renderer)
  20. super.onAdded(viewer)
  21. viewer.assetManager.exporter.getExporter('gltf', 'glb')?.extensions?.push(glTFTextureBasisUExtensionExport)
  22. }
  23. onRemove(viewer: ThreeViewer) {
  24. super.onRemove(viewer)
  25. const exporter = viewer.assetManager.exporter.getExporter('gltf', 'glb')
  26. const index = exporter?.extensions?.indexOf(glTFTextureBasisUExtensionExport)
  27. if (index !== undefined && index !== -1) exporter?.extensions?.splice(index, 1)
  28. }
  29. }
  30. export class KTX2Loader2 extends KTX2Loader implements ILoader {
  31. private _initTexture(t: CompressedTexture & ITexture) {
  32. upgradeTexture.call(t)
  33. t.userData.mimeType = 'image/ktx2'
  34. t.toJSON = (meta?: any)=>{
  35. return serializeTextureInExtras(t, meta, t.name, 'image/ktx2')
  36. }
  37. const cloneFn = t.clone
  38. t.clone = ()=>{
  39. const res = cloneFn.call(t)
  40. if (res.source !== t.source) // in case something changes
  41. res.source._sourceImgBuffer = t.source._sourceImgBuffer
  42. return this._initTexture(res)
  43. }
  44. return t
  45. }
  46. async createTexture(buffer: ArrayBuffer, config: any): Promise<CompressedTexture> {
  47. const buffer2 = new Uint8Array(buffer.slice(0)) // clones the buffer
  48. const texture = (await super.createTexture(buffer, config)) as CompressedTexture & ITexture
  49. texture.source._sourceImgBuffer = buffer2 // keep the same buffer when cloned and all, used in serializeTextureInExtras
  50. this._initTexture(texture)
  51. return texture
  52. }
  53. }
  54. export const KHR_TEXTURE_BASISU = 'KHR_texture_basisu'
  55. const glTFTextureBasisUExtensionExport = (w: GLTFWriter2)=> ({
  56. writeTexture: (texture: ITexture&ImportResultExtras, textureDef: any) => {
  57. // if (!w.options.embedImages) return // option is removed.
  58. if (texture.userData.mimeType !== 'image/ktx2') return
  59. if (textureDef.source !== undefined && textureDef.source !== null) {
  60. console.warn('ktx2 export: source already set')
  61. return
  62. }
  63. const sourceBuffer = texture.source._sourceImgBuffer || texture.__sourceBuffer // todo do this for all images that have a __sourceBuffer (in GLTFExporter.processImage or GLTFWriter2.processTexture)
  64. if (!sourceBuffer) {
  65. console.warn('ktx2 export: no source buffer for ktx2')
  66. return
  67. }
  68. textureDef.extensions = textureDef.extensions || {}
  69. const extensionDef: any = {}
  70. const blob = new Blob([sourceBuffer], {type: 'image/ktx2'})
  71. extensionDef.source = w.processImageBlob(blob, texture)
  72. textureDef.extensions[ KHR_TEXTURE_BASISU ] = extensionDef
  73. w.extensionsUsed[ KHR_TEXTURE_BASISU ] = true
  74. },
  75. })