Animación de Rotores de Drones en Cesium
Para simular el vuelo de un dron cuadricóptero en entornos de visualización 3D como Cesium, es necesario manipular los nodos del modelo glTF dinámicamente. Mediante la aplicación de matrices de transformación en un bucle de renderizado, podemos lograr el efecto de rotación continua de las hélices sin depender de animaciones óseas predefinidas, lo que permite un control directo mediante datos de sensores IoT.
Carga del Modelo y Bucle de Animación
El primer paso consiste en escuchar el evento de carga del modelo 3D. Una vez que el glTF se ha procesado, guardamos la referencia e iniciamos el bucle de actualización gráfica utilizando requestAnimationFrame.
droneEntity.readyEvent.addEventListener((loadedGltf) => {
activeDroneModel = loadedGltf;
startAnimationLoop();
});
Lógica de Rotación de Hélices
Dentro del bucle de animación, accedemos al diccionario de nodos del modelo. Identificamos los nodos correspondientes a las hélices y aplicmaos una rotación alrededor de su propio eje. Para evitar que la hélice orbite alrededor del centro del dron, debemos trasladarla al origen de coordenadas, aplicar la matriz de rotación en el eje Y y luego trasladarla de vuelta a su posición original. Las hélices opuestas deben girar en direcciones contrarias para simular la estabilidad aerodinámica real.
const components = activeDroneModel.model._nodesByName;
const counterClockwiseProps = ['prop_a', 'prop_d'];
for (const partName in components) {
if (partName.startsWith('prop_')) {
const mesh = components[partName];
const pivotPoint = Cesium.Matrix4.getTranslation(mesh.matrix, new Cesium.Cartesian3());
// Definir dirección de rotación (10 grados por fotograma)
let spinAngle = Cesium.Math.toRadians(10);
if (counterClockwiseProps.includes(partName)) {
spinAngle = Cesium.Math.toRadians(-10);
}
const spinMatrix = Cesium.Matrix3.fromRotationY(spinAngle);
// 1. Trasladar la malla al origen de coordenadas mundial
const offsetToZero = Cesium.Matrix4.fromTranslation(Cesium.Cartesian3.negate(pivotPoint, new Cesium.Cartesian3()));
const centeredMatrix = Cesium.Matrix4.multiply(offsetToZero, mesh.matrix, new Cesium.Matrix4());
// 2. Aplicar la rotación en el origen
const spunMatrix = Cesium.Matrix4.multiply(Cesium.Matrix4.fromRotationTranslation(spinMatrix), centeredMatrix, new Cesium.Matrix4());
// 3. Trasladar la malla de vuelta a su posición original en el dron
const offsetToOrigin = Cesium.Matrix4.fromTranslation(pivotPoint);
mesh.matrix = Cesium.Matrix4.multiply(offsetToOrigin, spunMatrix, new Cesium.Matrix4());
}
}
Preparación del Modelo 3D en Blender
Para que la lógica de transformación funcione correctamente, la estructura del modelo es fundamental. Las cuatro hélices deben ser mallas independientes de la estructura del chasis. Además, el punto de pivote (origen) de cada hélice debe estar situado exactamente en su centro geométrico, y no en el centro del dron completo.
En Blender, este ajuste se realiza seleccionando cada hélice inidvidualmente y navegando a: Object > Set Origin > Origin to Geometry. Esta separación de elementos y la correcta configuración de los orígenes garantiza que las matrices de traslación y rotación operen sobre el eje local de cada rotor de manera aislada.