ColladaLoader.js 70.8 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
	var cameras = {};
21

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

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

31
	var options = {
32 33 34 35
		// Force Geometry to always be centered at the local origin of the
		// containing Mesh.
		centerGeometry: false,

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
		// 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;

53 54 55
	function load ( url, readyCallback, progressCallback ) {

		var length = 0;
56 57 58

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

T
timk 已提交
59 60
			var req = new XMLHttpRequest();

61
			if ( req.overrideMimeType ) req.overrideMimeType( "text/xml" );
T
timk 已提交
62 63

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

				if( req.readyState == 4 ) {

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

69 70 71 72 73 74 75 76 77 78 79

						if ( req.responseXML ) {

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

						} else {

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

						}
80

T
timk 已提交
81
					}
82

83 84 85 86 87 88 89 90 91 92 93 94 95 96
				} else if ( req.readyState == 3 ) {

					if ( progressCallback ) {

						if ( length == 0 ) {

							length = req.getResponseHeader( "Content-Length" );

						}

						progressCallback( { total: length, loaded: req.responseText.length } );

					}

T
timk 已提交
97
				}
98

T
timk 已提交
99
			}
100 101 102 103

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

T
timk 已提交
104
		} else {
105

106
			alert( "Don't know how to parse XML!" );
107

T
timk 已提交
108
		}
109 110 111

	};

112
	function parse( doc, callBack, url ) {
113

T
timk 已提交
114 115
		COLLADA = doc;
		callBack = callBack || readyCallbackFunc;
116 117 118

		if ( url !== undefined ) {

119
			var parts = url.split( '/' );
T
timk 已提交
120
			parts.pop();
121
			baseUrl = parts.length < 1 ? '.' : parts.join( '/' ) + '/';
122

T
timk 已提交
123
		}
124

125 126
		parseAsset();
		setUpConversion();
127 128 129 130
		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" );
131
		cameras = parseLib( ".//dae:library_cameras/dae:camera", Camera, "camera" );
132 133 134 135
		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 已提交
136 137
		morphs = [];
		skins = [];
138

T
timk 已提交
139 140
		daeScene = parseScene();
		scene = new THREE.Object3D();
141

142
		for ( var i = 0; i < daeScene.nodes.length; i ++ ) {
143

144
			scene.add( createSceneGraph( daeScene.nodes[ i ] ) );
145

T
timk 已提交
146
		}
T
timk 已提交
147

T
timk 已提交
148 149 150
		createAnimations();

		var result = {
151 152

			scene: scene,
T
timk 已提交
153 154
			morphs: morphs,
			skins: skins,
155
			animations: animData,
T
timk 已提交
156 157 158
			dae: {
				images: images,
				materials: materials,
159
				cameras: cameras,
T
timk 已提交
160 161 162 163 164 165 166
				effects: effects,
				geometries: geometries,
				controllers: controllers,
				animations: animations,
				visualScenes: visualScenes,
				scene: daeScene
			}
167

T
timk 已提交
168
		};
169 170 171 172 173

		if ( callBack ) {

			callBack( result );

T
timk 已提交
174
		}
175

T
timk 已提交
176
		return result;
177 178 179 180 181

	};

	function setPreferredShading ( shading ) {

T
timk 已提交
182
		preferredShading = shading;
183 184 185

	};

186 187
	function parseAsset () {

188
		var elements = COLLADA.evaluate( '//dae:asset', COLLADA, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );
189 190 191

		var element = elements.iterateNext();

192
		if ( element && element.childNodes ) {
193

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

196
				var child = element.childNodes[ i ];
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224

				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;

				}

			}

		}

	};

225 226
	function parseLib ( q, classSpec, prefix ) {

227
		var elements = COLLADA.evaluate(q, COLLADA, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null) ;
228

T
timk 已提交
229 230 231
		var lib = {};
		var element = elements.iterateNext();
		var i = 0;
232 233 234 235

		while ( element ) {

			var daeElement = ( new classSpec() ).parse( element );
236
			if ( !daeElement.id || daeElement.id.length == 0 ) daeElement.id = prefix + ( i ++ );
237
			lib[ daeElement.id ] = daeElement;
238

T
timk 已提交
239
			element = elements.iterateNext();
240

T
timk 已提交
241
		}
242

T
timk 已提交
243
		return lib;
244 245 246

	};

247
	function parseScene() {
248

249
		var sceneElement = COLLADA.evaluate( './/dae:scene/dae:instance_visual_scene', COLLADA, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null ).iterateNext();
250 251 252 253

		if ( sceneElement ) {

			var url = sceneElement.getAttribute( 'url' ).replace( /^#/, '' );
254
			return visualScenes[ url.length > 0 ? url : 'visual_scene0' ];
255

T
timk 已提交
256
		} else {
257

T
timk 已提交
258
			return null;
259

T
timk 已提交
260
		}
261 262 263

	};

264
	function createAnimations() {
265

266 267 268 269 270 271 272
		animData = [];

		// fill in the keys
		recurseHierarchy( scene );

	};

273
	function recurseHierarchy( node ) {
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290

		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
			};
291

292
			animData.push(newData);
293

294 295 296 297 298 299 300 301 302 303 304 305 306 307
			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: []
				} ]
			}
308 309 310

		}

311 312 313 314 315 316 317 318 319 320 321 322 323 324
		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: []
				} );

			}

		}
325

326
		return newData;
327 328 329 330 331

	};

	function calcAnimationBounds () {

T
timk 已提交
332 333
		var start = 1000000;
		var end = -start;
T
timk 已提交
334
		var frames = 0;
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362

		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 已提交
363 364
			console.log("could not find morph controller!");
			return;
365

T
timk 已提交
366
		}
367

T
timk 已提交
368 369
		var morph = morphCtrl.morph;

370 371 372 373 374 375 376
		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 ||
377
				 !daeGeometry.mesh.primitives.length ) {
378
				 continue;
T
timk 已提交
379
			}
380 381 382 383 384

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

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

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

T
timk 已提交
387
			}
388

T
timk 已提交
389
		}
390

T
timk 已提交
391
		geometry.morphTargets.push( { name: "target_Z", vertices: geometry.vertices } );
392 393 394 395 396 397 398 399 400

	};

	function createSkin ( geometry, ctrl, applyBindShape ) {

		var skinCtrl = controllers[ ctrl.url ];

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

401
			console.log( "could not find skin controller!" );
T
timk 已提交
402
			return;
403

T
timk 已提交
404
		}
405 406 407

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

408
			console.log( "could not find the skeleton for the skin!" );
T
timk 已提交
409
			return;
410

T
timk 已提交
411
		}
412

T
timk 已提交
413
		var skin = skinCtrl.skin;
414
		var skeleton = daeScene.getChildById( ctrl.skeleton[ 0 ] );
T
timk 已提交
415
		var hierarchy = [];
416

T
timk 已提交
417
		applyBindShape = applyBindShape !== undefined ? applyBindShape : true;
418

T
timk 已提交
419 420 421
		var bones = [];
		geometry.skinWeights = [];
		geometry.skinIndices = [];
422

423 424
		//createBones( geometry.bones, skin, hierarchy, skeleton, null, -1 );
		//createWeights( skin, geometry.bones, geometry.skinIndices, geometry.skinWeights );
425

T
timk 已提交
426 427 428 429 430 431 432 433 434
		/*
		geometry.animation = {
			name: 'take_001',
			fps: 30,
			length: 2,
			JIT: true,
			hierarchy: hierarchy
		};
		*/
435 436 437 438 439 440 441

		if ( applyBindShape ) {

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

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

T
timk 已提交
442
			}
443

T
timk 已提交
444
		}
445 446 447 448 449

	};

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

T
timk 已提交
450
		node.world = node.world || new THREE.Matrix4();
451 452 453 454 455 456 457 458 459
		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 ) {

460
				node.world.copy( m );
461

T
timk 已提交
462
			}
463

T
timk 已提交
464
		}
465 466 467 468 469

		if ( parent ) {

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

T
timk 已提交
470 471
		}

472 473 474 475 476 477
		bones.push( node );

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

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

T
timk 已提交
478
		}
479 480 481 482 483

	};

	function setupSkinningMatrices ( bones, skin ) {

T
timk 已提交
484
		// FIXME: this is dumb...
485 486 487 488

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

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

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

493 494 495 496
			for ( var j = 0; j < skin.joints.length; j ++ ) {

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

T
timk 已提交
497 498
					found = j;
					break;
499

T
timk 已提交
500
				}
501

T
timk 已提交
502
			}
503

504
			if ( found >= 0 ) {
505 506 507

				var inv = skin.invBindMatrices[ found ];

T
timk 已提交
508 509
				bone.invBindMatrix = inv;
				bone.skinningMatrix = new THREE.Matrix4();
T
hmm  
timk 已提交
510
				bone.skinningMatrix.multiply(bone.world, inv); // (IBMi * JMi)
511

T
timk 已提交
512
				bone.weights = [];
513 514 515 516 517 518 519 520 521 522 523

				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 已提交
524
						}
525

T
timk 已提交
526
					}
527

T
timk 已提交
528
				}
529

T
timk 已提交
530
			} else {
531

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

T
timk 已提交
534
			}
535

T
timk 已提交
536
		}
537 538 539 540 541 542 543

	};

	function applySkin ( geometry, instanceCtrl, frame ) {

		var skinController = controllers[ instanceCtrl.url ];

T
timk 已提交
544
		frame = frame !== undefined ? frame : 40;
545 546 547

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

M
Mr.doob 已提交
548
			console.log( 'ColladaLoader: Could not find skin controller.' );
T
timk 已提交
549
			return;
550

T
timk 已提交
551 552
		}

553 554
		if ( !instanceCtrl.skeleton || !instanceCtrl.skeleton.length ) {

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

T
timk 已提交
558
		}
559

T
timk 已提交
560
		var animationBounds = calcAnimationBounds();
561 562 563
		var skeleton = daeScene.getChildById( instanceCtrl.skeleton[0], true ) ||
					   daeScene.getChildBySid( instanceCtrl.skeleton[0], true );

T
timk 已提交
564 565 566 567
		var i, j, w, vidx, weight;
		var v = new THREE.Vector3(), o, s;

		// move vertices to bind shape
