浏览代码

Editor: Refactored animation support.

Mr.doob 6 年之前
父节点
当前提交
cbb87c80da
共有 4 个文件被更改,包括 61 次插入60 次删除
  1. 5 0
      editor/js/Editor.js
  2. 5 1
      editor/js/Loader.js
  3. 28 59
      editor/js/Sidebar.Animation.js
  4. 23 0
      editor/js/Viewport.js

+ 5 - 0
editor/js/Editor.js

@@ -92,7 +92,9 @@ var Editor = function () {
 	this.materials = {};
 	this.textures = {};
 	this.scripts = {};
+
 	this.animations = {};
+	this.animationMixer = new THREE.AnimationMixer( this.scene );
 
 	this.selected = null;
 	this.helpers = {};
@@ -466,6 +468,9 @@ Editor.prototype = {
 		this.materials = {};
 		this.textures = {};
 		this.scripts = {};
+		
+		this.animations = {};
+		this.animationMixer.stopAllAction();
 
 		this.deselect();
 

+ 5 - 1
editor/js/Loader.js

@@ -217,6 +217,7 @@ var Loader = function ( editor ) {
 
 						var scene = result.scene;
 						scene.name = filename;
+
 						editor.addAnimation( scene, result.animations );
 						editor.execute( new AddObjectCommand( scene ) );
 
@@ -249,6 +250,7 @@ var Loader = function ( editor ) {
 
 						var scene = result.scene;
 						scene.name = filename;
+
 						editor.addAnimation( scene, result.animations );
 						editor.execute( new AddObjectCommand( scene ) );
 
@@ -347,8 +349,8 @@ var Loader = function ( editor ) {
 					var mesh = new THREE.Mesh( geometry, material );
 					mesh.mixer = new THREE.AnimationMixer( mesh );
 					mesh.name = filename;
-					editor.addAnimation( mesh, geometry.animations );
 
+					editor.addAnimation( mesh, geometry.animations );
 					editor.execute( new AddObjectCommand( mesh ) );
 
 				}, false );
@@ -684,6 +686,7 @@ var Loader = function ( editor ) {
 					loader.parse( file.asArrayBuffer(), '', function ( result ) {
 
 						var scene = result.scene;
+
 						editor.addAnimation( scene, result.animations );
 						editor.execute( new AddObjectCommand( scene ) );
 
@@ -697,6 +700,7 @@ var Loader = function ( editor ) {
 					loader.parse( file.asText(), '', function ( result ) {
 
 						var scene = result.scene;
+
 						editor.addAnimation( scene, result.animations );
 						editor.execute( new AddObjectCommand( scene ) );
 

+ 28 - 59
editor/js/Sidebar.Animation.js

@@ -5,34 +5,32 @@
 Sidebar.Animation = function ( editor ) {
 
 	var signals = editor.signals;
+	var mixer = editor.animationMixer;
 
-	var renderer = null;
-
-	signals.rendererChanged.add( function ( newRenderer ) {
-
-		renderer = newRenderer;
-
-	} );
+	var actions = {};
 
 	signals.objectSelected.add( function ( object ) {
 
-		var uuid = object !== null ? object.uuid : '';
-		var animations = editor.animations[ uuid ];
+		var animations = editor.animations[ object !== null ? object.uuid : '' ];
+
 		if ( animations !== undefined ) {
 
 			container.setDisplay( '' );
 
-			mixer = new THREE.AnimationMixer( object );
 			var options = {};
+			var firstAnimation;
+
 			for ( var animation of animations ) {
 
-				options[ animation.name ] = animation.name;
+				if ( firstAnimation === undefined ) firstAnimation = animation.name;
 
-				var action = mixer.clipAction( animation );
-				actions[ animation.name ] = action;
+				actions[ animation.name ] = mixer.clipAction( animation, object );
+				options[ animation.name ] = animation.name;
 
 			}
+
 			animationsSelect.setOptions( options );
+			animationsSelect.setValue( firstAnimation );
 
 		} else {
 
@@ -42,73 +40,44 @@ Sidebar.Animation = function ( editor ) {
 
 	} );
 
-	var mixer, currentAnimation, actions = {};
-
-	var clock = new THREE.Clock();
-	function updateAnimation() {
-
-		if ( mixer !== undefined && renderer !== null ) {
+	signals.objectRemoved.add( function ( object ) {
 
-			var dt = clock.getDelta();
-			mixer.update( dt * speed.getValue() );
-			if ( currentAnimation !== undefined && currentAnimation.isRunning() ) {
+		var animations = editor.animations[ object !== null ? object.uuid : '' ];
 
-				requestAnimationFrame( updateAnimation );
-				renderer.render( editor.scene, editor.camera );
-
-			} else {
+		if ( animations !== undefined ) {
 
-				currentAnimation = undefined;
-
-			}
+			mixer.uncacheRoot( object );
 
 		}
 
-	}
-
-	function playAnimation() {
-
-		currentAnimation = actions[ animationsSelect.getValue() ];
-		if ( currentAnimation !== undefined ) {
+	} );
 
-			stopAnimations();
-			currentAnimation.play();
-			updateAnimation();
+	function playAction() {
 
-		}
+		actions[ animationsSelect.getValue() ].play();
 
 	}
 
-	function stopAnimations() {
-
-		if ( mixer !== undefined ) {
+	function stopAction() {
 
-			mixer.stopAllAction();
-
-		}
+		actions[ animationsSelect.getValue() ].stop();
 
 	}
 
 	var container = new UI.Panel();
 	container.setDisplay( 'none' );
 
-	container.add( new UI.Text( 'Animation' ).setTextTransform( 'uppercase' ) );
+	container.add( new UI.Text( 'Animations' ).setTextTransform( 'uppercase' ) );
+	container.add( new UI.Break() );
+	container.add( new UI.Break() );
 
-	var div = new UI.Div().setMarginLeft( '90px' );
+	var div = new UI.Div();
 	container.add( div );
 
-	div.add( new UI.Button( "Play" ).setFontSize( '12px' ).onClick( playAnimation ).setMarginRight( '10px' ) );
-
-	div.add( new UI.Button( "Stop" ).setFontSize( '12px' ).onClick( stopAnimations ), new UI.Break() );
-
-	var animationsSelect = new UI.Select().setFontSize( '12px' ).setMarginTop( '10px' ).setMarginBottom( '10px' );
-	div.add( animationsSelect, new UI.Break() );
-
-	var row = new UI.Row();
-	div.add( row );
-
-	var speed = new UI.Number( 1 ).setRange( 0.25, 2 ).setStep( 0.5 ).setMarginLeft( '10px' );
-	row.add( new UI.Text( "Speed" ), speed );
+	var animationsSelect = new UI.Select().setFontSize( '12px' );
+	div.add( animationsSelect );
+	div.add( new UI.Button( 'Play' ).setMarginLeft( '4px' ).onClick( playAction ) );
+	div.add( new UI.Button( 'Stop' ).setMarginLeft( '4px' ).onClick( stopAction ) );
 
 	return container;
 

+ 23 - 0
editor/js/Viewport.js

@@ -519,6 +519,29 @@ var Viewport = function ( editor ) {
 
 	} );
 
+	// animations
+
+	var prevTime = performance.now();
+
+	function animate( time ) {
+
+		requestAnimationFrame( animate );
+
+		var mixer = editor.animationMixer;
+
+		if ( mixer.stats.actions.inUse > 0 ) {
+
+			editor.animationMixer.update( ( time - prevTime ) / 1000 );
+			render();
+
+		}
+
+		prevTime = time;
+
+	}
+
+	requestAnimationFrame( animate );
+
 	//
 
 	function render() {