Просмотр исходного кода

Minor optimizations and tweaks to make it a better example. Removed extraneous work in setting up the animation loop. Added support for array-style target addressing according to COLLADA spec. Added support for matrix transform updates. Added support for hierarchical animations as defined in COLLADA spec (Credit to ekitson).

John Pywtorak 13 лет назад
Родитель
Сommit
1dacb71d88
2 измененных файлов с 175 добавлено и 42 удалено
  1. 36 36
      examples/webgl_loader_collada_keyframe.html
  2. 139 6
      src/extras/loaders/ColladaLoader.js

+ 36 - 36
examples/webgl_loader_collada_keyframe.html

@@ -44,27 +44,24 @@
 
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
 
-			var container,
-				stats,
-				camera,
-				scene,
-				renderer,
-				pointLight,
-				model,
-				animations,
-				kfAnimations = [ ],
-				loader = new THREE.ColladaLoader(),
-				lastTimestamp,
-				startTime,
-				progress = 0;
+			var stats;
+			var scene;
+			var camera;
+			var renderer;
+			var model;
+			var animations;
+			var kfAnimations = [ ];
+			var kfAnimationsLength = 0;
+			var loader = new THREE.ColladaLoader();
+			var lastTimestamp;
+			var progress = 0;
 
 
 			loader.load( './models/collada/pump/pump.dae', function ( collada ) {
 			loader.load( './models/collada/pump/pump.dae', function ( collada ) {
 
 
 				model = collada.scene;
 				model = collada.scene;
 				animations = collada.animations;
 				animations = collada.animations;
-
-				model.scale.x = model.scale.y = model.scale.z = 0.125;
-				model.updateMatrix();
+				kfAnimationsLength = animations.length;
+				model.scale.x = model.scale.y = model.scale.z = 0.125; // 1/8 scale, modeled in cm
 
 
 				init();
 				init();
 				start();
 				start();
@@ -74,14 +71,15 @@
 
 
 			function init() {
 			function init() {
 
 
-				container = document.createElement( 'div' );
+				var container = document.createElement( 'div' );
 				document.body.appendChild( container );
 				document.body.appendChild( container );
 
 
-				model.getChildByName( 'camEye_camera', true ).visible = false;
-				model.getChildByName( 'camTarget_camera', true ).visible = false;
+				// Scene
 
 
 				scene = new THREE.Scene();
 				scene = new THREE.Scene();
 
 
+				// Camera
+
 				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 0.01, 1000 );
 				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 0.01, 1000 );
 				camera.position.set( -5.00181875, 3.42631375, 11.3102925 );
 				camera.position.set( -5.00181875, 3.42631375, 11.3102925 );
 				camera.lookAt( new THREE.Vector3( -1.224774125, 2.18410625, 4.57969125 ) );
 				camera.lookAt( new THREE.Vector3( -1.224774125, 2.18410625, 4.57969125 ) );
@@ -90,21 +88,17 @@
 
 
 				// KeyFrame Animations
 				// KeyFrame Animations
 
 
-				var animHandler = THREE.AnimationHandler,
-					toConvert = { };
+				var animHandler = THREE.AnimationHandler;
 
 
-				for ( var i = 0, il = animations.length; i < il; ++i ) {
-					var node = animations[ i ].node;
-					toConvert[ node.id ] = node;
-				}
+				for ( var i = 0; i < kfAnimationsLength; ++i ) {
 
 
-				for ( var i = 0, il = animations.length; i < il; ++i ) {
 					var animation = animations[ i ];
 					var animation = animations[ i ];
 					animHandler.add( animation );
 					animHandler.add( animation );
 
 
-					var kfAnimation = new THREE.KeyFrameAnimation( toConvert[ animation.node.id ], animation.name );
+					var kfAnimation = new THREE.KeyFrameAnimation( animation.node, animation.name );
 					kfAnimation.timeScale = 1;
 					kfAnimation.timeScale = 1;
 					kfAnimations.push( kfAnimation );
 					kfAnimations.push( kfAnimation );
+
 				}
 				}
 
 
 				// Grid
 				// Grid
@@ -127,20 +121,25 @@
 
 
 				// Add the COLLADA
 				// Add the COLLADA
 
 
+				model.getChildByName( 'camEye_camera', true ).visible = false;
+				model.getChildByName( 'camTarget_camera', true ).visible = false;
+
 				scene.add( model );
 				scene.add( model );
 
 
 				// Lights
 				// Lights
 
 
-				pointLight = new THREE.PointLight( 0xffffff, 1.5 );
+				pointLight = new THREE.PointLight( 0xffffff, 1.75 );
 				pointLight.position = camera.position;
 				pointLight.position = camera.position;
 				pointLight.rotation = camera.rotation;
 				pointLight.rotation = camera.rotation;
 				pointLight.scale = camera.scale;
 				pointLight.scale = camera.scale;
+
 				scene.add( pointLight );
 				scene.add( pointLight );
 
 
 				// Renderer
 				// Renderer
 
 
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setSize( window.innerWidth, window.innerHeight );
+
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );
 
 
 				// Stats
 				// Stats
@@ -148,28 +147,29 @@
 				stats = new Stats();
 				stats = new Stats();
 				stats.domElement.style.position = 'absolute';
 				stats.domElement.style.position = 'absolute';
 				stats.domElement.style.top = '0px';
 				stats.domElement.style.top = '0px';
+
 				container.appendChild( stats.domElement );
 				container.appendChild( stats.domElement );
 
 
 			}
 			}
 
 
 			function start() {
 			function start() {
 
 
-				for ( var i = 0, il = kfAnimations.length; i < il; ++i ) {
+				for ( var i = 0; i < kfAnimationsLength; ++i ) {
 
 
 					var animation = kfAnimations[i];
 					var animation = kfAnimations[i];
 
 
 					for ( var h = 0, hl = animation.hierarchy.length; h < hl; h++ ) {
 					for ( var h = 0, hl = animation.hierarchy.length; h < hl; h++ ) {
 
 
-						var keys = animation.data.hierarchy[ h ].keys,
-						sids = animation.data.hierarchy[ h ].sids,
-						obj = animation.hierarchy[ h ];
+						var keys = animation.data.hierarchy[ h ].keys;
+						var sids = animation.data.hierarchy[ h ].sids;
+						var obj = animation.hierarchy[ h ];
 
 
 						if ( keys.length && sids ) {
 						if ( keys.length && sids ) {
 
 
 							for ( var s = 0; s < sids.length; s++ ) {
 							for ( var s = 0; s < sids.length; s++ ) {
 
 
-								var sid = sids[ s ],
-								next = animation.getNextKeyWith( sid, h, 0 );
+								var sid = sids[ s ];
+								var next = animation.getNextKeyWith( sid, h, 0 );
 
 
 								if ( next ) next.apply( sid );
 								if ( next ) next.apply( sid );
 
 
@@ -196,7 +196,7 @@
 
 
 				if ( progress >= 0 && progress < 48 ) {
 				if ( progress >= 0 && progress < 48 ) {
 
 
-					for ( var i = 0, il = kfAnimations.length; i < il; ++i ) {
+					for ( var i = 0; i < kfAnimationsLength; ++i ) {
 
 
 						kfAnimations[ i ].update( frameTime );
 						kfAnimations[ i ].update( frameTime );
 
 
@@ -204,7 +204,7 @@
 
 
 				} else if ( progress >= 48 ) {
 				} else if ( progress >= 48 ) {
 
 
-					for ( var i = 0, il = kfAnimations.length; i < il; ++i ) {
+					for ( var i = 0; i < kfAnimationsLength; ++i ) {
 
 
 						kfAnimations[ i ].stop();
 						kfAnimations[ i ].stop();
 
 

+ 139 - 6
src/extras/loaders/ColladaLoader.js

@@ -1003,10 +1003,26 @@ THREE.ColladaLoader = function () {
 
 
 				var channel = node.channels[i],
 				var channel = node.channels[i],
 					fullSid = channel.fullSid,
 					fullSid = channel.fullSid,
-					member = getConvertedMember( channel.member ),
 					sampler = channel.sampler,
 					sampler = channel.sampler,
 					input = sampler.input,
 					input = sampler.input,
-					transform = node.getTransformBySid( channel.sid );
+					transform = node.getTransformBySid( channel.sid ),
+					member;
+
+				if ( channel.arrIndices ) {
+
+					member = [];
+
+					for ( var j = 0, jl = channel.arrIndices.length; j < jl; j++ ) {
+
+						member[ j ] = getConvertedIndex( channel.arrIndices[ j ] );
+
+					}
+
+				} else {
+
+					member = getConvertedMember( channel.member );
+
+				}
 
 
 				if ( transform ) {
 				if ( transform ) {
 
 
@@ -1125,7 +1141,11 @@ THREE.ColladaLoader = function () {
 				prevData = prevTarget.data,
 				prevData = prevTarget.data,
 				data;
 				data;
 
 
-			if ( prevData.length ) {
+			if ( prevTarget.type === 'matrix' ) {
+
+				data = prevData;
+
+			} else if ( prevData.length ) {
 
 
 				data = [];
 				data = [];
 
 
@@ -1927,16 +1947,80 @@ THREE.ColladaLoader = function () {
 
 
 	Transform.prototype.update = function ( data, member ) {
 	Transform.prototype.update = function ( data, member ) {
 
 
+		var members = [ 'X', 'Y', 'Z', 'ANGLE' ];
+
 		switch ( this.type ) {
 		switch ( this.type ) {
 
 
 			case 'matrix':
 			case 'matrix':
 
 
-				console.log( 'Currently not handling matrix transform updates' );
+				if ( ! member ) {
+
+					this.obj.copy( data );
+
+				} else if ( member.length === 1 ) {
+
+					switch ( member[ 0 ] ) {
+
+						case 0:
+
+							this.obj.n11 = data[ 0 ];
+							this.obj.n21 = data[ 1 ];
+							this.obj.n31 = data[ 2 ];
+							this.obj.n41 = data[ 3 ];
+
+							break;
+
+						case 1:
+
+							this.obj.n12 = data[ 0 ];
+							this.obj.n22 = data[ 1 ];
+							this.obj.n32 = data[ 2 ];
+							this.obj.n42 = data[ 3 ];
+
+							break;
+
+						case 2:
+
+							this.obj.n13 = data[ 0 ];
+							this.obj.n23 = data[ 1 ];
+							this.obj.n33 = data[ 2 ];
+							this.obj.n43 = data[ 3 ];
+
+							break;
+
+						case 3:
+
+							this.obj.n14 = data[ 0 ];
+							this.obj.n24 = data[ 1 ];
+							this.obj.n34 = data[ 2 ];
+							this.obj.n44 = data[ 3 ];
+
+							break;
+
+					}
+
+				} else if ( member.length === 2 ) {
+
+					var propName = 'n' + ( member[ 0 ] + 1 ) + ( member[ 1 ] + 1 );
+					this.obj[ propName ] = data;
+					
+				} else {
+
+					console.log('Incorrect addressing of matrix in transform.');
+
+				}
+
 				break;
 				break;
 
 
 			case 'translate':
 			case 'translate':
 			case 'scale':
 			case 'scale':
 
 
+				if ( Object.prototype.toString.call( member ) === '[object Array]' ) {
+
+					member = members[ member[ 0 ] ];
+
+				}
+
 				switch ( member ) {
 				switch ( member ) {
 
 
 					case 'X':
 					case 'X':
@@ -1967,6 +2051,12 @@ THREE.ColladaLoader = function () {
 
 
 			case 'rotate':
 			case 'rotate':
 
 
+				if ( Object.prototype.toString.call( member ) === '[object Array]' ) {
+
+					member = members[ member[ 0 ] ];
+
+				}
+
 				switch ( member ) {
 				switch ( member ) {
 
 
 					case 'X':
 					case 'X':
@@ -3329,6 +3419,25 @@ THREE.ColladaLoader = function () {
 
 
 			switch ( child.nodeName ) {
 			switch ( child.nodeName ) {
 
 
+				case 'animation':
+
+					var anim = ( new Animation() ).parse( child );
+
+					for ( var src in anim.source ) {
+
+						this.source[ src ] = anim.source[ src ];
+
+					}
+
+					for ( var j = 0; j < anim.channel.length; j ++ ) {
+
+						this.channel.push( anim.channel[ j ] );
+						this.sampler.push( anim.sampler[ j ] );
+
+					}
+
+					break;
+
 				case 'source':
 				case 'source':
 
 
 					var src = ( new Source() ).parse( child );
 					var src = ( new Source() ).parse( child );
@@ -3527,7 +3636,11 @@ THREE.ColladaLoader = function () {
 
 
 		var data;
 		var data;
 
 
-		if ( this.strideOut > 1 ) {
+		if ( type === 'matrix' && this.strideOut === 16 ) {
+
+			data = this.output[ ndx ];
+
+		} else if ( this.strideOut > 1 ) {
 
 
 			data = [];
 			data = [];
 			ndx *= this.strideOut;
 			ndx *= this.strideOut;
@@ -3555,6 +3668,10 @@ THREE.ColladaLoader = function () {
 
 
 				}
 				}
 
 
+			} else if ( this.strideOut === 4 && type === 'matrix' ) {
+
+				fixCoords( data, -1 );
+
 			}
 			}
 
 
 		} else {
 		} else {
@@ -3642,7 +3759,7 @@ THREE.ColladaLoader = function () {
 				nextTarget = nextKey.getTarget( target.sid ),
 				nextTarget = nextKey.getTarget( target.sid ),
 				data;
 				data;
 
 
-			if ( nextTarget ) {
+			if ( target.transform.type !== 'matrix' && nextTarget ) {
 
 
 				var scale = ( time - this.time ) / ( nextKey.time - this.time ),
 				var scale = ( time - this.time ) / ( nextKey.time - this.time ),
 					nextData = nextTarget.data,
 					nextData = nextTarget.data,
@@ -4150,6 +4267,22 @@ THREE.ColladaLoader = function () {
 
 
 	};
 	};
 
 
+	function getConvertedIndex( index ) {
+
+		if ( index > -1 && index < 3 ) {
+
+			var members = ['X', 'Y', 'Z'],
+				indices = { X: 0, Y: 1, Z: 2 };
+
+			index = getConvertedMember( members[ index ] );
+			index = indices[ index ];
+
+		}
+
+		return index;
+		
+	};
+
 	function getConvertedMember( member ) {
 	function getConvertedMember( member ) {
 
 
 		if ( options.convertUpAxis ) {
 		if ( options.convertUpAxis ) {