568 569 570 571 572

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

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

T
timk 已提交
573
		}
574

T
timk 已提交
575
		// process animation, or simply pose the rig if no animation
576 577 578

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

T
timk 已提交
579 580
			var bones = [];
			var skinned = [];
581

T
timk 已提交
582
			// zero skinned vertices
583 584 585

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

T
timk 已提交
586
				skinned.push( new THREE.Vertex( new THREE.Vector3() ) );
587

T
timk 已提交
588
			}
589 590

			// process the frame and setup the rig with a fresh
T
timk 已提交
591
			// transform, possibly from the bone's animation channel(s)
592 593 594 595

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

T
timk 已提交
596
			// skin 'm
597 598 599

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

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

602 603 604
				for ( j = 0; j < bones[ i ].weights.length; j ++ ) {

					w = bones[ i ].weights[ j ];
T
timk 已提交
605 606
					vidx = w.index;
					weight = w.weight;
607

T
timk 已提交
608 609
					o = geometry.vertices[vidx];
					s = skinned[vidx];
610

T
timk 已提交
611 612 613
					v.x = o.position.x;
					v.y = o.position.y;
					v.z = o.position.z;
614

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

T
timk 已提交
617 618 619
					s.position.x += (v.x * weight);
					s.position.y += (v.y * weight);
					s.position.z += (v.z * weight);
620

T
timk 已提交
621
				}
622

T
timk 已提交
623
			}
624

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

T
timk 已提交
627
		}
628 629 630 631 632

	};

	function createSceneGraph ( node, parent ) {

T
timk 已提交
633 634
		var obj = new THREE.Object3D();
		var skinned = false;
T
timk 已提交
635 636
		var skinController;
		var morphController;
637
		var i, j;
638

T
timk 已提交
639
		// FIXME: controllers
640

641
		for ( i = 0; i < node.controllers.length; i ++ ) {
642

643
			var controller = controllers[ node.controllers[ i ].url ];
644 645 646

			switch ( controller.type ) {

T
timk 已提交
647
				case 'skin':
648

649
					if ( geometries[ controller.skin.source ] ) {
650

T
timk 已提交
651
						var inst_geom = new InstanceGeometry();
652

T
timk 已提交
653
						inst_geom.url = controller.skin.source;
654 655 656
						inst_geom.instance_material = node.controllers[ i ].instance_material;

						node.geometries.push( inst_geom );
T
timk 已提交
657
						skinned = true;
658
						skinController = node.controllers[ i ];
659

660
					} else if ( controllers[ controller.skin.source ] ) {
661

T
timk 已提交
662 663
						// urgh: controller can be chained
						// handle the most basic case...
664 665

						var second = controllers[ controller.skin.source ];
T
timk 已提交
666 667
						morphController = second;
					//	skinController = node.controllers[i];
668 669 670

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

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

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

							node.geometries.push( inst_geom );

T
timk 已提交
678
						}
679

T
timk 已提交
680
					}
681

T
timk 已提交
682
					break;
683

T
timk 已提交
684
				case 'morph':
685

686
					if ( geometries[ controller.morph.source ] ) {
687

T
timk 已提交
688
						var inst_geom = new InstanceGeometry();
689

T
timk 已提交
690
						inst_geom.url = controller.morph.source;
691 692 693 694
						inst_geom.instance_material = node.controllers[ i ].instance_material;

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

T
timk 已提交
696
					}
697

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

T
timk 已提交
700 701
				default:
					break;
702

T
timk 已提交
703
			}
704

T
timk 已提交
705
		}
706

T
timk 已提交
707
		// FIXME: multi-material mesh?
T
timk 已提交
708
		// geometries
709 710 711

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

T
timk 已提交
712 713 714
			var instance_geometry = node.geometries[i];
			var instance_materials = instance_geometry.instance_material;
			var geometry = geometries[instance_geometry.url];
T
timk 已提交
715
			var used_materials = {};
716
			var used_materials_array = [];
T
timk 已提交
717 718
			var num_materials = 0;
			var first_material;
719 720 721

			if ( geometry ) {

722
				if ( !geometry.mesh || !geometry.mesh.primitives )
T
timk 已提交
723
					continue;
724

725
				if ( obj.name.length == 0 ) {
726

T
timk 已提交
727
					obj.name = geometry.id;
728

T
timk 已提交
729
				}
730

T
timk 已提交
731
				// collect used fx for this geometry-instance
732 733 734 735 736

				if ( instance_materials ) {

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

737 738
						var instance_material = instance_materials[ j ];
						var mat = materials[ instance_material.target ];
739
						var effect_id = mat.instance_effect.url;
740
						var shader = effects[ effect_id ].shader;
741

T
timk 已提交
742
						shader.material.opacity = !shader.material.opacity ? 1 : shader.material.opacity;
743 744
						used_materials[ instance_material.symbol ] = num_materials;
						used_materials_array.push( shader.material )
T
timk 已提交
745
						first_material = shader.material;
746
						first_material.name = mat.name == null || mat.name === '' ? mat.id : mat.name;
747 748
						num_materials ++;

T
timk 已提交
749
					}
750

T
timk 已提交
751
				}
752

T
timk 已提交
753
				var mesh;
754
				var material = first_material || new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.FlatShading } );
T
timk 已提交
755
				var geom = geometry.mesh.geometry3js;
756 757 758

				if ( num_materials > 1 ) {

T
timk 已提交
759
					material = new THREE.MeshFaceMaterial();
760
					geom.materials = used_materials_array;
761

762 763 764
					for ( j = 0; j < geom.faces.length; j ++ ) {

						var face = geom.faces[ j ];
765
						face.materialIndex = used_materials[ face.daeMaterial ]
766

T
timk 已提交
767
					}
768

T
timk 已提交
769
				}
770 771 772 773 774

				if ( skinController !== undefined) {

					applySkin( geom, skinController );

T
timk 已提交
775
					material.morphTargets = true;
776

T
timk 已提交
777 778
					mesh = new THREE.SkinnedMesh( geom, material );
					mesh.skeleton = skinController.skeleton;
779
					mesh.skinController = controllers[ skinController.url ];
T
timk 已提交
780
					mesh.skinInstanceController = skinController;
T
timk 已提交
781
					mesh.name = 'skin_' + skins.length;
782 783 784 785 786 787 788

					skins.push( mesh );

				} else if ( morphController !== undefined ) {

					createMorph( geom, morphController );

T
timk 已提交
789
					material.morphTargets = true;
790

T
timk 已提交
791 792
					mesh = new THREE.Mesh( geom, material );
					mesh.name = 'morph_' + morphs.length;
793 794 795

					morphs.push( mesh );

T
timk 已提交
796
				} else {
797

T
timk 已提交
798
					mesh = new THREE.Mesh( geom, material );
799
					// mesh.geom.name = geometry.id;
800

T
timk 已提交
801
				}
802

803
				node.geometries.length > 1 ? obj.add( mesh ) : obj = mesh;
804

T
timk 已提交
805
			}
806

T
timk 已提交
807
		}
808

809 810 811 812 813 814 815 816 817
		for ( i = 0; i < node.cameras.length; i ++ ) {

			var instance_camera = node.cameras[i];
			var cparams = cameras[instance_camera.url];

			obj = new THREE.PerspectiveCamera(cparams.fov, cparams.aspect_ratio, cparams.znear, cparams.zfar);

		}

818
		obj.name = node.id || "";
819 820 821 822 823 824
		obj.matrix = node.matrix;
		var props = node.matrix.decompose();
		obj.position = props[ 0 ];
		obj.quaternion = props[ 1 ];
		obj.useQuaternion = true;
		obj.scale = props[ 2 ];
825

826 827 828 829 830 831 832 833
		if ( options.centerGeometry && obj.geometry ) {

			var delta = THREE.GeometryUtils.center( obj.geometry );
			obj.quaternion.multiplyVector3( delta.multiplySelf( obj.scale ) );
			obj.position.subSelf( delta );

		}

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

836
			obj.add( createSceneGraph( node.nodes[i], node ) );
837

T
timk 已提交
838
		}
839

T
timk 已提交
840
		return obj;
841 842 843 844 845 846 847 848 849

	};

	function getJointId( skin, id ) {

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

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

T
timk 已提交
850
				return i;
851

T
timk 已提交
852
			}
853

T
timk 已提交
854
		}
855 856 857 858 859

	};

	function getLibraryNode( id ) {

860
		return COLLADA.evaluate( './/dae:library_nodes//dae:node[@id=\'' + id + '\']', COLLADA, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null ).iterateNext();
861 862 863 864 865

	};

	function getChannelsForNode (node ) {

T
timk 已提交
866 867 868
		var channels = [];
		var startTime = 1000000;
		var endTime = -1000000;
869 870 871

		for ( var id in animations ) {

T
timk 已提交
872
			var animation = animations[id];
873 874 875

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

T
timk 已提交
876 877 878
				var channel = animation.channel[i];
				var sampler = animation.sampler[i];
				var id = channel.target.split('/')[0];
879 880 881

				if ( id == node.id ) {

T
timk 已提交
882 883 884 885 886
					sampler.create();
					channel.sampler = sampler;
					startTime = Math.min(startTime, sampler.startTime);
					endTime = Math.max(endTime, sampler.endTime);
					channels.push(channel);
887

T
timk 已提交
888
				}
889

T
timk 已提交
890
			}
891

T
timk 已提交
892
		}
893 894 895

		if ( channels.length ) {

T
timk 已提交
896
			node.startTime = startTime;
897 898
			node.endTime = endTime;

T
timk 已提交
899
		}
900

T
timk 已提交
901
		return channels;
902 903 904 905 906

	};

	function calcFrameDuration( node ) {

T
timk 已提交
907
		var minT = 10000000;
908

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

T
timk 已提交
911
			var sampler = node.channels[i].sampler;
912

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

915 916 917
				var t0 = sampler.input[ j ];
				var t1 = sampler.input[ j + 1 ];
				minT = Math.min( minT, t1 - t0 );
918

T
timk 已提交
919 920
			}
		}
921

T
timk 已提交
922
		return minT;
