ColladaLoader.js 67.3 KB
Newer Older
T
credits  
timk 已提交
1 2 3 4
/**
 * @author Tim Knip / http://www.floorplanner.com/ / tim at floorplanner.com
 */

M
Mr.doob 已提交
5
THREE.ColladaLoader = function () {
6

T
timk 已提交
7 8 9
	var COLLADA = null;
	var scene = null;
	var daeScene;
10 11 12

	var readyCallbackFunc = null;

T
timk 已提交
13 14 15 16 17 18 19
 	var sources = {};
	var images = {};
	var animations = {};
	var controllers = {};
	var geometries = {};
	var materials = {};
	var effects = {};
20

21
	var animData;
T
timk 已提交
22
	var visualScenes;
T
timk 已提交
23
	var baseUrl;
T
timk 已提交
24 25
	var morphs;
	var skins;
26 27

	var flip_uv = true;
T
timk 已提交
28
	var preferredShading = THREE.SmoothShading;
M
Mr.doob 已提交
29

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
	var options = {
		// Axis conversion is done for geometries, animations, and controllers.
		// If we ever pull cameras or lights out of the COLLADA file, they'll
		// need extra work.
		convertUpAxis: false,

		subdivideFaces: true,

		upAxis: 'Y'
	};

	// TODO: support unit conversion as well
	var colladaUnit = 1.0;
	var colladaUp = 'Y';
	var upConversion = null;

	var TO_RADIANS = Math.PI / 180;

48 49 50 51
	function load ( url, readyCallback ) {

		if ( document.implementation && document.implementation.createDocument ) {

T
timk 已提交
52 53
			var req = new XMLHttpRequest();

54 55
			if( req.overrideMimeType ) {

T
timk 已提交
56
				// need this? yes... if extension is other then *.xml :-S
57 58

				req.overrideMimeType( "text/xml" );
59

T
timk 已提交
60 61 62
			}

			req.onreadystatechange = function() {
63 64 65 66

				if( req.readyState == 4 ) {

					if( req.status == 0 || req.status == 200 ) {
M
Mr.doob 已提交
67

68 69 70 71 72 73 74 75 76 77 78

						if ( req.responseXML ) {

							readyCallbackFunc = readyCallback;
							parse( req.responseXML, undefined, url );

						} else {

							console.error( "ColladaLoader: Empty or non-existing file (" + url + ")" );

						}
79

T
timk 已提交
80
					}
81

T
timk 已提交
82
				}
83

T
timk 已提交
84
			}
85 86 87 88

			req.open( "GET", url, true );
			req.send( null );

T
timk 已提交
89
		} else {
90

91
			alert( "Don't know how to parse XML!" );
92

T
timk 已提交
93
		}
94 95 96

	};

97
	function parse( doc, callBack, url ) {
98

T
timk 已提交
99 100
		COLLADA = doc;
		callBack = callBack || readyCallbackFunc;
101 102 103

		if ( url !== undefined ) {

104
			var parts = url.split( '/' );
T
timk 已提交
105
			parts.pop();
M
Mr.doob 已提交
106
			baseUrl = parts.length < 1 ? '' : parts.join( '/' ) + '/';
107

T
timk 已提交
108
		}
109

110 111
		parseAsset();
		setUpConversion();
112 113 114 115 116 117 118 119
		images = parseLib( "//dae:library_images/dae:image", _Image, "image" );
		materials = parseLib( "//dae:library_materials/dae:material", Material, "material") ;
		effects = parseLib( "//dae:library_effects/dae:effect", Effect, "effect" );
		geometries = parseLib( "//dae:library_geometries/dae:geometry", Geometry, "geometry" );
		controllers = parseLib( "//dae:library_controllers/dae:controller", Controller, "controller" );
		animations = parseLib( "//dae:library_animations/dae:animation", Animation, "animation" );
		visualScenes = parseLib( ".//dae:library_visual_scenes/dae:visual_scene", VisualScene, "visual_scene" );

T
timk 已提交
120 121
		morphs = [];
		skins = [];
122

T
timk 已提交
123 124
		daeScene = parseScene();
		scene = new THREE.Object3D();
125

126
		for ( var i = 0; i < daeScene.nodes.length; i ++ ) {
127

128
			scene.add( createSceneGraph( daeScene.nodes[ i ] ) );
129

T
timk 已提交
130
		}
T
timk 已提交
131

T
timk 已提交
132 133 134
		createAnimations();

		var result = {
135 136

			scene: scene,
T
timk 已提交
137 138
			morphs: morphs,
			skins: skins,
139
			animations: animData,
T
timk 已提交
140 141 142 143 144 145 146 147 148 149
			dae: {
				images: images,
				materials: materials,
				effects: effects,
				geometries: geometries,
				controllers: controllers,
				animations: animations,
				visualScenes: visualScenes,
				scene: daeScene
			}
150

T
timk 已提交
151
		};
152 153 154 155 156

		if ( callBack ) {

			callBack( result );

T
timk 已提交
157
		}
158

T
timk 已提交
159
		return result;
160 161 162 163 164

	};

	function setPreferredShading ( shading ) {

T
timk 已提交
165
		preferredShading = shading;
166 167 168

	};

169 170
	function parseAsset () {

171
		var elements = COLLADA.evaluate( '//dae:asset', COLLADA, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );
172 173 174

		var element = elements.iterateNext();

175
		if ( element && element.childNodes ) {
176

177
			for ( var i = 0; i < element.childNodes.length; i ++ ) {
178

179
				var child = element.childNodes[ i ];
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207

				switch ( child.nodeName ) {

					case 'unit':

						var meter = child.getAttribute( 'meter' );

						if ( meter ) {

							colladaUnit = parseFloat( meter );

						}

						break;

					case 'up_axis':

						colladaUp = child.textContent.charAt(0);
						break;

				}

			}

		}

	};

208 209
	function parseLib ( q, classSpec, prefix ) {

210
		var elements = COLLADA.evaluate(q, COLLADA, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null) ;
211

T
timk 已提交
212 213 214
		var lib = {};
		var element = elements.iterateNext();
		var i = 0;
215 216 217 218

		while ( element ) {

			var daeElement = ( new classSpec() ).parse( element );
219
			if ( !daeElement.id || daeElement.id.length == 0 ) daeElement.id = prefix + ( i ++ );
220
			lib[ daeElement.id ] = daeElement;
221

T
timk 已提交
222
			element = elements.iterateNext();
223

T
timk 已提交
224
		}
225

T
timk 已提交
226
		return lib;
227 228 229 230 231

	};

	function parseScene () {

232
		var sceneElement = COLLADA.evaluate( './/dae:scene/dae:instance_visual_scene', COLLADA, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null ).iterateNext();
233 234 235 236 237 238

		if ( sceneElement ) {

			var url = sceneElement.getAttribute( 'url' ).replace( /^#/, '' );
			return visualScenes[ url ];

T
timk 已提交
239
		} else {
240

T
timk 已提交
241
			return null;
242

T
timk 已提交
243
		}
244 245 246

	};

247
	function createAnimations() {
248

249 250 251 252 253 254 255
		animData = [];

		// fill in the keys
		recurseHierarchy( scene );

	};

256
	function recurseHierarchy( node ) {
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273

		var n = daeScene.getChildById( node.name, true ),
			newData = null;

		if ( n && n.keys ) {

			newData = {
				fps: 60,
				hierarchy: [ {
					node: n,
					keys: n.keys,
					sids: n.sids
				} ],
				node: node,
				name: 'animation_' + node.name,
				length: 0
			};
274

275
			animData.push(newData);
276

277 278 279 280 281 282 283 284 285 286 287 288 289 290
			for ( var i = 0, il = n.keys.length; i < il; i++ ) {

				newData.length = Math.max( newData.length, n.keys[i].time );

			}

		} else  {

			newData = {
				hierarchy: [ {
					keys: [],
					sids: []
				} ]
			}
291 292 293

		}

294 295 296 297 298 299 300 301 302 303 304 305 306 307
		for ( var i = 0, il = node.children.length; i < il; i++ ) {

			var d = recurseHierarchy( node.children[i] );

			for ( var j = 0, jl = d.hierarchy.length; j < jl; j ++ ) {

				newData.hierarchy.push( {
					keys: [],
					sids: []
				} );

			}

		}
308

309
		return newData;
310 311 312 313 314

	};

	function calcAnimationBounds () {

T
timk 已提交
315 316
		var start = 1000000;
		var end = -start;
T
timk 已提交
317
		var frames = 0;
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345

		for ( var id in animations ) {

			var animation = animations[ id ];

			for ( var i = 0; i < animation.sampler.length; i ++ ) {

				var sampler = animation.sampler[ i ];
				sampler.create();

				start = Math.min( start, sampler.startTime );
				end = Math.max( end, sampler.endTime );
				frames = Math.max( frames, sampler.input.length );

			}

		}

		return { start:start, end:end, frames:frames };

	};

	function createMorph ( geometry, ctrl ) {

		var morphCtrl = ctrl instanceof InstanceController ? controllers[ ctrl.url ] : ctrl;

		if ( !morphCtrl || !morphCtrl.morph ) {

T
timk 已提交
346 347
			console.log("could not find morph controller!");
			return;
348

T
timk 已提交
349
		}
350

T
timk 已提交
351 352
		var morph = morphCtrl.morph;

353 354 355 356 357 358 359
		for ( var i = 0; i < morph.targets.length; i ++ ) {

			var target_id = morph.targets[ i ];
			var daeGeometry = geometries[ target_id ];

			if ( !daeGeometry.mesh ||
				 !daeGeometry.mesh.primitives ||
360
				 !daeGeometry.mesh.primitives.length ) {
361
				 continue;
T
timk 已提交
362
			}
363 364 365 366 367

			var target = daeGeometry.mesh.primitives[ 0 ].geometry;

			if ( target.vertices.length === geometry.vertices.length ) {

T
timk 已提交
368
				geometry.morphTargets.push( { name: "target_1", vertices: target.vertices } );
369

T
timk 已提交
370
			}
371

T
timk 已提交
372
		}
373

T
timk 已提交
374
		geometry.morphTargets.push( { name: "target_Z", vertices: geometry.vertices } );
375 376 377 378 379 380 381 382 383

	};

	function createSkin ( geometry, ctrl, applyBindShape ) {

		var skinCtrl = controllers[ ctrl.url ];

		if ( !skinCtrl || !skinCtrl.skin ) {

384
			console.log( "could not find skin controller!" );
T
timk 已提交
385
			return;
386

T
timk 已提交
387
		}
388 389 390

		if ( !ctrl.skeleton || !ctrl.skeleton.length ) {

391
			console.log( "could not find the skeleton for the skin!" );
T
timk 已提交
392
			return;
393

T
timk 已提交
394
		}
395

T
timk 已提交
396
		var skin = skinCtrl.skin;
397
		var skeleton = daeScene.getChildById( ctrl.skeleton[ 0 ] );
T
timk 已提交
398
		var hierarchy = [];
399

T
timk 已提交
400
		applyBindShape = applyBindShape !== undefined ? applyBindShape : true;
401

T
timk 已提交
402 403 404
		var bones = [];
		geometry.skinWeights = [];
		geometry.skinIndices = [];
405

406 407
		//createBones( geometry.bones, skin, hierarchy, skeleton, null, -1 );
		//createWeights( skin, geometry.bones, geometry.skinIndices, geometry.skinWeights );
408

T
timk 已提交
409 410 411 412 413 414 415 416 417
		/*
		geometry.animation = {
			name: 'take_001',
			fps: 30,
			length: 2,
			JIT: true,
			hierarchy: hierarchy
		};
		*/
418 419 420 421 422 423 424

		if ( applyBindShape ) {

			for ( var i = 0; i < geometry.vertices.length; i ++ ) {

				skin.bindShapeMatrix.multiplyVector3( geometry.vertices[ i ].position );

T
timk 已提交
425
			}
426

T
timk 已提交
427
		}
428 429 430 431 432

	};

	function setupSkeleton ( node, bones, frame, parent ) {

T
timk 已提交
433
		node.world = node.world || new THREE.Matrix4();
434 435 436 437 438 439 440 441 442
		node.world.copy( node.matrix );

		if ( node.channels && node.channels.length ) {

			var channel = node.channels[ 0 ];
			var m = channel.sampler.output[ frame ];

			if ( m instanceof THREE.Matrix4 ) {

443
				node.world.copy( m );
444

T
timk 已提交
445
			}
446

T
timk 已提交
447
		}
448 449 450 451 452

		if ( parent ) {

			node.world.multiply( parent, node.world );

T
timk 已提交
453 454
		}

455 456 457 458 459 460
		bones.push( node );

		for ( var i = 0; i < node.nodes.length; i ++ ) {

			setupSkeleton( node.nodes[ i ], bones, frame, node.world );

T
timk 已提交
461
		}
462 463 464 465 466

	};

	function setupSkinningMatrices ( bones, skin ) {

T
timk 已提交
467
		// FIXME: this is dumb...
468 469 470 471

		for ( var i = 0; i < bones.length; i ++ ) {

			var bone = bones[ i ];
T
timk 已提交
472
			var found = -1;
473

M
Mr.doob 已提交
474 475
			if ( bone.type != 'JOINT' ) continue;

476 477 478 479
			for ( var j = 0; j < skin.joints.length; j ++ ) {

				if ( bone.sid == skin.joints[ j ] ) {

T
timk 已提交
480 481
					found = j;
					break;
482

T
timk 已提交
483
				}
484

T
timk 已提交
485
			}
486

487
			if ( found >= 0 ) {
488 489 490

				var inv = skin.invBindMatrices[ found ];

T
timk 已提交
491 492
				bone.invBindMatrix = inv;
				bone.skinningMatrix = new THREE.Matrix4();
T
hmm  
timk 已提交
493
				bone.skinningMatrix.multiply(bone.world, inv); // (IBMi * JMi)
494

T
timk 已提交
495
				bone.weights = [];
496 497 498 499 500 501 502 503 504 505 506

				for ( var j = 0; j < skin.weights.length; j ++ ) {

					for (var k = 0; k < skin.weights[ j ].length; k ++) {

						var w = skin.weights[ j ][ k ];

						if ( w.joint == found ) {

							bone.weights.push( w );

T
timk 已提交
507
						}
508

T
timk 已提交
509
					}
510

T
timk 已提交
511
				}
512

T
timk 已提交
513
			} else {
514

M
Mr.doob 已提交
515
				throw 'ColladaLoader: Could not find joint \'' + bone.sid + '\'.';
516

T
timk 已提交
517
			}
518

T
timk 已提交
519
		}
520 521 522 523 524 525 526

	};

	function applySkin ( geometry, instanceCtrl, frame ) {

		var skinController = controllers[ instanceCtrl.url ];

T
timk 已提交
527
		frame = frame !== undefined ? frame : 40;
528 529 530

		if ( !skinController || !skinController.skin ) {

M
Mr.doob 已提交
531
			console.log( 'ColladaLoader: Could not find skin controller.' );
T
timk 已提交
532
			return;
533

T
timk 已提交
534 535
		}

536 537
		if ( !instanceCtrl.skeleton || !instanceCtrl.skeleton.length ) {

M
Mr.doob 已提交
538
			console.log( 'ColladaLoader: Could not find the skeleton for the skin. ' );
T
timk 已提交
539
			return;
540

T
timk 已提交
541
		}
542

T
timk 已提交
543
		var animationBounds = calcAnimationBounds();
544 545 546
		var skeleton = daeScene.getChildById( instanceCtrl.skeleton[0], true ) ||
					   daeScene.getChildBySid( instanceCtrl.skeleton[0], true );

T
timk 已提交
547 548 549 550
		var i, j, w, vidx, weight;
		var v = new THREE.Vector3(), o, s;

		// move vertices to bind shape
551 552 553 554 555

		for ( i = 0; i < geometry.vertices.length; i ++ ) {

			skinController.skin.bindShapeMatrix.multiplyVector3( geometry.vertices[i].position );

T
timk 已提交
556
		}
557

T
timk 已提交
558
		// process animation, or simply pose the rig if no animation
559 560 561

		for ( frame = 0; frame < animationBounds.frames; frame ++ ) {

T
timk 已提交
562 563
			var bones = [];
			var skinned = [];
564

T
timk 已提交
565
			// zero skinned vertices
566 567 568

			for ( i = 0; i < geometry.vertices.length; i++ ) {

T
timk 已提交
569
				skinned.push( new THREE.Vertex( new THREE.Vector3() ) );
570

T
timk 已提交
571
			}
572 573

			// process the frame and setup the rig with a fresh
T
timk 已提交
574
			// transform, possibly from the bone's animation channel(s)
575 576 577 578

			setupSkeleton( skeleton, bones, frame );
			setupSkinningMatrices( bones, skinController.skin );

T
timk 已提交
579
			// skin 'm
580 581 582

			for ( i = 0; i < bones.length; i ++ ) {

M
Mr.doob 已提交
583 584
				if ( bones[ i ].type != 'JOINT' ) continue;

585 586 587
				for ( j = 0; j < bones[ i ].weights.length; j ++ ) {

					w = bones[ i ].weights[ j ];
T
timk 已提交
588 589
					vidx = w.index;
					weight = w.weight;
590

T
timk 已提交
591 592
					o = geometry.vertices[vidx];
					s = skinned[vidx];
593

T
timk 已提交
594 595 596
					v.x = o.position.x;
					v.y = o.position.y;
					v.z = o.position.z;
597

T
timk 已提交
598
					bones[i].skinningMatrix.multiplyVector3(v);
599

T
timk 已提交
600 601 602
					s.position.x += (v.x * weight);
					s.position.y += (v.y * weight);
					s.position.z += (v.z * weight);
603

T
timk 已提交
604
				}
605

T
timk 已提交
606
			}
607

T
timk 已提交
608
			geometry.morphTargets.push( { name: "target_" + frame, vertices: skinned } );
609

T
timk 已提交
610
		}
611 612 613 614 615

	};

	function createSceneGraph ( node, parent ) {

T
timk 已提交
616 617
		var obj = new THREE.Object3D();
		var skinned = false;
T
timk 已提交
618 619
		var skinController;
		var morphController;
620
		var i, j;
621

T
timk 已提交
622
		// FIXME: controllers
623

624
		for ( i = 0; i < node.controllers.length; i ++ ) {
625

626
			var controller = controllers[ node.controllers[ i ].url ];
627 628 629

			switch ( controller.type ) {

T
timk 已提交
630
				case 'skin':
631

632
					if ( geometries[ controller.skin.source ] ) {
633

T
timk 已提交
634
						var inst_geom = new InstanceGeometry();
635

T
timk 已提交
636
						inst_geom.url = controller.skin.source;
637 638 639
						inst_geom.instance_material = node.controllers[ i ].instance_material;

						node.geometries.push( inst_geom );
T
timk 已提交
640
						skinned = true;
641
						skinController = node.controllers[ i ];
642

643
					} else if ( controllers[ controller.skin.source ] ) {
644

T
timk 已提交
645 646
						// urgh: controller can be chained
						// handle the most basic case...
647 648

						var second = controllers[ controller.skin.source ];
T
timk 已提交
649 650
						morphController = second;
					//	skinController = node.controllers[i];
651 652 653

						if ( second.morph && geometries[ second.morph.source ] ) {

T
timk 已提交
654
							var inst_geom = new InstanceGeometry();
655

T
timk 已提交
656
							inst_geom.url = second.morph.source;
657 658 659 660
							inst_geom.instance_material = node.controllers[ i ].instance_material;

							node.geometries.push( inst_geom );

T
timk 已提交
661
						}
662

T
timk 已提交
663
					}
664

T
timk 已提交
665
					break;
666

T
timk 已提交
667
				case 'morph':
668

669
					if ( geometries[ controller.morph.source ] ) {
670

T
timk 已提交
671
						var inst_geom = new InstanceGeometry();
672

T
timk 已提交
673
						inst_geom.url = controller.morph.source;
674 675 676 677
						inst_geom.instance_material = node.controllers[ i ].instance_material;

						node.geometries.push( inst_geom );
						morphController = node.controllers[ i ];
678

T
timk 已提交
679
					}
680

M
Mr.doob 已提交
681
					console.log( 'ColladaLoader: Morph-controller partially supported.' );
682

T
timk 已提交
683 684
				default:
					break;
685

T
timk 已提交
686
			}
687

T
timk 已提交
688
		}
689

T
timk 已提交
690
		// FIXME: multi-material mesh?
T
timk 已提交
691
		// geometries
692 693 694

		for ( i = 0; i < node.geometries.length; i ++ ) {

T
timk 已提交
695 696 697
			var instance_geometry = node.geometries[i];
			var instance_materials = instance_geometry.instance_material;
			var geometry = geometries[instance_geometry.url];
T
timk 已提交
698
			var used_materials = {};
699
			var used_materials_array = [];
T
timk 已提交
700 701
			var num_materials = 0;
			var first_material;
702 703 704

			if ( geometry ) {

705
				if ( !geometry.mesh || !geometry.mesh.primitives )
T
timk 已提交
706
					continue;
707

708
				if ( obj.name.length == 0 ) {
709

T
timk 已提交
710
					obj.name = geometry.id;
711

T
timk 已提交
712
				}
713

T
timk 已提交
714
				// collect used fx for this geometry-instance
715 716 717 718 719

				if ( instance_materials ) {

					for ( j = 0; j < instance_materials.length; j ++ ) {

T
timk 已提交
720 721
						var inst_material = instance_materials[j];
						var effect_id = materials[inst_material.target].instance_effect.url;
T
timk 已提交
722
						var shader = effects[effect_id].shader;
723

T
timk 已提交
724
						shader.material.opacity = !shader.material.opacity ? 1 : shader.material.opacity;
725 726
						used_materials[inst_material.symbol] = num_materials;
						used_materials_array.push(shader.material)
T
timk 已提交
727
						first_material = shader.material;
728 729
						num_materials ++;

T
timk 已提交
730
					}
731

T
timk 已提交
732
				}
733

T
timk 已提交
734
				var mesh;
735
				var material = first_material || new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.FlatShading } );
T
timk 已提交
736
				var geom = geometry.mesh.geometry3js;
737 738 739

				if ( num_materials > 1 ) {

T
timk 已提交
740
					material = new THREE.MeshFaceMaterial();
741 742
					geom.materials = used_materials_array;
					
743 744 745
					for ( j = 0; j < geom.faces.length; j ++ ) {

						var face = geom.faces[ j ];
746
						face.materialIndex = used_materials[ face.daeMaterial ]
747

T
timk 已提交
748
					}
749

T
timk 已提交
750
				}
751 752 753 754 755

				if ( skinController !== undefined) {

					applySkin( geom, skinController );

T
timk 已提交
756
					material.morphTargets = true;
757

T
timk 已提交
758 759
					mesh = new THREE.SkinnedMesh( geom, material );
					mesh.skeleton = skinController.skeleton;
760
					mesh.skinController = controllers[ skinController.url ];
T
timk 已提交
761
					mesh.skinInstanceController = skinController;
T
timk 已提交
762
					mesh.name = 'skin_' + skins.length;
763 764 765 766 767 768 769

					skins.push( mesh );

				} else if ( morphController !== undefined ) {

					createMorph( geom, morphController );

T
timk 已提交
770
					material.morphTargets = true;
771

T
timk 已提交
772 773
					mesh = new THREE.Mesh( geom, material );
					mesh.name = 'morph_' + morphs.length;
774 775 776

					morphs.push( mesh );

T
timk 已提交
777
				} else {
778

T
timk 已提交
779
					mesh = new THREE.Mesh( geom, material );
780
					// mesh.geom.name = geometry.id;
781

T
timk 已提交
782
				}
783

784
				node.geometries.length > 1 ? obj.add( mesh ) : obj = mesh;
785

T
timk 已提交
786
			}
787

T
timk 已提交
788
		}
789

790
		obj.name = node.id || "";
791 792 793 794 795 796
		obj.matrix = node.matrix;
		var props = node.matrix.decompose();
		obj.position = props[ 0 ];
		obj.quaternion = props[ 1 ];
		obj.useQuaternion = true;
		obj.scale = props[ 2 ];
797

798 799
		for ( i = 0; i < node.nodes.length; i ++ ) {

800
			obj.add( createSceneGraph( node.nodes[i], node ) );
801

T
timk 已提交
802
		}
803

T
timk 已提交
804
		return obj;
805 806 807 808 809 810 811 812 813

	};

	function getJointId( skin, id ) {

		for ( var i = 0; i < skin.joints.length; i ++ ) {

			if ( skin.joints[ i ] == id ) {

T
timk 已提交
814
				return i;
815

T
timk 已提交
816
			}
817

T
timk 已提交
818
		}
819 820 821 822 823

	};

	function getLibraryNode( id ) {

824
		return COLLADA.evaluate( './/dae:library_nodes//dae:node[@id=\'' + id + '\']', COLLADA, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null ).iterateNext();
825 826 827 828 829

	};

	function getChannelsForNode (node ) {

T
timk 已提交
830 831 832
		var channels = [];
		var startTime = 1000000;
		var endTime = -1000000;
833 834 835

		for ( var id in animations ) {

T
timk 已提交
836
			var animation = animations[id];
837 838 839

			for ( var i = 0; i < animation.channel.length; i ++ ) {

T
timk 已提交
840 841 842
				var channel = animation.channel[i];
				var sampler = animation.sampler[i];
				var id = channel.target.split('/')[0];
843 844 845

				if ( id == node.id ) {

T
timk 已提交
846 847 848 849 850
					sampler.create();
					channel.sampler = sampler;
					startTime = Math.min(startTime, sampler.startTime);
					endTime = Math.max(endTime, sampler.endTime);
					channels.push(channel);
851

T
timk 已提交
852
				}
853

T
timk 已提交
854
			}
855

T
timk 已提交
856
		}
857 858 859

		if ( channels.length ) {

T
timk 已提交
860
			node.startTime = startTime;
861 862
			node.endTime = endTime;

T
timk 已提交
863
		}
864

T
timk 已提交
865
		return channels;
866 867 868 869 870

	};

	function calcFrameDuration( node ) {

T
timk 已提交
871
		var minT = 10000000;
872

873
		for ( var i = 0; i < node.channels.length; i ++ ) {
874

T
timk 已提交
875
			var sampler = node.channels[i].sampler;
876 877 878

			for (var j = 0; j < sampler.input.length - 1; j ++ ) {

879 880 881
				var t0 = sampler.input[ j ];
				var t1 = sampler.input[ j + 1 ];
				minT = Math.min( minT, t1 - t0 );
882

T
timk 已提交
883 884
			}
		}
885

T
timk 已提交
886
		return minT;
887 888 889 890 891

	};

	function calcMatrixAt( node, t ) {

T
timk 已提交
892
		var animated = {};
893

T
timk 已提交
894
		var i, j;
895 896 897 898

		for ( i = 0; i < node.channels.length; i ++ ) {

			var channel = node.channels[ i ];
T
timk 已提交
899
			animated[ channel.sid ] = channel;
900

T
timk 已提交
901
		}
902

T
timk 已提交
903
		var matrix = new THREE.Matrix4();
904 905 906

		for ( i = 0; i < node.transforms.length; i ++ ) {

T
timk 已提交
907 908
			var transform = node.transforms[i];
			var channel = animated[transform.sid];
909 910 911

			if ( channel !== undefined ) {

T
timk 已提交
912 913
				var sampler = channel.sampler;
				var value;
914 915 916 917 918

				for ( var j = 0; j < sampler.input.length - 1; j ++ ) {

					if ( sampler.input[j+1] > t ) {

T
timk 已提交
919 920 921
						value = sampler.output[j];
						//console.log(value.flatten)
						break;
922

T
timk 已提交
923
					}
924

T
timk 已提交
925
				}
926 927 928 929 930 931 932

				if ( value !== undefined ) {

					if ( value instanceof THREE.Matrix4 ) {

						matrix = matrix.multiply( matrix, value );

T
timk 已提交
933
					} else {
934

T
timk 已提交
935
						// FIXME: handle other types
936 937 938

						matrix = matrix.multiply( matrix, transform.matrix );

T
timk 已提交
939
					}
940

T
timk 已提交
941
				} else {
942 943 944

					matrix = matrix.multiply( matrix, transform.matrix );

T
timk 已提交
945
				}
946

T
timk 已提交
947
			} else {
948 949 950

				matrix = matrix.multiply( matrix, transform.matrix );

T
timk 已提交
951
			}
952

T
timk 已提交
953
		}
954

T
timk 已提交
955
		return matrix;
956 957 958 959 960 961 962

	};

	function bakeAnimations ( node ) {

		if ( node.channels && node.channels.length ) {

963 964
			var keys = [],
				sids = [];
965

966
			for ( var i = 0, il = node.channels.length; i < il; i++ ) {
967

968 969 970 971 972 973
				var channel = node.channels[i],
					fullSid = channel.fullSid,
					member = getConvertedMember( channel.member ),
					sampler = channel.sampler,
					input = sampler.input,
					transform = node.getTransformBySid( channel.sid );
974

975
				if ( transform ) {
976

977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
					if ( sids.indexOf( fullSid ) === -1 ) {

						sids.push( fullSid );

					}

					for ( var j = 0, jl = input.length; j < jl; j++ ) {

						var time = input[j],
							data = sampler.getData( transform.type, j ),
							key = findKey( keys, time );

						if ( !key ) {

							key = new Key( time );
							var timeNdx = findTimeNdx( keys, time );
							keys.splice( timeNdx == -1 ? keys.length : timeNdx, 0, key );

						}

						key.addTarget( fullSid, transform, member, data );

					}

				} else {

					console.log( 'Could not find transform "' + channel.sid + '" in node ' + node.id );

				}

			}

			// post process
			for ( var i = 0; i < sids.length; i++ ) {

				var sid = sids[ i ];

				for ( var j = 0; j < keys.length; j++ ) {

					var key = keys[ j ];

					if ( !key.hasTarget( sid ) ) {

						interpolateKeys( keys, key, j, sid );

					}

				}
1025

T
timk 已提交
1026
			}
1027

T
timk 已提交
1028
			node.keys = keys;
1029
			node.sids = sids;
1030

T
timk 已提交
1031
		}
1032 1033 1034

	};

