浏览代码

Merge pull request #11172 from jostschmithals/blendMeshExampleAlerts

Blendmesh example without alerts
Mr.doob 8 年之前
父节点
当前提交
122d6d787d
共有 1 个文件被更改,包括 108 次插入61 次删除
  1. 108 61
      examples/webgl_animation_skinning_blending.html

+ 108 - 61
examples/webgl_animation_skinning_blending.html

@@ -19,14 +19,21 @@
 				top: 0px; width: 100%;
 				top: 0px; width: 100%;
 				padding: 5px;
 				padding: 5px;
 			}
 			}
-			.ac {
+			a {
+				color: #bbb;
+			}
+			.ac {  /* prevent dat-gui from being selected */
 				-webkit-user-select: none;
 				-webkit-user-select: none;
 				-moz-user-select: none;
 				-moz-user-select: none;
 				-ms-user-select: none;
 				-ms-user-select: none;
 				user-select: none;
 				user-select: none;
 			}
 			}
-			a {
-				color: #bbb;
+			.no-pointer-events {
+				pointer-events: none;
+			}
+			.control-disabled {
+				color: #888;
+				text-decoration: line-through;
 			}
 			}
 		</style>
 		</style>
 	</head>
 	</head>
@@ -35,7 +42,8 @@
 		<div id="info">
 		<div id="info">
 			<a href="http://threejs.org" target="_blank">three.js</a> - Skeletal Animation Blending
 			<a href="http://threejs.org" target="_blank">three.js</a> - Skeletal Animation Blending
 			(model from <a href="http://realitymeltdown.com" target="_blank">realitymeltdown.com</a>)
 			(model from <a href="http://realitymeltdown.com" target="_blank">realitymeltdown.com</a>)
-			<br><br>- camera orbit/zoom/pan with left/middle/right mouse button -
+			<br><br>camera orbit/zoom/pan with left/middle/right mouse button
+			<br>Note: crossfades are possible with blend weights being set to (1,0,0), (0,1,0) or (0,0,1)
 		</div>
 		</div>
 
 
 		<script src="../build/three.js"></script>
 		<script src="../build/three.js"></script>
@@ -54,7 +62,10 @@
 			var scene, renderer, camera, controls, stats;
 			var scene, renderer, camera, controls, stats;
 			var mesh, skeleton, mixer;
 			var mesh, skeleton, mixer;
 
 
+			var crossFadeControls = [];
+
 			var idleAction, walkAction, runAction;
 			var idleAction, walkAction, runAction;
+			var idleWeight, walkWeight, runWeight;
 			var actions;
 			var actions;
 			var settings;
 			var settings;
 
 
@@ -175,10 +186,10 @@
 					'pause/continue':        pauseContinue,
 					'pause/continue':        pauseContinue,
 					'make single step':      toSingleStepMode,
 					'make single step':      toSingleStepMode,
 					'modify step size':      0.05,
 					'modify step size':      0.05,
-					'from walk to idle':     function () { prepareCrossFade( walkAction, idleAction, runAction, 1.0 ) },
-					'from idle to walk':     function () { prepareCrossFade( idleAction, walkAction, runAction, 0.5 ) },
-					'from walk to run':      function () { prepareCrossFade( walkAction, runAction, idleAction, 2.5 ) },
-					'from run to walk':      function () { prepareCrossFade( runAction, walkAction, idleAction, 5.0 ) },
+					'from walk to idle':     function () { prepareCrossFade( walkAction, idleAction, 1.0 ) },
+					'from idle to walk':     function () { prepareCrossFade( idleAction, walkAction, 0.5 ) },
+					'from walk to run':      function () { prepareCrossFade( walkAction, runAction, 2.5 ) },
+					'from run to walk':      function () { prepareCrossFade( runAction, walkAction, 5.0 ) },
 					'use default duration':  true,
 					'use default duration':  true,
 					'set custom duration':   3.5,
 					'set custom duration':   3.5,
 					'modify idle weight':    0.0,
 					'modify idle weight':    0.0,
@@ -194,10 +205,10 @@
 				folder3.add( settings, 'pause/continue' );
 				folder3.add( settings, 'pause/continue' );
 				folder3.add( settings, 'make single step' );
 				folder3.add( settings, 'make single step' );
 				folder3.add( settings, 'modify step size', 0.01, 0.1, 0.001 );
 				folder3.add( settings, 'modify step size', 0.01, 0.1, 0.001 );
-				folder4.add( settings, 'from walk to idle' );
-				folder4.add( settings, 'from idle to walk' );
-				folder4.add( settings, 'from walk to run' );
-				folder4.add( settings, 'from run to walk' );
+				crossFadeControls.push( folder4.add( settings, 'from walk to idle' ) );
+				crossFadeControls.push( folder4.add( settings, 'from idle to walk' ) );
+				crossFadeControls.push( folder4.add( settings, 'from walk to run' ) );
+				crossFadeControls.push( folder4.add( settings, 'from run to walk' ) );
 				folder4.add( settings, 'use default duration' );
 				folder4.add( settings, 'use default duration' );
 				folder4.add( settings, 'set custom duration', 0, 10, 0.01 );
 				folder4.add( settings, 'set custom duration', 0, 10, 0.01 );
 				folder5.add( settings, 'modify idle weight', 0.0, 1.0, 0.01 ).listen().onChange( function ( weight ) { setWeight( idleAction, weight ) } );
 				folder5.add( settings, 'modify idle weight', 0.0, 1.0, 0.01 ).listen().onChange( function ( weight ) { setWeight( idleAction, weight ) } );
@@ -212,6 +223,27 @@
 				folder5.open();
 				folder5.open();
 				folder6.open();
 				folder6.open();
 
 
