Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add control to play specific sequence-variations. #15

Merged
merged 3 commits into from
Jan 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 46 additions & 28 deletions M2Loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2853,13 +2853,13 @@ class SequenceManager {
this.sequences = sequences;
this.globalSequences = globalSequences;

this.currentSequenceId = - 1;

this._sequenceMap = new Map();
this._globalSequenceMap = new Map();
this._mixers = new Map();
this._globalMixers = new Map();

this._currentSequence = - 1;

for ( let i = 0; i < sequences.length; i ++ ) {

const sequence = sequences[ i ];
Expand All @@ -2880,7 +2880,7 @@ class SequenceManager {
const sequence = this.sequences[ i ];

const animations = this._sequenceMap.get( sequence.id );
animations.push( { clip, root, variationIndex: sequence.variationIndex } );
animations.push( { clip, root, flags: sequence.flags, variationIndex: sequence.variationIndex } );

if ( this._mixers.has( root ) === false ) {

Expand Down Expand Up @@ -2911,23 +2911,33 @@ class SequenceManager {

if ( animation.variationIndex === variationIndex ) {

const mixer = this._mixers.get( animation.root );
const action = mixer.clipAction( animation.clip );
action.play();
if ( animation.flags & M2_SEQUENCE_EMBEDDED_DATA ) {

const mixer = this._mixers.get( animation.root );
const action = mixer.clipAction( animation.clip );
action.play();

} else {

// TODO: Add support for sequences with external animation data (.anim files)

console.warn( 'THREE.M2Loader: Sequences with external animation data not yet supported.' );
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For simplicity, I have moved the M2_SEQUENCE_EMBEDDED_DATA check to playSequence(). Meaning the manager now reports all sequences and variations again but warns the users if animation data are not available.


}

}

}

this._currentSequence = id;
this.currentSequenceId = id;

}

stopSequence() {

if ( this._currentSequence === - 1 ) return;
if ( this.currentSequenceId === - 1 ) return;

const sequence = this._sequenceMap.get( this._currentSequence );
const sequence = this._sequenceMap.get( this.currentSequenceId );

for ( const animation of sequence ) {

Expand Down Expand Up @@ -2973,38 +2983,46 @@ class SequenceManager {

const list = [];

for ( let i = 0; i < this.sequences.length; i ++ ) {
for ( const id of this._sequenceMap.keys() ) {

const name = M2_ANIMATION_LIST[ id ];

const sequence = this.sequences[ i ];
if ( name === undefined ) {

// TODO: Add support for sequences with external animation data (.anim files)
console.warn( 'THREE.M2Loader: Unknown animation ID:', id );
name = '';

if ( sequence.flags & M2_SEQUENCE_EMBEDDED_DATA ) {
}

list.push( {
id: id,
name: name

const id = sequence.id;
} );

const name = M2_ANIMATION_LIST[ id ];
}

if ( name === undefined ) {
list.sort( compareId );

console.warn( 'THREE.M2Loader: Unknown animation ID:', id );
name = '';
return list;

}
}

list.push( {
id: id,
name: name
listVariations( id ) {

} );
const variationsSet = new Set();

}
const animations = this._sequenceMap.get( id );

for ( const animation of animations ) {

variationsSet.add( animation.variationIndex );

}

list.sort( sortId );
const variations = Array.from( variationsSet ).sort();

return list;
return variations;

}

Expand Down Expand Up @@ -3032,9 +3050,9 @@ class SequenceManager {

}

function sortId( a, b ) {
function compareId( a, b ) {

return a.id > b.id;
return a.id - b.id;


}
Expand Down
52 changes: 37 additions & 15 deletions test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
{
"imports": {
"three": "https://unpkg.com/[email protected]/build/three.module.js",
"three/addons/": "https://unpkg.com/[email protected]/examples/jsm/"
"three/addons/": "https://unpkg.com/[email protected]/examples/jsm/",
"lil-gui": "https://unpkg.com/[email protected]/dist/lil-gui.esm.js"
}
}
</script>
Expand All @@ -27,13 +28,14 @@
import * as THREE from 'three';

import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
import { GUI } from 'lil-gui';

import { M2Loader } from '../M2Loader.js';

const params = {
asset: 'cat/druidcat2.m2',
sequences: 0,
sequence: 0,
variation: 0,
playGlobalSequences: true
};

Expand All @@ -51,7 +53,7 @@

let camera, scene, renderer, controls, loader, clock;

let gui, animationFolder;
let gui, animationFolder, variationCtrl;

let m2Scene, m2SequenceManager;

Expand Down Expand Up @@ -115,20 +117,17 @@

// animations

animationFolder = gui.addFolder( 'Animations' );

m2SequenceManager = m2.userData.sequenceManager;

// the list() methods provide arrays with all available sequences (animations)
// the list() method provide arrays with all available sequences (animations)

const sequences = m2SequenceManager.listSequences();

animationFolder = gui.addFolder( 'Animations' );

if ( sequences.length > 0 ) {

const sequence = sequences[ 0 ]; // pick first sequence
m2SequenceManager.playSequence( sequence.id );

// make all sequences selectable via the UI
// make all sequences and variations selectable via the UI

const uiSequences = {};

Expand All @@ -139,15 +138,21 @@

}

animationFolder.add( params, 'sequences', uiSequences ).onChange( onSequenceChange );
animationFolder.add( params, 'sequence', uiSequences ).onChange( onSequenceChange );
variationCtrl = animationFolder.add( params, 'variation', [] ).onChange( onVariationChange );

// play first sequence

const sequence = sequences[ 0 ];
onSequenceChange( sequence.id );

}

if ( m2SequenceManager.hasGlobalSequences() ) {

m2SequenceManager.playGlobalSequences();

animationFolder.add( params, 'playGlobalSequences' ).onChange( onPlayGlobalSequencesChange );

m2SequenceManager.playGlobalSequences();

}

Expand Down Expand Up @@ -203,7 +208,8 @@
m2SequenceManager.stopSequence();
m2SequenceManager.stopGlobalSequences();

params.sequences = 0;
params.sequence = 0;
params.variation = 0;
params.playGlobalSequences = true;

animationFolder.destroy();
Expand All @@ -217,6 +223,22 @@
m2SequenceManager.stopSequence();
m2SequenceManager.playSequence( id );

//

params.variation = 0;

const variations = m2SequenceManager.listVariations( id );
variationCtrl.options( variations );

( variations.length > 1 ) ? variationCtrl.enable() : variationCtrl.disable();

}

function onVariationChange( variationIndex ) {

m2SequenceManager.stopSequence();
m2SequenceManager.playSequence( m2SequenceManager.currentSequenceId, variationIndex );

}

function onPlayGlobalSequencesChange( value ) {
Expand Down