1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
	function findKey ( keys, time) {

		var retVal = null;

		for ( var i = 0, il = keys.length; i < il && retVal == null; i++ ) {

			var key = keys[i];

			if ( key.time === time ) {

				retVal = key;

			} else if ( key.time > time ) {

				break;

			}

		}

		return retVal;

	};

	function findTimeNdx ( keys, time) {

		var ndx = -1;

		for ( var i = 0, il = keys.length; i < il && ndx == -1; i++ ) {

			var key = keys[i];

			if ( key.time >= time ) {

				ndx = i;

			}

		}

		return ndx;

	};

	function interpolateKeys ( keys, key, ndx, fullSid ) {

		var prevKey = getPrevKeyWith( keys, fullSid, ndx ? ndx-1 : 0 ),
			nextKey = getNextKeyWith( keys, fullSid, ndx+1 );

		if ( prevKey && nextKey ) {

			var scale = (key.time - prevKey.time) / (nextKey.time - prevKey.time),
				prevTarget = prevKey.getTarget( fullSid ),
				nextData = nextKey.getTarget( fullSid ).data,
				prevData = prevTarget.data,
				data;

			if ( prevData.length ) {

				data = [];

				for ( var i = 0; i < prevData.length; ++i ) {

					data[ i ] = prevData[ i ] + ( nextData[ i ] - prevData[ i ] ) * scale;

				}

			} else {

				data = prevData + ( nextData - prevData ) * scale;

			}

			key.addTarget( fullSid, prevTarget.transform, prevTarget.member, data );

		}

	};

	// Get next key with given sid

	function getNextKeyWith( keys, fullSid, ndx ) {

		for ( ; ndx < keys.length; ndx++ ) {

			var key = keys[ ndx ];

			if ( key.hasTarget( fullSid ) ) {

				return key;

			}

		}

		return null;

	};

	// Get previous key with given sid

	function getPrevKeyWith( keys, fullSid, ndx ) {

		ndx = ndx >= 0 ? ndx : ndx + keys.length;

		for ( ; ndx >= 0; ndx-- ) {

			var key = keys[ ndx ];

			if ( key.hasTarget( fullSid ) ) {

				return key;

			}

		}

		return null;

	};