+				crossFadeControls.forEach( function ( control ) {
+
+					control.classList1 = control.domElement.parentElement.parentElement.classList;
+					control.classList2 = control.domElement.previousElementSibling.classList;
+
+					control.setDisabled = function () {
+
+						control.classList1.add( 'no-pointer-events' );
+						control.classList2.add( 'control-disabled' );
+
+					};
+
+					control.setEnabled = function () {
+
+						control.classList1.remove( 'no-pointer-events' );
+						control.classList2.remove( 'control-disabled' );
+
+					};
+
+				} );
+
 			}
 			}
 
 
 
 
@@ -318,67 +350,33 @@
 			}
 			}
 
 
 
 
-			function prepareCrossFade( startAction, endAction, otherAction, defaultDuration ) {
-
-				var duration;
+			function prepareCrossFade( startAction, endAction, defaultDuration ) {
 
 
-				// If the current weight values don't allow the choosen crossfade type,
-				// display a message only, and modify the blend weights accordingly; else go on
+				// Switch default / custom crossfade duration (according to the user's choice)
 
 
-				if ( startAction.getEffectiveWeight() !== 1 ||
-					 endAction.getEffectiveWeight()   !== 0 ||
-					 otherAction.getEffectiveWeight() !== 0 ) {
+				var duration = setCrossFadeDuration( defaultDuration );
 
 
-					displayMessage();
-					prepareWeightsForCrossfade( startAction, endAction, otherAction );
+				// Make sure that we don't go on in singleStepMode, and that all actions are unpaused
 
 
-				} else {
-
-					// Switch default / custom crossfade duration (according to the user's choice)
-
-					var duration = setCrossFadeDuration( defaultDuration );
-
-					// Make sure that we don't go on in singleStepMode, and that all actions are unpaused
-
-					singleStepMode = false;
-					unPauseAllActions();
-
-					// If the current action is 'idle' (duration 4 sec), execute the crossfade immediately;
-					// else wait until the current action has finished its current loop
+				singleStepMode = false;
+				unPauseAllActions();
 
 
-					if ( startAction === idleAction ) {
+				// If the current action is 'idle' (duration 4 sec), execute the crossfade immediately;
+				// else wait until the current action has finished its current loop
 
 
-						executeCrossFade( startAction, endAction, duration );
+				if ( startAction === idleAction ) {
 
 
-					} else {
+					executeCrossFade( startAction, endAction, duration );
 
 
-						synchronizeCrossFade( startAction, endAction, duration );
+				} else {
 
 
-					}
+					synchronizeCrossFade( startAction, endAction, duration );
 
 
 				}
 				}
 
 
 			}
 			}
 
 
 
 
-			function displayMessage() {
-
-				alert( 'Crossfading is not useful if its start animation isn\'t already running before (or if it is not the only one at this moment).\n\n' +
-					   'Thus the initial blend weights are now modified according to your crossfade choice.\n\n' +
-					   'That being done you can try the same crossfade again by clicking its button!\n\n' );
-
-			}
-
-
-			function prepareWeightsForCrossfade( startAction, endAction, otherAction ) {
-
-				setWeight( startAction, 1 );
-				setWeight( endAction,   0 );
-				setWeight( otherAction, 0 );
-
-			}
-
-
 			function setCrossFadeDuration( defaultDuration ) {
 			function setCrossFadeDuration( defaultDuration ) {
 
 
 				// Switch default crossfade duration <-> custom crossfade duration
 				// Switch default crossfade duration <-> custom crossfade duration
@@ -442,6 +440,49 @@
 			}
 			}
 
 
 
 
+			// Called by the render loop
+
+			function updateWeightSliders() {
+
+				settings[ 'modify idle weight' ] = idleWeight;
+				settings[ 'modify walk weight' ] = walkWeight;
+				settings[ 'modify run weight' ] = runWeight;
+
+			}
+
+
+			// Called by the render loop
+
+			function updateCrossFadeControls() {
+
+				crossFadeControls.forEach( function ( control ) {
+
+					control.setDisabled();
+
+				} );
+
+				if ( idleWeight === 1 && walkWeight === 0 && runWeight === 0 ) {
+
+					crossFadeControls[ 1 ].setEnabled();
+
+				}
+
+				if ( idleWeight === 0 && walkWeight === 1 && runWeight === 0 ) {
+
+					crossFadeControls[ 0 ].setEnabled();
+					crossFadeControls[ 2 ].setEnabled();
+
+				}
+
+				if ( idleWeight === 0 && walkWeight === 0 && runWeight === 1 ) {
+
+					crossFadeControls[ 3 ].setEnabled();
+
+				}
+
+			}
+
+
 			function onWindowResize() {
 			function onWindowResize() {
 
 
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.aspect = window.innerWidth / window.innerHeight;
@@ -458,11 +499,17 @@
 
 
 				requestAnimationFrame( animate );
 				requestAnimationFrame( animate );
 
 
+				idleWeight = idleAction.getEffectiveWeight();
+				walkWeight = walkAction.getEffectiveWeight();
+				runWeight = runAction.getEffectiveWeight();
+
 				// Update the panel values if weights are modified from "outside" (by crossfadings)
 				// Update the panel values if weights are modified from "outside" (by crossfadings)
 
 
-				settings[ 'modify idle weight' ] = idleAction.getEffectiveWeight();
-				settings[ 'modify walk weight' ] = walkAction.getEffectiveWeight();
-				settings[ 'modify run weight' ] = runAction.getEffectiveWeight();
+				updateWeightSliders();
+
+				// Enable/disable crossfade controls according to current weight values
+
+				updateCrossFadeControls();
 
 
 				// Get the time elapsed since the last frame, used for mixer update (if not in single step mode)
 				// Get the time elapsed since the last frame, used for mixer update (if not in single step mode)