Siento que estoy cerca pero todavía me falta algo. Esto es lo que tengo hasta ahora
var files = window.files; console.log(files) // => (3) [File, File, File] // File objects: // 0: File {correctName: 'test.bin', name: 'test.bin' …} // 1: File {correctName: 'test.gltf', name: 'test.gltf', …} // 2: File {correctName: 'test.png', name: 'teest.png', …} var fi = new BABYLON.FilesInput(engine, scene, (s) => { console.log('here in scene loaded callback'); }) fi.loadFiles({ dataTransfer: { files: asheFiles } });Sin embargo, nunca se llama a la devolución de llamada cargada de la escena. Tampoco veo que se represente nada en el elemento de lienzo de la página.
Sé que claramente hay una manera de hacerlo según el ejemplo que tienen aquí: https://sandbox.babylonjs.com/
Solo estoy tratando de descubrir cómo recrear eso.
Bien amigos, tengo una solución.
Después de buscar en muchas de sus páginas de documentación, foros en línea y preguntas similares aquí en Stackoverflow, me di cuenta de que Babylon js realmente no tiene una API de carga directa de archivos. Tienen funciones que pueden tomar objetos de archivo como argumentos, pero en última instancia eso no satisface las necesidades de digerir un archivo gltf que se divide en varias partes, a saber, .gltf, .png y .bin. Dado que el uso de un método provisto como BABYLON.SceneLoader.Append en el archivo gltf fallará una vez que BABYLON lo analice e inmediatamente comience a solicitar los archivos adjuntos (.png y .bin) a través de la web. Aquí, en teoría, podría usar un archivo .glb, pero ese no es el formato de archivo que estoy usando en mi proyecto.
Necesita piratear la biblioteca para que le permita hacer lo que necesita. Empecé a mirar el código de ejemplo utilizado en el sandbox vinculado arriba. Usan esta clase FileInput para cargar de alguna manera todos los archivos adjuntos después de un evento de arrastrar y soltar. Emulé la funcionalidad de arrastrar y soltar a través de:
function sceneLoadedCB(newScene) { window.scene = newSene; initCamera(newScene, canvas); } const fi = new BABYLON.FilesInput(engine, scene, sceneLoadedCB) fi.loadFiles({ dataTransfer: { files: [gltfFileObject, pngFileObject, binFileObject] } })Esto habría sido lo suficientemente bueno para mis propósitos, excepto que siempre creará otro objeto de escena en lugar del actual, evitando que cargue una escena con múltiples objetos gltf. Los contenedores de activos no funcionarán para resolver esto, ya que siempre están vinculados a la escena con la que se crearon; no puede transferir activos de una escena a otra.
No realicé ingeniería inversa de la lógica que analiza y agrupa los archivos como parte del mismo objeto gltf. Pero encontré que esta propiedad estática de la clase FilesInputStore se usa como un lugar para almacenar objetos de archivo JavaScript reales. Si completa esta tienda con su archivo gltf que acompaña a los activos de archivo, podrá cargarlos juntos como parte de su archivo gltf.
Manifestación:
var theScene // your babylon scene instance const renderLoop = (sceneToRender) => { sceneToRender = sceneToRender || window.scene sceneToRender.render(); sceneToRender.getEngine().runRenderLoop(renderLoop); }; yourGLTFFiles.forEach((file) => { window.BABYLON.FilesInputStore.FilesToLoad[file.name] = file }) const gltfFile = yourGLTFFiles.find((file) => file.name.includes('gltf')) BABYLON.SceneLoader.Append('file:', gltfFile, theScene, function (loadedScene) { console.log('here in scene loaded callback, scene: ', loadedScene) // below will be true since append adds to the scene instance you passed it console.log(loadedScene === theScene) renderLoop(theScene) });Esto me tomó una eternidad para resolver. ¡Espero que esta solución le ahorre tiempo en la construcción de su increíble proyecto!