T
timk 已提交
1156
	function _Image() {
1157

T
timk 已提交
1158 1159
		this.id = "";
		this.init_from = "";
1160 1161 1162

	};

T
timk 已提交
1163
	_Image.prototype.parse = function(element) {
1164

T
timk 已提交
1165
		this.id = element.getAttribute('id');
1166 1167 1168 1169 1170 1171 1172

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

			var child = element.childNodes[ i ];

			if ( child.nodeName == 'init_from' ) {

T
timk 已提交
1173
				this.init_from = child.textContent;
1174

T
timk 已提交
1175
			}
1176

T
timk 已提交
1177
		}
1178

T
timk 已提交
1179
		return this;
1180 1181 1182

	};

T
timk 已提交
1183
	function Controller() {
1184

T
timk 已提交
1185 1186 1187 1188 1189
		this.id = "";
		this.name = "";
		this.type = "";
		this.skin = null;
		this.morph = null;
1190 1191 1192 1193 1194

	};

	Controller.prototype.parse = function( element ) {

T
timk 已提交
1195 1196 1197
		this.id = element.getAttribute('id');
		this.name = element.getAttribute('name');
		this.type = "none";
1198 1199 1200 1201 1202 1203 1204

		for ( var i = 0; i < element.childNodes.length; i++ ) {

			var child = element.childNodes[ i ];

			switch ( child.nodeName ) {

T
timk 已提交
1205
				case 'skin':
1206

T
timk 已提交
1207 1208 1209
					this.skin = (new Skin()).parse(child);
					this.type = child.nodeName;
					break;
1210

T
timk 已提交
1211
				case 'morph':
1212

T
timk 已提交
1213 1214 1215
					this.morph = (new Morph()).parse(child);
					this.type = child.nodeName;
					break;
1216

T
timk 已提交
1217 1218
				default:
					break;
1219

T
timk 已提交
1220 1221
			}
		}
1222

T
timk 已提交
1223
		return this;
1224 1225 1226

	};

T
timk 已提交
1227
	function Morph() {
1228

M
Mr.doob 已提交
1229 1230 1231 1232
		this.method = null;
		this.source = null;
		this.targets = null;
		this.weights = null;
1233 1234 1235 1236 1237

	};

	Morph.prototype.parse = function( element ) {

T
timk 已提交
1238 1239 1240
		var sources = {};
		var inputs = [];
		var i;
1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251

		this.method = element.getAttribute( 'method' );
		this.source = element.getAttribute( 'source' ).replace( /^#/, '' );

		for ( i = 0; i < element.childNodes.length; i ++ ) {

			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
1252
				case 'source':
1253 1254 1255

					var source = ( new Source() ).parse( child );
					sources[ source.id ] = source;
T
timk 已提交
1256
					break;
1257

T
timk 已提交
1258
				case 'targets':
1259 1260

					inputs = this.parseInputs( child );
T
timk 已提交
1261
					break;
1262

T
timk 已提交
1263
				default:
1264 1265

					console.log( child.nodeName );
T
timk 已提交
1266
					break;
1267

T
timk 已提交
1268
			}
1269

T
timk 已提交
1270
		}
1271 1272 1273 1274 1275 1276 1277 1278

		for ( i = 0; i < inputs.length; i ++ ) {

			var input = inputs[ i ];
			var source = sources[ input.source ];

			switch ( input.semantic ) {

T
timk 已提交
1279
				case 'MORPH_TARGET':
1280

T
timk 已提交
1281 1282
					this.targets = source.read();
					break;
1283

T
timk 已提交
1284
				case 'MORPH_WEIGHT':
1285

T
timk 已提交
1286 1287
					this.weights = source.read();
					break;
1288

T
timk 已提交
1289 1290
				default:
					break;
1291

T
timk 已提交
1292 1293
			}
		}
1294

T
timk 已提交
1295
		return this;
1296 1297 1298

	};

T
timk 已提交
1299
	Morph.prototype.parseInputs = function(element) {
1300

T
timk 已提交
1301
		var inputs = [];
1302 1303 1304

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

T
timk 已提交
1305
			var child = element.childNodes[i];
1306 1307 1308 1309
			if ( child.nodeType != 1) continue;

			switch ( child.nodeName ) {

T
timk 已提交
1310
				case 'input':
1311 1312

					inputs.push( (new Input()).parse(child) );
T
timk 已提交
1313
					break;
1314

T
timk 已提交
1315 1316 1317 1318
				default:
					break;
			}
		}
1319

T
timk 已提交
1320
		return inputs;
1321 1322 1323

	};

T
timk 已提交
1324
	function Skin() {
1325

T
timk 已提交
1326
		this.source = "";
T
timk 已提交
1327 1328 1329 1330
		this.bindShapeMatrix = null;
		this.invBindMatrices = [];
		this.joints = [];
		this.weights = [];
1331 1332 1333 1334 1335

	};

	Skin.prototype.parse = function( element ) {

T
timk 已提交
1336 1337
		var sources = {};
		var joints, weights;
1338 1339

		this.source = element.getAttribute( 'source' ).replace( /^#/, '' );
T
timk 已提交
1340 1341 1342
		this.invBindMatrices = [];
		this.joints = [];
		this.weights = [];
1343 1344 1345

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

T
timk 已提交
1346
			var child = element.childNodes[i];
1347 1348 1349 1350
			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
1351
				case 'bind_shape_matrix':
1352

T
timk 已提交
1353
					var f = _floats(child.textContent);
1354
					this.bindShapeMatrix = getConvertedMat4( f );
T
timk 已提交
1355
					break;
1356

T
timk 已提交
1357
				case 'source':
1358

T
timk 已提交
1359
					var src = new Source().parse(child);
1360
					sources[ src.id ] = src;
T
timk 已提交
1361
					break;
1362

T
timk 已提交
1363
				case 'joints':
1364

T
timk 已提交
1365 1366
					joints = child;
					break;
1367

T
timk 已提交
1368
				case 'vertex_weights':
1369

T
timk 已提交
1370 1371
					weights = child;
					break;
1372

T
timk 已提交
1373
				default:
1374 1375

					console.log( child.nodeName );
T
timk 已提交
1376
					break;
1377

T
timk 已提交
1378 1379
			}
		}
1380 1381 1382 1383

		this.parseJoints( joints, sources );
		this.parseWeights( weights, sources );

T
timk 已提交
1384
		return this;
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396

	};

	Skin.prototype.parseJoints = function ( element, sources ) {

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
1397
				case 'input':
1398 1399 1400 1401 1402 1403

					var input = ( new Input() ).parse( child );
					var source = sources[ input.source ];

					if ( input.semantic == 'JOINT' ) {

T
timk 已提交
1404
						this.joints = source.read();
1405 1406 1407

					} else if ( input.semantic == 'INV_BIND_MATRIX' ) {

T
timk 已提交
1408
						this.invBindMatrices = source.read();
1409

T
timk 已提交
1410
					}
1411

T
timk 已提交
1412
					break;
1413

T
timk 已提交
1414 1415 1416
				default:
					break;
			}
1417

T
timk 已提交
1418
		}
1419 1420 1421 1422 1423

	};

	Skin.prototype.parseWeights = function ( element, sources ) {

T
timk 已提交
1424
		var v, vcount, inputs = [];
1425 1426 1427 1428 1429 1430 1431 1432

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
1433
				case 'input':
1434

1435
					inputs.push( ( new Input() ).parse( child ) );
T
timk 已提交
1436
					break;
1437

T
timk 已提交
1438
				case 'v':
1439

1440
					v = _ints( child.textContent );
T
timk 已提交
1441
					break;
1442

T
timk 已提交
1443
				case 'vcount':
1444

1445
					vcount = _ints( child.textContent );
T
timk 已提交
1446
					break;
1447

T
timk 已提交
1448 1449
				default:
					break;
1450

T
timk 已提交
1451
			}
1452

T
timk 已提交
1453
		}
1454

T
timk 已提交
1455
		var index = 0;