923 924 925 926 927

	};

	function calcMatrixAt( node, t ) {

T
timk 已提交
928
		var animated = {};
929

T
timk 已提交
930
		var i, j;
931 932 933 934

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

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

T
timk 已提交
937
		}
938

T
timk 已提交
939
		var matrix = new THREE.Matrix4();
940 941 942

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

943 944
			var transform = node.transforms[ i ];
			var channel = animated[ transform.sid ];
945 946 947

			if ( channel !== undefined ) {

T
timk 已提交
948 949
				var sampler = channel.sampler;
				var value;
950

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

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

955
						value = sampler.output[ j ];
T
timk 已提交
956 957
						//console.log(value.flatten)
						break;
958

T
timk 已提交
959
					}
960

T
timk 已提交
961
				}
962 963 964 965 966 967 968

				if ( value !== undefined ) {

					if ( value instanceof THREE.Matrix4 ) {

						matrix = matrix.multiply( matrix, value );

T
timk 已提交
969
					} else {
970

T
timk 已提交
971
						// FIXME: handle other types
972 973 974

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

T
timk 已提交
975
					}
976

T
timk 已提交
977
				} else {
978 979 980

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

T
timk 已提交
981
				}
982

T
timk 已提交
983
			} else {
984 985 986

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

T
timk 已提交
987
			}
988

T
timk 已提交
989
		}
990

T
timk 已提交
991
		return matrix;
992 993 994 995 996 997 998

	};

	function bakeAnimations ( node ) {

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

999 1000
			var keys = [],
				sids = [];
1001

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

1004 1005 1006 1007 1008 1009
				var channel = node.channels[i],
					fullSid = channel.fullSid,
					member = getConvertedMember( channel.member ),
					sampler = channel.sampler,
					input = sampler.input,
					transform = node.getTransformBySid( channel.sid );
1010

1011
				if ( transform ) {
1012

1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 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
					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 );

					}

				}
1061

T
timk 已提交
1062
			}
1063

T
timk 已提交
1064
			node.keys = keys;
1065
			node.sids = sids;
1066

T
timk 已提交
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 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191
	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 已提交
1192
	function _Image() {
1193

T
timk 已提交
1194 1195
		this.id = "";
		this.init_from = "";
1196 1197 1198

	};

T
timk 已提交
1199
	_Image.prototype.parse = function(element) {
1200

T
timk 已提交
1201
		this.id = element.getAttribute('id');
1202 1203 1204 1205 1206 1207 1208

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

			var child = element.childNodes[ i ];

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

T
timk 已提交
1209
				this.init_from = child.textContent;
1210

T
timk 已提交
1211
			}
1212

T
timk 已提交
1213
		}
1214

T
timk 已提交
1215
		return this;
1216 1217 1218

	};

T
timk 已提交
1219
	function Controller() {
1220

T
timk 已提交
1221 1222 1223 1224 1225
		this.id = "";
		this.name = "";
		this.type = "";
		this.skin = null;
		this.morph = null;
1226 1227 1228 1229 1230

	};

	Controller.prototype.parse = function( element ) {

T
timk 已提交
1231 1232 1233
		this.id = element.getAttribute('id');
		this.name = element.getAttribute('name');
		this.type = "none";
1234 1235 1236 1237 1238 1239 1240

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

			var child = element.childNodes[ i ];

			switch ( child.nodeName ) {

T
timk 已提交
1241
				case 'skin':
1242

T
timk 已提交
1243 1244 1245
					this.skin = (new Skin()).parse(child);
					this.type = child.nodeName;
					break;
1246

T
timk 已提交
1247
				case 'morph':
1248

T
timk 已提交
1249 1250 1251
					this.morph = (new Morph()).parse(child);
					this.type = child.nodeName;
					break;
1252

T
timk 已提交
1253 1254
				default:
					break;
1255

T
timk 已提交
1256 1257
			}
		}
1258

T
timk 已提交
1259
		return this;
1260 1261 1262

	};

T
timk 已提交
1263
	function Morph() {
1264

M
Mr.doob 已提交
1265 1266 1267 1268
		this.method = null;
		this.source = null;
		this.targets = null;
		this.weights = null;
1269 1270 1271 1272 1273

	};

	Morph.prototype.parse = function( element ) {

T
timk 已提交
1274 1275 1276
		var sources = {};
		var inputs = [];
		var i;
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287

		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 已提交
1288
				case 'source':
1289 1290 1291

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

T
timk 已提交
1294
				case 'targets':
1295 1296

					inputs = this.parseInputs( child );
T
timk 已提交
1297
					break;
1298

T
timk 已提交
1299
				default:
1300 1301

					console.log( child.nodeName );
T
timk 已提交
1302
					break;
1303

T
timk 已提交
1304
			}
1305

T
timk 已提交
1306
		}
1307 1308 1309 1310 1311 1312 1313 1314

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

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

			switch ( input.semantic ) {

T
timk 已提交
1315
				case 'MORPH_TARGET':
1316

T
timk 已提交
1317 1318
					this.targets = source.read();
					break;
1319

T
timk 已提交
1320
				case 'MORPH_WEIGHT':
1321

T
timk 已提交
1322 1323
					this.weights = source.read();
					break;
1324

T
timk 已提交
1325 1326
				default:
					break;
1327

T
timk 已提交
1328 1329
			}
		}
1330

T
timk 已提交
1331
		return this;
1332 1333 1334

	};

T
timk 已提交
1335
	Morph.prototype.parseInputs = function(element) {
1336

T
timk 已提交
1337
		var inputs = [];
1338 1339 1340

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

T
timk 已提交
1341
			var child = element.childNodes[i];
1342 1343 1344 1345
			if ( child.nodeType != 1) continue;

			switch ( child.nodeName ) {

T
timk 已提交
1346
				case 'input':
1347 1348

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

T
timk 已提交
1351 1352 1353 1354
				default:
					break;
			}
		}
1355

T
timk 已提交
1356
		return inputs;
1357 1358 1359

	};

T
timk 已提交
1360
	function Skin() {
1361

T
timk 已提交
1362
		this.source = "";
T
timk 已提交
1363 1364 1365 1366
		this.bindShapeMatrix = null;
		this.invBindMatrices = [];
		this.joints = [];
		this.weights = [];
1367 1368 1369 1370 1371

	};

	Skin.prototype.parse = function( element ) {

T
timk 已提交
1372 1373
		var sources = {};
		var joints, weights;
1374 1375

		this.source = element.getAttribute( 'source' ).replace( /^#/, '' );
T
timk 已提交
1376 1377 1378
		this.invBindMatrices = [];
		this.joints = [];
		this.weights = [];
1379 1380 1381

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

T
timk 已提交
1382
			var child = element.childNodes[i];
1383 1384 1385 1386
			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
1387
				case 'bind_shape_matrix':
1388

T
timk 已提交
1389
					var f = _floats(child.textContent);
1390
					this.bindShapeMatrix = getConvertedMat4( f );
T
timk 已提交
1391
					break;
1392

T
timk 已提交
1393
				case 'source':
1394

T
timk 已提交
1395
					var src = new Source().parse(child);
1396
					sources[ src.id ] = src;
T
timk 已提交
1397
					break;
1398

T
timk 已提交
1399
				case 'joints':
1400

T
timk 已提交
1401 1402
					joints = child;
					break;
1403

T
timk 已提交
1404
				case 'vertex_weights':
1405

T
timk 已提交
1406 1407
					weights = child;
					break;
1408

T
timk 已提交
1409
				default:
1410 1411

					console.log( child.nodeName );
T
timk 已提交
1412
					break;
1413

T
timk 已提交
1414 1415
			}
		}
1416 1417 1418 1419

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

T
timk 已提交
1420
		return this;
1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432

	};

	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 已提交
1433
				case 'input':
1434 1435 1436 1437 1438 1439

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

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

T
timk 已提交
1440
						this.joints = source.read();
1441 1442 1443

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

T
timk 已提交
1444
						this.invBindMatrices = source.read();
1445

T
timk 已提交
1446
					}
1447

T
timk 已提交
1448
					break;
1449

T
timk 已提交
1450 1451 1452
				default:
					break;
			}
1453

T
timk 已提交
1454
		}
1455 1456 1457 1458 1459

	};

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

T
timk 已提交
1460
		var v, vcount, inputs = [];
1461 1462 1463 1464 1465 1466 1467 1468

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

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

			switch ( child.nodeName ) {

T
timk 已提交
1469
				case 'input':
1470

1471
					inputs.push( ( new Input() ).parse( child ) );
T
timk 已提交
1472
					break;
1473

T
timk 已提交
1474
				case 'v':
1475

1476
					v = _ints( child.textContent );
T
timk 已提交
1477
					break;
1478

T
timk 已提交
1479
				case 'vcount':
1480

1481
					vcount = _ints( child.textContent );
T
timk 已提交
1482
					break;
1483

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

T
timk 已提交
1487
			}
1488

T
timk 已提交
1489
		}
1490

T
timk 已提交
1491
		var index = 0;
1492 1493 1494

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

T
timk 已提交
1495 1496
			var numBones = vcount[i];
			var vertex_weights = [];
1497 1498 1499

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

T
timk 已提交
1500
				var influence = {};
1501 1502 1503 1504 1505 1506 1507 1508

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

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

					switch ( input.semantic ) {

T
timk 已提交
1509
						case 'JOINT':
1510

T
timk 已提交
1511
							influence.joint = value;//this.joints[value];
T
timk 已提交
1512
							break;
1513

T
timk 已提交
1514
						case 'WEIGHT':
1515 1516

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

T
timk 已提交
1519 1520
						default:
							break;
1521

T
timk 已提交
1522
					}
1523

T
timk 已提交
1524
				}
1525 1526

				vertex_weights.push( influence );
T
timk 已提交
1527 1528
				index += inputs.length;
			}
1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543

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

				vertex_weights[ j ].index = i;

			}

			this.weights.push( vertex_weights );

		}

	};

	function VisualScene () {

T
timk 已提交
1544 1545 1546 1547
		this.id = "";
		this.name = "";
		this.nodes = [];
		this.scene = new THREE.Object3D();
1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558

	};

	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 已提交
1559
				return node;
1560

T
timk 已提交
1561
			}
1562

T
timk 已提交
1563
		}
1564

T
timk 已提交
1565
		return null;
