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.

script.ts 2.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import {
  2. _testFinish,
  3. _testStart,
  4. downloadBlob,
  5. HemisphereLight,
  6. IObject3D,
  7. LoadingScreenPlugin,
  8. ThreeViewer,
  9. } from 'threepipe'
  10. import {AssimpJsPlugin} from '@threepipe/plugin-assimpjs'
  11. const viewer = new ThreeViewer({
  12. canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
  13. msaa: true,
  14. plugins: [LoadingScreenPlugin],
  15. })
  16. // Export to fbx is done by first exporting to glb and converting that to fbx using AssimpJsPlugin
  17. async function init() {
  18. const assimp = viewer.addPluginSync(AssimpJsPlugin)
  19. await assimp.init()
  20. viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')
  21. // load a file
  22. const result = await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
  23. autoCenter: true,
  24. autoScale: true,
  25. })
  26. let fbxBlob: Blob | undefined = undefined
  27. let converting = false
  28. async function exportFbx() {
  29. if (fbxBlob) return fbxBlob
  30. if (converting) {
  31. console.warn('Already converting, please wait...')
  32. return
  33. }
  34. converting = true
  35. // export to glb
  36. fbxBlob = await assimp.exportModel('fbx', result, {
  37. embedUrlImages: true,
  38. })
  39. // const blob = await viewer.exportScene(); // its possible to export the whole scene also
  40. if (!fbxBlob) {
  41. alert('Failed to convert glb to fbx')
  42. converting = false
  43. return
  44. }
  45. // clear scene
  46. viewer.scene.disposeSceneModels()
  47. // load a light and fbx file
  48. const hemiLight = viewer.scene.addObject(new HemisphereLight(0xffffff, 0x444444, 5), {addToRoot: true})
  49. hemiLight.name = 'Hemisphere Light'
  50. await viewer.load({
  51. path: 'file.fbx',
  52. file: fbxBlob,
  53. }, {
  54. autoCenter: true,
  55. autoScale: true,
  56. })
  57. converting = false
  58. return fbxBlob
  59. }
  60. // add download button
  61. const convertButton = document.createElement('button')
  62. convertButton.innerText = 'Convert to fbx'
  63. convertButton.style.position = 'absolute'
  64. convertButton.style.bottom = '6rem'
  65. convertButton.style.right = '3rem'
  66. convertButton.style.zIndex = '10000'
  67. convertButton.onclick = async() => {
  68. await exportFbx()
  69. }
  70. document.body.appendChild(convertButton)
  71. const downloadButton = document.createElement('button')
  72. downloadButton.innerText = 'Download as .fbx'
  73. downloadButton.style.position = 'absolute'
  74. downloadButton.style.bottom = '3rem'
  75. downloadButton.style.right = '3rem'
  76. downloadButton.style.zIndex = '10000'
  77. downloadButton.onclick = async() => {
  78. await exportFbx()
  79. if (fbxBlob) downloadBlob(fbxBlob, 'file.fbx')
  80. }
  81. document.body.appendChild(downloadButton)
  82. }
  83. _testStart()
  84. init().finally(_testFinish)