1456 1457 1458

		for ( var i = 0; i < vcount.length; i ++ ) {

T
timk 已提交
1459 1460
			var numBones = vcount[i];
			var vertex_weights = [];
1461 1462 1463

			for ( var j = 0; j < numBones; j++ ) {

T
timk 已提交
1464
				var influence = {};
1465 1466 1467 1468 1469 1470 1471 1472

				for ( var k = 0; k < inputs.length; k ++ ) {

					var input = inputs[ k ];
					var value = v[ index + input.offset ];

					switch ( input.semantic ) {

T
timk 已提交
1473
						case 'JOINT':
1474

T
timk 已提交
1475
							influence.joint = value;//this.joints[value];
T
timk 已提交
1476
							break;
1477

T
timk 已提交
1478
						case 'WEIGHT':
1479 1480

							influence.weight = sources[ input.source ].data[ value ];
T
timk 已提交
1481
							break;
1482

T
timk 已提交
1483 1484
						default:
							break;
1485

T
timk 已提交
1486
					}
1487

T
timk 已提交
1488
				}
1489 1490

				vertex_weights.push( influence );
T
timk 已提交
1491 1492
				index += inputs.length;
			}
1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507

			for ( var j = 0; j < vertex_weights.length; j ++ ) {

				vertex_weights[ j ].index = i;

			}

			this.weights.push( vertex_weights );

		}

	};

	function VisualScene () {

T
timk 已提交
1508 1509 1510 1511
		this.id = "";
		this.name = "";
		this.nodes = [];
		this.scene = new THREE.Object3D();
1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522

	};

	VisualScene.prototype.getChildById = function( id, recursive ) {

		for ( var i = 0; i < this.nodes.length; i ++ ) {

			var node = this.nodes[ i ].getChildById( id, recursive );

			if ( node ) {

T
timk 已提交
1523
				return node;
1524

T
timk 已提交
1525
			}
1526

T
timk 已提交
1527
		}
1528

T
timk 已提交
1529
		return null;
1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540

	};

	VisualScene.prototype.getChildBySid = function( sid, recursive ) {

		for ( var i = 0; i < this.nodes.length; i ++ ) {

			var node = this.nodes[ i ].getChildBySid( sid, recursive );

			if ( node ) {

T
timk 已提交
1541
				return node;
1542

T
timk 已提交
1543
			}
1544

T
timk 已提交
1545
		}
1546

T
timk 已提交
1547
		return null;
1548 1549 1550 1551 1552 1553 1554

	};

	VisualScene.prototype.parse = function( element ) {

		this.id = element.getAttribute( 'id' );
		this.name = element.getAttribute( 'name' );
T
timk 已提交
1555
		this.nodes = [];
1556 1557 1558 1559 1560 1561 1562 1563

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
1564
				case 'node':
1565 1566

					this.nodes.push( ( new Node() ).parse( child ) );
T
timk 已提交
1567
					break;
1568

T
timk 已提交
1569 1570
				default:
					break;
1571

T
timk 已提交
1572
			}
1573

T
timk 已提交
1574
		}
1575

T
timk 已提交
1576
		return this;
1577 1578 1579

	};

T
timk 已提交
1580
	function Node() {
1581

T
timk 已提交
1582 1583 1584 1585 1586 1587 1588
		this.id = "";
		this.name = "";
		this.sid = "";
		this.nodes = [];
		this.controllers = [];
		this.transforms = [];
		this.geometries = [];
T
timk 已提交
1589
		this.channels = [];
T
timk 已提交
1590
		this.matrix = new THREE.Matrix4();
1591 1592 1593 1594 1595 1596 1597

	};

	Node.prototype.getChannelForTransform = function( transformSid ) {

		for ( var i = 0; i < this.channels.length; i ++ ) {

T
timk 已提交
1598 1599 1600 1601 1602 1603 1604 1605
			var channel = this.channels[i];
			var parts = channel.target.split('/');
			var id = parts.shift();
			var sid = parts.shift();
			var dotSyntax = (sid.indexOf(".") >= 0);
			var arrSyntax = (sid.indexOf("(") >= 0);
			var arrIndices;
			var member;
1606 1607 1608

			if ( dotSyntax ) {

T
timk 已提交
1609 1610 1611
				parts = sid.split(".");
				sid = parts.shift();
				member = parts.shift();
1612 1613 1614

			} else if ( arrSyntax ) {

T
timk 已提交
1615 1616
				arrIndices = sid.split("(");
				sid = arrIndices.shift();
1617 1618 1619 1620 1621

				for ( var j = 0; j < arrIndices.length; j ++ ) {

					arrIndices[ j ] = parseInt( arrIndices[ j ].replace( /\)/, '' ) );

T
timk 已提交
1622
				}
1623

T
timk 已提交
1624
			}
1625

1626
			if ( sid == transformSid ) {
1627

1628
				channel.info = { sid: sid, dotSyntax: dotSyntax, arrSyntax: arrSyntax, arrIndices: arrIndices };
T
timk 已提交
1629
				return channel;
1630

T
timk 已提交
1631
			}
1632

T
timk 已提交
1633
		}
1634

T
timk 已提交
1635
		return null;