1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576

	};

	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 已提交
1577
				return node;
1578

T
timk 已提交
1579
			}
1580

T
timk 已提交
1581
		}
1582

T
timk 已提交
1583
		return null;
1584 1585 1586 1587 1588 1589 1590

	};

	VisualScene.prototype.parse = function( element ) {

		this.id = element.getAttribute( 'id' );
		this.name = element.getAttribute( 'name' );
T
timk 已提交
1591
		this.nodes = [];
1592 1593 1594 1595 1596 1597 1598 1599

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

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

			switch ( child.nodeName ) {

T
timk 已提交
1600
				case 'node':
1601 1602

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

T
timk 已提交
1605 1606
				default:
					break;
1607

T
timk 已提交
1608
			}
1609

T
timk 已提交
1610
		}
1611

T
timk 已提交
1612
		return this;
1613 1614 1615

	};

T
timk 已提交
1616
	function Node() {
1617

T
timk 已提交
1618 1619 1620 1621 1622 1623 1624
		this.id = "";
		this.name = "";
		this.sid = "";
		this.nodes = [];
		this.controllers = [];
		this.transforms = [];
		this.geometries = [];
T
timk 已提交
1625
		this.channels = [];
T
timk 已提交
1626
		this.matrix = new THREE.Matrix4();
1627 1628 1629 1630 1631 1632 1633

	};

	Node.prototype.getChannelForTransform = function( transformSid ) {

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

T
timk 已提交
1634 1635 1636 1637 1638 1639 1640 1641
			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;
1642 1643 1644

			if ( dotSyntax ) {

T
timk 已提交
1645 1646 1647
				parts = sid.split(".");
				sid = parts.shift();
				member = parts.shift();
1648 1649 1650

			} else if ( arrSyntax ) {

T
timk 已提交
1651 1652
				arrIndices = sid.split("(");
				sid = arrIndices.shift();
1653 1654 1655 1656 1657

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

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

T
timk 已提交
1658
				}
1659

T
timk 已提交
1660
			}
1661

1662
			if ( sid == transformSid ) {
1663

1664
				channel.info = { sid: sid, dotSyntax: dotSyntax, arrSyntax: arrSyntax, arrIndices: arrIndices };
T
timk 已提交
1665
				return channel;
1666

T
timk 已提交
1667
			}
1668

T
timk 已提交
1669
		}
1670

T
timk 已提交
1671
		return null;
1672 1673 1674 1675 1676 1677 1678

	};

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

		if ( this.id == id ) {

T
timk 已提交
1679
			return this;
1680

T
timk 已提交
1681
		}
1682 1683 1684 1685 1686 1687 1688 1689 1690

		if ( recursive ) {

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

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

				if ( n ) {

T
timk 已提交
1691
					return n;
1692

T
timk 已提交
1693
				}
1694

T
timk 已提交
1695
			}
1696

T
timk 已提交
1697
		}
1698

T
timk 已提交
1699
		return null;
1700 1701 1702 1703 1704 1705 1706

	};

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

		if ( this.sid == sid ) {

T
timk 已提交
1707
			return this;
1708

T
timk 已提交
1709
		}
1710 1711 1712 1713 1714 1715 1716 1717 1718

		if ( recursive ) {

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

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

				if ( n ) {

T
timk 已提交
1719
					return n;
1720

T
timk 已提交
1721
				}
1722

T
timk 已提交
1723 1724
			}
		}
1725

T
timk 已提交
1726
		return null;
1727 1728 1729 1730 1731 1732 1733 1734 1735

	};

	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 已提交
1736
		}
1737

T
timk 已提交
1738
		return null;
1739 1740 1741 1742 1743

	};

	Node.prototype.parse = function( element ) {

T
timk 已提交
1744
		var url;
1745

T
timk 已提交
1746 1747 1748 1749
		this.id = element.getAttribute('id');
		this.sid = element.getAttribute('sid');
		this.name = element.getAttribute('name');
		this.type = element.getAttribute('type');
1750

T
timk 已提交
1751
		this.type = this.type == 'JOINT' ? this.type : 'NODE';
1752

T
timk 已提交
1753 1754 1755
		this.nodes = [];
		this.transforms = [];
		this.geometries = [];
1756
		this.cameras = [];
T
timk 已提交
1757 1758 1759
		this.controllers = [];
		this.matrix = new THREE.Matrix4();

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

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

			switch ( child.nodeName ) {

T
timk 已提交
1767
				case 'node':
1768 1769

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

T
timk 已提交
1772
				case 'instance_camera':
1773

1774
					this.cameras.push( ( new InstanceCamera() ).parse( child ) );
T
timk 已提交
1775
					break;
1776

T
timk 已提交
1777
				case 'instance_controller':
1778 1779

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

T
timk 已提交
1782
				case 'instance_geometry':
1783 1784

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

T
timk 已提交
1787
				case 'instance_light':
1788

T
timk 已提交
1789
					break;
1790

T
timk 已提交
1791
				case 'instance_node':
1792 1793 1794 1795 1796 1797 1798 1799

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

					if ( iNode ) {

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

T
timk 已提交
1800
					}
1801

T
timk 已提交
1802
					break;
1803

T
timk 已提交
1804 1805 1806 1807 1808 1809
				case 'rotate':
				case 'translate':
				case 'scale':
				case 'matrix':
				case 'lookat':
				case 'skew':
1810 1811

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

T
timk 已提交
1814 1815
				case 'extra':
					break;
1816

T
timk 已提交
1817
				default:
1818 1819

					console.log( child.nodeName );
T
timk 已提交
1820
					break;
1821

T
timk 已提交
1822
			}
1823

T
timk 已提交
1824
		}
1825 1826 1827 1828

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

T
timk 已提交
1829
		this.updateMatrix();
1830

T
timk 已提交
1831
		return this;
1832 1833 1834 1835 1836

	};

	Node.prototype.updateMatrix = function () {

T
timk 已提交
1837
		this.matrix.identity();
1838 1839 1840

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

1841
			this.transforms[ i ].apply( this.matrix );
1842

T
timk 已提交
1843
		}
1844 1845 1846 1847 1848

	};

	function Transform () {

T
timk 已提交
1849 1850 1851
		this.sid = "";
		this.type = "";
		this.data = [];
1852
		this.obj = null;
1853 1854 1855 1856 1857 1858

	};

	Transform.prototype.parse = function ( element ) {

		this.sid = element.getAttribute( 'sid' );
T
timk 已提交
1859
		this.type = element.nodeName;
1860
		this.data = _floats( element.textContent );
1861
		this.convert();
1862

T
timk 已提交
1863
		return this;
1864 1865 1866

	};

1867
	Transform.prototype.convert = function () {
1868

1869
		switch ( this.type ) {
1870

1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900
			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 ) {
1901 1902 1903

		switch ( this.type ) {

T
timk 已提交
1904
			case 'matrix':
1905

1906
				matrix.multiplySelf( this.obj );
T
timk 已提交
1907
				break;
1908

T
timk 已提交
1909
			case 'translate':
1910

1911
				matrix.translate( this.obj );
T
timk 已提交
1912
				break;
1913

T
timk 已提交
1914
			case 'rotate':
1915

1916
				matrix.rotateByAxis( this.obj, this.angle );
T
timk 已提交
1917
				break;
1918

T
timk 已提交
1919
			case 'scale':
1920

1921
				matrix.scale( this.obj );
T
timk 已提交
1922
				break;
1923

1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934
		}

	};

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

		switch ( this.type ) {

			case 'matrix':

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

1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980
			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;
1981

1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003
					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;

		}
2004 2005

	};
T
timk 已提交
2006 2007

	function InstanceController() {
2008

T
timk 已提交
2009 2010 2011
		this.url = "";
		this.skeleton = [];
		this.instance_material = [];
2012 2013 2014 2015 2016

	};

	InstanceController.prototype.parse = function ( element ) {

T
timk 已提交
2017 2018 2019
		this.url = element.getAttribute('url').replace(/^#/, '');
		this.skeleton = [];
		this.instance_material = [];
2020 2021 2022

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

T
timk 已提交
2023 2024
			var child = element.childNodes[i];
			if (child.nodeType != 1) continue;
2025 2026 2027

			switch ( child.nodeName ) {

T
timk 已提交
2028
				case 'skeleton':
2029 2030

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

T
timk 已提交
2033
				case 'bind_material':
2034

2035
					var instances = COLLADA.evaluate( './/dae:instance_material', child, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );
2036 2037 2038

					if ( instances ) {

T
timk 已提交
2039
						var instance = instances.iterateNext();
2040 2041 2042

						while ( instance ) {

T
timk 已提交
2043
							this.instance_material.push((new InstanceMaterial()).parse(instance));
2044 2045
							instance = instances.iterateNext();

T
timk 已提交
2046
						}
2047

T
timk 已提交
2048
					}
2049

T
timk 已提交
2050
					break;
2051

T
timk 已提交
2052 2053
				case 'extra':
					break;
2054

T
timk 已提交
2055 2056
				default:
					break;
2057

T
timk 已提交
2058 2059
			}
		}
2060

T
timk 已提交
2061
		return this;
2062 2063 2064 2065 2066

	};

	function InstanceMaterial () {

T
timk 已提交
2067 2068
		this.symbol = "";
		this.target = "";
2069 2070 2071 2072 2073

	};

	InstanceMaterial.prototype.parse = function ( element ) {

T
timk 已提交
2074 2075 2076
		this.symbol = element.getAttribute('symbol');
		this.target = element.getAttribute('target').replace(/^#/, '');
		return this;
2077 2078 2079

	};

T
timk 已提交
2080
	function InstanceGeometry() {
2081

T
timk 已提交
2082 2083
		this.url = "";
		this.instance_material = [];
2084 2085 2086

	};

2087
	InstanceGeometry.prototype.parse = function ( element ) {
2088

T
timk 已提交
2089 2090
		this.url = element.getAttribute('url').replace(/^#/, '');
		this.instance_material = [];
2091 2092 2093

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

T
timk 已提交
2094
			var child = element.childNodes[i];
2095
			if ( child.nodeType != 1 ) continue;
2096 2097 2098

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

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

2101
				if ( instances ) {
2102

T
timk 已提交
2103
					var instance = instances.iterateNext();
2104 2105 2106 2107 2108 2109

					while ( instance ) {

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

T
timk 已提交
2110
					}
2111

T
timk 已提交
2112
				}
2113

T
timk 已提交
2114
				break;
2115

T
timk 已提交
2116
			}
2117

T
timk 已提交
2118
		}
2119

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

	};

