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

Modern Mixer-based Animation System #6934

Merged
merged 161 commits into from
Sep 21, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
161 commits
Select commit Hold shift + click to select a range
24998be
Track/Clip/Action/Mixer implementation in progress.
bhouston Jul 22, 2015
9ad046d
create the files for the individual animation components.
bhouston Jul 22, 2015
0962f90
implement some of the TODOs. add lots of verbose debug info.
bhouston Jul 22, 2015
69a3556
descriptions of the classes.
bhouston Jul 22, 2015
cb2d50b
more TODOs.
bhouston Jul 22, 2015
c88066f
Clip,Action,Mixer -> Animation*
bhouston Jul 23, 2015
8e94b36
introduce the TrackBinding class for better organization.
bhouston Jul 24, 2015
c873ac8
remove ConstantTrack and Track classes, not needed.
bhouston Jul 24, 2015
516dce8
place holders for test animations.
bhouston Jul 24, 2015
bbe37cc
TrackBinding -> PropertyBinding. Add example clips.
bhouston Jul 25, 2015
70f58ec
improve nodeName parsing and resolving to support uuids.
bhouston Jul 25, 2015
99e08d4
support node.uuid as identifies in trackNames.
bhouston Jul 25, 2015
dadc0a1
add example of how to specify a morph target animation.
bhouston Jul 25, 2015
87b5f7e
remove three-math from npm build, never used.
bhouston Jul 25, 2015
aa5ed5d
begin track/clip/mixer example.
bhouston Jul 25, 2015
907c698
Merge branch 'dev' of git@github.com:mrdoob/three.js.git into modernA…
bhouston Jul 25, 2015
70b6e13
only build three.js and three.min.js for npm module.
bhouston Jul 25, 2015
0be1e5f
fixing compile errors.
bhouston Jul 25, 2015
633e071
add new animation classes to common includes.
bhouston Jul 25, 2015
d74c89c
debugging new animation system along with example.
bhouston Jul 25, 2015
b396969
more bug fixing.
bhouston Jul 25, 2015
1e219a6
add support for binding to materials.
bhouston Jul 25, 2015
b67cca3
more minor bug fixing with Animation.
bhouston Jul 25, 2015
ea152c1
add support for propertybindings to sub materials, and it works.
bhouston Jul 25, 2015
77612e4
optimization - stage one. Reduce temp memory allocations, cache Prop…
bhouston Jul 25, 2015
56e20cb
minor optimization.
bhouston Jul 25, 2015
6311e13
add support for morphTarget name resolution - untested.
bhouston Jul 25, 2015
dc0ab1e
resolving bone names (two ways now to specify bones), allow for discr…
bhouston Jul 25, 2015
39bedda
move towards delta time.
bhouston Jul 26, 2015
e6aad57
visibility track works.
bhouston Jul 26, 2015
74c2898
make morph target animation clips work.
bhouston Jul 26, 2015
e5857aa
minor error.
bhouston Jul 26, 2015
d0dc293
mention optimization technique.
bhouston Jul 26, 2015
0e5c35f
first pass at parsing JSONLoader hierarchy animations (keyframe + mor…
bhouston Jul 27, 2015
1be1d05
memeoization of lerp. add optimize, trim, validate, sort to Keyframe…
bhouston Jul 27, 2015
4657a76
fix bugs in KeyframeTrack.optimize/validate. Expand capabilities of …
bhouston Jul 27, 2015
85d8a7a
optimize Action.toAnimationClipTime().
bhouston Jul 27, 2015
876eda7
only update scene graph values if actually different, only call trigg…
bhouston Jul 27, 2015
9eb5ca1
bones work! various optimizations.
bhouston Jul 27, 2015
281f510
avoid clones while interpolating values.
bhouston Jul 27, 2015
728c305
create Mixer recreation of classic ThreeJS examples.
bhouston Jul 27, 2015
cf34318
optimizations and added USCCharacterMixer (mixer-based USCCharacter).
bhouston Jul 27, 2015
2bd48d5
start to replace the internals of MorphAnimMesh.
bhouston Jul 27, 2015
8705887
begin fadeIn, fadeOut commands - not tested.
bhouston Jul 28, 2015
8590ad5
allow for PropertyBindings to bind/unbind. PropertyBindings are refe…
bhouston Jul 28, 2015
eec2153
add wrap scheduling. updates to MD2Character, USCCharacter.
bhouston Jul 28, 2015
e3b2c75
introduce time awareness in AnimationAction.
bhouston Jul 28, 2015
dff0e17
cleaning up time handling in AnimationAction - moving to relative time.
bhouston Jul 28, 2015
996879a
minor bug fixes.
bhouston Jul 30, 2015
08f03bb
more minor bugs.
bhouston Jul 30, 2015
9947cdc
minor bone bugs. webgl_animation_skinning_morph.html works.
bhouston Jul 30, 2015
cc3684a
faster KeyframeTrack.getAt - local walk from last value.
bhouston Jul 30, 2015
a95ec4d
debugging lack of morphTargets working.
bhouston Jul 30, 2015
a044dc9
fix bug where the keyframe track couldn't get back to the first key.
bhouston Jul 31, 2015
9583d29
fix skeleton in example, better comments.
bhouston Jul 31, 2015
002c313
begin conversion of BlendCharacter to new animation system.
bhouston Jul 31, 2015
bfee311
BlendCharacter example mostly working with new animation system.
bhouston Jul 31, 2015
eb64f9e
add optimization for consecutive keys that are identical -- no linear…
bhouston Jul 31, 2015
055dc34
BlendCharacter example works great.
bhouston Aug 1, 2015
16ee794
get UCSCharacter working again.
bhouston Aug 1, 2015
4985ed0
update morphanimmesh to work with the new mixer.
bhouston Aug 1, 2015
e9cd1a2
memorize the KeyframeTrack.setResult()
bhouston Aug 2, 2015
ac5802c
get webgl_shader_physical animation working again.
bhouston Aug 2, 2015
5022f4f
fix issues brought up by @liammagee
bhouston Aug 2, 2015
4143536
fix bug.
bhouston Aug 2, 2015
8652335
remove debugging output.
bhouston Aug 2, 2015
759ca9c
fix comments.
bhouston Aug 2, 2015
4acb726
fix comments.
bhouston Aug 2, 2015
5b41c70
allow for events to be send on Action loop and finish.
bhouston Aug 3, 2015
3d2b5eb
name all anonymous functions for better results when profiling.
bhouston Aug 3, 2015
30c9d9b
pull out functions into class members.
bhouston Aug 3, 2015
a335247
reduce use of maps where possible in favor of arrays.
bhouston Aug 3, 2015
8da58ca
get rid of another map used in a tight inner loop.
bhouston Aug 3, 2015
31bd3bf
remove old propertyBindings map and replace it with an array.
bhouston Aug 3, 2015
e3604c6
fix obvious bugs.
bhouston Aug 3, 2015
4b884a3
address @mrdoob comment: https://github.com/mrdoob/three.js/pull/6934…
bhouston Aug 17, 2015
ef5fc2e
initial attempt at implementing @mrdoob's suggestion here: https://gi…
bhouston Aug 17, 2015
73a55e9
complete creation of type-specific KeyframeTrack classes.
bhouston Aug 19, 2015
fa92cf1
Merge branch 'dev' of git@github.com:mrdoob/three.js into modernAnima…
bhouston Aug 19, 2015
4c7962b
allow for automatic detection of AnimationClip lengths.
bhouston Aug 20, 2015
75b996a
allow for tracks to parse themselves via static memebers.
bhouston Aug 20, 2015
cce8794
object loader can now parse tracks on individual objects for scene an…
bhouston Aug 20, 2015
0de4a55
fix name bug in scene object tracks.
bhouston Aug 20, 2015
6564cc8
combine all tracks on a subhierarchy into one animation clip on the t…
bhouston Aug 20, 2015
de83df1
upgrade webgl_morphnormals.html to use new Mixer animation framework.
bhouston Aug 21, 2015
355434e
allow for automatic detection of AnimationClip lengths.
bhouston Aug 20, 2015
fe6b0b3
allow for tracks to parse themselves via static memebers.
bhouston Aug 20, 2015
a15ffe8
fix bug in ObjectLoader.
bhouston Aug 25, 2015
ac12e43
add KeyframeTrack.shift function to move keyframes around in time.
bhouston Aug 25, 2015
40a952e
allow for cloning of boolean keyframe tracks.
bhouston Aug 25, 2015
d69840c
KeyframeTrack.trim( start, end ). Return this if possible. Use fps …
bhouston Aug 26, 2015
a185475
add *KeyframeTrack.clone().
bhouston Aug 26, 2015
fc212a3
add first example for loading node animations from ObjectLoader.
bhouston Aug 26, 2015
1cefeae
fix potential null reference.
bhouston Aug 26, 2015
8b071b9
add ability to multiple QuaternionKeyframeTracks with quaternions.
bhouston Aug 26, 2015
8b5f0d5
fix off by one bugs in KeyframeTrack.shift/scale - was skipping first…
bhouston Aug 26, 2015
3905008
cleaning up example for node animations.
bhouston Aug 26, 2015
d76c4fc
playing around with getting node animations oriented the right way.
bhouston Aug 26, 2015
7634394
comment out hack to try and get quaternions to match.
bhouston Aug 27, 2015
e39745f
add json scene file.
bhouston Aug 27, 2015
bb72081
Merge remote-tracking branch 'origin/sceneAnimations'
jackcaron Aug 27, 2015
84a9423
improve keyframe track parsing to be more flexible.
bhouston Aug 28, 2015
b29835c
Merge remote-tracking branch 'origin/dev'
jackcaron Aug 28, 2015
0feb6bd
Merge remote-tracking branch 'origin/sceneAnimations'
jackcaron Aug 28, 2015
aa44449
missing equal sign
jackcaron Aug 28, 2015
3b894ac
forgot the 'function'
jackcaron Aug 28, 2015
2d1745d
new track system, plus blend shapes
jackcaron Aug 28, 2015
333b3e0
Merge pull request #3 from jackcaron/sceneAnimations
bhouston Aug 28, 2015
0e66ebc
messing around with 'animations' compatibility with ThreeJS JSON expo…
bhouston Sep 1, 2015
0fd51ae
Merge branch 'sceneAnimations' of git@github.com:bhouston/three.js.gi…
bhouston Sep 1, 2015
7e60f3a
add new .clips support on Nodes and Geometries for simple/fast Animat…
bhouston Sep 2, 2015
1f858e1
Merge branch 'dev' of git@github.com:mrdoob/three.js into sceneAnimat…
bhouston Sep 2, 2015
454847c
manual merge of blender Clip (blend shape + node animation) support.
bhouston Sep 2, 2015
4456091
update format version to 4.4
bhouston Sep 2, 2015
4e37704
fix double used variable nb_curves
bhouston Sep 2, 2015
4cc6755
add more authors.
bhouston Sep 2, 2015
9c0dc9b
webgl_animation_scene.html
bhouston Sep 2, 2015
aa176dc
white background helps everything standout better.
bhouston Sep 2, 2015
eeb750b
remove dat GUI, not needed.
bhouston Sep 2, 2015
d37a239
better scene title.
bhouston Sep 2, 2015
f5a1820
cleanup json models.
bhouston Sep 2, 2015
babd98d
restore part of Blender JSON exporter missed in merge.
bhouston Sep 2, 2015
9ac106f
do not export Blender's distance parameter as it isn't a cutoff dista…
bhouston Sep 2, 2015
71480f0
adapt webgl_animation_skinning_morph to the new clip design.
bhouston Sep 2, 2015
43f821d
remove console.log.
bhouston Sep 2, 2015
801124d
simplifying code in the clip-based animation system.
bhouston Sep 3, 2015
10364f8
bugs.
bhouston Sep 3, 2015
a1a88eb
updating examples to new Clip parsing inside of JSONLoader/ObjectLoader.
bhouston Sep 3, 2015
ce70dc6
refactor JSONLoader's loading of clips. Load morph sequences into cl…
bhouston Sep 3, 2015
e6795ff
removing MorphAnimMesh from various examples.
bhouston Sep 3, 2015
03269bf
remove MorphAnimMesh were possible from examples and just use the Mixer.
bhouston Sep 3, 2015
9ae28c8
rotate blender tracks by 90 degrees around x-axis.
bhouston Sep 3, 2015
f30db85
improved webgl_animation_blend example.
bhouston Sep 3, 2015
f32440c
remove unused animation clip creator.
bhouston Sep 3, 2015
e0fdbbd
allow for setting per action local roots.
bhouston Sep 3, 2015
3cf8527
allow for local roots on actions.
bhouston Sep 7, 2015
2f0287e
simplify physical_shading example with new Animation clip support.
bhouston Sep 3, 2015
3a24fca
use a single mixer for shadow map performance.
bhouston Sep 4, 2015
8f79ee4
Merge branch 'nnn' into temp
bhouston Sep 7, 2015
f89af19
remove MorphAnimMesh from MD2Character and MD2Loader while retaining …
bhouston Sep 4, 2015
a1fb6c3
fix bug, not calling AnimationAction.init.
bhouston Sep 4, 2015
6179248
Merge branch 'dev' into temp
bhouston Sep 7, 2015
a73bd43
Convert canvas horse morph to Mixer.
bhouston Sep 4, 2015
5dad759
demote MorphAnimMesh.js and MorphAnimation.js
bhouston Sep 4, 2015
8f2e0f6
webgl_loader_md2 should start with an initial animation.
bhouston Sep 4, 2015
a9dbaa9
demote Animation, AnimationHandler, KeyFrameAnimation.
bhouston Sep 4, 2015
399458c
move examples/js/Animation* to example/js/loaders/collada/Animation*
bhouston Sep 4, 2015
e9d593b
fix two broken examples.
bhouston Sep 4, 2015
922a9dc
optimize Mixer (lazy updates to cache, use map instead of linear sear…
bhouston Sep 7, 2015
6310c50
add Action loop styles, LoopOnce, LoopRepeat and LoopPingPong
bhouston Sep 8, 2015
5b30934
loopStyle --> loop. remove left over debugging console.error
bhouston Sep 8, 2015
3bfc0b1
remvoe debug comments, and a forgotten reset of propertyBindingNamesT…
bhouston Sep 8, 2015
94478be
simplify Action propertyBinding caches.
bhouston Sep 8, 2015
63414e3
remove debug comment.
bhouston Sep 8, 2015
8a0053f
fix bug in AnimationAction introduced in rewrite for LoopPingPong.
bhouston Sep 8, 2015
ef42280
simplify AnimationMixer to prevent bugs.
bhouston Sep 8, 2015
32befcc
make it easy to synchronize to actions together.
bhouston Sep 8, 2015
8ee9c98
write animations at the root
jackcaron Sep 17, 2015
cedf004
put blend shape first, more stable approach
jackcaron Sep 17, 2015
036147e
geometry/object.clips -> geometry/object.animation
bhouston Sep 17, 2015
94d8f1a
remove some left over console.log statements.
bhouston Sep 17, 2015
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
12 changes: 7 additions & 5 deletions examples/canvas_morphtargets_horse.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

var container, stats;
var camera, scene, projector, renderer;
var mesh, animation;
var mesh, mixer;

init();
animate();
Expand Down Expand Up @@ -69,8 +69,10 @@
mesh.scale.set( 1.5, 1.5, 1.5 );
scene.add( mesh );

animation = new THREE.MorphAnimation( mesh );
animation.play();
mixer = new THREE.AnimationMixer( mesh );

var clip = THREE.AnimationClip.CreateFromMorphTargetSequence( 'gallop', geometry.morphTargets, 30 );
mixer.addAction( new THREE.AnimationAction( clip ).warpToDuration( 1.5 ) );

} );