1636 1637 1638 1639 1640 1641 1642

	};

	Node.prototype.getChildById = function ( id, recursive ) {

		if ( this.id == id ) {

T
timk 已提交
1643
			return this;
1644

T
timk 已提交
1645
		}
1646 1647 1648 1649 1650 1651 1652 1653 1654

		if ( recursive ) {

			for ( var i = 0; i < this.nodes.length; i ++ ) {

				var n = this.nodes[ i ].getChildById( id, recursive );

				if ( n ) {

T
timk 已提交
1655
					return n;
1656

T
timk 已提交
1657
				}
1658

T
timk 已提交
1659
			}
1660

T
timk 已提交
1661
		}
1662

T
timk 已提交
1663
		return null;
1664 1665 1666 1667 1668 1669 1670

	};

	Node.prototype.getChildBySid = function ( sid, recursive ) {

		if ( this.sid == sid ) {

T
timk 已提交
1671
			return this;
1672

T
timk 已提交
1673
		}
1674 1675 1676 1677 1678 1679 1680 1681 1682

		if ( recursive ) {

			for ( var i = 0; i < this.nodes.length; i ++ ) {

				var n = this.nodes[ i ].getChildBySid( sid, recursive );

				if ( n ) {

T
timk 已提交
1683
					return n;
1684

T
timk 已提交
1685
				}
1686

T
timk 已提交
1687 1688
			}
		}
1689

T
timk 已提交
1690
		return null;
1691 1692 1693 1694 1695 1696 1697 1698 1699

	};

	Node.prototype.getTransformBySid = function ( sid ) {

		for ( var i = 0; i < this.transforms.length; i ++ ) {

			if ( this.transforms[ i ].sid == sid ) return this.transforms[ i ];

T
timk 已提交
1700
		}
1701

T
timk 已提交
1702
		return null;
1703 1704 1705 1706 1707

	};

	Node.prototype.parse = function( element ) {

T
timk 已提交
1708
		var url;
1709

T
timk 已提交
1710 1711 1712 1713
		this.id = element.getAttribute('id');
		this.sid = element.getAttribute('sid');
		this.name = element.getAttribute('name');
		this.type = element.getAttribute('type');
1714

T
timk 已提交
1715
		this.type = this.type == 'JOINT' ? this.type : 'NODE';
1716

T
timk 已提交
1717 1718 1719 1720 1721 1722
		this.nodes = [];
		this.transforms = [];
		this.geometries = [];
		this.controllers = [];
		this.matrix = new THREE.Matrix4();

1723 1724 1725
		for ( var i = 0; i < element.childNodes.length; i ++ ) {

			var child = element.childNodes[ i ];
1726
			if ( child.nodeType != 1 ) continue;
1727 1728 1729

			switch ( child.nodeName ) {

T
timk 已提交
1730
				case 'node':
1731 1732

					this.nodes.push( ( new Node() ).parse( child ) );
T
timk 已提交
1733
					break;
1734

T
timk 已提交
1735
				case 'instance_camera':
1736

T
timk 已提交
1737
					break;
1738

T
timk 已提交
1739
				case 'instance_controller':
1740 1741

					this.controllers.push( ( new InstanceController() ).parse( child ) );
T
timk 已提交
1742
					break;
1743

T
timk 已提交
1744
				case 'instance_geometry':
1745 1746

					this.geometries.push( ( new InstanceGeometry() ).parse( child ) );
T
timk 已提交
1747
					break;
1748

T
timk 已提交
1749
				case 'instance_light':
1750

T
timk 已提交
1751
					break;
1752

T
timk 已提交
1753
				case 'instance_node':
1754 1755 1756 1757 1758 1759 1760 1761

					url = child.getAttribute( 'url' ).replace( /^#/, '' );
					var iNode = getLibraryNode( url );

					if ( iNode ) {

						this.nodes.push( ( new Node() ).parse( iNode )) ;

T
timk 已提交
1762
					}
1763

T
timk 已提交
1764
					break;
1765

T
timk 已提交
1766 1767 1768 1769 1770 1771
				case 'rotate':
				case 'translate':
				case 'scale':
				case 'matrix':
				case 'lookat':
				case 'skew':
1772 1773

					this.transforms.push( ( new Transform() ).parse( child ) );
T
timk 已提交
1774
					break;
1775

T
timk 已提交
1776 1777
				case 'extra':
					break;
1778

T
timk 已提交
1779
				default:
1780 1781

					console.log( child.nodeName );
T
timk 已提交
1782
					break;
1783

T
timk 已提交
1784
			}
1785

T
timk 已提交
1786
		}
1787 1788 1789 1790

		this.channels = getChannelsForNode( this );
		bakeAnimations( this );

T
timk 已提交
1791
		this.updateMatrix();
1792

T
timk 已提交
1793
		return this;
1794 1795 1796 1797 1798

	};

	Node.prototype.updateMatrix = function () {

T
timk 已提交
1799
		this.matrix.identity();
1800 1801 1802

		for ( var i = 0; i < this.transforms.length; i ++ ) {

1803
			this.transforms[ i ].apply( this.matrix );
1804

T
timk 已提交
1805
		}
1806 1807 1808 1809 1810

	};

	function Transform () {

T
timk 已提交
1811 1812 1813
		this.sid = "";
		this.type = "";
		this.data = [];
1814
		this.obj = null;
1815 1816 1817 1818 1819 1820

	};

	Transform.prototype.parse = function ( element ) {

		this.sid = element.getAttribute( 'sid' );
T
timk 已提交
1821
		this.type = element.nodeName;
1822
		this.data = _floats( element.textContent );
1823
		this.convert();
1824

T
timk 已提交
1825
		return this;
1826 1827 1828

	};

1829
	Transform.prototype.convert = function () {
1830

1831
		switch ( this.type ) {
1832

1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862
			case 'matrix':

				this.obj = getConvertedMat4( this.data );
				break;

			case 'rotate':

				this.angle = this.data[3] * TO_RADIANS;

			case 'translate':

				fixCoords( this.data, -1 );
				this.obj = new THREE.Vector3( this.data[ 0 ], this.data[ 1 ], this.data[ 2 ] );
				break;

			case 'scale':

				fixCoords( this.data, 1 );
				this.obj = new THREE.Vector3( this.data[ 0 ], this.data[ 1 ], this.data[ 2 ] );
				break;

			default:
				console.log( 'Can not convert Transform of type ' + this.type );
				break;

		}

	};

	Transform.prototype.apply = function ( matrix ) {
1863 1864 1865

		switch ( this.type ) {

T
timk 已提交
1866
			case 'matrix':
1867

1868
				matrix.multiplySelf( this.obj );
T
timk 已提交
1869
				break;
1870

T
timk 已提交
1871
			case 'translate':
1872

1873
				matrix.translate( this.obj );
T
timk 已提交
1874
				break;
1875

T
timk 已提交
1876
			case 'rotate':
1877

1878
				matrix.rotateByAxis( this.obj, this.angle );
T
timk 已提交
1879
				break;
1880

T
timk 已提交
1881
			case 'scale':
1882

1883
				matrix.scale( this.obj );
T
timk 已提交
1884
				break;
1885

1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896
		}

	};

	Transform.prototype.update = function ( data, member ) {

		switch ( this.type ) {

			case 'matrix':

				console.log( 'Currently not handling matrix transform updates' );
T
timk 已提交
1897
				break;
1898

1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942
			case 'translate':
			case 'scale':

				switch ( member ) {

					case 'X':

						this.obj.x = data;
						break;

					case 'Y':

						this.obj.y = data;
						break;

					case 'Z':

						this.obj.z = data;
						break;

					default:

						this.obj.x = data[ 0 ];
						this.obj.y = data[ 1 ];
						this.obj.z = data[ 2 ];
						break;

				}

				break;

			case 'rotate':

				switch ( member ) {

					case 'X':

						this.obj.x = data;
						break;

					case 'Y':

						this.obj.y = data;
						break;
1943

1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965
					case 'Z':

						this.obj.z = data;
						break;

					case 'ANGLE':

						this.angle = data * TO_RADIANS;
						break;

					default:

						this.obj.x = data[ 0 ];
						this.obj.y = data[ 1 ];
						this.obj.z = data[ 2 ];
						this.angle = data[ 3 ] * TO_RADIANS;
						break;

				}
				break;

		}
1966 1967

	};
T
timk 已提交
1968 1969

	function InstanceController() {
1970

T
timk 已提交
1971 1972 1973
		this.url = "";
		this.skeleton = [];
		this.instance_material = [];
1974 1975 1976 1977 1978

	};

	InstanceController.prototype.parse = function ( element ) {

T
timk 已提交
1979 1980 1981
		this.url = element.getAttribute('url').replace(/^#/, '');
		this.skeleton = [];
		this.instance_material = [];
1982 1983 1984

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

T
timk 已提交
1985 1986
			var child = element.childNodes[i];
			if (child.nodeType != 1) continue;
1987 1988 1989

			switch ( child.nodeName ) {

T
timk 已提交
1990
				case 'skeleton':
1991 1992

					this.skeleton.push( child.textContent.replace(/^#/, '') );
T
timk 已提交
1993
					break;
1994

T
timk 已提交
1995
				case 'bind_material':
1996

1997
					var instances = COLLADA.evaluate( './/dae:instance_material', child, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );
1998 1999 2000

					if ( instances ) {

T
timk 已提交
2001
						var instance = instances.iterateNext();
2002 2003 2004

						while ( instance ) {

T
timk 已提交
2005
							this.instance_material.push((new InstanceMaterial()).parse(instance));
2006 2007
							instance = instances.iterateNext();

T
timk 已提交
2008
						}
2009

T
timk 已提交
2010
					}
2011

T
timk 已提交
2012
					break;
2013

T
timk 已提交
2014 2015
				case 'extra':
					break;
2016

T
timk 已提交
2017 2018
				default:
					break;
2019

T
timk 已提交
2020 2021
			}
		}
2022

T
timk 已提交
2023
		return this;
2024 2025 2026 2027 2028

	};

	function InstanceMaterial () {

T
timk 已提交
2029 2030
		this.symbol = "";
		this.target = "";
2031 2032 2033 2034 2035

	};

	InstanceMaterial.prototype.parse = function ( element ) {

T
timk 已提交
2036 2037 2038
		this.symbol = element.getAttribute('symbol');
		this.target = element.getAttribute('target').replace(/^#/, '');
		return this;
2039 2040 2041

	};

T
timk 已提交
2042
	function InstanceGeometry() {
2043

T
timk 已提交
2044 2045
		this.url = "";
		this.instance_material = [];
2046 2047 2048

	};

2049
	InstanceGeometry.prototype.parse = function ( element ) {
2050

T
timk 已提交
2051 2052
		this.url = element.getAttribute('url').replace(/^#/, '');
		this.instance_material = [];
2053 2054 2055

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

T
timk 已提交
2056
			var child = element.childNodes[i];
2057
			if ( child.nodeType != 1 ) continue;
2058 2059 2060

			if ( child.nodeName == 'bind_material' ) {

2061
				var instances = COLLADA.evaluate( './/dae:instance_material', child, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );
2062

2063
				if ( instances ) {
2064

T
timk 已提交
2065
					var instance = instances.iterateNext();
2066 2067 2068 2069 2070 2071

					while ( instance ) {

						this.instance_material.push( (new InstanceMaterial()).parse(instance) );
						instance = instances.iterateNext();

T
timk 已提交
2072
					}
2073

T
timk 已提交
2074
				}
2075

T
timk 已提交
2076
				break;
2077

T
timk 已提交
2078
			}
2079

T
timk 已提交
2080
		}
2081

T
timk 已提交
2082
		return this;
2083 2084 2085

	};

T
timk 已提交
2086
	function Geometry() {
2087

T
timk 已提交
2088 2089
		this.id = "";
		this.mesh = null;
2090 2091 2092 2093 2094

	};

	Geometry.prototype.parse = function ( element ) {

T
timk 已提交
2095
		this.id = element.getAttribute('id');
2096 2097 2098

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

T
timk 已提交
2099
			var child = element.childNodes[i];
2100 2101 2102

			switch ( child.nodeName ) {

T
timk 已提交
2103
				case 'mesh':
2104

T
timk 已提交
2105 2106
					this.mesh = (new Mesh(this)).parse(child);
					break;
2107

2108
				case 'extra':
2109

2110 2111 2112
					// console.log( child );
					break;

T
timk 已提交
2113 2114 2115 2116
				default:
					break;
			}
		}
2117

T
timk 已提交
2118
		return this;
2119 2120 2121 2122 2123

	};

	function Mesh( geometry ) {

T
timk 已提交
2124 2125 2126
		this.geometry = geometry.id;
		this.primitives = [];
		this.vertices = null;
M
Mr.doob 已提交
2127
		this.geometry3js = null;
2128 2129 2130 2131 2132

	};

	Mesh.prototype.parse = function( element ) {

T
timk 已提交
2133
		this.primitives = [];
2134

T
timk 已提交
2135
		var i, j;
2136 2137 2138

		for ( i = 0; i < element.childNodes.length; i ++ ) {

2139
			var child = element.childNodes[ i ];
2140

2141
			switch ( child.nodeName ) {
2142

T
timk 已提交
2143
				case 'source':
2144

2145
					_source( child );
T
timk 已提交
2146
					break;
2147

T
timk 已提交
2148
				case 'vertices':
2149

2150
					this.vertices = ( new Vertices() ).parse( child );
T
timk 已提交
2151
					break;
2152

T
timk 已提交
2153
				case 'triangles':
2154

2155
					this.primitives.push( ( new Triangles().parse( child ) ) );
T
timk 已提交
2156
					break;
2157

T
timk 已提交
2158
				case 'polygons':
2159

2160
					console.warn( 'polygon holes not yet supported!' );
2161

T
timk 已提交
2162
				case 'polylist':
2163

2164
					this.primitives.push( ( new Polylist().parse( child ) ) );
T
timk 已提交
2165
					break;
2166

T
timk 已提交
2167 2168
				default:
					break;
2169

T
timk 已提交
2170
			}
2171

T
timk 已提交
2172
		}
2173

T
timk 已提交
2174
		this.geometry3js = new THREE.Geometry();
2175 2176 2177

		var vertexData = sources[ this.vertices.input['POSITION'].source ].data;

2178
		for ( i = 0; i < vertexData.length; i += 3 ) {
2179

2180
			var v = new THREE.Vertex( getConvertedVec3( vertexData, i ) );
2181
			this.geometry3js.vertices.push( v );
2182

T
timk 已提交
2183
		}
T
timk 已提交
2184

2185 2186
		for ( i = 0; i < this.primitives.length; i ++ ) {

2187
			var primitive = this.primitives[ i ];
2188
			primitive.setVertices( this.vertices );
2189
			this.handlePrimitive( primitive, this.geometry3js );
2190

T
timk 已提交
2191
		}
2192

T
timk 已提交
2193 2194 2195 2196
		this.geometry3js.computeCentroids();
		this.geometry3js.computeFaceNormals();
		this.geometry3js.computeVertexNormals();
		this.geometry3js.computeBoundingBox();
2197

T
timk 已提交
2198
		return this;
2199 2200 2201

	};

2202
	Mesh.prototype.handlePrimitive = function( primitive, geom ) {
2203

T
timk 已提交
2204 2205
		var i = 0, j, k, p = primitive.p, inputs = primitive.inputs;
		var input, index, idx32;
2206
		var source, numParams;
T
timk 已提交
2207
		var vcIndex = 0, vcount = 3;
T
timk 已提交
2208
		var texture_sets = [];
2209 2210 2211

		for ( j = 0; j < inputs.length; j ++ ) {

2212
			input = inputs[ j ];
2213

2214
			switch ( input.semantic ) {
2215

2216 2217 2218
				case 'TEXCOORD':
					texture_sets.push( input.set );
					break;
2219

T
timk 已提交
2220
			}
2221

T
timk 已提交
2222
		}
2223 2224 2225

		while ( i < p.length ) {

T
timk 已提交
2226 2227 2228
			var vs = [];
			var ns = [];
			var ts = {};
2229
			var cs = [];
2230 2231 2232 2233 2234

			if ( primitive.vcount ) {

				vcount = primitive.vcount[ vcIndex ++ ];

T
timk 已提交
2235
			}
2236 2237 2238 2239 2240

			for ( j = 0; j < vcount; j ++ ) {

				for ( k = 0; k < inputs.length; k ++ ) {

2241 2242 2243 2244
					input = inputs[ k ];
					source = sources[ input.source ];

					index = p[ i + ( j * inputs.length ) + input.offset ];
T
timk 已提交
2245 2246
					numParams = source.accessor.params.length;
					idx32 = index * numParams;
2247

2248
					switch ( input.semantic ) {
2249

T
timk 已提交
2250
						case 'VERTEX':
2251

2252
							vs.push( index );
2253

T
timk 已提交
2254
							break;
2255

T
timk 已提交
2256
						case 'NORMAL':
2257

2258
							ns.push( getConvertedVec3( source.data, idx32 ) );
2259

T
timk 已提交
2260
							break;
2261

T
timk 已提交
2262
						case 'TEXCOORD':
2263

2264
							if ( ts[ input.set ] === undefined ) ts[ input.set ] = [];
2265 2266
							// invert the V
							ts[ input.set ].push( new THREE.UV( source.data[ idx32 ], 1.0 - source.data[ idx32 + 1 ] ) );
2267

T
timk 已提交
2268
							break;
2269

2270
						case 'COLOR':
2271 2272

							cs.push( new THREE.Color().setRGB( source.data[ idx32 ], source.data[ idx32 + 1 ], source.data[ idx32 + 2 ] ) );
2273 2274 2275

							break;

T
timk 已提交
2276 2277
						default:
							break;
2278

T
timk 已提交
2279
					}
2280

T
timk 已提交
2281
				}
2282

T
timk 已提交
2283
			}
2284

2285

2286 2287 2288 2289 2290 2291 2292 2293 2294
			var face = null, faces = [], uv, uvArr;

			if ( vcount === 3 ) {

				faces.push( new THREE.Face3( vs[0], vs[1], vs[2], [ ns[0], ns[1], ns[2] ], cs.length ? cs : new THREE.Color() ) );

			} else if ( vcount === 4 ) {

				faces.push( new THREE.Face4( vs[0], vs[1], vs[2], vs[3], [ ns[0], ns[1], ns[2], ns[3] ], cs.length ? cs : new THREE.Color() ) );
2295

2296
			} else if ( vcount > 4 && options.subdivideFaces ) {
2297

2298 2299
				var clr = cs.length ? cs : new THREE.Color(),
					vec1, vec2, vec3, v1, v2, norm;
2300

2301 2302
				// subdivide into multiple Face3s
				for ( k = 1; k < vcount-1; ) {
2303

2304 2305 2306 2307
					// FIXME: normals don't seem to be quite right
					faces.push( new THREE.Face3( vs[0], vs[k], vs[k+1], [ ns[0], ns[k++], ns[k] ],  clr ) );

				}
2308 2309

			}
2310

2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323
			if ( faces.length ) {

				for (var ndx = 0, len = faces.length; ndx < len; ndx++) {

					face = faces[ndx];
					face.daeMaterial = primitive.material;
					geom.faces.push( face );

					for ( k = 0; k < texture_sets.length; k++ ) {

						uv = ts[ texture_sets[k] ];

						if ( vcount > 4 ) {
2324

2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336
							// Grab the right UVs for the vertices in this face
							uvArr = [ uv[0], uv[ndx+1], uv[ndx+2] ];

						} else if ( vcount === 4 ) {

							uvArr = [ uv[0], uv[1], uv[2], uv[3] ];

						} else {

							uvArr = [ uv[0], uv[1], uv[2] ];

						}
2337

2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352
						if ( !geom.faceVertexUvs[k] ) {

							geom.faceVertexUvs[k] = [];

						}

						geom.faceVertexUvs[k].push( uvArr );

					}

				}

			} else {

				console.log( 'dropped face with vcount ' + vcount + ' for geometry with id: ' + geom.id );
2353 2354 2355

			}

T
timk 已提交
2356
			i += inputs.length * vcount;
2357

T
timk 已提交
2358
		}
2359 2360 2361 2362 2363 2364 2365

	};


	function Polylist () {
	};

T
timk 已提交
2366 2367
	Polylist.prototype = new Triangles();
	Polylist.prototype.constructor = Polylist;
2368 2369 2370

	function Triangles( flip_uv ) {

T
timk 已提交
2371 2372 2373
		this.material = "";
		this.count = 0;
		this.inputs = [];
M
Mr.doob 已提交
2374
		this.vcount = null;
T
timk 已提交
2375 2376
		this.p = [];
		this.geometry = new THREE.Geometry();
2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387

	};

	Triangles.prototype.setVertices = function ( vertices ) {

		for ( var i = 0; i < this.inputs.length; i ++ ) {

			if ( this.inputs[ i ].source == vertices.id ) {

				this.inputs[ i ].source = vertices.input[ 'POSITION' ].source;

T
timk 已提交
2388
			}
2389

T
timk 已提交
2390
		}
2391 2392 2393

	};

2394
	Triangles.prototype.parse = function ( element ) {
2395

T
timk 已提交
2396
		this.inputs = [];
2397 2398
		this.material = element.getAttribute( 'material' );
		this.count = _attr_as_int( element, 'count', 0 );
2399 2400 2401 2402 2403 2404 2405

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

			var child = element.childNodes[ i ];

			switch ( child.nodeName ) {

T
timk 已提交
2406
				case 'input':
2407

2408
					this.inputs.push( ( new Input() ).parse( element.childNodes[ i ] ) );
T
timk 已提交
2409
					break;
2410

T
timk 已提交
2411
				case 'vcount':
2412

2413
					this.vcount = _ints( child.textContent );
T
timk 已提交
2414
					break;
2415

T
timk 已提交
2416
				case 'p':
2417

2418
					this.p = _ints( child.textContent );
T
timk 已提交
2419
					break;
2420

T
timk 已提交
2421 2422
				default:
					break;
2423

T
timk 已提交
2424
			}
2425

T
timk 已提交
2426
		}
2427

T
timk 已提交
2428
		return this;
2429 2430 2431

	};

T
timk 已提交
2432
	function Accessor() {
2433

T
timk 已提交
2434 2435 2436 2437
		this.source = "";
		this.count = 0;
		this.stride = 0;
		this.params = [];
2438 2439 2440

	};

2441
	Accessor.prototype.parse = function ( element ) {
2442

T
timk 已提交
2443
		this.params = [];
2444 2445 2446
		this.source = element.getAttribute( 'source' );
		this.count = _attr_as_int( element, 'count', 0 );
		this.stride = _attr_as_int( element, 'stride', 0 );
2447 2448 2449

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

2450
			var child = element.childNodes[ i ];
2451 2452 2453

			if ( child.nodeName == 'param' ) {

T
timk 已提交
2454
				var param = {};
2455 2456 2457
				param[ 'name' ] = child.getAttribute( 'name' );
				param[ 'type' ] = child.getAttribute( 'type' );
				this.params.push( param );
2458

T
timk 已提交
2459
			}
2460

T
timk 已提交
2461
		}
2462

T
timk 已提交
2463
		return this;
2464 2465 2466

	};

T
timk 已提交
2467
	function Vertices() {
2468

T
timk 已提交
2469
		this.input = {};
2470 2471 2472 2473 2474

	};

	Vertices.prototype.parse = function ( element ) {

T
timk 已提交
2475
		this.id = element.getAttribute('id');
2476 2477 2478 2479 2480

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

			if ( element.childNodes[i].nodeName == 'input' ) {

2481 2482
				var input = ( new Input() ).parse( element.childNodes[ i ] );
				this.input[ input.semantic ] = input;
2483

T
timk 已提交
2484
			}
2485

T
timk 已提交
2486
		}
2487

T
timk 已提交
2488
		return this;
2489 2490 2491 2492 2493

	};

	function Input () {

T
timk 已提交
2494 2495 2496 2497
		this.semantic = "";
		this.offset = 0;
		this.source = "";
		this.set = 0;
2498 2499 2500 2501 2502

	};

	Input.prototype.parse = function ( element ) {

T
timk 已提交
2503 2504 2505 2506
		this.semantic = element.getAttribute('semantic');
		this.source = element.getAttribute('source').replace(/^#/, '');
		this.set = _attr_as_int(element, 'set', -1);
		this.offset = _attr_as_int(element, 'offset', 0);
2507 2508 2509

		if ( this.semantic == 'TEXCOORD' && this.set < 0 ) {

T
timk 已提交
2510
			this.set = 0;
2511

T
timk 已提交
2512
		}
2513

T
timk 已提交
2514
		return this;
2515 2516 2517 2518 2519

	};

	function Source ( id ) {

T
timk 已提交
2520 2521
		this.id = id;
		this.type = null;
2522 2523 2524 2525 2526 2527 2528 2529 2530

	};

	Source.prototype.parse = function ( element ) {

		this.id = element.getAttribute( 'id' );

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

T
timk 已提交
2531
			var child = element.childNodes[i];
2532 2533 2534

			switch ( child.nodeName ) {

T
timk 已提交
2535
				case 'bool_array':
2536

2537
					this.data = _bools( child.textContent );
T
timk 已提交
2538 2539
					this.type = child.nodeName;
					break;
2540

T
timk 已提交
2541
				case 'float_array':
2542

2543
					this.data = _floats( child.textContent );
T
timk 已提交
2544 2545
					this.type = child.nodeName;
					break;
2546

T
timk 已提交
2547
				case 'int_array':
2548

2549
					this.data = _ints( child.textContent );
T
timk 已提交
2550 2551
					this.type = child.nodeName;
					break;
2552

T
timk 已提交
2553 2554
				case 'IDREF_array':
				case 'Name_array':
2555

2556
					this.data = _strings( child.textContent );
T
timk 已提交
2557 2558
					this.type = child.nodeName;
					break;
2559

T
timk 已提交
2560
				case 'technique_common':
2561 2562 2563

					for ( var j = 0; j < child.childNodes.length; j ++ ) {

2564
						if ( child.childNodes[ j ].nodeName == 'accessor' ) {
2565

2566
							this.accessor = ( new Accessor() ).parse( child.childNodes[ j ] );
T
timk 已提交
2567
							break;
2568

T
timk 已提交
2569 2570 2571
						}
					}
					break;
2572

T
timk 已提交
2573
				default:
M
Mr.doob 已提交
2574
					// console.log(child.nodeName);
T
timk 已提交
2575
					break;
2576

T
timk 已提交
2577
			}
2578

T
timk 已提交
2579
		}
2580

T
timk 已提交
2581
		return this;
2582 2583 2584 2585 2586

	};

	Source.prototype.read = function () {

T
timk 已提交
2587
		var result = [];
2588

T
timk 已提交
2589
		//for (var i = 0; i < this.accessor.params.length; i++) {
2590

2591
			var param = this.accessor.params[ 0 ];
2592

T
timk 已提交
2593
			//console.log(param.name + " " + param.type);
2594

2595
			switch ( param.type ) {
2596

T
timk 已提交
2597
				case 'IDREF':
2598
				case 'Name': case 'name':
T
timk 已提交
2599
				case 'float':
2600

T
timk 已提交
2601
					return this.data;
2602

T
timk 已提交
2603
				case 'float4x4':
2604 2605 2606

					for ( var j = 0; j < this.data.length; j += 16 ) {

2607
						var s = this.data.slice( j, j + 16 );
2608
						var m = getConvertedMat4( s );
2609
						result.push( m );
T
timk 已提交
2610
					}
2611

T
timk 已提交
2612
					break;
2613

T
timk 已提交
2614
				default:
2615

M
Mr.doob 已提交
2616
					console.log( 'ColladaLoader: Source: Read dont know how to read ' + param.type + '.' );
T
timk 已提交
2617
					break;
2618

T
timk 已提交
2619
			}
2620

T
timk 已提交
2621
		//}
2622

T
timk 已提交
2623
		return result;
2624 2625 2626 2627 2628

	};

	function Material () {

T
timk 已提交
2629 2630 2631
		this.id = "";
		this.name = "";
		this.instance_effect = null;
2632 2633 2634 2635 2636

	};

	Material.prototype.parse = function ( element ) {

2637 2638
		this.id = element.getAttribute( 'id' );
		this.name = element.getAttribute( 'name' );
2639 2640 2641

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

2642 2643 2644
			if ( element.childNodes[ i ].nodeName == 'instance_effect' ) {

				this.instance_effect = ( new InstanceEffect() ).parse( element.childNodes[ i ] );
T
timk 已提交
2645
				break;
2646

T
timk 已提交
2647
			}
2648

T
timk 已提交
2649
		}