T
timk 已提交
2124
	function Geometry() {
2125

T
timk 已提交
2126 2127
		this.id = "";
		this.mesh = null;
2128 2129 2130 2131 2132

	};

	Geometry.prototype.parse = function ( element ) {

T
timk 已提交
2133
		this.id = element.getAttribute('id');
2134 2135 2136

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

T
timk 已提交
2137
			var child = element.childNodes[i];
2138 2139 2140

			switch ( child.nodeName ) {

T
timk 已提交
2141
				case 'mesh':
2142

T
timk 已提交
2143 2144
					this.mesh = (new Mesh(this)).parse(child);
					break;
2145

2146
				case 'extra':
2147

2148 2149 2150
					// console.log( child );
					break;

T
timk 已提交
2151 2152 2153 2154
				default:
					break;
			}
		}
2155

T
timk 已提交
2156
		return this;
2157 2158 2159 2160 2161

	};

	function Mesh( geometry ) {

T
timk 已提交
2162 2163 2164
		this.geometry = geometry.id;
		this.primitives = [];
		this.vertices = null;
M
Mr.doob 已提交
2165
		this.geometry3js = null;
2166 2167 2168 2169 2170

	};

	Mesh.prototype.parse = function( element ) {

T
timk 已提交
2171
		this.primitives = [];
2172

T
timk 已提交
2173
		var i, j;
2174 2175 2176

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

2177
			var child = element.childNodes[ i ];
2178

2179
			switch ( child.nodeName ) {
2180

T
timk 已提交
2181
				case 'source':
2182

2183
					_source( child );
T
timk 已提交
2184
					break;
2185

T
timk 已提交
2186
				case 'vertices':
2187

2188
					this.vertices = ( new Vertices() ).parse( child );
T
timk 已提交
2189
					break;
2190

T
timk 已提交
2191
				case 'triangles':
2192

2193
					this.primitives.push( ( new Triangles().parse( child ) ) );
T
timk 已提交
2194
					break;
2195

T
timk 已提交
2196
				case 'polygons':
2197

2198
					console.warn( 'polygon holes not yet supported!' );
2199

T
timk 已提交
2200
				case 'polylist':
2201

2202
					this.primitives.push( ( new Polylist().parse( child ) ) );
T
timk 已提交
2203
					break;
2204

T
timk 已提交
2205 2206
				default:
					break;
2207

T
timk 已提交
2208
			}
2209

T
timk 已提交
2210
		}
2211

T
timk 已提交
2212
		this.geometry3js = new THREE.Geometry();
2213 2214 2215

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

2216
		for ( i = 0; i < vertexData.length; i += 3 ) {
2217

2218
			var v = new THREE.Vertex( getConvertedVec3( vertexData, i ) );
2219
			this.geometry3js.vertices.push( v );
2220

T
timk 已提交
2221
		}
T
timk 已提交
2222

2223 2224
		for ( i = 0; i < this.primitives.length; i ++ ) {

2225
			var primitive = this.primitives[ i ];
2226
			primitive.setVertices( this.vertices );
2227
			this.handlePrimitive( primitive, this.geometry3js );
2228

T
timk 已提交
2229
		}
2230

T
timk 已提交
2231 2232
		this.geometry3js.computeCentroids();
		this.geometry3js.computeFaceNormals();
2233
		
2234
		if ( this.geometry3js.calcNormals ) {
2235 2236
			
			this.geometry3js.computeVertexNormals();
2237
			delete this.geometry3js.calcNormals;
2238 2239 2240
			
		}
		
T
timk 已提交
2241
		this.geometry3js.computeBoundingBox();
2242

T
timk 已提交
2243
		return this;
2244 2245 2246

	};

2247
	Mesh.prototype.handlePrimitive = function( primitive, geom ) {
2248

T
timk 已提交
2249 2250
		var i = 0, j, k, p = primitive.p, inputs = primitive.inputs;
		var input, index, idx32;
2251
		var source, numParams;
2252
		var vcIndex = 0, vcount = 3, maxOffset = 0;
T
timk 已提交
2253
		var texture_sets = [];
2254 2255 2256

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

2257
			input = inputs[ j ];
2258 2259
			var offset = input.offset + 1;
			maxOffset = (maxOffset < offset)? offset : maxOffset;
2260

2261
			switch ( input.semantic ) {
2262

2263 2264 2265
				case 'TEXCOORD':
					texture_sets.push( input.set );
					break;
2266

T
timk 已提交
2267
			}
2268

T
timk 已提交
2269
		}
2270 2271 2272

		while ( i < p.length ) {

T
timk 已提交
2273 2274 2275
			var vs = [];
			var ns = [];
			var ts = {};
2276
			var cs = [];
2277 2278 2279 2280 2281

			if ( primitive.vcount ) {

				vcount = primitive.vcount[ vcIndex ++ ];

T
timk 已提交
2282
			}
2283 2284 2285 2286 2287

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

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

2288 2289 2290
					input = inputs[ k ];
					source = sources[ input.source ];

2291
					index = p[ i + ( j * maxOffset ) + input.offset ];
T
timk 已提交
2292 2293
					numParams = source.accessor.params.length;
					idx32 = index * numParams;
2294

2295
					switch ( input.semantic ) {
2296

T
timk 已提交
2297
						case 'VERTEX':
2298

2299
							vs.push( index );
2300

T
timk 已提交
2301
							break;
2302

T
timk 已提交
2303
						case 'NORMAL':
2304

2305
							ns.push( getConvertedVec3( source.data, idx32 ) );
2306

T
timk 已提交
2307
							break;
2308

T
timk 已提交
2309
						case 'TEXCOORD':
2310

2311
							if ( ts[ input.set ] === undefined ) ts[ input.set ] = [];
2312 2313
							// invert the V
							ts[ input.set ].push( new THREE.UV( source.data[ idx32 ], 1.0 - source.data[ idx32 + 1 ] ) );
2314

T
timk 已提交
2315
							break;
2316

2317
						case 'COLOR':
2318 2319

							cs.push( new THREE.Color().setRGB( source.data[ idx32 ], source.data[ idx32 + 1 ], source.data[ idx32 + 2 ] ) );
2320 2321 2322

							break;

T
timk 已提交
2323 2324
						default:
							break;
2325

T
timk 已提交
2326
					}
2327

T
timk 已提交
2328
				}
2329

T
timk 已提交
2330
			}
2331

2332

2333 2334
			var face = null, faces = [], uv, uvArr;

2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359
			if ( ns.length == 0 ) {
				
				// check the vertices source
				input = this.vertices.input.NORMAL;

				if ( input ) {

					source = sources[ input.source ];
					numParams = source.accessor.params.length;

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

						ns.push( getConvertedVec3( source.data, vs[ ndx ] * numParams ) );

					}

				}
				else {
					
					geom.calcNormals = true;
					
				}

			}

2360 2361
			if ( vcount === 3 ) {

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

			} else if ( vcount === 4 ) {
2365 2366
				
				faces.push( new THREE.Face4( vs[0], vs[1], vs[2], vs[3], ns, cs.length ? cs : new THREE.Color() ) );
2367

2368
			} else if ( vcount > 4 && options.subdivideFaces ) {
2369

2370 2371
				var clr = cs.length ? cs : new THREE.Color(),
					vec1, vec2, vec3, v1, v2, norm;
2372

2373 2374
				// subdivide into multiple Face3s
				for ( k = 1; k < vcount-1; ) {
2375

2376 2377 2378 2379
					// 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 ) );

				}
2380 2381

			}
2382

2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395
			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 ) {
2396

2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408
							// 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] ];

						}
2409

2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424
						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 );
2425 2426 2427

			}

2428
			i += maxOffset * vcount;
2429

T
timk 已提交
2430
		}
2431 2432 2433 2434 2435 2436 2437

	};


	function Polylist () {
	};

T
timk 已提交
2438 2439
	Polylist.prototype = new Triangles();
	Polylist.prototype.constructor = Polylist;
2440 2441 2442

	function Triangles( flip_uv ) {

T
timk 已提交
2443 2444 2445
		this.material = "";
		this.count = 0;
		this.inputs = [];
M
Mr.doob 已提交
2446
		this.vcount = null;
T
timk 已提交
2447 2448
		this.p = [];
		this.geometry = new THREE.Geometry();
2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459

	};

	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 已提交
2460
			}
2461

T
timk 已提交
2462
		}
2463 2464 2465

	};

2466
	Triangles.prototype.parse = function ( element ) {
2467

T
timk 已提交
2468
		this.inputs = [];
2469 2470
		this.material = element.getAttribute( 'material' );
		this.count = _attr_as_int( element, 'count', 0 );
2471 2472 2473 2474 2475 2476 2477

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

			var child = element.childNodes[ i ];

			switch ( child.nodeName ) {

T
timk 已提交
2478
				case 'input':
2479

2480
					this.inputs.push( ( new Input() ).parse( element.childNodes[ i ] ) );
T
timk 已提交
2481
					break;
2482

T
timk 已提交
2483
				case 'vcount':
2484

2485
					this.vcount = _ints( child.textContent );
T
timk 已提交
2486
					break;
2487

T
timk 已提交
2488
				case 'p':
2489

2490
					this.p = _ints( child.textContent );
T
timk 已提交
2491
					break;
2492

T
timk 已提交
2493 2494
				default:
					break;
2495

T
timk 已提交
2496
			}
2497

T
timk 已提交
2498
		}
2499

T
timk 已提交
2500
		return this;
2501 2502 2503

	};

T
timk 已提交
2504
	function Accessor() {
2505

T
timk 已提交
2506 2507 2508 2509
		this.source = "";
		this.count = 0;
		this.stride = 0;
		this.params = [];
2510 2511 2512

	};

