Estoy usando Three.js para crear una animación, pero mi función animate() no funciona correctamente. Código simplificado a continuación:
let obj; let camera = new THREE.PerspectiveCamera(fov, asp, near, far); let scene = new THREE.Scene(); const loader = new THREE.GLTFLoader(); async function init() { obj = await loader.loadAsync("./public/modelo/scene.gltf"); scene.add(obj.scene); animate(obj.scene.children[0]); renderer.render(scene, camera); function animate(objeto){ console.log(objeto); requestAnimationFrame(animate); objeto.rotation.z += 0.005; renderer.render(scene, camera); } } init(); La función funciona para la primera llamada, pero después de eso puedo ver que las cosas van mal a través de mi instrucción console.log() . En la primera ejecución de animate() , la línea imprime el objeto, como se esperaba. Pero, en todas las llamadas subsiguientes, la instrucción solo devuelve un número de coma flotante que aumenta considerablemente con cada llamada sucesiva. Revisé y me aseguré de que el objeto estuviera intacto al final de la primera llamada a la función, así que no estoy seguro de qué está pasando aquí. ¿Alguna sugerencia?
El problema está en esta línea en su código:
requestAnimationFrame(animate); De la documentación de MDN para requestAnimationFrame , la devolución de llamada que pasa, aquí animate , es:
La función para llamar cuando sea el momento de actualizar su animación para el próximo repintado. A la función de devolución de llamada se le pasa un solo argumento, un DOMHighResTimeStamp similar al devuelto por performance.now(), que indica el momento en el que requestAnimationFrame() comienza a ejecutar funciones de devolución de llamada.
En otras palabras, se llama a su animate con una marca de tiempo, que de alguna manera me imagino que se comporta como un número (no estoy personalmente familiarizado con lo que es DOMHighResTimeStamp ) y explica lo que está viendo. Ciertamente no lo llamarán con su "objeto" como argumento.
Para asegurarse de eso, simplemente pase como devolución de llamada una función llamará a animate con el argumento correcto. Reemplace la llamada anterior con
requestAnimationFrame(() => { animate(objeto); }); EDITAR: o como sugiere @Bergi, podemos evitar la necesidad de un argumento simplemente definiendo objeto fuera de animate , en la función de init . Dado que siempre llamas a animate con este mismo argumento, no hay necesidad de pasarlo específicamente, por lo que tu código puede ser simplemente:
async function init() { obj = await loader.loadAsync("./public/modelo/scene.gltf"); const objeto = obj.scene.children[0]; scene.add(obj.scene); animate(); renderer.render(scene, camera); function animate(){ console.log(objeto); requestAnimationFrame(animate); objeto.rotation.z += 0.005; renderer.render(scene, camera); } }