Con il sistema di animazione di three.js si possono animare varie proprietà dei modelli:
le ossa di un [page:SkinnedMesh modello skinned], i target morph, le diverse proprietà dei materiali
(colori, opacità, booleani), la visibilità e le trasformazioni. Le proprietà di animazione possono essere
sfumate, incrociate e deformate. Il peso e la scala temporale di diverse animazioni simultanee sullo stesso
oggetto o su oggetti diversi possono essere modificate in modo indipendente. È possibile sincronizzare
diverse animazioni sullo stesso oggetto e su oggetti diversi.
Per ottenere tutto questo in un sistema omogeneo, il [link:https://github.com/mrdoob/three.js/issues/6881 sistema di animazione di three.js]
è stato cambiato completamente nel 2015 (attenzione alle informazioni non aggiornate!), ed ora ha un'architettura simile a quella di Unity/Unreal Engine 4.
Questa pagina fornisce una breve panoramica dei componenti principali del sistema e di come lavorano insieme.
Se si è importato con successo un oggetto 3D animato (non importa se ha ossa o target morph o entrambi)
- per esempio esportandolo da Blender con [link:https://github.com/KhronosGroup/glTF-Blender-IO l'exporter glTF Blender] e caricandolo
nella scena three.js usando [page:GLTFLoader] - uno dei campi di risposta dovrà essere un array chiamato "animations", contenente
gli [page:AnimationClip AnimationClips] per questo modello (vedi l'elenco dei possibili loader qui sotto).
Ogni `AnimationClip` contiene solitamente i dati per una certa attività dell'oggetto. Se la mesh è un personaggio,
per esempio, ci può essere un AnimationClip per la camminata, un altro per il salto e un terzo per il salto laterale e così via.
All'interno di un `AnimationClip` i dati, per ogni propietà di animazione, sono memorizzati in un [page:KeyframeTrack] separato.
Supponendo che un oggetto personaggio abbia uno [page:Skeleton scheletro], un keyframe track potrebbe memorizzare i dati relativi alle variazioni di
posizione dell'osso inferiore del braccio nel tempo, un'altra traccia potrebbe memorizzare i dati relativi alle variazioni di rotazione dello stesso osso,
una terza traccia la posizione, la rotazione e la scala di un altro osso e così via. Dovrebbe essere chiaro, che un AnimationClip può essere composto
da molte tracce di questo tipo.
Supponendo che il modello abbia dei target morph (per esempio un target morph che mostra una faccia amichevole e un altro che mostra una faccia arrabbiata),
ogni traccia contiene le informazioni su come l'influenza di un certo target morph cambia durante l'esecuzione del clip.
I dati memorizzati costituiscono solo la base per le animazioni - la riproduzione vera e propria è controllata dall'[page:AnimationMixer]. È possibile immaginarlo non solo come un lettore di animazioni, ma come un simulatore di un hardware come una vera e propria console di mixaggio, che può controllare diverse animazioni simultaneamente, mescolandole e fondendole.
Lo stesso `AnimationMixer` ha pochissime proprietà e metodi (generali), perché può essere controllato dall'[page:AnimationAction AnimationActions]. Per configurare un `AnimationAction` è necessario specificare quando un `AnimationClip` deve essere eseguito, messo in pausa o stoppato su uno dei mixer, se e con quale frequenza la clip deve essere ripetuta, se deve essere eseguita con una dissolvenza o una scala temporale e altre cose aggiuntive come dissolvenza incrociata o sincronizzazione.
Se si desidera che un gruppo di oggetti riceva uno stato di animazione condiviso, è possibile utilizzare un [page:AnimationObjectGroup].
Si noti che non tutti i formati includono le animazioni (in particolare OBJ non lo fa) e che solo alcuni loader di three.js supportano le sequenze [page:AnimationClip AnimationClip]. Di seguito alcuni che supportano questo tipo di animazioni:
Si noti che 3ds max e Maya attualmente non possono esportare più animazioni (ovvero animazioni che non si trovano nella stessa timeline) direttamente in un singolo file.
let mesh;
// Create an AnimationMixer, and get the list of AnimationClip instances
const mixer = new THREE.AnimationMixer( mesh );
const clips = mesh.animations;
// Update the mixer on each frame
function update () {
mixer.update( deltaSeconds );
}
// Play a specific animation
const clip = THREE.AnimationClip.findByName( clips, 'dance' );
const action = mixer.clipAction( clip );
action.play();
// Play all animations
clips.forEach( function ( clip ) {
mixer.clipAction( clip ).play();
} );