2513
	Accessor.prototype.parse = function ( element ) {
2514

T
timk 已提交
2515
		this.params = [];
2516 2517 2518
		this.source = element.getAttribute( 'source' );
		this.count = _attr_as_int( element, 'count', 0 );
		this.stride = _attr_as_int( element, 'stride', 0 );
2519 2520 2521

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

2522
			var child = element.childNodes[ i ];
2523 2524 2525

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

T
timk 已提交
2526
				var param = {};
2527 2528 2529
				param[ 'name' ] = child.getAttribute( 'name' );
				param[ 'type' ] = child.getAttribute( 'type' );
				this.params.push( param );
2530

T
timk 已提交
2531
			}
2532

T
timk 已提交
2533
		}
2534

T
timk 已提交
2535
		return this;
2536 2537 2538

	};

T
timk 已提交
2539
	function Vertices() {
2540

T
timk 已提交
2541
		this.input = {};
2542 2543 2544 2545 2546

	};

	Vertices.prototype.parse = function ( element ) {

T
timk 已提交
2547
		this.id = element.getAttribute('id');
2548 2549 2550 2551 2552

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

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

2553 2554
				var input = ( new Input() ).parse( element.childNodes[ i ] );
				this.input[ input.semantic ] = input;
2555

T
timk 已提交
2556
			}
2557

T
timk 已提交
2558
		}
2559

T
timk 已提交
2560
		return this;
2561 2562 2563 2564 2565

	};

	function Input () {

T
timk 已提交
2566 2567 2568 2569
		this.semantic = "";
		this.offset = 0;
		this.source = "";
		this.set = 0;
2570 2571 2572 2573 2574

	};

	Input.prototype.parse = function ( element ) {

T
timk 已提交
2575 2576 2577 2578
		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);
2579 2580 2581

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

T
timk 已提交
2582
			this.set = 0;
2583

T
timk 已提交
2584
		}
2585

T
timk 已提交
2586
		return this;
2587 2588 2589 2590 2591

	};

	function Source ( id ) {

T
timk 已提交
2592 2593
		this.id = id;
		this.type = null;
2594 2595 2596 2597 2598 2599 2600 2601 2602

	};

	Source.prototype.parse = function ( element ) {

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

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

T
timk 已提交
2603
			var child = element.childNodes[i];
2604 2605 2606

			switch ( child.nodeName ) {

T
timk 已提交
2607
				case 'bool_array':
2608

2609
					this.data = _bools( child.textContent );
T
timk 已提交
2610 2611
					this.type = child.nodeName;
					break;
2612

T
timk 已提交
2613
				case 'float_array':
2614

2615
					this.data = _floats( child.textContent );
T
timk 已提交
2616 2617
					this.type = child.nodeName;
					break;
2618

T
timk 已提交
2619
				case 'int_array':
2620

2621
					this.data = _ints( child.textContent );
T
timk 已提交
2622 2623
					this.type = child.nodeName;
					break;
2624

T
timk 已提交
2625 2626
				case 'IDREF_array':
				case 'Name_array':
2627

2628
					this.data = _strings( child.textContent );
T
timk 已提交
2629 2630
					this.type = child.nodeName;
					break;
2631

T
timk 已提交
2632
				case 'technique_common':
2633 2634 2635

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

2636
						if ( child.childNodes[ j ].nodeName == 'accessor' ) {
2637

2638
							this.accessor = ( new Accessor() ).parse( child.childNodes[ j ] );
T
timk 已提交
2639
							break;
2640

T
timk 已提交
2641 2642 2643
						}
					}
					break;
2644

T
timk 已提交
2645
				default:
M
Mr.doob 已提交
2646
					// console.log(child.nodeName);
T
timk 已提交
2647
					break;
2648

T
timk 已提交
2649
			}
2650

T
timk 已提交
2651
		}
2652

T
timk 已提交
2653
		return this;
2654 2655 2656 2657 2658

	};

	Source.prototype.read = function () {

T
timk 已提交
2659
		var result = [];
2660

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

2663
			var param = this.accessor.params[ 0 ];
2664

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

2667
			switch ( param.type ) {
2668

T
timk 已提交
2669
				case 'IDREF':
2670
				case 'Name': case 'name':
T
timk 已提交
2671
				case 'float':
2672

T
timk 已提交
2673
					return this.data;
2674

T
timk 已提交
2675
				case 'float4x4':
2676 2677 2678

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

2679
						var s = this.data.slice( j, j + 16 );
2680
						var m = getConvertedMat4( s );
2681
						result.push( m );
T
timk 已提交
2682
					}
2683

T
timk 已提交
2684
					break;
2685

T
timk 已提交
2686
				default:
2687

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

T
timk 已提交
2691
			}
2692

T
timk 已提交
2693
		//}
2694

T
timk 已提交
2695
		return result;
2696 2697 2698 2699 2700

	};

	function Material () {

T
timk 已提交
2701 2702 2703
		this.id = "";
		this.name = "";
		this.instance_effect = null;
2704 2705 2706 2707 2708

	};

	Material.prototype.parse = function ( element ) {

2709 2710
		this.id = element.getAttribute( 'id' );
		this.name = element.getAttribute( 'name' );
2711 2712 2713

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

2714 2715 2716
			if ( element.childNodes[ i ].nodeName == 'instance_effect' ) {

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

T
timk 已提交
2719
			}
2720

T
timk 已提交
2721
		}
2722

T
timk 已提交
2723
		return this;
2724 2725 2726 2727 2728

	};

	function ColorOrTexture () {

2729 2730
		this.color = new THREE.Color( 0 );
		this.color.setRGB( Math.random(), Math.random(), Math.random() );
T
timk 已提交
2731
		this.color.a = 1.0;
2732

T
timk 已提交
2733 2734
		this.texture = null;
		this.texcoord = null;
2735
		this.texOpts = null;
2736 2737 2738 2739 2740

	};

	ColorOrTexture.prototype.isColor = function () {

2741
		return ( this.texture == null );
2742 2743 2744 2745 2746

	};

	ColorOrTexture.prototype.isTexture = function () {

2747
		return ( this.texture != null );
2748 2749 2750 2751 2752 2753 2754

	};

	ColorOrTexture.prototype.parse = function ( element ) {

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

2755 2756
			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;
2757 2758 2759

			switch ( child.nodeName ) {

T
timk 已提交
2760
				case 'color':
2761

2762
					var rgba = _floats( child.textContent );
T
timk 已提交
2763
					this.color = new THREE.Color(0);
2764
					this.color.setRGB( rgba[0], rgba[1], rgba[2] );
T
timk 已提交
2765 2766
					this.color.a = rgba[3];
					break;
2767

T
timk 已提交
2768
				case 'texture':
2769

T
timk 已提交
2770 2771
					this.texture = child.getAttribute('texture');
					this.texcoord = child.getAttribute('texcoord');
2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782
					// 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 已提交
2783
					break;
2784

T
timk 已提交
2785 2786
				default:
					break;
2787

T
timk 已提交
2788
			}
2789

T
timk 已提交
2790
		}
2791

T
timk 已提交
2792
		return this;
2793 2794 2795

	};

2796 2797
	ColorOrTexture.prototype.parseTexture = function ( element ) {

2798
		if ( ! element.childNodes ) return this;
2799

2800 2801
		// This should be supported by Maya, 3dsMax, and MotionBuilder

2802
		if ( element.childNodes[1] && element.childNodes[1].nodeName === 'extra' ) {
2803

2804
			element = element.childNodes[1];
2805

2806
			if ( element.childNodes[1] && element.childNodes[1].nodeName === 'technique' ) {
2807

2808
				element = element.childNodes[1];
2809 2810 2811 2812 2813

			}

		}

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

2816
			var child = element.childNodes[ i ];
2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845

			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;

	};

2846 2847
	function Shader ( type, effect ) {

T
timk 已提交
2848
		this.type = type;
T
timk 已提交
2849
		this.effect = effect;
M
Mr.doob 已提交
2850
		this.material = null;
2851 2852 2853 2854 2855 2856 2857

	};

	Shader.prototype.parse = function ( element ) {

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

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

2861
			switch ( child.nodeName ) {
2862

T
timk 已提交
2863 2864 2865 2866 2867
				case 'ambient':
				case 'emission':
				case 'diffuse':
				case 'specular':
				case 'transparent':
2868

2869
					this[ child.nodeName ] = ( new ColorOrTexture() ).parse( child );
T
timk 已提交
2870
					break;
2871

T
timk 已提交
2872 2873 2874
				case 'shininess':
				case 'reflectivity':
				case 'transparency':
2875

2876
					var f = evaluateXPath( child, './/dae:float' );
2877 2878 2879 2880

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

T
timk 已提交
2881
					break;
2882

T
timk 已提交
2883 2884
				default:
					break;
2885

T
timk 已提交
2886
			}
2887

T
timk 已提交
2888
		}
2889

T
timk 已提交
2890
		this.create();
T
timk 已提交
2891
		return this;
2892 2893 2894

	};

T
timk 已提交
2895
	Shader.prototype.create = function() {
2896

T
timk 已提交
2897
		var props = {};
2898 2899 2900 2901 2902 2903
		var transparent = ( this['transparency'] !== undefined && this['transparency'] < 1.0 );

		for ( var prop in this ) {

			switch ( prop ) {

T
timk 已提交
2904 2905 2906 2907
				case 'ambient':
				case 'emission':
				case 'diffuse':
				case 'specular':
2908

T
timk 已提交
2909
					var cot = this[prop];
2910 2911 2912 2913 2914 2915 2916

					if ( cot instanceof ColorOrTexture ) {

						if ( cot.isTexture() ) {

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

2917
								if ( this.effect.sampler.source == this.effect.surface.sid ) {
2918

T
timk 已提交
2919
									var image = images[this.effect.surface.init_from];
2920 2921 2922

									if ( image ) {

2923
										var texture = THREE.ImageUtils.loadTexture(baseUrl + image.init_from);
2924 2925
										texture.wrapS = cot.texOpts.wrapU ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping;
										texture.wrapT = cot.texOpts.wrapV ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping;
2926 2927 2928 2929 2930
										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;
2931

T
timk 已提交
2932
									}
2933

T
timk 已提交
2934
								}
2935

T
timk 已提交
2936
							}
2937

T
timk 已提交
2938
						} else {
2939

2940
							if ( prop == 'diffuse' ) {
2941

2942
								props[ 'color' ] = cot.color.getHex();
2943

2944
							} else if ( !transparent ) {
2945

2946
								props[ prop ] = cot.color.getHex();
2947

T
timk 已提交
2948
							}
2949

T
timk 已提交
2950
						}
2951

T
timk 已提交
2952
					}
2953

T
timk 已提交
2954
					break;
2955

T
timk 已提交
2956 2957
				case 'shininess':
				case 'reflectivity':
2958

2959
					props[ prop ] = this[ prop ];
T
timk 已提交
2960
					break;
2961

T
timk 已提交
2962
				case 'transparency':
2963 2964 2965

					if ( transparent ) {

2966 2967
						props[ 'transparent' ] = true;
						props[ 'opacity' ] = this[ prop ];
T
timk 已提交
2968
						transparent = true;
2969

T
timk 已提交
2970
					}
2971

T
timk 已提交
2972
					break;
2973

T
timk 已提交
2974 2975
				default:
					break;
2976

T
timk 已提交
2977
			}
2978

T
timk 已提交
2979 2980
		}

