Bläddra i källkod

Merge remote-tracking branch 'AddictArts/dev_colladaMatrixXforms' into dev

Mr.doob 13 år sedan
förälder
incheckning
06b0238b96
2 ändrade filer med 175 tillägg och 42 borttagningar
  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();
 
-			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 ) {
 
 				model = collada.scene;
 				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();
 				start();
@@ -74,14 +71,15 @@
 
 			function init() {
 
-				container = document.createElement( 'div' );
+				var container = document.createElement( 'div' );
 				document.body.appendChild( container );
 
-				model.getChildByName( 'camEye_camera', true ).visible = false;
-				model.getChildByName( 'camTarget_camera', true ).visible = false;
+				// Scene
 
 				scene = new THREE.Scene();
 
+				// Camera
+
 				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 0.01, 1000 );
 				camera.position.set( -5.00181875, 3.42631375, 11.3102925 );
 				camera.lookAt( new THREE.Vector3( -1.224774125, 2.18410625, 4.57969125 ) );
@@ -90,21 +88,17 @@
 
 				// 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 ];
 					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;
 					kfAnimations.push( kfAnimation );
+
 				}
 
 				// Grid
@@ -127,20 +121,25 @@
 
 				// Add the COLLADA
 
+				model.getChildByName( 'camEye_camera', true ).visible = false;
+				model.getChildByName( 'camTarget_camera', true ).visible = false;
+
 				scene.add( model );
 
 				// Lights
 
-				pointLight = new THREE.PointLight( 0xffffff, 1.5 );
+				pointLight = new THREE.PointLight( 0xffffff, 1.75 );
 				pointLight.position = camera.position;
 				pointLight.rotation = camera.rotation;
 				pointLight.scale = camera.scale;
+
 				scene.add( pointLight );
 
 				// Renderer
 
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setSize( window.innerWidth, window.innerHeight );
+
 				container.appendChild( renderer.domElement );
 
 				// Stats
@@ -148,28 +147,29 @@
 				stats = new Stats();
 				stats.domElement.style.position = 'absolute';
 				stats.domElement.style.top = '0px';
+
 				container.appendChild( stats.domElement );
 
 			}
 
 			function start() {
 
-				for ( var i = 0, il = kfAnimations.length; i < il; ++i ) {
+				for ( var i = 0; i < kfAnimationsLength; ++i ) {
 
 					var animation = kfAnimations[i];
 
 					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 ) {
 
 							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 );
 
@@ -196,7 +196,7 @@
 
 				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 );
 
@@ -204,7 +204,7 @@
 
 				} else if ( progress >= 48 ) {
 
-					for ( var i = 0, il = kfAnimations.length; i < il; ++i ) {
+					for ( var i = 0; i < kfAnimationsLength; ++i ) {
 
 						kfAnimations[ i ].stop();
 

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

@@ -1003,10 +1003,26 @@ THREE.ColladaLoader = function () {
 
 				var channel = node.channels[i],
 					fullSid = channel.fullSid,
-					member = getConvertedMember( channel.member ),
 					sampler = channel.sampler,
 					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 ) {
 
@@ -1125,7 +1141,11 @@ THREE.ColladaLoader = function () {
 				prevData = prevTarget.data,
 				data;
 
-			if ( prevData.length ) {
+			if ( prevTarget.type === 'matrix' ) {
+
+				data = prevData;
+
+			} else if ( prevData.length ) {
 
 				data = [];
 
@@ -1927,16 +1947,80 @@ THREE.ColladaLoader = function () {
 
 	Transform.prototype.update = function ( data, member ) {
 
+		var members = [ 'X', 'Y', 'Z', 'ANGLE' ];
+
 		switch ( this.type ) {
 
 			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;
 
 			case 'translate':
 			case 'scale':
 
+				if ( Object.prototype.toString.call( member ) === '[object Array]' ) {
+
+					member = members[ member[ 0 ] ];
+
+				}
+
 				switch ( member ) {
 
 					case 'X':
@@ -1967,6 +2051,12 @@ THREE.ColladaLoader = function () {
 
 			case 'rotate':
 
+				if ( Object.prototype.toString.call( member ) === '[object Array]' ) {
+
+					member = members[ member[ 0 ] ];
+
+				}
+
 				switch ( member ) {
 
 					case 'X':
@@ -3329,6 +3419,25 @@ THREE.ColladaLoader = function () {
 
 			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':
 
 					var src = ( new Source() ).parse( child );
@@ -3527,7 +3636,11 @@ THREE.ColladaLoader = function () {
 
 		var data;
 
-		if ( this.strideOut > 1 ) {
+		if ( type === 'matrix' && this.strideOut === 16 ) {
+
+			data = this.output[ ndx ];
+
+		} else if ( this.strideOut > 1 ) {
 
 			data = [];
 			ndx *= this.strideOut;
@@ -3555,6 +3668,10 @@ THREE.ColladaLoader = function () {
 
 				}
 
+			} else if ( this.strideOut === 4 && type === 'matrix' ) {
+
+				fixCoords( data, -1 );
+
 			}
 
 		} else {
@@ -3642,7 +3759,7 @@ THREE.ColladaLoader = function () {
 				nextTarget = nextKey.getTarget( target.sid ),
 				data;
 
-			if ( nextTarget ) {
+			if ( target.transform.type !== 'matrix' && nextTarget ) {
 
 				var scale = ( time - this.time ) / ( nextKey.time - this.time ),
 					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 ) {
 
 		if ( options.convertUpAxis ) {