2650

T
timk 已提交
2651
		return this;
2652 2653 2654 2655 2656

	};

	function ColorOrTexture () {

2657 2658
		this.color = new THREE.Color( 0 );
		this.color.setRGB( Math.random(), Math.random(), Math.random() );
T
timk 已提交
2659
		this.color.a = 1.0;
2660

T
timk 已提交
2661 2662
		this.texture = null;
		this.texcoord = null;
2663
		this.texOpts = null;
2664 2665 2666 2667 2668

	};

	ColorOrTexture.prototype.isColor = function () {

2669
		return ( this.texture == null );
2670 2671 2672 2673 2674

	};

	ColorOrTexture.prototype.isTexture = function () {

2675
		return ( this.texture != null );
2676 2677 2678 2679 2680 2681 2682

	};

	ColorOrTexture.prototype.parse = function ( element ) {

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

2683 2684
			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;
2685 2686 2687

			switch ( child.nodeName ) {

T
timk 已提交
2688
				case 'color':
2689

2690
					var rgba = _floats( child.textContent );
T
timk 已提交
2691
					this.color = new THREE.Color(0);
2692
					this.color.setRGB( rgba[0], rgba[1], rgba[2] );
T
timk 已提交
2693 2694
					this.color.a = rgba[3];
					break;
2695

T
timk 已提交
2696
				case 'texture':
2697

T
timk 已提交
2698 2699
					this.texture = child.getAttribute('texture');
					this.texcoord = child.getAttribute('texcoord');
2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710
					// Defaults from:
					// https://collada.org/mediawiki/index.php/Maya_texture_placement_MAYA_extension
					this.texOpts = {
						offsetU: 0,
						offsetV: 0,
						repeatU: 1,
						repeatV: 1,
						wrapU: 1,
						wrapV: 1,
					};
					this.parseTexture( child );
T
timk 已提交
2711
					break;
2712

T
timk 已提交
2713 2714
				default:
					break;
2715

T
timk 已提交
2716
			}
2717

T
timk 已提交
2718
		}
2719

T
timk 已提交
2720
		return this;
2721 2722 2723

	};

2724 2725
	ColorOrTexture.prototype.parseTexture = function ( element ) {

2726
		if ( ! element.childNodes ) return this;
2727

2728 2729
		// This should be supported by Maya, 3dsMax, and MotionBuilder

2730
		if ( element.childNodes[1] && element.childNodes[1].nodeName === 'extra' ) {
2731

2732
			element = element.childNodes[1];
2733

2734
			if ( element.childNodes[1] && element.childNodes[1].nodeName === 'technique' ) {
2735

2736
				element = element.childNodes[1];
2737 2738 2739 2740 2741

			}

		}

2742
		for ( var i = 0; i < element.childNodes.length; i ++ ) {
2743

2744
			var child = element.childNodes[ i ];
2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773

			switch ( child.nodeName ) {

				case 'offsetU':
				case 'offsetV':
				case 'repeatU':
				case 'repeatV':

					this.texOpts[ child.nodeName ] = parseFloat( child.textContent );
					break;

				case 'wrapU':
				case 'wrapV':

					this.texOpts[ child.nodeName ] = parseInt( child.textContent );
					break;

				default:
					this.texOpts[ child.nodeName ] = child.textContent;
					break;

			}

		}

		return this;

	};

2774 2775
	function Shader ( type, effect ) {

T
timk 已提交
2776
		this.type = type;
T
timk 已提交
2777
		this.effect = effect;
M
Mr.doob 已提交
2778
		this.material = null;
2779 2780 2781 2782 2783 2784 2785

	};

	Shader.prototype.parse = function ( element ) {

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

2786 2787
			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;
2788

2789
			switch ( child.nodeName ) {
2790

T
timk 已提交
2791 2792 2793 2794 2795
				case 'ambient':
				case 'emission':
				case 'diffuse':
				case 'specular':
				case 'transparent':
2796

2797
					this[ child.nodeName ] = ( new ColorOrTexture() ).parse( child );
T
timk 已提交
2798
					break;
2799

T
timk 已提交
2800 2801 2802
				case 'shininess':
				case 'reflectivity':
				case 'transparency':
2803

2804
					var f = evaluateXPath( child, './/dae:float' );
2805 2806 2807 2808

					if ( f.length > 0 )
						this[ child.nodeName ] = parseFloat( f[ 0 ].textContent );

T
timk 已提交
2809
					break;
2810

T
timk 已提交
2811 2812
				default:
					break;
2813

T
timk 已提交
2814
			}
2815

T
timk 已提交
2816
		}
2817

T
timk 已提交
2818
		this.create();
T
timk 已提交
2819
		return this;
2820 2821 2822

	};

T
timk 已提交
2823
	Shader.prototype.create = function() {
2824

T
timk 已提交
2825
		var props = {};
2826 2827 2828 2829 2830 2831
		var transparent = ( this['transparency'] !== undefined && this['transparency'] < 1.0 );

		for ( var prop in this ) {

			switch ( prop ) {

T
timk 已提交
2832 2833 2834 2835
				case 'ambient':
				case 'emission':
				case 'diffuse':
				case 'specular':
2836

T
timk 已提交
2837
					var cot = this[prop];
2838 2839 2840 2841 2842 2843 2844

					if ( cot instanceof ColorOrTexture ) {

						if ( cot.isTexture() ) {

							if ( this.effect.sampler && this.effect.surface ) {

2845
								if ( this.effect.sampler.source == this.effect.surface.sid ) {
2846

T
timk 已提交
2847
									var image = images[this.effect.surface.init_from];
2848 2849 2850

									if ( image ) {

2851 2852 2853 2854 2855 2856 2857 2858
										var texture = THREE.ImageUtils.loadTexture(baseUrl + image.init_from);
										texture.wrapS = cot.texOpts.wrapU;
										texture.wrapT = cot.texOpts.wrapV;
										texture.offset.x = cot.texOpts.offsetU;
										texture.offset.y = cot.texOpts.offsetV;
										texture.repeat.x = cot.texOpts.repeatU;
										texture.repeat.y = cot.texOpts.repeatV;
										props['map'] = texture;
2859

T
timk 已提交
2860
									}
2861

T
timk 已提交
2862
								}
2863

T
timk 已提交
2864
							}
2865

T
timk 已提交
2866
						} else {
2867

2868
							if ( prop == 'diffuse' ) {
2869

2870
								props[ 'color' ] = cot.color.getHex();
2871

2872
							} else if ( !transparent ) {
2873

2874
								props[ prop ] = cot.color.getHex();
2875

T
timk 已提交
2876
							}
2877

T
timk 已提交
2878
						}
2879

T
timk 已提交
2880
					}
2881

T
timk 已提交
2882
					break;
2883

T
timk 已提交
2884 2885
				case 'shininess':
				case 'reflectivity':
2886

2887
					props[ prop ] = this[ prop ];
T
timk 已提交
2888
					break;
2889

T
timk 已提交
2890
				case 'transparency':
2891 2892 2893

					if ( transparent ) {

2894 2895
						props[ 'transparent' ] = true;
						props[ 'opacity' ] = this[ prop ];
T
timk 已提交
2896
						transparent = true;
2897

T
timk 已提交
2898
					}
2899

T
timk 已提交
2900
					break;
2901

T
timk 已提交
2902 2903
				default:
					break;
2904

T
timk 已提交
2905
			}
2906

T
timk 已提交
2907 2908
		}

2909 2910 2911 2912 2913
		props[ 'shading' ] = preferredShading;
		this.material = new THREE.MeshLambertMaterial( props );

		switch ( this.type ) {

T
timk 已提交
2914 2915 2916
			case 'constant':
			case 'lambert':
				break;
2917

T
timk 已提交
2918 2919
			case 'phong':
			case 'blinn':
2920

T
timk 已提交
2921
			default:
2922

M
Mr.doob 已提交
2923
				/*
2924 2925
				if ( !transparent ) {

T
hmm  
timk 已提交
2926
				//	this.material = new THREE.MeshPhongMaterial(props);
2927

T
timk 已提交
2928
				}
M
Mr.doob 已提交
2929
				*/
2930

T
timk 已提交
2931
				break;
2932

T
timk 已提交
2933
		}
2934

T
timk 已提交
2935
		return this.material;
2936 2937 2938 2939 2940

	};

	function Surface ( effect ) {

T
timk 已提交
2941
		this.effect = effect;
M
Mr.doob 已提交
2942 2943
		this.init_from = null;
		this.format = null;
2944 2945 2946 2947 2948 2949 2950

	};

	Surface.prototype.parse = function ( element ) {

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

2951 2952
			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;
2953 2954 2955

			switch ( child.nodeName ) {

T
timk 已提交
2956
				case 'init_from':
2957

T
timk 已提交
2958 2959
					this.init_from = child.textContent;
					break;
2960

T
timk 已提交
2961
				case 'format':
2962

T
timk 已提交
2963 2964
					this.format = child.textContent;
					break;
2965

T
timk 已提交
2966
				default:
2967

2968
					console.log( "unhandled Surface prop: " + child.nodeName );
T
timk 已提交
2969
					break;
2970

T
timk 已提交
2971
			}
2972

T
timk 已提交
2973
		}