2981 2982 2983 2984 2985
		props[ 'shading' ] = preferredShading;
		this.material = new THREE.MeshLambertMaterial( props );

		switch ( this.type ) {

T
timk 已提交
2986 2987 2988
			case 'constant':
			case 'lambert':
				break;
2989

T
timk 已提交
2990 2991
			case 'phong':
			case 'blinn':
2992

T
timk 已提交
2993
			default:
2994

M
Mr.doob 已提交
2995
				/*
2996 2997
				if ( !transparent ) {

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

T
timk 已提交
3000
				}
M
Mr.doob 已提交
3001
				*/
3002

T
timk 已提交
3003
				break;
3004

T
timk 已提交
3005
		}
3006

T
timk 已提交
3007
		return this.material;
3008 3009 3010 3011 3012

	};

	function Surface ( effect ) {

T
timk 已提交
3013
		this.effect = effect;
M
Mr.doob 已提交
3014 3015
		this.init_from = null;
		this.format = null;
3016 3017 3018 3019 3020 3021 3022

	};

	Surface.prototype.parse = function ( element ) {

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

3023 3024
			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;
3025 3026 3027

			switch ( child.nodeName ) {

T
timk 已提交
3028
				case 'init_from':
3029

T
timk 已提交
3030 3031
					this.init_from = child.textContent;
					break;
3032

T
timk 已提交
3033
				case 'format':
3034

T
timk 已提交
3035 3036
					this.format = child.textContent;
					break;
3037

T
timk 已提交
3038
				default:
3039

3040
					console.log( "unhandled Surface prop: " + child.nodeName );
T
timk 已提交
3041
					break;
3042

T
timk 已提交
3043
			}
3044

T
timk 已提交
3045
		}
3046

T
timk 已提交
3047
		return this;
3048 3049 3050 3051 3052

	};

	function Sampler2D ( effect ) {

T
timk 已提交
3053
		this.effect = effect;
M
Mr.doob 已提交
3054 3055 3056 3057 3058 3059
		this.source = null;
		this.wrap_s = null;
		this.wrap_t = null;
		this.minfilter = null;
		this.magfilter = null;
		this.mipfilter = null;
3060 3061 3062 3063 3064 3065 3066 3067 3068 3069

	};

	Sampler2D.prototype.parse = function ( element ) {

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

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

3070
			switch ( child.nodeName ) {
3071

T
timk 已提交
3072
				case 'source':
3073

T
timk 已提交
3074 3075
					this.source = child.textContent;
					break;
3076

T
timk 已提交
3077
				case 'minfilter':
3078

T
timk 已提交
3079 3080
					this.minfilter = child.textContent;
					break;
3081

T
timk 已提交
3082
				case 'magfilter':
3083

T
timk 已提交
3084 3085
					this.magfilter = child.textContent;
					break;
3086

T
timk 已提交
3087
				case 'mipfilter':
3088

T
timk 已提交
3089 3090
					this.mipfilter = child.textContent;
					break;
3091

T
timk 已提交
3092
				case 'wrap_s':
3093

T
timk 已提交
3094 3095
					this.wrap_s = child.textContent;
					break;
3096

T
timk 已提交
3097
				case 'wrap_t':
3098

T
timk 已提交
3099 3100
					this.wrap_t = child.textContent;
					break;
3101

T
timk 已提交
3102
				default:
3103

3104
					console.log( "unhandled Sampler2D prop: " + child.nodeName );
T
timk 已提交
3105
					break;
3106

T
timk 已提交
3107
			}
3108

T
timk 已提交
3109
		}
3110

T
timk 已提交
3111
		return this;
3112 3113 3114 3115 3116

	};

	function Effect () {

T
timk 已提交
3117 3118 3119
		this.id = "";
		this.name = "";
		this.shader = null;
M
Mr.doob 已提交
3120 3121
		this.surface = null;
		this.sampler = null;
3122 3123 3124 3125 3126 3127 3128

	};

	Effect.prototype.create = function () {

		if ( this.shader == null ) {

T
timk 已提交
3129
			return null;
3130

T
timk 已提交
3131
		}
3132 3133 3134 3135 3136 3137 3138

	};

	Effect.prototype.parse = function ( element ) {

		this.id = element.getAttribute( 'id' );
		this.name = element.getAttribute( 'name' );
T
timk 已提交
3139
		this.shader = null;
3140 3141 3142 3143 3144 3145 3146 3147

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

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

			switch ( child.nodeName ) {

T
timk 已提交
3148
				case 'profile_COMMON':
3149 3150

					this.parseTechnique( this.parseProfileCOMMON( child ) );
T
timk 已提交
3151
					break;
3152

T
timk 已提交
3153 3154
				default:
					break;
3155

T
timk 已提交
3156
			}
3157

T
timk 已提交
3158
		}
3159

T
timk 已提交
3160
		return this;
3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174

	};

	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 已提交
3175
				case 'surface':
3176 3177

					this.surface = ( new Surface( this ) ).parse( child );
T
timk 已提交
3178 3179
					this.surface.sid = sid;
					break;
3180

T
timk 已提交
3181
				case 'sampler2D':
3182 3183

					this.sampler = ( new Sampler2D( this ) ).parse( child );
T
timk 已提交
3184 3185
					this.sampler.sid = sid;
					break;
3186

T
timk 已提交
3187
				case 'extra':
3188

T
timk 已提交
3189
					break;
3190

T
timk 已提交
3191
				default:
3192 3193

					console.log( child.nodeName );
T
timk 已提交
3194
					break;
3195

T
timk 已提交
3196
			}
3197

T
timk 已提交
3198
		}
3199 3200 3201 3202 3203

	};

	Effect.prototype.parseProfileCOMMON = function ( element ) {

T
timk 已提交
3204
		var technique;
3205 3206 3207 3208 3209 3210 3211 3212 3213

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

			var child = element.childNodes[ i ];

			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
3214
				case 'profile_COMMON':
3215 3216

					this.parseProfileCOMMON( child );
T
timk 已提交
3217
					break;
3218

T
timk 已提交
3219
				case 'technique':
3220

T
timk 已提交
3221
					technique = child;
T
timk 已提交
3222
					break;
3223

T
timk 已提交
3224
				case 'newparam':
3225 3226

					this.parseNewparam( child );
T
timk 已提交
3227
					break;
3228

T
timk 已提交
3229 3230
				case 'extra':
					break;
3231

T
timk 已提交
3232
				default:
3233 3234

					console.log( child.nodeName );
T
timk 已提交
3235
					break;
3236

T
timk 已提交
3237
			}
3238

T
timk 已提交
3239
		}
3240

T
timk 已提交
3241
		return technique;
3242 3243 3244 3245 3246 3247 3248

	};

	Effect.prototype.parseTechnique= function ( element ) {

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

T
timk 已提交
3249
			var child = element.childNodes[i];
3250
			if ( child.nodeType != 1 ) continue;
3251 3252 3253

			switch ( child.nodeName ) {

3254
				case 'constant':
T
timk 已提交
3255 3256 3257
				case 'lambert':
				case 'blinn':
				case 'phong':
3258 3259

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

T
timk 已提交
3262 3263
				default:
					break;
3264

T
timk 已提交
3265
			}
3266

T
timk 已提交
3267
		}
3268 3269 3270 3271 3272

	};

	function InstanceEffect () {

T
timk 已提交
3273
		this.url = "";
3274 3275 3276 3277 3278 3279

	};

	InstanceEffect.prototype.parse = function ( element ) {

		this.url = element.getAttribute( 'url' ).replace( /^#/, '' );
T
timk 已提交
3280
		return this;
3281 3282

	};
T
timk 已提交
3283 3284

	function Animation() {
3285

T
timk 已提交
3286 3287 3288 3289 3290
		this.id = "";
		this.name = "";
		this.source = {};
		this.sampler = [];
		this.channel = [];
3291 3292 3293 3294 3295 3296 3297

	};

	Animation.prototype.parse = function ( element ) {

		this.id = element.getAttribute( 'id' );
		this.name = element.getAttribute( 'name' );
T
timk 已提交
3298
		this.source = {};
3299 3300 3301 3302 3303 3304 3305 3306 3307

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

			var child = element.childNodes[ i ];

			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
3308
				case 'source':
3309 3310 3311

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

T
timk 已提交
3314
				case 'sampler':
3315 3316

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

T
timk 已提交
3319
				case 'channel':
3320 3321

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

T
timk 已提交
3324 3325
				default:
					break;
3326

T
timk 已提交
3327
			}
3328

T
timk 已提交
3329
		}
3330

T
timk 已提交
3331
		return this;
T
timk 已提交
3332