Expand Down Expand Up @@ -129,11 +131,11 @@

camera.lookAt( camera.target );

if ( animation ) {
if ( mixer ) {

var time = Date.now();

animation.update( time - prevTime );
mixer.update( ( time - prevTime ) * 0.001 );

prevTime = time;

Expand Down
139 changes: 139 additions & 0 deletions examples/js/AnimationClipCreator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/**
*
* Creator of typical test AnimationClips / KeyframeTracks
*
* @author Ben Houston / http://clara.io/
* @author David Sarno / http://lighthaus.us/
*/

THREE.AnimationClipCreator = function() {
};

THREE.AnimationClipCreator.CreateRotationAnimation = function( period, axis ) {

var keys = [];
keys.push( { time: 0, value: 0 } );
keys.push( { time: period, value: 360 } );

axis = axis || 'x';
var trackName = '.rotation[' + axis + ']';

var track = new THREE.NumberKeyframeTrack( trackName, keys );

var clip = new THREE.AnimationClip( 'rotate.x', 10, [ track ] );
//console.log( 'rotateClip', clip );

return clip;
};

THREE.AnimationClipCreator.CreateScaleAxisAnimation = function( period, axis ) {

var keys = [];
keys.push( { time: 0, value: 0 } );
keys.push( { time: period, value: 360 } );

axis = axis || 'x';
var trackName = '.scale[' + axis + ']';

var track = new THREE.NumberKeyframeTrack( trackName, keys );

var clip = new THREE.AnimationClip( 'scale.x', 10, [ track ] );
//console.log( 'scaleClip', clip );

return clip;
};

THREE.AnimationClipCreator.CreateShakeAnimation = function( duration, shakeScale ) {

var keys = [];

for( var i = 0; i < duration * 10; i ++ ) {

keys.push( {
time: ( i / 10.0 ),
value: new THREE.Vector3( Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0 ).multiply( shakeScale )
} );

}

var trackName = '.position';

var track = new THREE.VectorKeyframeTrack( trackName, keys );

var clip = new THREE.AnimationClip( 'shake' + duration, duration, [ track ] );
//console.log( 'shakeClip', clip );

return clip;
};


THREE.AnimationClipCreator.CreatePulsationAnimation = function( duration, pulseScale ) {

var keys = [];

for( var i = 0; i < duration * 10; i ++ ) {

var scaleFactor = Math.random() * pulseScale;
keys.push( {
time: ( i / 10.0 ),
value: new THREE.Vector3( scaleFactor, scaleFactor, scaleFactor )
} );

}

var trackName = '.scale';

var track = new THREE.VectorKeyframeTrack( trackName, keys );

var clip = new THREE.AnimationClip( 'scale' + duration, duration, [ track ] );
//console.log( 'scaleClip', clip );

return clip;
};


THREE.AnimationClipCreator.CreateVisibilityAnimation = function( duration ) {

var keys = [];
keys.push( {
time: 0,
value: true
Copy link
Owner

Choose a reason for hiding this comment

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

How about doing something more like value: new THREE.BooleanAnimationValue( true ) and remove all the PropertyBinding stuff?

I did something like that for frame.js:
https://github.com/mrdoob/frame.js/blob/master/src/Frame.js

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do not quite understand.

I've made a quick stab at create types for the KeyframeTracks, but I am not sure that is what you mean.

There are three complexities in this PR that I am not sure the best way to solve:

The first is how to have polymorphic interpolate/accumulate/set operators. This functionality is required both by KeyframeTrack (interpolate/set), and AnimationMixer (accumulate/set). Interpolating quaternions (.slerp) is different than interpolating vectors (.lerp) and is different than interpolating numbers (just use math directly.) Also setting objects like Quaternion/Vector is different than setting primitives like number.

The second problem is how to handle setting properties on the scene graph. It is more complex than the set operation described above. When setting things on the scene graph one still needs to be aware of whether one is setting an object or a primitive, but one also needs to be aware of whether one is setting an array element (see my functions setValue_propertyIndexed/getValue_propertyIndexed).

Lastly, a lot of the complexity of PropertyBinding is because it uses flexible path definitions to identity nodes. It supports the following types of paths:

.propertyName  // e.g. .visible, .rotation, .scale, .castShadow
.propertyName[accessor]  // e.g.  .rotation[x], .scale[z]
nodeName.propertyName  // e.g. myNode.rotation
nodeID.propertyName[accessor] // e.g. eb0e0f09-c2cd-4be4-b567-c3f9a1160a3c.position[y]
.objectName.propertyName // e.g. .material.transparent
.objectName.propertyName[accessor] // e.g. .material.diffuse[r]
.materials[objectIndex].propertyName // e.g. .materials[0].opacity
.bone[Armature.DEF_cog].position // virtual property, bone name reolved to index at bind time
.morphTarget[morphTargetName] // virtual property, bone name reolved to index at bind time

The last two are virtual properties because I am allowing for bone names and morph names to be used as an accessor when binding, and then automatically resolved to the numbered indices for run-time efficiency.

I believe that allowing for these types of paths for tracks allows just about anything in ThreeJS to be animated easily as part of one animation clip.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

BTW the classes I added are:

BooleanKeyframeTrack
StringKeyframeTrack
VectorKeyframeTrack
QuaternionKeyframeTrack
NumberKeyframeTrack

https://github.com/mrdoob/three.js/pull/6934/files#diff-9ed93c77fab8c29ff951e4c81708dfd7R1

I haven't tested them as I am unsure if this is the right direction -- I think that this change isn't what you want as it seems to be very verbose and not that useful.

I do think that PropertyBinding may not be the prettiest class, it is actually pretty compact and fast and it can be refactored in the future by someone smarter than me while retaining its functionality. I do not expose PropertyBinding really through the API for the Mixer or Keyframe Tracks, it is really an internal use class - that is why I am okay with it not being super pretty.

Copy link
Owner

Choose a reason for hiding this comment

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

These classes are what I meant yes. As you know, I prefer things to be as explicit so the code is easy to follow/understand.

} );
keys.push( {
time: duration - 1,
value: false
} );
keys.push( {
time: duration,
value: true
} );

var trackName = '.visible';

var track = new THREE.BooleanKeyframeTrack( trackName, keys );

var clip = new THREE.AnimationClip( 'visible' + duration, duration, [ track ] );
//console.log( 'scaleClip', clip );

return clip;
};


THREE.AnimationClipCreator.CreateMaterialColorAnimation = function( duration, colors, loop ) {

var timeStep = duration / colors.length;
var keys = [];
for( var i = 0; i <= colors.length; i ++ ) {
keys.push( { time: i * timeStep, value: colors[ i % colors.length ] } );
}

var trackName = '.material[0].color';

var track = new THREE.ColorKeyframeTrack( trackName, keys );

var clip = new THREE.AnimationClip( 'colorDiffuse', 10, [ track ] );
//console.log( 'diffuseClip', clip );

return clip;
};

Loading