2974

T
timk 已提交
2975
		return this;
2976 2977 2978 2979 2980

	};

	function Sampler2D ( effect ) {

T
timk 已提交
2981
		this.effect = effect;
M
Mr.doob 已提交
2982 2983 2984 2985 2986 2987
		this.source = null;
		this.wrap_s = null;
		this.wrap_t = null;
		this.minfilter = null;
		this.magfilter = null;
		this.mipfilter = null;
2988 2989 2990 2991 2992 2993 2994 2995 2996 2997

	};

	Sampler2D.prototype.parse = function ( element ) {

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;

2998
			switch ( child.nodeName ) {
2999

T
timk 已提交
3000
				case 'source':
3001

T
timk 已提交
3002 3003
					this.source = child.textContent;
					break;
3004

T
timk 已提交
3005
				case 'minfilter':
3006

T
timk 已提交
3007 3008
					this.minfilter = child.textContent;
					break;
3009

T
timk 已提交
3010
				case 'magfilter':
3011

T
timk 已提交
3012 3013
					this.magfilter = child.textContent;
					break;
3014

T
timk 已提交
3015
				case 'mipfilter':
3016

T
timk 已提交
3017 3018
					this.mipfilter = child.textContent;
					break;
3019

T
timk 已提交
3020
				case 'wrap_s':
3021

T
timk 已提交
3022 3023
					this.wrap_s = child.textContent;
					break;
3024

T
timk 已提交
3025
				case 'wrap_t':
3026

T
timk 已提交
3027 3028
					this.wrap_t = child.textContent;
					break;
3029

T
timk 已提交
3030
				default:
3031

3032
					console.log( "unhandled Sampler2D prop: " + child.nodeName );
T
timk 已提交
3033
					break;
3034

T
timk 已提交
3035
			}
3036

T
timk 已提交
3037
		}
3038

T
timk 已提交
3039
		return this;
3040 3041 3042 3043 3044

	};

	function Effect () {

T
timk 已提交
3045 3046 3047
		this.id = "";
		this.name = "";
		this.shader = null;
M
Mr.doob 已提交
3048 3049
		this.surface = null;
		this.sampler = null;
3050 3051 3052 3053 3054 3055 3056

	};

	Effect.prototype.create = function () {

		if ( this.shader == null ) {

T
timk 已提交
3057
			return null;
3058

T
timk 已提交
3059
		}
3060 3061 3062 3063 3064 3065 3066

	};

	Effect.prototype.parse = function ( element ) {

		this.id = element.getAttribute( 'id' );
		this.name = element.getAttribute( 'name' );
T
timk 已提交
3067
		this.shader = null;
3068 3069 3070 3071 3072 3073 3074 3075

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
3076
				case 'profile_COMMON':
3077 3078

					this.parseTechnique( this.parseProfileCOMMON( child ) );
T
timk 已提交
3079
					break;
3080

T
timk 已提交
3081 3082
				default:
					break;
3083

T
timk 已提交
3084
			}
3085

T
timk 已提交
3086
		}
3087

T
timk 已提交
3088
		return this;
3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102

	};

	Effect.prototype.parseNewparam = function ( element ) {

		var sid = element.getAttribute( 'sid' );

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
3103
				case 'surface':
3104 3105

					this.surface = ( new Surface( this ) ).parse( child );
T
timk 已提交
3106 3107
					this.surface.sid = sid;
					break;
3108

T
timk 已提交
3109
				case 'sampler2D':
3110 3111

					this.sampler = ( new Sampler2D( this ) ).parse( child );
T
timk 已提交
3112 3113
					this.sampler.sid = sid;
					break;
3114

T
timk 已提交
3115
				case 'extra':
3116

T
timk 已提交
3117
					break;
3118

T
timk 已提交
3119
				default:
3120 3121

					console.log( child.nodeName );
T
timk 已提交
3122
					break;
3123

T
timk 已提交
3124
			}
3125

T
timk 已提交
3126
		}
3127 3128 3129 3130 3131

	};

	Effect.prototype.parseProfileCOMMON = function ( element ) {

T
timk 已提交
3132
		var technique;
3133 3134 3135 3136 3137 3138 3139 3140 3141

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

			var child = element.childNodes[ i ];

			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
3142
				case 'profile_COMMON':
3143 3144

					this.parseProfileCOMMON( child );
T
timk 已提交
3145
					break;
3146

T
timk 已提交
3147
				case 'technique':
3148

T
timk 已提交
3149
					technique = child;
T
timk 已提交
3150
					break;
3151

T
timk 已提交
3152
				case 'newparam':
3153 3154

					this.parseNewparam( child );
T
timk 已提交
3155
					break;
3156

T
timk 已提交
3157 3158
				case 'extra':
					break;
3159

T
timk 已提交
3160
				default:
3161 3162

					console.log( child.nodeName );
T
timk 已提交
3163
					break;
3164

T
timk 已提交
3165
			}
3166

T
timk 已提交
3167
		}
3168

T
timk 已提交
3169
		return technique;
3170 3171 3172 3173 3174 3175 3176

	};

	Effect.prototype.parseTechnique= function ( element ) {

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

T
timk 已提交
3177
			var child = element.childNodes[i];
3178
			if ( child.nodeType != 1 ) continue;
3179 3180 3181

			switch ( child.nodeName ) {

T
timk 已提交
3182 3183 3184
				case 'lambert':
				case 'blinn':
				case 'phong':
3185 3186

					this.shader = ( new Shader( child.nodeName, this ) ).parse( child );
T
timk 已提交
3187
					break;
3188

T
timk 已提交
3189 3190
				default:
					break;
3191

T
timk 已提交
3192
			}
3193

T
timk 已提交
3194
		}
3195 3196 3197 3198 3199

	};

	function InstanceEffect () {

T
timk 已提交
3200
		this.url = "";
3201 3202 3203 3204 3205 3206

	};

	InstanceEffect.prototype.parse = function ( element ) {

		this.url = element.getAttribute( 'url' ).replace( /^#/, '' );
T
timk 已提交
3207
		return this;
3208 3209

	};
T
timk 已提交
3210 3211

	function Animation() {
3212

T
timk 已提交
3213 3214 3215 3216 3217
		this.id = "";
		this.name = "";
		this.source = {};
		this.sampler = [];
		this.channel = [];
3218 3219 3220 3221 3222 3223 3224

	};

	Animation.prototype.parse = function ( element ) {

		this.id = element.getAttribute( 'id' );
		this.name = element.getAttribute( 'name' );
T
timk 已提交
3225
		this.source = {};
3226 3227 3228 3229 3230 3231 3232 3233 3234

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

			var child = element.childNodes[ i ];

			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
3235
				case 'source':
3236 3237 3238

					var src = ( new Source() ).parse( child );
					this.source[ src.id ] = src;
T
timk 已提交
3239
					break;
3240

T
timk 已提交
3241
				case 'sampler':
3242 3243

					this.sampler.push( ( new Sampler( this ) ).parse( child ) );
T
timk 已提交
3244
					break;
3245

T
timk 已提交
3246
				case 'channel':
3247 3248

					this.channel.push( ( new Channel( this ) ).parse( child ) );
T
timk 已提交
3249
					break;
3250

T
timk 已提交
3251 3252
				default:
					break;
3253

T
timk 已提交
3254
			}
3255

T
timk 已提交
3256
		}
3257

T
timk 已提交
3258
		return this;
T
timk 已提交
3259

3260 3261 3262 3263
	};

	function Channel( animation ) {

T
timk 已提交
3264 3265 3266
		this.animation = animation;
		this.source = "";
		this.target = "";
3267
		this.fullSid = null;
M
Mr.doob 已提交
3268 3269 3270 3271 3272
		this.sid = null;
		this.dotSyntax = null;
		this.arrSyntax = null;
		this.arrIndices = null;
		this.member = null;
3273 3274 3275 3276 3277 3278 3279 3280 3281 3282

	};

	Channel.prototype.parse = function ( element ) {

		this.source = element.getAttribute( 'source' ).replace( /^#/, '' );
		this.target = element.getAttribute( 'target' );

		var parts = this.target.split( '/' );

T
timk 已提交
3283 3284
		var id = parts.shift();
		var sid = parts.shift();
3285 3286 3287 3288 3289 3290

		var dotSyntax = ( sid.indexOf(".") >= 0 );
		var arrSyntax = ( sid.indexOf("(") >= 0 );

		if ( dotSyntax ) {

T
timk 已提交
3291
			parts = sid.split(".");
3292 3293
			this.sid = parts.shift();
			this.member = parts.shift();
3294 3295 3296

		} else if ( arrSyntax ) {

3297 3298
			var arrIndices = sid.split("(");
			this.sid = arrIndices.shift();
3299 3300 3301 3302 3303

			for (var j = 0; j < arrIndices.length; j ++ ) {

				arrIndices[j] = parseInt( arrIndices[j].replace(/\)/, '') );

T
timk 已提交
3304
			}
3305

3306 3307 3308 3309 3310 3311
			this.arrIndices = arrIndices;

		} else {

			this.sid = sid;

T
timk 已提交
3312
		}
3313

3314
		this.fullSid = sid;
T
timk 已提交
3315 3316
		this.dotSyntax = dotSyntax;
		this.arrSyntax = arrSyntax;
3317

T
timk 已提交
3318
		return this;
3319 3320 3321 3322 3323

	};

	function Sampler ( animation ) {

T
timk 已提交
3324 3325 3326
		this.id = "";
		this.animation = animation;
		this.inputs = [];
M
Mr.doob 已提交
3327 3328
		this.input = null;
		this.output = null;
3329
		this.strideOut = null;
M
Mr.doob 已提交
3330 3331 3332
		this.interpolation = null;
		this.startTime = null;
		this.endTime = null;
T
timk 已提交
3333
		this.duration = 0;
3334 3335 3336 3337 3338 3339

	};

	Sampler.prototype.parse = function ( element ) {

		this.id = element.getAttribute( 'id' );
T
timk 已提交
3340
		this.inputs = [];
3341 3342 3343 3344 3345 3346 3347 3348

		for ( var i = 0; i < element.childNodes.length; i ++ ) {

			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
3349
				case 'input':
3350 3351

					this.inputs.push( (new Input()).parse( child ) );
T
timk 已提交
3352
					break;
3353

T
timk 已提交
3354 3355
				default:
					break;
3356

T
timk 已提交
3357
			}
3358

T
timk 已提交
3359
		}
3360

T
timk 已提交
3361
		return this;
3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373

	};

	Sampler.prototype.create = function () {

		for ( var i = 0; i < this.inputs.length; i ++ ) {

			var input = this.inputs[ i ];
			var source = this.animation.source[ input.source ];

			switch ( input.semantic ) {

T
timk 已提交
3374
				case 'INPUT':
3375

T
timk 已提交
3376 3377
					this.input = source.read();
					break;
3378

T
timk 已提交
3379
				case 'OUTPUT':
3380

T
timk 已提交
3381
					this.output = source.read();
3382
					this.strideOut = source.accessor.stride;
T
timk 已提交
3383
					break;
3384

T
timk 已提交
3385
				case 'INTERPOLATION':
3386

T
timk 已提交
3387 3388
					this.interpolation = source.read();
					break;
3389

T
timk 已提交
3390
				case 'IN_TANGENT':
3391

T
timk 已提交
3392
					break;
3393

T
timk 已提交
3394
				case 'OUT_TANGENT':
3395

T
timk 已提交
3396
					break;
3397

T
timk 已提交
3398
				default:
3399

T
timk 已提交
3400 3401
					console.log(input.semantic);
					break;
3402

T
timk 已提交
3403
			}
3404

T
timk 已提交
3405
		}
3406

T
timk 已提交
3407 3408 3409
		this.startTime = 0;
		this.endTime = 0;
		this.duration = 0;
3410 3411 3412

		if ( this.input.length ) {

T
timk 已提交
3413 3414
			this.startTime = 100000000;
			this.endTime = -100000000;
3415 3416 3417 3418 3419 3420

			for ( var i = 0; i < this.input.length; i ++ ) {

				this.startTime = Math.min( this.startTime, this.input[ i ] );
				this.endTime = Math.max( this.endTime, this.input[ i ] );

T
timk 已提交
3421
			}
3422

T
timk 已提交
3423
			this.duration = this.endTime - this.startTime;
3424

T
timk 已提交
3425
		}
3426 3427 3428

	};