3333 3334 3335 3336
	};

	function Channel( animation ) {

T
timk 已提交
3337 3338 3339
		this.animation = animation;
		this.source = "";
		this.target = "";
3340
		this.fullSid = null;
M
Mr.doob 已提交
3341 3342 3343 3344 3345
		this.sid = null;
		this.dotSyntax = null;
		this.arrSyntax = null;
		this.arrIndices = null;
		this.member = null;
3346 3347 3348 3349 3350 3351 3352 3353 3354 3355

	};

	Channel.prototype.parse = function ( element ) {

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

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

T
timk 已提交
3356 3357
		var id = parts.shift();
		var sid = parts.shift();
3358 3359 3360 3361 3362 3363

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

		if ( dotSyntax ) {

T
timk 已提交
3364
			parts = sid.split(".");
3365 3366
			this.sid = parts.shift();
			this.member = parts.shift();
3367 3368 3369

		} else if ( arrSyntax ) {

3370 3371
			var arrIndices = sid.split("(");
			this.sid = arrIndices.shift();
3372 3373 3374 3375 3376

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

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

T
timk 已提交
3377
			}
3378

3379 3380 3381 3382 3383 3384
			this.arrIndices = arrIndices;

		} else {

			this.sid = sid;

T
timk 已提交
3385
		}
3386

3387
		this.fullSid = sid;
T
timk 已提交
3388 3389
		this.dotSyntax = dotSyntax;
		this.arrSyntax = arrSyntax;
3390

T
timk 已提交
3391
		return this;
3392 3393 3394 3395 3396

	};

	function Sampler ( animation ) {

T
timk 已提交
3397 3398 3399
		this.id = "";
		this.animation = animation;
		this.inputs = [];
M
Mr.doob 已提交
3400 3401
		this.input = null;
		this.output = null;
3402
		this.strideOut = null;
M
Mr.doob 已提交
3403 3404 3405
		this.interpolation = null;
		this.startTime = null;
		this.endTime = null;
T
timk 已提交
3406
		this.duration = 0;
3407 3408 3409 3410 3411 3412

	};

	Sampler.prototype.parse = function ( element ) {

		this.id = element.getAttribute( 'id' );
T
timk 已提交
3413
		this.inputs = [];
3414 3415 3416 3417 3418 3419 3420 3421

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

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

			switch ( child.nodeName ) {

T
timk 已提交
3422
				case 'input':
3423 3424

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

T
timk 已提交
3427 3428
				default:
					break;
3429

T
timk 已提交
3430
			}
3431

T
timk 已提交
3432
		}
3433

T
timk 已提交
3434
		return this;
3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446

	};

	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 已提交
3447
				case 'INPUT':
3448

T
timk 已提交
3449 3450
					this.input = source.read();
					break;
3451

T
timk 已提交
3452
				case 'OUTPUT':
3453

T
timk 已提交
3454
					this.output = source.read();
3455
					this.strideOut = source.accessor.stride;
T
timk 已提交
3456
					break;
3457

T
timk 已提交
3458
				case 'INTERPOLATION':
3459

T
timk 已提交
3460 3461
					this.interpolation = source.read();
					break;
3462

T
timk 已提交
3463
				case 'IN_TANGENT':
3464

T
timk 已提交
3465
					break;
3466

T
timk 已提交
3467
				case 'OUT_TANGENT':
3468

T
timk 已提交
3469
					break;
3470

T
timk 已提交
3471
				default:
3472

T
timk 已提交
3473 3474
					console.log(input.semantic);
					break;
3475

T
timk 已提交
3476
			}
3477

T
timk 已提交
3478
		}
3479

T
timk 已提交
3480 3481 3482
		this.startTime = 0;
		this.endTime = 0;
		this.duration = 0;
3483 3484 3485

		if ( this.input.length ) {

T
timk 已提交
3486 3487
			this.startTime = 100000000;
			this.endTime = -100000000;
3488 3489 3490 3491 3492 3493

			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 已提交
3494
			}
3495

T
timk 已提交
3496
			this.duration = this.endTime - this.startTime;
3497

T
timk 已提交
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 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661
	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 );

		}

M
Mr.doob 已提交
3662 3663 3664
	};

	function Camera() {
3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715

		this.id = "";
		this.name = "";

	};

	Camera.prototype.parse = function ( element ) {

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

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

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

			switch ( child.nodeName ) {

				case 'optics':

					this.parseOptics( child );
					break;

				default:
					break;

			}

		}

		return this;

	};

	Camera.prototype.parseOptics = function ( element ) {

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

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

				var technique = element.childNodes[ i ];

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

					if ( technique.childNodes[ j ].nodeName == 'perspective' ) {

						var perspective = technique.childNodes[ j ];

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

							var param = perspective.childNodes[ k ];
M
Mr.doob 已提交
3716

3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746
							switch ( param.nodeName ) {

								case 'xfov':
									this.fov = param.textContent;
									break;
								case 'znear':
									this.znear = .4;//param.textContent;
									break;
								case 'zfar':
									this.zfar = 1e15;//param.textContent;
									break;
								case 'aspect_ratio':
									this.aspect_ratio = param.textContent;
									break;

							}

						}

					}

				}
				
			}

		}
		
		return this;

	};
M
Mr.doob 已提交
3747

3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759
	function InstanceCamera() {

		this.url = "";

	};

	InstanceCamera.prototype.parse = function ( element ) {

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

		return this;

3760 3761
	};

3762
	function _source( element ) {
3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776

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

		if ( sources[ id ] != undefined ) {

			return sources[ id ];

		}

		sources[ id ] = ( new Source(id )).parse( element );
		return sources[ id ];

	};

3777
	function _nsResolver( nsPrefix ) {
3778 3779 3780

		if ( nsPrefix == "dae" ) {

T
timk 已提交
3781
			return "http://www.collada.org/2005/11/COLLADASchema";
3782

T
timk 已提交
3783
		}
3784

T
timk 已提交
3785
		return null;
3786 3787 3788

	};

3789
	function _bools( str ) {
3790 3791

		var raw = _strings( str );
T
timk 已提交
3792
		var data = [];
3793

3794
		for ( var i = 0, l = raw.length; i < l; i ++ ) {
3795 3796

			data.push( (raw[i] == 'true' || raw[i] == '1') ? true : false );
3797

T
timk 已提交
3798
		}
3799

T
timk 已提交
3800
		return data;
3801 3802 3803

	};

3804
	function _floats( str ) {
3805

T
timk 已提交
3806 3807
		var raw = _strings(str);
		var data = [];
3808

3809
		for ( var i = 0, l = raw.length; i < l; i ++ ) {
3810 3811 3812

			data.push( parseFloat( raw[ i ] ) );

T
timk 已提交
3813
		}
3814

T
timk 已提交
3815
		return data;
3816 3817

	};
T
timk 已提交
3818

3819
	function _ints( str ) {
3820 3821

		var raw = _strings( str );
T
timk 已提交
3822
		var data = [];
3823

3824
		for ( var i = 0, l = raw.length; i < l; i ++ ) {
3825 3826 3827

			data.push( parseInt( raw[ i ], 10 ) );

T
timk 已提交
3828
		}
3829

T
timk 已提交
3830
		return data;
3831 3832 3833

	};

3834
	function _strings( str ) {
3835

3836
		return ( str.length > 0 ) ? _trimString( str ).split( /\s+/ ) : [];
3837 3838

	};
T
timk 已提交
3839

3840
	function _trimString( str ) {
3841 3842 3843 3844

		return str.replace( /^\s+/, "" ).replace( /\s+$/, "" );

	};
T
timk 已提交
3845

3846
	function _attr_as_float( element, name, defaultValue ) {
3847 3848 3849 3850 3851

		if ( element.hasAttribute( name ) ) {

			return parseFloat( element.getAttribute( name ) );

T
timk 已提交
3852
		} else {
3853

T
timk 已提交
3854
			return defaultValue;
3855

T
timk 已提交
3856
		}
3857 3858

	};
T
timk 已提交
3859

3860
	function _attr_as_int( element, name, defaultValue ) {
3861 3862 3863 3864 3865

		if ( element.hasAttribute( name ) ) {

			return parseInt( element.getAttribute( name ), 10) ;

T
timk 已提交
3866
		} else {
3867

T
timk 已提交
3868
			return defaultValue;
3869

T
timk 已提交
3870
		}
3871 3872

	};
T
timk 已提交
3873

3874
	function _attr_as_string( element, name, defaultValue ) {
3875 3876 3877 3878 3879

		if ( element.hasAttribute( name ) ) {

			return element.getAttribute( name );

T
timk 已提交
3880
		} else {
3881

T
timk 已提交
3882
			return defaultValue;
3883

T
timk 已提交
3884
		}
3885 3886 3887

	};

3888
	function _format_float( f, num ) {
3889 3890 3891

		if ( f === undefined ) {

T
timk 已提交
3892
			var s = '0.';
3893 3894 3895

			while ( s.length < num + 2 ) {

T
timk 已提交
3896
				s += '0';
3897

T
timk 已提交
3898
			}
3899

T
timk 已提交
3900
			return s;
3901

T
timk 已提交
3902
		}
3903

T
timk 已提交
3904
		num = num || 2;
3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918

		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( '.' );

	};

3919
	function evaluateXPath( node, query ) {
3920

3921
		var instances = COLLADA.evaluate( query, node, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );
3922

T
timk 已提交
3923 3924
		var inst = instances.iterateNext();
		var result = [];
3925 3926 3927 3928

		while ( inst ) {

			result.push( inst );
T
timk 已提交
3929
			inst = instances.iterateNext();
3930 3931 3932

		}

T
timk 已提交
3933
		return result;
3934 3935 3936

	};

3937 3938
	// Up axis conversion

3939
	function setUpConversion() {
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

		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;

			}

		}

	};

3970
	function fixCoords( data, sign ) {
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 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027

		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;

		}

	};

4028
	function getConvertedVec3( data, offset ) {
4029 4030 4031 4032 4033 4034 4035

		var arr = [ data[ offset ], data[ offset + 1 ], data[ offset + 2 ] ];
		fixCoords( arr, -1 );
		return new THREE.Vector3( arr[ 0 ], arr[ 1 ], arr[ 2 ] );

	};

4036
	function getConvertedMat4( data ) {
4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092

		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]
			);

	};

4093
	function getConvertedMember( member ) {
4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168

		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 已提交
4169
	return {
4170

T
timk 已提交
4171
		load: load,
4172
		parse: parse,
T
timk 已提交
4173
		setPreferredShading: setPreferredShading,
T
timk 已提交
4174
		applySkin: applySkin,
4175 4176
		geometries : geometries,
		options: options
4177

T
timk 已提交
4178
	};
4179

M
Mr.doob 已提交
4180
};