3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590
	Sampler.prototype.getData = function ( type, ndx ) {

		var data;

		if ( this.strideOut > 1 ) {

			data = [];
			ndx *= this.strideOut;

			for ( var i = 0; i < this.strideOut; ++i ) {

				data[ i ] = this.output[ ndx + i ];

			}

			if ( this.strideOut === 3 ) {

				switch ( type ) {

					case 'rotate':
					case 'translate':

						fixCoords( data, -1 );
						break;

					case 'scale':

						fixCoords( data, 1 );
						break;

				}

			}

		} else {

			data = this.output[ ndx ];

		}

		return data;

	};

	function Key ( time ) {

		this.targets = [];
		this.time = time;

	};

	Key.prototype.addTarget = function ( fullSid, transform, member, data ) {

		this.targets.push( {
			sid: fullSid,
			member: member,
			transform: transform,
			data: data
		} );

	};

	Key.prototype.apply = function ( opt_sid ) {

		for ( var i = 0; i < this.targets.length; ++i ) {

			var target = this.targets[ i ];

			if ( !opt_sid || target.sid === opt_sid ) {

				target.transform.update( target.data, target.member );

			}

		}

	};

	Key.prototype.getTarget = function ( fullSid ) {

		for ( var i = 0; i < this.targets.length; ++i ) {

			if ( this.targets[ i ].sid === fullSid ) {

				return this.targets[ i ];

			}

		}

		return null;

	};

	Key.prototype.hasTarget = function ( fullSid ) {

		for ( var i = 0; i < this.targets.length; ++i ) {

			if ( this.targets[ i ].sid === fullSid ) {

				return true;

			}

		}

		return false;

	};

	// TODO: Currently only doing linear interpolation. Should support full COLLADA spec.
	Key.prototype.interpolate = function ( nextKey, time ) {

		for ( var i = 0; i < this.targets.length; ++i ) {

			var target = this.targets[ i ],
				nextTarget = nextKey.getTarget( target.sid ),
				data;

			if ( nextTarget ) {

				var scale = ( time - this.time ) / ( nextKey.time - this.time ),
					nextData = nextTarget.data,
					prevData = target.data;

				// check scale error

				if ( scale < 0 || scale > 1 ) {

					console.log( "Key.interpolate: Warning! Scale out of bounds:" + scale );
					scale = scale < 0 ? 0 : 1;

				}

				if ( prevData.length ) {

					data = [];

					for ( var j = 0; j < prevData.length; ++j ) {

						data[ j ] = prevData[ j ] + ( nextData[ j ] - prevData[ j ] ) * scale;

					}

				} else {

					data = prevData + ( nextData - prevData ) * scale;

				}

			} else {

				data = target.data;

			}

			target.transform.update( data, target.member );

		}

	};

3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609
	function _source ( element ) {

		var id = element.getAttribute( 'id' );

		if ( sources[ id ] != undefined ) {

			return sources[ id ];

		}

		sources[ id ] = ( new Source(id )).parse( element );
		return sources[ id ];

	};

	function _nsResolver ( nsPrefix ) {

		if ( nsPrefix == "dae" ) {

T
timk 已提交
3610
			return "http://www.collada.org/2005/11/COLLADASchema";
3611

T
timk 已提交
3612
		}
3613

T
timk 已提交
3614
		return null;
3615 3616 3617

	};

T
timk 已提交
3618
	function _bools ( str ) {
3619 3620

		var raw = _strings( str );
T
timk 已提交
3621
		var data = [];
3622

3623
		for ( var i = 0; i < raw.length; i ++ ) {
3624 3625

			data.push( (raw[i] == 'true' || raw[i] == '1') ? true : false );
3626

T
timk 已提交
3627
		}
3628

T
timk 已提交
3629
		return data;
3630 3631 3632

	};

T
timk 已提交
3633
	function _floats ( str ) {
3634

T
timk 已提交
3635 3636
		var raw = _strings(str);
		var data = [];
3637 3638 3639 3640 3641

		for ( var i = 0; i < raw.length; i ++ ) {

			data.push( parseFloat( raw[ i ] ) );

T
timk 已提交
3642
		}
3643

T
timk 已提交
3644
		return data;
3645 3646

	};
T
timk 已提交
3647 3648

	function _ints ( str ) {
3649 3650

		var raw = _strings( str );
T
timk 已提交
3651
		var data = [];
3652 3653 3654 3655 3656

		for ( var i = 0; i < raw.length; i ++ ) {

			data.push( parseInt( raw[ i ], 10 ) );

T
timk 已提交
3657
		}
3658

T
timk 已提交
3659
		return data;
3660 3661 3662

	};

T
timk 已提交
3663
	function _strings ( str ) {
3664 3665 3666 3667

		return _trimString( str ).split( /\s+/ );

	};
T
timk 已提交
3668 3669

	function _trimString ( str ) {
3670 3671 3672 3673

		return str.replace( /^\s+/, "" ).replace( /\s+$/, "" );

	};
T
timk 已提交
3674 3675

	function _attr_as_float ( element, name, defaultValue ) {
3676 3677 3678 3679 3680

		if ( element.hasAttribute( name ) ) {

			return parseFloat( element.getAttribute( name ) );

T
timk 已提交
3681
		} else {
3682

T
timk 已提交
3683
			return defaultValue;
3684

T
timk 已提交
3685
		}
3686 3687

	};
T
timk 已提交
3688 3689

	function _attr_as_int ( element, name, defaultValue ) {
3690 3691 3692 3693 3694

		if ( element.hasAttribute( name ) ) {

			return parseInt( element.getAttribute( name ), 10) ;

T
timk 已提交
3695
		} else {
3696

T
timk 已提交
3697
			return defaultValue;
3698

T
timk 已提交
3699
		}
3700 3701

	};
T
timk 已提交
3702 3703

	function _attr_as_string ( element, name, defaultValue ) {
3704 3705 3706 3707 3708

		if ( element.hasAttribute( name ) ) {

			return element.getAttribute( name );

T
timk 已提交
3709
		} else {
3710

T
timk 已提交
3711
			return defaultValue;
3712

T
timk 已提交
3713
		}
3714 3715 3716 3717 3718 3719 3720

	};

	function _format_float ( f, num ) {

		if ( f === undefined ) {

T
timk 已提交
3721
			var s = '0.';
3722 3723 3724

			while ( s.length < num + 2 ) {

T
timk 已提交
3725
				s += '0';
3726

T
timk 已提交
3727
			}
3728

T
timk 已提交
3729
			return s;
3730

T
timk 已提交
3731
		}
3732

T
timk 已提交
3733
		num = num || 2;
3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749

		var parts = f.toString().split( '.' );
		parts[ 1 ] = parts.length > 1 ? parts[ 1 ].substr( 0, num ) : "0";

		while( parts[ 1 ].length < num ) {

			parts[ 1 ] += '0';

		}

		return parts.join( '.' );

	};

	function evaluateXPath ( node, query ) {

3750
		var instances = COLLADA.evaluate( query, node, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );
3751

T
timk 已提交
3752 3753
		var inst = instances.iterateNext();
		var result = [];
3754 3755 3756 3757

		while ( inst ) {

			result.push( inst );
T
timk 已提交
3758
			inst = instances.iterateNext();
3759 3760 3761

		}

T
timk 已提交
3762
		return result;
3763 3764 3765

	};

3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997
	// Up axis conversion

	function setUpConversion () {

		if ( !options.convertUpAxis || colladaUp === options.upAxis ) {

			upConversion = null;

		} else {

			switch ( colladaUp ) {

				case 'X':

					upConversion = options.upAxis === 'Y' ? 'XtoY' : 'XtoZ';
					break;

				case 'Y':

					upConversion = options.upAxis === 'X' ? 'YtoX' : 'YtoZ';
					break;

				case 'Z':

					upConversion = options.upAxis === 'X' ? 'ZtoX' : 'ZtoY';
					break;

			}

		}

	};

	function fixCoords ( data, sign ) {

		if ( !options.convertUpAxis || colladaUp === options.upAxis ) {

			return;

		}

		switch ( upConversion ) {

			case 'XtoY':

				var tmp = data[ 0 ];
				data[ 0 ] = sign * data[ 1 ];
				data[ 1 ] = tmp;
				break;

			case 'XtoZ':

				var tmp = data[ 2 ];
				data[ 2 ] = data[ 1 ];
				data[ 1 ] = data[ 0 ];
				data[ 0 ] = tmp;
				break;

			case 'YtoX':

				var tmp = data[ 0 ];
				data[ 0 ] = data[ 1 ];
				data[ 1 ] = sign * tmp;
				break;

			case 'YtoZ':

				var tmp = data[ 1 ];
				data[ 1 ] = sign * data[ 2 ];
				data[ 2 ] = tmp;
				break;

			case 'ZtoX':

				var tmp = data[ 0 ];
				data[ 0 ] = data[ 1 ];
				data[ 1 ] = data[ 2 ];
				data[ 2 ] = tmp;
				break;

			case 'ZtoY':

				var tmp = data[ 1 ];
				data[ 1 ] = data[ 2 ];
				data[ 2 ] = sign * tmp;
				break;

		}

	};

	function getConvertedVec3 ( data, offset ) {

		var arr = [ data[ offset ], data[ offset + 1 ], data[ offset + 2 ] ];
		fixCoords( arr, -1 );
		return new THREE.Vector3( arr[ 0 ], arr[ 1 ], arr[ 2 ] );

	};

	function getConvertedMat4 ( data ) {

		if ( options.convertUpAxis ) {

			// First fix rotation and scale

			// Columns first
			var arr = [ data[ 0 ], data[ 4 ], data[ 8 ] ];
			fixCoords( arr, -1 );
			data[ 0 ] = arr[ 0 ];
			data[ 4 ] = arr[ 1 ];
			data[ 8 ] = arr[ 2 ];
			arr = [ data[ 1 ], data[ 5 ], data[ 9 ] ];
			fixCoords( arr, -1 );
			data[ 1 ] = arr[ 0 ];
			data[ 5 ] = arr[ 1 ];
			data[ 9 ] = arr[ 2 ];
			arr = [ data[ 2 ], data[ 6 ], data[ 10 ] ];
			fixCoords( arr, -1 );
			data[ 2 ] = arr[ 0 ];
			data[ 6 ] = arr[ 1 ];
			data[ 10 ] = arr[ 2 ];
			// Rows second
			arr = [ data[ 0 ], data[ 1 ], data[ 2 ] ];
			fixCoords( arr, -1 );
			data[ 0 ] = arr[ 0 ];
			data[ 1 ] = arr[ 1 ];
			data[ 2 ] = arr[ 2 ];
			arr = [ data[ 4 ], data[ 5 ], data[ 6 ] ];
			fixCoords( arr, -1 );
			data[ 4 ] = arr[ 0 ];
			data[ 5 ] = arr[ 1 ];
			data[ 6 ] = arr[ 2 ];
			arr = [ data[ 8 ], data[ 9 ], data[ 10 ] ];
			fixCoords( arr, -1 );
			data[ 8 ] = arr[ 0 ];
			data[ 9 ] = arr[ 1 ];
			data[ 10 ] = arr[ 2 ];

			// Now fix translation
			arr = [ data[ 3 ], data[ 7 ], data[ 11 ] ];
			fixCoords( arr, -1 );
			data[ 3 ] = arr[ 0 ];
			data[ 7 ] = arr[ 1 ];
			data[ 11 ] = arr[ 2 ];

		}

		return new THREE.Matrix4(
			data[0], data[1], data[2], data[3],
			data[4], data[5], data[6], data[7],
			data[8], data[9], data[10], data[11],
			data[12], data[13], data[14], data[15]
			);

	};

	function getConvertedMember ( member ) {

		if ( options.convertUpAxis ) {

			switch ( member ) {

				case 'X':

					switch ( upConversion ) {

						case 'XtoY':
						case 'XtoZ':
						case 'YtoX':

							member = 'Y';
							break;

						case 'ZtoX':

							member = 'Z';
							break;

					}

					break;

				case 'Y':

					switch ( upConversion ) {

						case 'XtoY':
						case 'YtoX':
						case 'ZtoX':

							member = 'X';
							break;

						case 'XtoZ':
						case 'YtoZ':
						case 'ZtoY':

							member = 'Z';
							break;

					}

					break;

				case 'Z':

					switch ( upConversion ) {

						case 'XtoZ':

							member = 'X';
							break;

						case 'YtoZ':
						case 'ZtoX':
						case 'ZtoY':

							member = 'Y';
							break;

					}

					break;

			}

		}

		return member;

	};

T
timk 已提交
3998
	return {
3999

T
timk 已提交
4000
		load: load,
4001
		parse: parse,
T
timk 已提交
4002
		setPreferredShading: setPreferredShading,
T
timk 已提交
4003
		applySkin: applySkin,
4004 4005
		geometries : geometries,
		options: options
4006

T
timk 已提交
4007
	};
4008

M
Mr.doob 已提交
4009
};