ColladaLoader.js 77.6 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
		// 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,

43
		upAxis: 'Y',
44

45 46
		// For reflective or refractive materials we'll use this cubemap
		defaultEnvMap: null
47

48 49 50 51 52 53
	};

	var colladaUnit = 1.0;
	var colladaUp = 'Y';
	var upConversion = null;

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

		var length = 0;
57 58 59

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

M
Mr.doob 已提交
60
			var request = new XMLHttpRequest();
T
timk 已提交
61

M
Mr.doob 已提交
62
			request.onreadystatechange = function() {
T
timk 已提交
63

M
Mr.doob 已提交
64
				if( request.readyState == 4 ) {
65

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

M
Mr.doob 已提交
68

M
Mr.doob 已提交
69
						if ( request.responseXML ) {
70 71

							readyCallbackFunc = readyCallback;
M
Mr.doob 已提交
72
							parse( request.responseXML, undefined, url );
73

74 75 76 77 78 79 80
						} else if ( request.responseText ) {

							readyCallbackFunc = readyCallback;
							var xmlParser = new DOMParser();
							var responseXML = xmlParser.parseFromString( request.responseText, "application/xml" );
							parse( responseXML, undefined, url );

81 82 83 84 85
						} else {

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

						}
86

T
timk 已提交
87
					}
88

M
Mr.doob 已提交
89
				} else if ( request.readyState == 3 ) {
90 91 92 93 94

					if ( progressCallback ) {

						if ( length == 0 ) {

M
Mr.doob 已提交
95
							length = request.getResponseHeader( "Content-Length" );
96 97 98

						}

M
Mr.doob 已提交
99
						progressCallback( { total: length, loaded: request.responseText.length } );
100 101 102

					}

T
timk 已提交
103
				}
104

T
timk 已提交
105
			}
106

M
Mr.doob 已提交
107 108
			request.open( "GET", url, true );
			request.send( null );
109

T
timk 已提交
110
		} else {
111

112
			alert( "Don't know how to parse XML!" );
113

T
timk 已提交
114
		}
115 116 117

	};

118
	function parse( doc, callBack, url ) {
119

T
timk 已提交
120 121
		COLLADA = doc;
		callBack = callBack || readyCallbackFunc;
122 123 124

		if ( url !== undefined ) {

125
			var parts = url.split( '/' );
T
timk 已提交
126
			parts.pop();
127
			baseUrl = ( parts.length < 1 ? '.' : parts.join( '/' ) ) + '/';
128

T
timk 已提交
129
		}
130

131 132
		parseAsset();
		setUpConversion();
133
		images = parseLib( "//dae:library_images/dae:image", _Image, "image" );
134
		materials = parseLib( "//dae:library_materials/dae:material", Material, "material" );
135 136
		effects = parseLib( "//dae:library_effects/dae:effect", Effect, "effect" );
		geometries = parseLib( "//dae:library_geometries/dae:geometry", Geometry, "geometry" );
137
		cameras = parseLib( ".//dae:library_cameras/dae:camera", Camera, "camera" );
138 139 140 141
		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 已提交
142 143
		morphs = [];
		skins = [];
144

T
timk 已提交
145 146
		daeScene = parseScene();
		scene = new THREE.Object3D();
147

148
		for ( var i = 0; i < daeScene.nodes.length; i ++ ) {
149

150
			scene.add( createSceneGraph( daeScene.nodes[ i ] ) );
151

T
timk 已提交
152
		}
T
timk 已提交
153

T
timk 已提交
154 155 156
		createAnimations();

		var result = {
157 158

			scene: scene,
T
timk 已提交
159 160
			morphs: morphs,
			skins: skins,
161
			animations: animData,
T
timk 已提交
162 163 164
			dae: {
				images: images,
				materials: materials,
165
				cameras: cameras,
T
timk 已提交
166 167 168 169 170 171 172
				effects: effects,
				geometries: geometries,
				controllers: controllers,
				animations: animations,
				visualScenes: visualScenes,
				scene: daeScene
			}
173

T
timk 已提交
174
		};
175 176 177 178 179

		if ( callBack ) {

			callBack( result );

T
timk 已提交
180
		}
181

T
timk 已提交
182
		return result;
183 184 185 186 187

	};

	function setPreferredShading ( shading ) {

T
timk 已提交
188
		preferredShading = shading;
189 190 191

	};

192 193
	function parseAsset () {

194
		var elements = COLLADA.evaluate( '//dae:asset', COLLADA, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );
195 196 197

		var element = elements.iterateNext();

198
		if ( element && element.childNodes ) {
199

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

202
				var child = element.childNodes[ i ];
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230

				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;

				}

			}

		}

	};

231 232
	function parseLib ( q, classSpec, prefix ) {

233
		var elements = COLLADA.evaluate(q, COLLADA, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null) ;
234

T
timk 已提交
235 236 237
		var lib = {};
		var element = elements.iterateNext();
		var i = 0;
238 239 240 241

		while ( element ) {

			var daeElement = ( new classSpec() ).parse( element );
242
			if ( !daeElement.id || daeElement.id.length == 0 ) daeElement.id = prefix + ( i ++ );
243
			lib[ daeElement.id ] = daeElement;
244

T
timk 已提交
245
			element = elements.iterateNext();
246

T
timk 已提交
247
		}
248

T
timk 已提交
249
		return lib;
250 251 252

	};

253
	function parseScene() {
254

255
		var sceneElement = COLLADA.evaluate( './/dae:scene/dae:instance_visual_scene', COLLADA, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null ).iterateNext();
256 257 258 259

		if ( sceneElement ) {

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

T
timk 已提交
262
		} else {
263

T
timk 已提交
264
			return null;
265

T
timk 已提交
266
		}
267 268 269

	};

270
	function createAnimations() {
271

272 273 274 275 276 277 278
		animData = [];

		// fill in the keys
		recurseHierarchy( scene );

	};

279
	function recurseHierarchy( node ) {
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296

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

298
			animData.push(newData);
299

300 301 302 303 304 305 306 307 308 309 310 311 312 313
			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: []
				} ]
			}
314 315 316

		}

317 318 319 320 321 322 323 324 325 326 327 328 329 330
		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: []
				} );

			}

		}
331

332
		return newData;
333 334 335 336 337

	};

	function calcAnimationBounds () {

T
timk 已提交
338 339
		var start = 1000000;
		var end = -start;
T
timk 已提交
340
		var frames = 0;
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368

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

T
timk 已提交
372
		}
373

T
timk 已提交
374 375
		var morph = morphCtrl.morph;

376 377 378 379 380 381 382
		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 ||
383
				 !daeGeometry.mesh.primitives.length ) {
384
				 continue;
T
timk 已提交
385
			}
386 387 388 389 390

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

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

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

T
timk 已提交
393
			}
394

T
timk 已提交
395
		}
396

T
timk 已提交
397
		geometry.morphTargets.push( { name: "target_Z", vertices: geometry.vertices } );
398 399 400 401 402 403 404 405 406

	};

	function createSkin ( geometry, ctrl, applyBindShape ) {

		var skinCtrl = controllers[ ctrl.url ];

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

407
			console.log( "could not find skin controller!" );
T
timk 已提交
408
			return;
409

T
timk 已提交
410
		}
411 412 413

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

414
			console.log( "could not find the skeleton for the skin!" );
T
timk 已提交
415
			return;
416

T
timk 已提交
417
		}
418

T
timk 已提交
419
		var skin = skinCtrl.skin;
420
		var skeleton = daeScene.getChildById( ctrl.skeleton[ 0 ] );
T
timk 已提交
421
		var hierarchy = [];
422

T
timk 已提交
423
		applyBindShape = applyBindShape !== undefined ? applyBindShape : true;
424

T
timk 已提交
425 426 427
		var bones = [];
		geometry.skinWeights = [];
		geometry.skinIndices = [];
428

429 430
		//createBones( geometry.bones, skin, hierarchy, skeleton, null, -1 );
		//createWeights( skin, geometry.bones, geometry.skinIndices, geometry.skinWeights );
431

T
timk 已提交
432 433 434 435 436 437 438 439 440
		/*
		geometry.animation = {
			name: 'take_001',
			fps: 30,
			length: 2,
			JIT: true,
			hierarchy: hierarchy
		};
		*/
441 442 443 444 445

		if ( applyBindShape ) {

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

446
				geometry.vertices[ i ].applyMatrix4( skin.bindShapeMatrix );
447

T
timk 已提交
448
			}
449

T
timk 已提交
450
		}
451 452 453 454 455

	};

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

T
timk 已提交
456
		node.world = node.world || new THREE.Matrix4();
457 458 459 460 461 462 463 464 465
		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 ) {

466
				node.world.copy( m );
467

T
timk 已提交
468
			}
469

T
timk 已提交
470
		}
471 472 473

		if ( parent ) {

474
			node.world.multiplyMatrices( parent, node.world );
475

T
timk 已提交
476 477
		}

478 479 480 481 482 483
		bones.push( node );

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

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

T
timk 已提交
484
		}
485 486 487 488 489

	};

	function setupSkinningMatrices ( bones, skin ) {

T
timk 已提交
490
		// FIXME: this is dumb...
491 492 493 494

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

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

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

499 500 501 502
			for ( var j = 0; j < skin.joints.length; j ++ ) {

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

T
timk 已提交
503 504
					found = j;
					break;
505

T
timk 已提交
506
				}
507

T
timk 已提交
508
			}
509

510
			if ( found >= 0 ) {
511 512 513

				var inv = skin.invBindMatrices[ found ];

T
timk 已提交
514 515
				bone.invBindMatrix = inv;
				bone.skinningMatrix = new THREE.Matrix4();
516
				bone.skinningMatrix.multiplyMatrices(bone.world, inv); // (IBMi * JMi)
517

T
timk 已提交
518
				bone.weights = [];
519 520 521 522 523 524 525 526 527 528 529

				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 已提交
530
						}
531

T
timk 已提交
532
					}
533

T
timk 已提交
534
				}
535

T
timk 已提交
536
			} else {
537

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

T
timk 已提交
540
			}
541

T
timk 已提交
542
		}
543 544 545 546 547 548 549

	};

	function applySkin ( geometry, instanceCtrl, frame ) {

		var skinController = controllers[ instanceCtrl.url ];

T
timk 已提交
550
		frame = frame !== undefined ? frame : 40;
551 552 553

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

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

T
timk 已提交
557 558
		}

559 560
		if ( !instanceCtrl.skeleton || !instanceCtrl.skeleton.length ) {

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

T
timk 已提交
564
		}
565

T
timk 已提交
566
		var animationBounds = calcAnimationBounds();
567 568 569
		var skeleton = daeScene.getChildById( instanceCtrl.skeleton[0], true ) ||
					   daeScene.getChildBySid( instanceCtrl.skeleton[0], true );

T
timk 已提交
570 571 572 573
		var i, j, w, vidx, weight;
		var v = new THREE.Vector3(), o, s;

		// move vertices to bind shape
574 575 576

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

577
			geometry.vertices[i].applyMatrix4( skinController.skin.bindShapeMatrix );
578

T
timk 已提交
579
		}
580

T
timk 已提交
581
		// process animation, or simply pose the rig if no animation
582 583 584

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

T
timk 已提交
585 586
			var bones = [];
			var skinned = [];
587

T
timk 已提交
588
			// zero skinned vertices
589 590 591

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

M
Mr.doob 已提交
592
				skinned.push( new THREE.Vector3() );
593

T
timk 已提交
594
			}
595 596

			// process the frame and setup the rig with a fresh
T
timk 已提交
597
			// transform, possibly from the bone's animation channel(s)
598 599 600 601

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

T
timk 已提交
602
			// skin 'm
603 604 605

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

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

608 609 610
				for ( j = 0; j < bones[ i ].weights.length; j ++ ) {

					w = bones[ i ].weights[ j ];
T
timk 已提交
611 612
					vidx = w.index;
					weight = w.weight;
613

T
timk 已提交
614 615
					o = geometry.vertices[vidx];
					s = skinned[vidx];
616

617 618 619
					v.x = o.x;
					v.y = o.y;
					v.z = o.z;
620

621
					v.applyMatrix4( bones[i].skinningMatrix );
622

623 624 625
					s.x += (v.x * weight);
					s.y += (v.y * weight);
					s.z += (v.z * weight);
626

T
timk 已提交
627
				}
628

T
timk 已提交
629
			}
630

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

T
timk 已提交
633
		}
634 635 636 637 638

	};

	function createSceneGraph ( node, parent ) {

T
timk 已提交
639 640
		var obj = new THREE.Object3D();
		var skinned = false;
T
timk 已提交
641 642
		var skinController;
		var morphController;
643
		var i, j;
644

T
timk 已提交
645
		// FIXME: controllers
646

647
		for ( i = 0; i < node.controllers.length; i ++ ) {
648

649
			var controller = controllers[ node.controllers[ i ].url ];
650 651 652

			switch ( controller.type ) {

T
timk 已提交
653
				case 'skin':
654

655
					if ( geometries[ controller.skin.source ] ) {
656

T
timk 已提交
657
						var inst_geom = new InstanceGeometry();
658

T
timk 已提交
659
						inst_geom.url = controller.skin.source;
660 661 662
						inst_geom.instance_material = node.controllers[ i ].instance_material;

						node.geometries.push( inst_geom );
T
timk 已提交
663
						skinned = true;
664
						skinController = node.controllers[ i ];
665

666
					} else if ( controllers[ controller.skin.source ] ) {
667

T
timk 已提交
668 669
						// urgh: controller can be chained
						// handle the most basic case...
670 671

						var second = controllers[ controller.skin.source ];
T
timk 已提交
672 673
						morphController = second;
					//	skinController = node.controllers[i];
674 675 676

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

T
timk 已提交
677
							var inst_geom = new InstanceGeometry();
678

T
timk 已提交
679
							inst_geom.url = second.morph.source;
680 681 682 683
							inst_geom.instance_material = node.controllers[ i ].instance_material;

							node.geometries.push( inst_geom );

T
timk 已提交
684
						}
685

T
timk 已提交
686
					}
687

T
timk 已提交
688
					break;
689

T
timk 已提交
690
				case 'morph':
691

692
					if ( geometries[ controller.morph.source ] ) {
693

T
timk 已提交
694
						var inst_geom = new InstanceGeometry();
695

T
timk 已提交
696
						inst_geom.url = controller.morph.source;
697 698 699 700
						inst_geom.instance_material = node.controllers[ i ].instance_material;

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

T
timk 已提交
702
					}
703

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

T
timk 已提交
706 707
				default:
					break;
708

T
timk 已提交
709
			}
710

T
timk 已提交
711
		}
712

T
timk 已提交
713
		// FIXME: multi-material mesh?
T
timk 已提交
714
		// geometries
715

716 717
		var double_sided_materials = {};

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

T
timk 已提交
720 721
			var instance_geometry = node.geometries[i];
			var instance_materials = instance_geometry.instance_material;
722
			var geometry = geometries[ instance_geometry.url ];
T
timk 已提交
723
			var used_materials = {};
724
			var used_materials_array = [];
T
timk 已提交
725 726
			var num_materials = 0;
			var first_material;
727 728 729

			if ( geometry ) {

730
				if ( !geometry.mesh || !geometry.mesh.primitives )
T
timk 已提交
731
					continue;
732

733
				if ( obj.name.length == 0 ) {
734

T
timk 已提交
735
					obj.name = geometry.id;
736

T
timk 已提交
737
				}
738

T
timk 已提交
739
				// collect used fx for this geometry-instance
740 741 742 743 744

				if ( instance_materials ) {

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

745 746
						var instance_material = instance_materials[ j ];
						var mat = materials[ instance_material.target ];
747
						var effect_id = mat.instance_effect.url;
748
						var shader = effects[ effect_id ].shader;
749 750 751 752
						var material3js = shader.material;

						if ( geometry.doubleSided ) {

753 754 755 756 757 758 759 760 761
							if ( !( material3js in double_sided_materials ) ) {

								var _copied_material = material3js.clone();
								_copied_material.side = THREE.DoubleSide;
								double_sided_materials[ material3js ] = _copied_material;

							}

							material3js = double_sided_materials[ material3js ];
762

763 764 765
						}

						material3js.opacity = !material3js.opacity ? 1 : material3js.opacity;
766
						used_materials[ instance_material.symbol ] = num_materials;
767 768
						used_materials_array.push( material3js );
						first_material = material3js;
769
						first_material.name = mat.name == null || mat.name === '' ? mat.id : mat.name;
770 771
						num_materials ++;

T
timk 已提交
772
					}
773

T
timk 已提交
774
				}
775

T
timk 已提交
776
				var mesh;
J
Jeff Terrace 已提交
777
				var material = first_material || new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.FlatShading, side: geometry.doubleSided ? THREE.DoubleSide : THREE.FrontSide } );
T
timk 已提交
778
				var geom = geometry.mesh.geometry3js;
779 780 781

				if ( num_materials > 1 ) {

782
					material = new THREE.MeshFaceMaterial( used_materials_array );
783

784 785 786
					for ( j = 0; j < geom.faces.length; j ++ ) {

						var face = geom.faces[ j ];
787
						face.materialIndex = used_materials[ face.daeMaterial ]
788

T
timk 已提交
789
					}
790

T
timk 已提交
791
				}
792

793
				if ( skinController !== undefined ) {
794 795 796

					applySkin( geom, skinController );

T
timk 已提交
797
					material.morphTargets = true;
798

799
					mesh = new THREE.SkinnedMesh( geom, material, false );
T
timk 已提交
800
					mesh.skeleton = skinController.skeleton;
801
					mesh.skinController = controllers[ skinController.url ];
T
timk 已提交
802
					mesh.skinInstanceController = skinController;
T
timk 已提交
803
					mesh.name = 'skin_' + skins.length;
804 805 806 807 808 809 810

					skins.push( mesh );

				} else if ( morphController !== undefined ) {

					createMorph( geom, morphController );

T
timk 已提交
811
					material.morphTargets = true;
812

T
timk 已提交
813 814
					mesh = new THREE.Mesh( geom, material );
					mesh.name = 'morph_' + morphs.length;
815 816 817

					morphs.push( mesh );

T
timk 已提交
818
				} else {
819

T
timk 已提交
820
					mesh = new THREE.Mesh( geom, material );
821
					// mesh.geom.name = geometry.id;
822

T
timk 已提交
823
				}
824

825
				node.geometries.length > 1 ? obj.add( mesh ) : obj = mesh;
826

T
timk 已提交
827
			}
828

T
timk 已提交
829
		}
830

831 832 833 834 835 836 837 838 839
		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);

		}

M
Mr.doob 已提交
840
		obj.name = node.name || node.id || "";
841
		obj.matrix = node.matrix;
842

843 844 845 846 847
		var props = node.matrix.decompose();
		obj.position = props[ 0 ];
		obj.quaternion = props[ 1 ];
		obj.useQuaternion = true;
		obj.scale = props[ 2 ];
848

J
Jihoon Lee 已提交
849 850 851
    // unit conversion
    obj.scale.multiplyScalar(colladaUnit);

852 853 854
		if ( options.centerGeometry && obj.geometry ) {

			var delta = THREE.GeometryUtils.center( obj.geometry );
855
			delta.multiply( obj.scale );
856
			delta.applyQuaternion( obj.quaternion );
857

858
			obj.position.sub( delta );
859 860 861

		}

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

864
			obj.add( createSceneGraph( node.nodes[i], node ) );
865

T
timk 已提交
866
		}
867

T
timk 已提交
868
		return obj;
869 870 871 872 873 874 875 876 877

	};

	function getJointId( skin, id ) {

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

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

T
timk 已提交
878
				return i;
879

T
timk 已提交
880
			}
881

T
timk 已提交
882
		}
883 884 885 886 887

	};

	function getLibraryNode( id ) {

888
		return COLLADA.evaluate( './/dae:library_nodes//dae:node[@id=\'' + id + '\']', COLLADA, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null ).iterateNext();
889 890 891 892 893

	};

	function getChannelsForNode (node ) {

T
timk 已提交
894 895 896
		var channels = [];
		var startTime = 1000000;
		var endTime = -1000000;
897 898 899

		for ( var id in animations ) {

T
timk 已提交
900
			var animation = animations[id];
901 902 903

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

T
timk 已提交
904 905 906
				var channel = animation.channel[i];
				var sampler = animation.sampler[i];
				var id = channel.target.split('/')[0];
907 908 909

				if ( id == node.id ) {

T
timk 已提交
910 911 912 913 914
					sampler.create();
					channel.sampler = sampler;
					startTime = Math.min(startTime, sampler.startTime);
					endTime = Math.max(endTime, sampler.endTime);
					channels.push(channel);
915

T
timk 已提交
916
				}
917

T
timk 已提交
918
			}
919

T
timk 已提交
920
		}
921 922 923

		if ( channels.length ) {

T
timk 已提交
924
			node.startTime = startTime;
925 926
			node.endTime = endTime;

T
timk 已提交
927
		}
928

T
timk 已提交
929
		return channels;
930 931 932 933 934

	};

	function calcFrameDuration( node ) {

T
timk 已提交
935
		var minT = 10000000;
936

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

T
timk 已提交
939
			var sampler = node.channels[i].sampler;
940

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

943 944 945
				var t0 = sampler.input[ j ];
				var t1 = sampler.input[ j + 1 ];
				minT = Math.min( minT, t1 - t0 );
946

T
timk 已提交
947 948
			}
		}
949

T
timk 已提交
950
		return minT;
951 952 953 954 955

	};

	function calcMatrixAt( node, t ) {

T
timk 已提交
956
		var animated = {};
957

T
timk 已提交
958
		var i, j;
959 960 961 962

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

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

T
timk 已提交
965
		}
966

T
timk 已提交
967
		var matrix = new THREE.Matrix4();
968 969 970

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

971 972
			var transform = node.transforms[ i ];
			var channel = animated[ transform.sid ];
973 974 975

			if ( channel !== undefined ) {

T
timk 已提交
976 977
				var sampler = channel.sampler;
				var value;
978

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

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

983
						value = sampler.output[ j ];
T
timk 已提交
984 985
						//console.log(value.flatten)
						break;
986

T
timk 已提交
987
					}
988

T
timk 已提交
989
				}
990 991 992 993 994

				if ( value !== undefined ) {

					if ( value instanceof THREE.Matrix4 ) {

995
						matrix.multiplyMatrices( matrix, value );
996

T
timk 已提交
997
					} else {
998

T
timk 已提交
999
						// FIXME: handle other types
1000

1001
						matrix.multiplyMatrices( matrix, transform.matrix );
1002

T
timk 已提交
1003
					}
1004

T
timk 已提交
1005
				} else {
1006

1007
					matrix.multiplyMatrices( matrix, transform.matrix );
1008

T
timk 已提交
1009
				}
1010

T
timk 已提交
1011
			} else {
1012

1013
				matrix.multiplyMatrices( matrix, transform.matrix );
1014

T
timk 已提交
1015
			}
1016

T
timk 已提交
1017
		}
1018

T
timk 已提交
1019
		return matrix;
1020 1021 1022 1023 1024 1025 1026

	};

	function bakeAnimations ( node ) {

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

1027 1028
			var keys = [],
				sids = [];
1029

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

1032 1033 1034 1035
				var channel = node.channels[i],
					fullSid = channel.fullSid,
					sampler = channel.sampler,
					input = sampler.input,
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053
					transform = node.getTransformBySid( channel.sid ),
					member;

				if ( channel.arrIndices ) {

					member = [];

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

						member[ j ] = getConvertedIndex( channel.arrIndices[ j ] );

					}

				} else {

					member = getConvertedMember( channel.member );

				}
1054

1055
				if ( transform ) {
1056

1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104
					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 );

					}

				}
1105

T
timk 已提交
1106
			}
1107

T
timk 已提交
1108
			node.keys = keys;
1109
			node.sids = sids;
1110

T
timk 已提交
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
	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;

1172 1173 1174 1175 1176
			if ( prevTarget.type === 'matrix' ) {

				data = prevData;

			} else if ( prevData.length ) {
1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239

				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 已提交
1240
	function _Image() {
1241

T
timk 已提交
1242 1243
		this.id = "";
		this.init_from = "";
1244 1245 1246

	};

T
timk 已提交
1247
	_Image.prototype.parse = function(element) {
1248

T
timk 已提交
1249
		this.id = element.getAttribute('id');
1250 1251 1252 1253 1254 1255 1256

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

			var child = element.childNodes[ i ];

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

T
timk 已提交
1257
				this.init_from = child.textContent;
1258

T
timk 已提交
1259
			}
1260

T
timk 已提交
1261
		}
1262

T
timk 已提交
1263
		return this;
1264 1265 1266

	};

T
timk 已提交
1267
	function Controller() {
1268

T
timk 已提交
1269 1270 1271 1272 1273
		this.id = "";
		this.name = "";
		this.type = "";
		this.skin = null;
		this.morph = null;
1274 1275 1276 1277 1278

	};

	Controller.prototype.parse = function( element ) {

T
timk 已提交
1279 1280 1281
		this.id = element.getAttribute('id');
		this.name = element.getAttribute('name');
		this.type = "none";
1282 1283 1284 1285 1286 1287 1288

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

			var child = element.childNodes[ i ];

			switch ( child.nodeName ) {

T
timk 已提交
1289
				case 'skin':
1290

T
timk 已提交
1291 1292 1293
					this.skin = (new Skin()).parse(child);
					this.type = child.nodeName;
					break;
1294

T
timk 已提交
1295
				case 'morph':
1296

T
timk 已提交
1297 1298 1299
					this.morph = (new Morph()).parse(child);
					this.type = child.nodeName;
					break;
1300

T
timk 已提交
1301 1302
				default:
					break;
1303

T
timk 已提交
1304 1305
			}
		}
1306

T
timk 已提交
1307
		return this;
1308 1309 1310

	};

T
timk 已提交
1311
	function Morph() {
1312

M
Mr.doob 已提交
1313 1314 1315 1316
		this.method = null;
		this.source = null;
		this.targets = null;
		this.weights = null;
1317 1318 1319 1320 1321

	};

	Morph.prototype.parse = function( element ) {

T
timk 已提交
1322 1323 1324
		var sources = {};
		var inputs = [];
		var i;
1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335

		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 已提交
1336
				case 'source':
1337 1338 1339

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

T
timk 已提交
1342
				case 'targets':
1343 1344

					inputs = this.parseInputs( child );
T
timk 已提交
1345
					break;
1346

T
timk 已提交
1347
				default:
1348 1349

					console.log( child.nodeName );
T
timk 已提交
1350
					break;
1351

T
timk 已提交
1352
			}
1353

T
timk 已提交
1354
		}
1355 1356 1357 1358 1359 1360 1361 1362

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

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

			switch ( input.semantic ) {

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

T
timk 已提交
1365 1366
					this.targets = source.read();
					break;
1367

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

T
timk 已提交
1370 1371
					this.weights = source.read();
					break;
1372

T
timk 已提交
1373 1374
				default:
					break;
1375

T
timk 已提交
1376 1377
			}
		}
1378

T
timk 已提交
1379
		return this;
1380 1381 1382

	};

T
timk 已提交
1383
	Morph.prototype.parseInputs = function(element) {
1384

T
timk 已提交
1385
		var inputs = [];
1386 1387 1388

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

T
timk 已提交
1389
			var child = element.childNodes[i];
1390 1391 1392 1393
			if ( child.nodeType != 1) continue;

			switch ( child.nodeName ) {

T
timk 已提交
1394
				case 'input':
1395 1396

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

T
timk 已提交
1399 1400 1401 1402
				default:
					break;
			}
		}
1403

T
timk 已提交
1404
		return inputs;
1405 1406 1407

	};

T
timk 已提交
1408
	function Skin() {
1409

T
timk 已提交
1410
		this.source = "";
T
timk 已提交
1411 1412 1413 1414
		this.bindShapeMatrix = null;
		this.invBindMatrices = [];
		this.joints = [];
		this.weights = [];
1415 1416 1417 1418 1419

	};

	Skin.prototype.parse = function( element ) {

T
timk 已提交
1420 1421
		var sources = {};
		var joints, weights;
1422 1423

		this.source = element.getAttribute( 'source' ).replace( /^#/, '' );
T
timk 已提交
1424 1425 1426
		this.invBindMatrices = [];
		this.joints = [];
		this.weights = [];
1427 1428 1429

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

T
timk 已提交
1430
			var child = element.childNodes[i];
1431 1432 1433 1434
			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
1435
				case 'bind_shape_matrix':
1436

T
timk 已提交
1437
					var f = _floats(child.textContent);
1438
					this.bindShapeMatrix = getConvertedMat4( f );
T
timk 已提交
1439
					break;
1440

T
timk 已提交
1441
				case 'source':
1442

T
timk 已提交
1443
					var src = new Source().parse(child);
1444
					sources[ src.id ] = src;
T
timk 已提交
1445
					break;
1446

T
timk 已提交
1447
				case 'joints':
1448

T
timk 已提交
1449 1450
					joints = child;
					break;
1451

T
timk 已提交
1452
				case 'vertex_weights':
1453

T
timk 已提交
1454 1455
					weights = child;
					break;
1456

T
timk 已提交
1457
				default:
1458 1459

					console.log( child.nodeName );
T
timk 已提交
1460
					break;
1461

T
timk 已提交
1462 1463
			}
		}
1464 1465 1466 1467

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

T
timk 已提交
1468
		return this;
1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480

	};

	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 已提交
1481
				case 'input':
1482 1483 1484 1485 1486 1487

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

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

T
timk 已提交
1488
						this.joints = source.read();
1489 1490 1491

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

T
timk 已提交
1492
						this.invBindMatrices = source.read();
1493

T
timk 已提交
1494
					}
1495

T
timk 已提交
1496
					break;
1497

T
timk 已提交
1498 1499 1500
				default:
					break;
			}
1501

T
timk 已提交
1502
		}
1503 1504 1505 1506 1507

	};

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

T
timk 已提交
1508
		var v, vcount, inputs = [];
1509 1510 1511 1512 1513 1514 1515 1516

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

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

			switch ( child.nodeName ) {

T
timk 已提交
1517
				case 'input':
1518

1519
					inputs.push( ( new Input() ).parse( child ) );
T
timk 已提交
1520
					break;
1521

T
timk 已提交
1522
				case 'v':
1523

1524
					v = _ints( child.textContent );
T
timk 已提交
1525
					break;
1526

T
timk 已提交
1527
				case 'vcount':
1528

1529
					vcount = _ints( child.textContent );
T
timk 已提交
1530
					break;
1531

T
timk 已提交
1532 1533
				default:
					break;
1534

T
timk 已提交
1535
			}
1536

T
timk 已提交
1537
		}
1538

T
timk 已提交
1539
		var index = 0;
1540 1541 1542

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

T
timk 已提交
1543 1544
			var numBones = vcount[i];
			var vertex_weights = [];
1545 1546 1547

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

T
timk 已提交
1548
				var influence = {};
1549 1550 1551 1552 1553 1554 1555 1556

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

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

					switch ( input.semantic ) {

T
timk 已提交
1557
						case 'JOINT':
1558

T
timk 已提交
1559
							influence.joint = value;//this.joints[value];
T
timk 已提交
1560
							break;
1561

T
timk 已提交
1562
						case 'WEIGHT':
1563 1564

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

T
timk 已提交
1567 1568
						default:
							break;
1569

T
timk 已提交
1570
					}
1571

T
timk 已提交
1572
				}
1573 1574

				vertex_weights.push( influence );
T
timk 已提交
1575 1576
				index += inputs.length;
			}
1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591

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

				vertex_weights[ j ].index = i;

			}

			this.weights.push( vertex_weights );

		}

	};

	function VisualScene () {

T
timk 已提交
1592 1593 1594 1595
		this.id = "";
		this.name = "";
		this.nodes = [];
		this.scene = new THREE.Object3D();
1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606

	};

	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 已提交
1607
				return node;
1608

T
timk 已提交
1609
			}
1610

T
timk 已提交
1611
		}
1612

T
timk 已提交
1613
		return null;
1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624

	};

	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 已提交
1625
				return node;
1626

T
timk 已提交
1627
			}
1628

T
timk 已提交
1629
		}
1630

T
timk 已提交
1631
		return null;
1632 1633 1634 1635 1636 1637 1638

	};

	VisualScene.prototype.parse = function( element ) {

		this.id = element.getAttribute( 'id' );
		this.name = element.getAttribute( 'name' );
T
timk 已提交
1639
		this.nodes = [];
1640 1641 1642 1643 1644 1645 1646 1647

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

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

			switch ( child.nodeName ) {

T
timk 已提交
1648
				case 'node':
1649 1650

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

T
timk 已提交
1653 1654
				default:
					break;
1655

T
timk 已提交
1656
			}
1657

T
timk 已提交
1658
		}
1659

T
timk 已提交
1660
		return this;
1661 1662 1663

	};

T
timk 已提交
1664
	function Node() {
1665

T
timk 已提交
1666 1667 1668 1669 1670 1671 1672
		this.id = "";
		this.name = "";
		this.sid = "";
		this.nodes = [];
		this.controllers = [];
		this.transforms = [];
		this.geometries = [];
T
timk 已提交
1673
		this.channels = [];
T
timk 已提交
1674
		this.matrix = new THREE.Matrix4();
1675 1676 1677 1678 1679 1680 1681

	};

	Node.prototype.getChannelForTransform = function( transformSid ) {

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

T
timk 已提交
1682 1683 1684 1685 1686 1687 1688 1689
			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;
1690 1691 1692

			if ( dotSyntax ) {

T
timk 已提交
1693 1694 1695
				parts = sid.split(".");
				sid = parts.shift();
				member = parts.shift();
1696 1697 1698

			} else if ( arrSyntax ) {

T
timk 已提交
1699 1700
				arrIndices = sid.split("(");
				sid = arrIndices.shift();
1701 1702 1703 1704 1705

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

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

T
timk 已提交
1706
				}
1707

T
timk 已提交
1708
			}
1709

1710
			if ( sid == transformSid ) {
1711

1712
				channel.info = { sid: sid, dotSyntax: dotSyntax, arrSyntax: arrSyntax, arrIndices: arrIndices };
T
timk 已提交
1713
				return channel;
1714

T
timk 已提交
1715
			}
1716

T
timk 已提交
1717
		}
1718

T
timk 已提交
1719
		return null;
1720 1721 1722 1723 1724 1725 1726

	};

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

		if ( this.id == id ) {

T
timk 已提交
1727
			return this;
1728

T
timk 已提交
1729
		}
1730 1731 1732 1733 1734 1735 1736 1737 1738

		if ( recursive ) {

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

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

				if ( n ) {

T
timk 已提交
1739
					return n;
1740

T
timk 已提交
1741
				}
1742

T
timk 已提交
1743
			}
1744

T
timk 已提交
1745
		}
1746

T
timk 已提交
1747
		return null;
1748 1749 1750 1751 1752 1753 1754

	};

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

		if ( this.sid == sid ) {

T
timk 已提交
1755
			return this;
1756

T
timk 已提交
1757
		}
1758 1759 1760 1761 1762 1763 1764 1765 1766

		if ( recursive ) {

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

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

				if ( n ) {

T
timk 已提交
1767
					return n;
1768

T
timk 已提交
1769
				}
1770

T
timk 已提交
1771 1772
			}
		}
1773

T
timk 已提交
1774
		return null;
1775 1776 1777 1778 1779 1780 1781 1782 1783

	};

	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 已提交
1784
		}
1785

T
timk 已提交
1786
		return null;
1787 1788 1789 1790 1791

	};

	Node.prototype.parse = function( element ) {

T
timk 已提交
1792
		var url;
1793

T
timk 已提交
1794 1795 1796 1797
		this.id = element.getAttribute('id');
		this.sid = element.getAttribute('sid');
		this.name = element.getAttribute('name');
		this.type = element.getAttribute('type');
1798

T
timk 已提交
1799
		this.type = this.type == 'JOINT' ? this.type : 'NODE';
1800

T
timk 已提交
1801 1802 1803
		this.nodes = [];
		this.transforms = [];
		this.geometries = [];
1804
		this.cameras = [];
T
timk 已提交
1805 1806 1807
		this.controllers = [];
		this.matrix = new THREE.Matrix4();

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

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

			switch ( child.nodeName ) {

T
timk 已提交
1815
				case 'node':
1816 1817

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

T
timk 已提交
1820
				case 'instance_camera':
1821

1822
					this.cameras.push( ( new InstanceCamera() ).parse( child ) );
T
timk 已提交
1823
					break;
1824

T
timk 已提交
1825
				case 'instance_controller':
1826 1827

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

T
timk 已提交
1830
				case 'instance_geometry':
1831 1832

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

T
timk 已提交
1835
				case 'instance_light':
1836

T
timk 已提交
1837
					break;
1838

T
timk 已提交
1839
				case 'instance_node':
1840 1841 1842 1843 1844 1845 1846 1847

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

					if ( iNode ) {

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

T
timk 已提交
1848
					}
1849

T
timk 已提交
1850
					break;
1851

T
timk 已提交
1852 1853 1854 1855 1856 1857
				case 'rotate':
				case 'translate':
				case 'scale':
				case 'matrix':
				case 'lookat':
				case 'skew':
1858 1859

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

T
timk 已提交
1862 1863
				case 'extra':
					break;
1864

T
timk 已提交
1865
				default:
1866 1867

					console.log( child.nodeName );
T
timk 已提交
1868
					break;
1869

T
timk 已提交
1870
			}
1871

T
timk 已提交
1872
		}
1873 1874 1875 1876

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

T
timk 已提交
1877
		this.updateMatrix();
1878

T
timk 已提交
1879
		return this;
1880 1881 1882 1883 1884

	};

	Node.prototype.updateMatrix = function () {

T
timk 已提交
1885
		this.matrix.identity();
1886 1887 1888

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

1889
			this.transforms[ i ].apply( this.matrix );
1890

T
timk 已提交
1891
		}
1892 1893 1894 1895 1896

	};

	function Transform () {

T
timk 已提交
1897 1898 1899
		this.sid = "";
		this.type = "";
		this.data = [];
1900
		this.obj = null;
1901 1902 1903 1904 1905 1906

	};

	Transform.prototype.parse = function ( element ) {

		this.sid = element.getAttribute( 'sid' );
T
timk 已提交
1907
		this.type = element.nodeName;
1908
		this.data = _floats( element.textContent );
1909
		this.convert();
1910

T
timk 已提交
1911
		return this;
1912 1913 1914

	};

1915
	Transform.prototype.convert = function () {
1916

1917
		switch ( this.type ) {
1918

1919 1920 1921 1922 1923 1924 1925
			case 'matrix':

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

			case 'rotate':

1926
				this.angle = THREE.Math.degToRad( this.data[3] );
1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948

			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 ) {
1949 1950 1951

		switch ( this.type ) {

T
timk 已提交
1952
			case 'matrix':
1953

1954 1955
				matrix.multiply( this.obj );

T
timk 已提交
1956
				break;
1957

T
timk 已提交
1958
			case 'translate':
1959

1960
				matrix.translate( this.obj );
1961

T
timk 已提交
1962
				break;
1963

T
timk 已提交
1964
			case 'rotate':
1965

1966
				matrix.rotateByAxis( this.obj, this.angle );
1967

T
timk 已提交
1968
				break;
1969

T
timk 已提交
1970
			case 'scale':
1971

1972
				matrix.scale( this.obj );
1973

T
timk 已提交
1974
				break;
1975

1976 1977 1978 1979 1980 1981
		}

	};

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

1982 1983
		var members = [ 'X', 'Y', 'Z', 'ANGLE' ];

1984 1985 1986 1987
		switch ( this.type ) {

			case 'matrix':

1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037
				if ( ! member ) {

					this.obj.copy( data );

				} else if ( member.length === 1 ) {

					switch ( member[ 0 ] ) {

						case 0:

							this.obj.n11 = data[ 0 ];
							this.obj.n21 = data[ 1 ];
							this.obj.n31 = data[ 2 ];
							this.obj.n41 = data[ 3 ];

							break;

						case 1:

							this.obj.n12 = data[ 0 ];
							this.obj.n22 = data[ 1 ];
							this.obj.n32 = data[ 2 ];
							this.obj.n42 = data[ 3 ];

							break;

						case 2:

							this.obj.n13 = data[ 0 ];
							this.obj.n23 = data[ 1 ];
							this.obj.n33 = data[ 2 ];
							this.obj.n43 = data[ 3 ];

							break;

						case 3:

							this.obj.n14 = data[ 0 ];
							this.obj.n24 = data[ 1 ];
							this.obj.n34 = data[ 2 ];
							this.obj.n44 = data[ 3 ];

							break;

					}

				} else if ( member.length === 2 ) {

					var propName = 'n' + ( member[ 0 ] + 1 ) + ( member[ 1 ] + 1 );
					this.obj[ propName ] = data;
2038

2039 2040 2041 2042 2043 2044
				} else {

					console.log('Incorrect addressing of matrix in transform.');

				}

T
timk 已提交
2045
				break;
2046

2047 2048 2049
			case 'translate':
			case 'scale':

2050 2051 2052 2053 2054 2055
				if ( Object.prototype.toString.call( member ) === '[object Array]' ) {

					member = members[ member[ 0 ] ];

				}

2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085
				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':

2086 2087 2088 2089 2090 2091
				if ( Object.prototype.toString.call( member ) === '[object Array]' ) {

					member = members[ member[ 0 ] ];

				}

2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102
				switch ( member ) {

					case 'X':

						this.obj.x = data;
						break;

					case 'Y':

						this.obj.y = data;
						break;
2103

2104 2105 2106 2107 2108 2109 2110
					case 'Z':

						this.obj.z = data;
						break;

					case 'ANGLE':

2111
						this.angle = THREE.Math.degToRad( data );
2112 2113 2114 2115 2116 2117 2118
						break;

					default:

						this.obj.x = data[ 0 ];
						this.obj.y = data[ 1 ];
						this.obj.z = data[ 2 ];
2119
						this.angle = THREE.Math.degToRad( data[ 3 ] );
2120 2121 2122 2123 2124 2125
						break;

				}
				break;

		}
2126 2127

	};
T
timk 已提交
2128 2129

	function InstanceController() {
2130

T
timk 已提交
2131 2132 2133
		this.url = "";
		this.skeleton = [];
		this.instance_material = [];
2134 2135 2136 2137 2138

	};

	InstanceController.prototype.parse = function ( element ) {

T
timk 已提交
2139 2140 2141
		this.url = element.getAttribute('url').replace(/^#/, '');
		this.skeleton = [];
		this.instance_material = [];
2142 2143 2144

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

2145 2146
			var child = element.childNodes[ i ];
			if ( child.nodeType !== 1 ) continue;
2147 2148 2149

			switch ( child.nodeName ) {

T
timk 已提交
2150
				case 'skeleton':
2151 2152

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

T
timk 已提交
2155
				case 'bind_material':
2156

2157
					var instances = COLLADA.evaluate( './/dae:instance_material', child, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );
2158 2159 2160

					if ( instances ) {

T
timk 已提交
2161
						var instance = instances.iterateNext();
2162 2163 2164

						while ( instance ) {

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

T
timk 已提交
2168
						}
2169

T
timk 已提交
2170
					}
2171

T
timk 已提交
2172
					break;
2173

T
timk 已提交
2174 2175
				case 'extra':
					break;
2176

T
timk 已提交
2177 2178
				default:
					break;
2179

T
timk 已提交
2180 2181
			}
		}
2182

T
timk 已提交
2183
		return this;
2184 2185 2186 2187 2188

	};

	function InstanceMaterial () {

T
timk 已提交
2189 2190
		this.symbol = "";
		this.target = "";
2191 2192 2193 2194 2195

	};

	InstanceMaterial.prototype.parse = function ( element ) {

T
timk 已提交
2196 2197 2198
		this.symbol = element.getAttribute('symbol');
		this.target = element.getAttribute('target').replace(/^#/, '');
		return this;
2199 2200 2201

	};

T
timk 已提交
2202
	function InstanceGeometry() {
2203

T
timk 已提交
2204 2205
		this.url = "";
		this.instance_material = [];
2206 2207 2208

	};

2209
	InstanceGeometry.prototype.parse = function ( element ) {
2210

T
timk 已提交
2211 2212
		this.url = element.getAttribute('url').replace(/^#/, '');
		this.instance_material = [];
2213 2214 2215

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

T
timk 已提交
2216
			var child = element.childNodes[i];
2217
			if ( child.nodeType != 1 ) continue;
2218 2219 2220

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

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

2223
				if ( instances ) {
2224

T
timk 已提交
2225
					var instance = instances.iterateNext();
2226 2227 2228 2229 2230 2231

					while ( instance ) {

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

T
timk 已提交
2232
					}
2233

T
timk 已提交
2234
				}
2235

T
timk 已提交
2236
				break;
2237

T
timk 已提交
2238
			}
2239

T
timk 已提交
2240
		}
2241

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

	};

T
timk 已提交
2246
	function Geometry() {
2247

T
timk 已提交
2248 2249
		this.id = "";
		this.mesh = null;
2250 2251 2252 2253 2254

	};

	Geometry.prototype.parse = function ( element ) {

T
timk 已提交
2255
		this.id = element.getAttribute('id');
2256

2257 2258
		extractDoubleSided( this, element );

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

T
timk 已提交
2261
			var child = element.childNodes[i];
2262 2263 2264

			switch ( child.nodeName ) {

T
timk 已提交
2265
				case 'mesh':
2266

T
timk 已提交
2267 2268
					this.mesh = (new Mesh(this)).parse(child);
					break;
2269

2270
				case 'extra':
2271

2272 2273 2274
					// console.log( child );
					break;

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

T
timk 已提交
2280
		return this;
2281 2282 2283 2284 2285

	};

	function Mesh( geometry ) {

T
timk 已提交
2286 2287 2288
		this.geometry = geometry.id;
		this.primitives = [];
		this.vertices = null;
M
Mr.doob 已提交
2289
		this.geometry3js = null;
2290 2291 2292 2293 2294

	};

	Mesh.prototype.parse = function( element ) {

T
timk 已提交
2295
		this.primitives = [];
2296

T
timk 已提交
2297
		var i, j;
2298 2299 2300

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

2301
			var child = element.childNodes[ i ];
2302

2303
			switch ( child.nodeName ) {
2304

T
timk 已提交
2305
				case 'source':
2306

2307
					_source( child );
T
timk 已提交
2308
					break;
2309

T
timk 已提交
2310
				case 'vertices':
2311

2312
					this.vertices = ( new Vertices() ).parse( child );
T
timk 已提交
2313
					break;
2314

T
timk 已提交
2315
				case 'triangles':
2316

2317
					this.primitives.push( ( new Triangles().parse( child ) ) );
T
timk 已提交
2318
					break;
2319

T
timk 已提交
2320
				case 'polygons':
2321

2322 2323
					this.primitives.push( ( new Polygons().parse( child ) ) );
					break;
2324

T
timk 已提交
2325
				case 'polylist':
2326

2327
					this.primitives.push( ( new Polylist().parse( child ) ) );
T
timk 已提交
2328
					break;
2329

T
timk 已提交
2330 2331
				default:
					break;
2332

T
timk 已提交
2333
			}
2334

T
timk 已提交
2335
		}
2336

T
timk 已提交
2337
		this.geometry3js = new THREE.Geometry();
2338 2339 2340

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

2341
		for ( i = 0; i < vertexData.length; i += 3 ) {
2342

M
Mr.doob 已提交
2343
			this.geometry3js.vertices.push( getConvertedVec3( vertexData, i ).clone() );
2344

T
timk 已提交
2345
		}
T
timk 已提交
2346

2347 2348
		for ( i = 0; i < this.primitives.length; i ++ ) {

2349
			var primitive = this.primitives[ i ];
2350
			primitive.setVertices( this.vertices );
2351
			this.handlePrimitive( primitive, this.geometry3js );
2352

T
timk 已提交
2353
		}
2354

T
timk 已提交
2355 2356
		this.geometry3js.computeCentroids();
		this.geometry3js.computeFaceNormals();
2357

2358
		if ( this.geometry3js.calcNormals ) {
2359

2360
			this.geometry3js.computeVertexNormals();
2361
			delete this.geometry3js.calcNormals;
2362

2363
		}
2364

T
timk 已提交
2365
		this.geometry3js.computeBoundingBox();
2366

T
timk 已提交
2367
		return this;
2368 2369 2370

	};

2371
	Mesh.prototype.handlePrimitive = function( primitive, geom ) {
2372

2373
		var j, k, pList = primitive.p, inputs = primitive.inputs;
T
timk 已提交
2374
		var input, index, idx32;
2375
		var source, numParams;
2376
		var vcIndex = 0, vcount = 3, maxOffset = 0;
T
timk 已提交
2377
		var texture_sets = [];
2378 2379 2380

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

2381
			input = inputs[ j ];
2382 2383
			var offset = input.offset + 1;
			maxOffset = (maxOffset < offset)? offset : maxOffset;
2384

2385
			switch ( input.semantic ) {
2386

2387 2388 2389
				case 'TEXCOORD':
					texture_sets.push( input.set );
					break;
2390

T
timk 已提交
2391
			}
2392

T
timk 已提交
2393
		}
2394

2395
		for ( var pCount = 0; pCount < pList.length; ++pCount ) {
2396

2397
			var p = pList[ pCount ], i = 0;
2398

2399
			while ( i < p.length ) {
2400

2401 2402
				var vs = [];
				var ns = [];
2403
				var ts = null;
2404
				var cs = [];
2405

2406
				if ( primitive.vcount ) {
2407

2408
					vcount = primitive.vcount.length ? primitive.vcount[ vcIndex ++ ] : primitive.vcount;
2409

2410
				} else {
2411

2412
					vcount = p.length / maxOffset;
2413

2414
				}
2415 2416


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

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

2421 2422
						input = inputs[ k ];
						source = sources[ input.source ];
2423

2424 2425 2426
						index = p[ i + ( j * maxOffset ) + input.offset ];
						numParams = source.accessor.params.length;
						idx32 = index * numParams;
2427

2428
						switch ( input.semantic ) {
2429

2430
							case 'VERTEX':
2431

2432
								vs.push( index );
2433

2434
								break;
2435

2436
							case 'NORMAL':
2437

2438
								ns.push( getConvertedVec3( source.data, idx32 ) );
2439

2440
								break;
2441

2442
							case 'TEXCOORD':
2443

2444
								ts = ts || { };
2445 2446
								if ( ts[ input.set ] === undefined ) ts[ input.set ] = [];
								// invert the V
M
Mr.doob 已提交
2447
								ts[ input.set ].push( new THREE.Vector2( source.data[ idx32 ], source.data[ idx32 + 1 ] ) );
2448

2449
								break;
2450

2451
							case 'COLOR':
2452

2453 2454 2455 2456 2457
								cs.push( new THREE.Color().setRGB( source.data[ idx32 ], source.data[ idx32 + 1 ], source.data[ idx32 + 2 ] ) );

								break;

							default:
2458

2459 2460 2461
								break;

						}
2462

T
timk 已提交
2463
					}
2464

T
timk 已提交
2465
				}
2466

2467
				if ( ns.length == 0 ) {
2468 2469

					// check the vertices inputs
2470
					input = this.vertices.input.NORMAL;
2471

2472
					if ( input ) {
2473

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

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

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

2481
						}
2482

2483 2484
					} else {

2485
						geom.calcNormals = true;
2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507

					}

				}

				if ( !ts ) {

					ts = { };
					// check the vertices inputs
					input = this.vertices.input.TEXCOORD;

					if ( input ) {

						texture_sets.push( input.set );
						source = sources[ input.source ];
						numParams = source.accessor.params.length;

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

							idx32 = vs[ ndx ] * numParams;
							if ( ts[ input.set ] === undefined ) ts[ input.set ] = [ ];
							// invert the V
M
Mr.doob 已提交
2508
							ts[ input.set ].push( new THREE.Vector2( source.data[ idx32 ], 1.0 - source.data[ idx32 + 1 ] ) );
2509 2510 2511

						}

2512
					}
2513 2514 2515

				}

2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538
				if ( cs.length == 0 ) {

					// check the vertices inputs
					input = this.vertices.input.COLOR;

					if ( input ) {

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

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

							idx32 = vs[ ndx ] * numParams;
							cs.push( new THREE.Color().setRGB( source.data[ idx32 ], source.data[ idx32 + 1 ], source.data[ idx32 + 2 ] ) );

						}

					}

				}

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

2539
				if ( vcount === 3 ) {
2540

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

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

2546
				} else if ( vcount > 4 && options.subdivideFaces ) {
2547

2548 2549
					var clr = cs.length ? cs : new THREE.Color(),
						vec1, vec2, vec3, v1, v2, norm;
2550

2551
					// subdivide into multiple Face3s
2552 2553

					for ( k = 1; k < vcount - 1; ) {
2554

2555
						// FIXME: normals don't seem to be quite right
2556

2557
						faces.push( new THREE.Face3( vs[0], vs[k], vs[k+1], [ ns[0], ns[k++], ns[k] ],  clr ) );
2558

2559
					}
2560 2561

				}
2562

2563
				if ( faces.length ) {
2564

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

2567 2568 2569
						face = faces[ndx];
						face.daeMaterial = primitive.material;
						geom.faces.push( face );
2570

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

2573
							uv = ts[ texture_sets[k] ];
2574

2575
							if ( vcount > 4 ) {
2576

2577 2578
								// Grab the right UVs for the vertices in this face
								uvArr = [ uv[0], uv[ndx+1], uv[ndx+2] ];
2579

2580
							} else if ( vcount === 4 ) {
2581

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

2584
							} else {
2585

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

2588
							}
2589

2590
							if ( !geom.faceVertexUvs[k] ) {
2591

2592
								geom.faceVertexUvs[k] = [];
2593

2594
							}
2595

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

2598
						}
2599 2600 2601

					}

2602
				} else {
2603

2604
					console.log( 'dropped face with vcount ' + vcount + ' for geometry with id: ' + geom.id );
2605

2606
				}
2607

2608
				i += maxOffset * vcount;
2609

2610
			}
T
timk 已提交
2611
		}
2612 2613 2614

	};

2615
	function Polygons () {
2616

T
timk 已提交
2617 2618 2619
		this.material = "";
		this.count = 0;
		this.inputs = [];
M
Mr.doob 已提交
2620
		this.vcount = null;
T
timk 已提交
2621 2622
		this.p = [];
		this.geometry = new THREE.Geometry();
2623 2624 2625

	};

2626
	Polygons.prototype.setVertices = function ( vertices ) {
2627 2628 2629 2630 2631 2632 2633

		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 已提交
2634
			}
2635

T
timk 已提交
2636
		}
2637 2638 2639

	};

2640
	Polygons.prototype.parse = function ( element ) {
2641

2642 2643
		this.material = element.getAttribute( 'material' );
		this.count = _attr_as_int( element, 'count', 0 );
2644 2645 2646 2647 2648 2649 2650

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

			var child = element.childNodes[ i ];

			switch ( child.nodeName ) {

T
timk 已提交
2651
				case 'input':
2652

2653
					this.inputs.push( ( new Input() ).parse( element.childNodes[ i ] ) );
T
timk 已提交
2654
					break;
2655

T
timk 已提交
2656
				case 'vcount':
2657

2658
					this.vcount = _ints( child.textContent );
T
timk 已提交
2659
					break;
2660

T
timk 已提交
2661
				case 'p':
2662

2663 2664 2665 2666 2667 2668
					this.p.push( _ints( child.textContent ) );
					break;

				case 'ph':

					console.warn( 'polygon holes not yet supported!' );
T
timk 已提交
2669
					break;
2670

T
timk 已提交
2671 2672
				default:
					break;
2673

T
timk 已提交
2674
			}
2675

T
timk 已提交
2676
		}
2677

T
timk 已提交
2678
		return this;
2679 2680 2681

	};

2682 2683 2684 2685 2686 2687 2688 2689
	function Polylist () {

		Polygons.call( this );

		this.vcount = [];

	};

2690
	Polylist.prototype = Object.create( Polygons.prototype );
2691 2692 2693 2694 2695 2696 2697

	function Triangles () {

		Polygons.call( this );

		this.vcount = 3;

2698 2699
	};

2700
	Triangles.prototype = Object.create( Polygons.prototype );
2701

T
timk 已提交
2702
	function Accessor() {
2703

T
timk 已提交
2704 2705 2706 2707
		this.source = "";
		this.count = 0;
		this.stride = 0;
		this.params = [];
2708 2709 2710

	};

2711
	Accessor.prototype.parse = function ( element ) {
2712

T
timk 已提交
2713
		this.params = [];
2714 2715 2716
		this.source = element.getAttribute( 'source' );
		this.count = _attr_as_int( element, 'count', 0 );
		this.stride = _attr_as_int( element, 'stride', 0 );
2717 2718 2719

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

2720
			var child = element.childNodes[ i ];
2721 2722 2723

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

T
timk 已提交
2724
				var param = {};
2725 2726 2727
				param[ 'name' ] = child.getAttribute( 'name' );
				param[ 'type' ] = child.getAttribute( 'type' );
				this.params.push( param );
2728

T
timk 已提交
2729
			}
2730

T
timk 已提交
2731
		}
2732

T
timk 已提交
2733
		return this;
2734 2735 2736

	};

T
timk 已提交
2737
	function Vertices() {
2738

T
timk 已提交
2739
		this.input = {};
2740 2741 2742 2743 2744

	};

	Vertices.prototype.parse = function ( element ) {

T
timk 已提交
2745
		this.id = element.getAttribute('id');
2746 2747 2748 2749 2750

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

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

2751 2752
				var input = ( new Input() ).parse( element.childNodes[ i ] );
				this.input[ input.semantic ] = input;
2753

T
timk 已提交
2754
			}
2755

T
timk 已提交
2756
		}
2757

T
timk 已提交
2758
		return this;
2759 2760 2761 2762 2763

	};

	function Input () {

T
timk 已提交
2764 2765 2766 2767
		this.semantic = "";
		this.offset = 0;
		this.source = "";
		this.set = 0;
2768 2769 2770 2771 2772

	};

	Input.prototype.parse = function ( element ) {

T
timk 已提交
2773 2774 2775 2776
		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);
2777 2778 2779

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

T
timk 已提交
2780
			this.set = 0;
2781

T
timk 已提交
2782
		}
2783

T
timk 已提交
2784
		return this;
2785 2786 2787 2788 2789

	};

	function Source ( id ) {

T
timk 已提交
2790 2791
		this.id = id;
		this.type = null;
2792 2793 2794 2795 2796 2797 2798 2799 2800

	};

	Source.prototype.parse = function ( element ) {

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

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

T
timk 已提交
2801
			var child = element.childNodes[i];
2802 2803 2804

			switch ( child.nodeName ) {

T
timk 已提交
2805
				case 'bool_array':
2806

2807
					this.data = _bools( child.textContent );
T
timk 已提交
2808 2809
					this.type = child.nodeName;
					break;
2810

T
timk 已提交
2811
				case 'float_array':
2812

2813
					this.data = _floats( child.textContent );
T
timk 已提交
2814 2815
					this.type = child.nodeName;
					break;
2816

T
timk 已提交
2817
				case 'int_array':
2818

2819
					this.data = _ints( child.textContent );
T
timk 已提交
2820 2821
					this.type = child.nodeName;
					break;
2822

T
timk 已提交
2823 2824
				case 'IDREF_array':
				case 'Name_array':
2825

2826
					this.data = _strings( child.textContent );
T
timk 已提交
2827 2828
					this.type = child.nodeName;
					break;
2829

T
timk 已提交
2830
				case 'technique_common':
2831 2832 2833

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

2834
						if ( child.childNodes[ j ].nodeName == 'accessor' ) {
2835

2836
							this.accessor = ( new Accessor() ).parse( child.childNodes[ j ] );
T
timk 已提交
2837
							break;
2838

T
timk 已提交
2839 2840 2841
						}
					}
					break;
2842

T
timk 已提交
2843
				default:
M
Mr.doob 已提交
2844
					// console.log(child.nodeName);
T
timk 已提交
2845
					break;
2846

T
timk 已提交
2847
			}
2848

T
timk 已提交
2849
		}
2850

T
timk 已提交
2851
		return this;
2852 2853 2854 2855 2856

	};

	Source.prototype.read = function () {

T
timk 已提交
2857
		var result = [];
2858

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

2861
			var param = this.accessor.params[ 0 ];
2862

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

2865
			switch ( param.type ) {
2866

T
timk 已提交
2867
				case 'IDREF':
2868
				case 'Name': case 'name':
T
timk 已提交
2869
				case 'float':
2870

T
timk 已提交
2871
					return this.data;
2872

T
timk 已提交
2873
				case 'float4x4':
2874 2875 2876

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

2877
						var s = this.data.slice( j, j + 16 );
2878
						var m = getConvertedMat4( s );
2879
						result.push( m );
T
timk 已提交
2880
					}
2881

T
timk 已提交
2882
					break;
2883

T
timk 已提交
2884
				default:
2885

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

T
timk 已提交
2889
			}
2890

T
timk 已提交
2891
		//}
2892

T
timk 已提交
2893
		return result;
2894 2895 2896 2897 2898

	};

	function Material () {

T
timk 已提交
2899 2900 2901
		this.id = "";
		this.name = "";
		this.instance_effect = null;
2902 2903 2904 2905 2906

	};

	Material.prototype.parse = function ( element ) {

2907 2908
		this.id = element.getAttribute( 'id' );
		this.name = element.getAttribute( 'name' );
2909 2910 2911

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

2912 2913 2914
			if ( element.childNodes[ i ].nodeName == 'instance_effect' ) {

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

T
timk 已提交
2917
			}
2918

T
timk 已提交
2919
		}
2920

T
timk 已提交
2921
		return this;
2922 2923 2924 2925 2926

	};

	function ColorOrTexture () {

2927 2928
		this.color = new THREE.Color( 0 );
		this.color.setRGB( Math.random(), Math.random(), Math.random() );
T
timk 已提交
2929
		this.color.a = 1.0;
2930

T
timk 已提交
2931 2932
		this.texture = null;
		this.texcoord = null;
2933
		this.texOpts = null;
2934 2935 2936 2937 2938

	};

	ColorOrTexture.prototype.isColor = function () {

2939
		return ( this.texture == null );
2940 2941 2942 2943 2944

	};

	ColorOrTexture.prototype.isTexture = function () {

2945
		return ( this.texture != null );
2946 2947 2948 2949 2950 2951 2952

	};

	ColorOrTexture.prototype.parse = function ( element ) {

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

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

			switch ( child.nodeName ) {

T
timk 已提交
2958
				case 'color':
2959

2960
					var rgba = _floats( child.textContent );
T
timk 已提交
2961
					this.color = new THREE.Color(0);
2962
					this.color.setRGB( rgba[0], rgba[1], rgba[2] );
T
timk 已提交
2963 2964
					this.color.a = rgba[3];
					break;
2965

T
timk 已提交
2966
				case 'texture':
2967

T
timk 已提交
2968 2969
					this.texture = child.getAttribute('texture');
					this.texcoord = child.getAttribute('texcoord');
2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980
					// 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 已提交
2981
					break;
2982

T
timk 已提交
2983 2984
				default:
					break;
2985

T
timk 已提交
2986
			}
2987

T
timk 已提交
2988
		}
2989

T
timk 已提交
2990
		return this;
2991 2992 2993

	};

2994 2995
	ColorOrTexture.prototype.parseTexture = function ( element ) {

2996
		if ( ! element.childNodes ) return this;
2997

2998 2999
		// This should be supported by Maya, 3dsMax, and MotionBuilder

3000
		if ( element.childNodes[1] && element.childNodes[1].nodeName === 'extra' ) {
3001

3002
			element = element.childNodes[1];
3003

3004
			if ( element.childNodes[1] && element.childNodes[1].nodeName === 'technique' ) {
3005

3006
				element = element.childNodes[1];
3007 3008 3009 3010 3011

			}

		}

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

3014
			var child = element.childNodes[ i ];
3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043

			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;

	};

3044 3045
	function Shader ( type, effect ) {

T
timk 已提交
3046
		this.type = type;
T
timk 已提交
3047
		this.effect = effect;
M
Mr.doob 已提交
3048
		this.material = null;
3049 3050 3051 3052 3053 3054 3055

	};

	Shader.prototype.parse = function ( element ) {

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

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

3059
			switch ( child.nodeName ) {
3060

T
timk 已提交
3061 3062 3063 3064 3065
				case 'ambient':
				case 'emission':
				case 'diffuse':
				case 'specular':
				case 'transparent':
3066

3067
					this[ child.nodeName ] = ( new ColorOrTexture() ).parse( child );
T
timk 已提交
3068
					break;
3069

T
timk 已提交
3070 3071
				case 'shininess':
				case 'reflectivity':
3072
				case 'index_of_refraction':
T
timk 已提交
3073
				case 'transparency':
3074

3075
					var f = evaluateXPath( child, './/dae:float' );
3076 3077 3078 3079

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

T
timk 已提交
3080
					break;
3081

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

T
timk 已提交
3085
			}
3086

T
timk 已提交
3087
		}
3088

T
timk 已提交
3089
		this.create();
T
timk 已提交
3090
		return this;
3091 3092 3093

	};

T
timk 已提交
3094
	Shader.prototype.create = function() {
3095

T
timk 已提交
3096
		var props = {};
3097 3098 3099 3100 3101 3102
		var transparent = ( this['transparency'] !== undefined && this['transparency'] < 1.0 );

		for ( var prop in this ) {

			switch ( prop ) {

T
timk 已提交
3103 3104 3105 3106
				case 'ambient':
				case 'emission':
				case 'diffuse':
				case 'specular':
3107

3108
					var cot = this[ prop ];
3109 3110 3111 3112 3113

					if ( cot instanceof ColorOrTexture ) {

						if ( cot.isTexture() ) {

3114 3115 3116
							var samplerId = cot.texture;
							var surfaceId = this.effect.sampler[samplerId].source;
              
3117

3118
							if (surfaceId) {
3119

3120 3121
								var surface = this.effect.surface[surfaceId];
								var image = images[surface.init_from];
3122

3123
								if (image) {
3124

3125 3126 3127 3128 3129 3130 3131 3132
									var texture = THREE.ImageUtils.loadTexture(baseUrl + image.init_from);
									texture.wrapS = cot.texOpts.wrapU ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping;
									texture.wrapT = cot.texOpts.wrapV ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping;
									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;
3133

3134 3135
									// Texture with baked lighting?
									if (prop === 'emission') props['emissive'] = 0xffffff;
3136

T
timk 已提交
3137
								}
3138

T
timk 已提交
3139
							}
3140

3141
						} else if ( prop === 'diffuse' || !transparent ) {
3142

3143
							if ( prop === 'emission' ) {
3144 3145 3146 3147 3148 3149 3150 3151

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

							} else {

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

							}
3152

T
timk 已提交
3153
						}
3154

T
timk 已提交
3155
					}
3156

T
timk 已提交
3157
					break;
3158

T
timk 已提交
3159
				case 'shininess':
3160

3161 3162
					props[ prop ] = this[ prop ];
					break;
3163

T
timk 已提交
3164
				case 'reflectivity':
3165

3166
					props[ prop ] = this[ prop ];
3167
					if( props[ prop ] > 0.0 ) props['envMap'] = options.defaultEnvMap;
3168 3169
					props['combine'] = THREE.MixOperation;	//mix regular shading with reflective component
					break;
3170

3171
				case 'index_of_refraction':
3172

3173
					props[ 'refractionRatio' ] = this[ prop ]; //TODO: "index_of_refraction" becomes "refractionRatio" in shader, but I'm not sure if the two are actually comparable
3174
					if ( this[ prop ] !== 1.0 ) props['envMap'] = options.defaultEnvMap;
T
timk 已提交
3175
					break;
3176

T
timk 已提交
3177
				case 'transparency':
3178 3179 3180

					if ( transparent ) {

3181 3182
						props[ 'transparent' ] = true;
						props[ 'opacity' ] = this[ prop ];
T
timk 已提交
3183
						transparent = true;
3184

T
timk 已提交
3185
					}
3186

T
timk 已提交
3187
					break;
3188

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

T
timk 已提交
3192
			}
3193

T
timk 已提交
3194 3195
		}

3196
		props[ 'shading' ] = preferredShading;
3197
		props[ 'side' ] = this.effect.doubleSided ? THREE.DoubleSide : THREE.FrontSide;
3198 3199 3200

		switch ( this.type ) {

T
timk 已提交
3201
			case 'constant':
3202

3203
				if (props.emissive != undefined) props.color = props.emissive;
3204
				this.material = new THREE.MeshBasicMaterial( props );
T
timk 已提交
3205
				break;
3206

T
timk 已提交
3207 3208
			case 'phong':
			case 'blinn':
3209

3210
				if (props.diffuse != undefined) props.color = props.diffuse;
3211 3212
				this.material = new THREE.MeshPhongMaterial( props );
				break;
3213

3214 3215
			case 'lambert':
			default:
3216

3217
				if (props.diffuse != undefined) props.color = props.diffuse;
3218
				this.material = new THREE.MeshLambertMaterial( props );
T
timk 已提交
3219
				break;
3220

T
timk 已提交
3221
		}
3222

T
timk 已提交
3223
		return this.material;
3224 3225 3226 3227 3228

	};

	function Surface ( effect ) {

T
timk 已提交
3229
		this.effect = effect;
M
Mr.doob 已提交
3230 3231
		this.init_from = null;
		this.format = null;
3232 3233 3234 3235 3236 3237 3238

	};

	Surface.prototype.parse = function ( element ) {

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

3239 3240
			var child = element.childNodes[ i ];
			if ( child.nodeType != 1 ) continue;
3241 3242 3243

			switch ( child.nodeName ) {

T
timk 已提交
3244
				case 'init_from':
3245

T
timk 已提交
3246 3247
					this.init_from = child.textContent;
					break;
3248

T
timk 已提交
3249
				case 'format':
3250

T
timk 已提交
3251 3252
					this.format = child.textContent;
					break;
3253

T
timk 已提交
3254
				default:
3255

3256
					console.log( "unhandled Surface prop: " + child.nodeName );
T
timk 已提交
3257
					break;
3258

T
timk 已提交
3259
			}
3260

T
timk 已提交
3261
		}
3262

T
timk 已提交
3263
		return this;
3264 3265 3266 3267 3268

	};

	function Sampler2D ( effect ) {

T
timk 已提交
3269
		this.effect = effect;
M
Mr.doob 已提交
3270 3271 3272 3273 3274 3275
		this.source = null;
		this.wrap_s = null;
		this.wrap_t = null;
		this.minfilter = null;
		this.magfilter = null;
		this.mipfilter = null;
3276 3277 3278 3279 3280 3281 3282 3283 3284 3285

	};

	Sampler2D.prototype.parse = function ( element ) {

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

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

3286
			switch ( child.nodeName ) {
3287

T
timk 已提交
3288
				case 'source':
3289

T
timk 已提交
3290 3291
					this.source = child.textContent;
					break;
3292

T
timk 已提交
3293
				case 'minfilter':
3294

T
timk 已提交
3295 3296
					this.minfilter = child.textContent;
					break;
3297

T
timk 已提交
3298
				case 'magfilter':
3299

T
timk 已提交
3300 3301
					this.magfilter = child.textContent;
					break;
3302

T
timk 已提交
3303
				case 'mipfilter':
3304

T
timk 已提交
3305 3306
					this.mipfilter = child.textContent;
					break;
3307

T
timk 已提交
3308
				case 'wrap_s':
3309

T
timk 已提交
3310 3311
					this.wrap_s = child.textContent;
					break;
3312

T
timk 已提交
3313
				case 'wrap_t':
3314

T
timk 已提交
3315 3316
					this.wrap_t = child.textContent;
					break;
3317

T
timk 已提交
3318
				default:
3319

3320
					console.log( "unhandled Sampler2D prop: " + child.nodeName );
T
timk 已提交
3321
					break;
3322

T
timk 已提交
3323
			}
3324

T
timk 已提交
3325
		}
3326

T
timk 已提交
3327
		return this;
3328 3329 3330 3331 3332

	};

	function Effect () {

T
timk 已提交
3333 3334 3335
		this.id = "";
		this.name = "";
		this.shader = null;
3336 3337
		this.surface = {};
		this.sampler = {};
3338 3339 3340 3341 3342 3343 3344

	};

	Effect.prototype.create = function () {

		if ( this.shader == null ) {

T
timk 已提交
3345
			return null;
3346

T
timk 已提交
3347
		}
3348 3349 3350 3351 3352 3353 3354

	};

	Effect.prototype.parse = function ( element ) {

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

3356
		extractDoubleSided( this, element );
3357

T
timk 已提交
3358
		this.shader = null;
3359 3360 3361 3362 3363 3364 3365 3366

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

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

			switch ( child.nodeName ) {

T
timk 已提交
3367
				case 'profile_COMMON':
3368 3369

					this.parseTechnique( this.parseProfileCOMMON( child ) );
T
timk 已提交
3370
					break;
3371

T
timk 已提交
3372 3373
				default:
					break;
3374

T
timk 已提交
3375
			}
3376

T
timk 已提交
3377
		}
3378

T
timk 已提交
3379
		return this;
3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393

	};

	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 已提交
3394
				case 'surface':
3395

3396
					this.surface[sid] = ( new Surface( this ) ).parse( child );
T
timk 已提交
3397
					break;
3398

T
timk 已提交
3399
				case 'sampler2D':
3400

3401
					this.sampler[sid] = ( new Sampler2D( this ) ).parse( child );
T
timk 已提交
3402
					break;
3403

T
timk 已提交
3404
				case 'extra':
3405

T
timk 已提交
3406
					break;
3407

T
timk 已提交
3408
				default:
3409 3410

					console.log( child.nodeName );
T
timk 已提交
3411
					break;
3412

T
timk 已提交
3413
			}
3414

T
timk 已提交
3415
		}
3416 3417 3418 3419 3420

	};

	Effect.prototype.parseProfileCOMMON = function ( element ) {

T
timk 已提交
3421
		var technique;
3422 3423 3424 3425 3426 3427 3428 3429 3430

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

			var child = element.childNodes[ i ];

			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

T
timk 已提交
3431
				case 'profile_COMMON':
3432 3433

					this.parseProfileCOMMON( child );
T
timk 已提交
3434
					break;
3435

T
timk 已提交
3436
				case 'technique':
3437

T
timk 已提交
3438
					technique = child;
T
timk 已提交
3439
					break;
3440

T
timk 已提交
3441
				case 'newparam':
3442 3443

					this.parseNewparam( child );
T
timk 已提交
3444
					break;
3445

3446 3447 3448 3449 3450 3451
				case 'image':

					var _image = ( new _Image() ).parse( child );
					images[ _image.id ] = _image;
					break;

T
timk 已提交
3452 3453
				case 'extra':
					break;
3454

T
timk 已提交
3455
				default:
3456 3457

					console.log( child.nodeName );
T
timk 已提交
3458
					break;
3459

T
timk 已提交
3460
			}
3461

T
timk 已提交
3462
		}
3463

T
timk 已提交
3464
		return technique;
3465 3466 3467 3468 3469 3470 3471

	};

	Effect.prototype.parseTechnique= function ( element ) {

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

T
timk 已提交
3472
			var child = element.childNodes[i];
3473
			if ( child.nodeType != 1 ) continue;
3474 3475 3476

			switch ( child.nodeName ) {

3477
				case 'constant':
T
timk 已提交
3478 3479 3480
				case 'lambert':
				case 'blinn':
				case 'phong':
3481 3482

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

T
timk 已提交
3485 3486
				default:
					break;
3487

T
timk 已提交
3488
			}
3489

T
timk 已提交
3490
		}
3491 3492 3493 3494 3495

	};

	function InstanceEffect () {

T
timk 已提交
3496
		this.url = "";
3497 3498 3499 3500 3501 3502

	};

	InstanceEffect.prototype.parse = function ( element ) {

		this.url = element.getAttribute( 'url' ).replace( /^#/, '' );
T
timk 已提交
3503
		return this;
3504 3505

	};
T
timk 已提交
3506 3507

	function Animation() {
3508

T
timk 已提交
3509 3510 3511 3512 3513
		this.id = "";
		this.name = "";
		this.source = {};
		this.sampler = [];
		this.channel = [];
3514 3515 3516 3517 3518 3519 3520

	};

	Animation.prototype.parse = function ( element ) {

		this.id = element.getAttribute( 'id' );
		this.name = element.getAttribute( 'name' );
T
timk 已提交
3521
		this.source = {};
3522 3523 3524 3525 3526 3527 3528 3529 3530

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

			var child = element.childNodes[ i ];

			if ( child.nodeType != 1 ) continue;

			switch ( child.nodeName ) {

3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549
				case 'animation':

					var anim = ( new Animation() ).parse( child );

					for ( var src in anim.source ) {

						this.source[ src ] = anim.source[ src ];

					}

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

						this.channel.push( anim.channel[ j ] );
						this.sampler.push( anim.sampler[ j ] );

					}

					break;

T
timk 已提交
3550
				case 'source':
3551 3552 3553

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

T
timk 已提交
3556
				case 'sampler':
3557 3558

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

T
timk 已提交
3561
				case 'channel':
3562 3563

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

T
timk 已提交
3566 3567
				default:
					break;
3568

T
timk 已提交
3569
			}
3570

T
timk 已提交
3571
		}
3572

T
timk 已提交
3573
		return this;
T
timk 已提交
3574

3575 3576 3577 3578
	};

	function Channel( animation ) {

T
timk 已提交
3579 3580 3581
		this.animation = animation;
		this.source = "";
		this.target = "";
3582
		this.fullSid = null;
M
Mr.doob 已提交
3583 3584 3585 3586 3587
		this.sid = null;
		this.dotSyntax = null;
		this.arrSyntax = null;
		this.arrIndices = null;
		this.member = null;
3588 3589 3590 3591 3592 3593 3594 3595 3596 3597

	};

	Channel.prototype.parse = function ( element ) {

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

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

T
timk 已提交
3598 3599
		var id = parts.shift();
		var sid = parts.shift();
3600 3601 3602 3603 3604 3605

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

		if ( dotSyntax ) {

T
timk 已提交
3606
			parts = sid.split(".");
3607 3608
			this.sid = parts.shift();
			this.member = parts.shift();
3609 3610 3611

		} else if ( arrSyntax ) {

3612 3613
			var arrIndices = sid.split("(");
			this.sid = arrIndices.shift();
3614 3615 3616 3617 3618

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

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

T
timk 已提交
3619
			}
3620

3621 3622 3623 3624 3625 3626
			this.arrIndices = arrIndices;

		} else {

			this.sid = sid;

T
timk 已提交
3627
		}
3628

3629
		this.fullSid = sid;
T
timk 已提交
3630 3631
		this.dotSyntax = dotSyntax;
		this.arrSyntax = arrSyntax;
3632

T
timk 已提交
3633
		return this;
3634 3635 3636 3637 3638

	};

	function Sampler ( animation ) {

T
timk 已提交
3639 3640 3641
		this.id = "";
		this.animation = animation;
		this.inputs = [];
M
Mr.doob 已提交
3642 3643
		this.input = null;
		this.output = null;
3644
		this.strideOut = null;
M
Mr.doob 已提交
3645 3646 3647
		this.interpolation = null;
		this.startTime = null;
		this.endTime = null;
T
timk 已提交
3648
		this.duration = 0;
3649 3650 3651 3652 3653 3654

	};

	Sampler.prototype.parse = function ( element ) {

		this.id = element.getAttribute( 'id' );
T
timk 已提交
3655
		this.inputs = [];
3656 3657 3658 3659 3660 3661 3662 3663

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

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

			switch ( child.nodeName ) {

T
timk 已提交
3664
				case 'input':
3665 3666

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

T
timk 已提交
3669 3670
				default:
					break;
3671

T
timk 已提交
3672
			}
3673

T
timk 已提交
3674
		}
3675

T
timk 已提交
3676
		return this;
3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688

	};

	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 已提交
3689
				case 'INPUT':
3690

T
timk 已提交
3691 3692
					this.input = source.read();
					break;
3693

T
timk 已提交
3694
				case 'OUTPUT':
3695

T
timk 已提交
3696
					this.output = source.read();
3697
					this.strideOut = source.accessor.stride;
T
timk 已提交
3698
					break;
3699

T
timk 已提交
3700
				case 'INTERPOLATION':
3701

T
timk 已提交
3702 3703
					this.interpolation = source.read();
					break;
3704

T
timk 已提交
3705
				case 'IN_TANGENT':
3706

T
timk 已提交
3707
					break;
3708

T
timk 已提交
3709
				case 'OUT_TANGENT':
3710

T
timk 已提交
3711
					break;
3712

T
timk 已提交
3713
				default:
3714

T
timk 已提交
3715 3716
					console.log(input.semantic);
					break;
3717

T
timk 已提交
3718
			}
3719

T
timk 已提交
3720
		}
3721

T
timk 已提交
3722 3723 3724
		this.startTime = 0;
		this.endTime = 0;
		this.duration = 0;
3725 3726 3727

		if ( this.input.length ) {

T
timk 已提交
3728 3729
			this.startTime = 100000000;
			this.endTime = -100000000;
3730 3731 3732 3733 3734 3735

			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 已提交
3736
			}
3737

T
timk 已提交
3738
			this.duration = this.endTime - this.startTime;
3739

T
timk 已提交
3740
		}
3741 3742 3743

	};

3744 3745 3746 3747
	Sampler.prototype.getData = function ( type, ndx ) {

		var data;

3748 3749 3750 3751 3752
		if ( type === 'matrix' && this.strideOut === 16 ) {

			data = this.output[ ndx ];

		} else if ( this.strideOut > 1 ) {
3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779

			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;

				}

3780 3781 3782 3783
			} else if ( this.strideOut === 4 && type === 'matrix' ) {

				fixCoords( data, -1 );

3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870
			}

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

3871
			if ( target.transform.type !== 'matrix' && nextTarget ) {
3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911

				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 已提交
3912 3913 3914
	};

	function Camera() {
3915 3916 3917

		this.id = "";
		this.name = "";
3918
		this.technique = "";
3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959

	};

	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 ++ ) {

3960 3961 3962
					this.technique = technique.childNodes[ j ].nodeName;

					if ( this.technique == 'perspective' ) {
3963 3964 3965 3966 3967 3968

						var perspective = technique.childNodes[ j ];

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

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

3970 3971
							switch ( param.nodeName ) {

3972 3973 3974
								case 'yfov':
									this.yfov = param.textContent;
									break;
3975
								case 'xfov':
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
									this.xfov = param.textContent;
									break;
								case 'znear':
									this.znear = param.textContent;
									break;
								case 'zfar':
									this.zfar = param.textContent;
									break;
								case 'aspect_ratio':
									this.aspect_ratio = param.textContent;
									break;

							}

						}

					} else if ( this.technique == 'orthographic' ) {

						var orthographic = technique.childNodes[ j ];

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

							var param = orthographic.childNodes[ k ];

							switch ( param.nodeName ) {

								case 'xmag':
									this.xmag = param.textContent;
									break;
								case 'ymag':
									this.ymag = param.textContent;
4007 4008
									break;
								case 'znear':
4009
									this.znear = param.textContent;
4010 4011
									break;
								case 'zfar':
4012
									this.zfar = param.textContent;
4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024
									break;
								case 'aspect_ratio':
									this.aspect_ratio = param.textContent;
									break;

							}

						}

					}

				}
4025

4026 4027 4028
			}

		}
4029

4030 4031 4032
		return this;

	};
M
Mr.doob 已提交
4033

4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045
	function InstanceCamera() {

		this.url = "";

	};

	InstanceCamera.prototype.parse = function ( element ) {

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

		return this;

4046 4047
	};

4048
	function _source( element ) {
4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062

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

		if ( sources[ id ] != undefined ) {

			return sources[ id ];

		}

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

	};

4063
	function _nsResolver( nsPrefix ) {
4064 4065 4066

		if ( nsPrefix == "dae" ) {

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

T
timk 已提交
4069
		}
4070

T
timk 已提交
4071
		return null;
4072 4073 4074

	};

4075
	function _bools( str ) {
4076 4077

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

4080
		for ( var i = 0, l = raw.length; i < l; i ++ ) {
4081 4082

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

T
timk 已提交
4084
		}
4085

T
timk 已提交
4086
		return data;
4087 4088 4089

	};

4090
	function _floats( str ) {
4091

T
timk 已提交
4092 4093
		var raw = _strings(str);
		var data = [];
4094

4095
		for ( var i = 0, l = raw.length; i < l; i ++ ) {
4096 4097 4098

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

T
timk 已提交
4099
		}
4100

T
timk 已提交
4101
		return data;
4102 4103

	};
T
timk 已提交
4104

4105
	function _ints( str ) {
4106 4107

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

4110
		for ( var i = 0, l = raw.length; i < l; i ++ ) {
4111 4112 4113

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

T
timk 已提交
4114
		}
4115

T
timk 已提交
4116
		return data;
4117 4118 4119

	};

4120
	function _strings( str ) {
4121

4122
		return ( str.length > 0 ) ? _trimString( str ).split( /\s+/ ) : [];
4123 4124

	};
T
timk 已提交
4125

4126
	function _trimString( str ) {
4127 4128 4129 4130

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

	};
T
timk 已提交
4131

4132
	function _attr_as_float( element, name, defaultValue ) {
4133 4134 4135 4136 4137

		if ( element.hasAttribute( name ) ) {

			return parseFloat( element.getAttribute( name ) );

T
timk 已提交
4138
		} else {
4139

T
timk 已提交
4140
			return defaultValue;
4141

T
timk 已提交
4142
		}
4143 4144

	};
T
timk 已提交
4145

4146
	function _attr_as_int( element, name, defaultValue ) {
4147 4148 4149 4150 4151

		if ( element.hasAttribute( name ) ) {

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

T
timk 已提交
4152
		} else {
4153

T
timk 已提交
4154
			return defaultValue;
4155

T
timk 已提交
4156
		}
4157 4158

	};
T
timk 已提交
4159

4160
	function _attr_as_string( element, name, defaultValue ) {
4161 4162 4163 4164 4165

		if ( element.hasAttribute( name ) ) {

			return element.getAttribute( name );

T
timk 已提交
4166
		} else {
4167

T
timk 已提交
4168
			return defaultValue;
4169

T
timk 已提交
4170
		}
4171 4172 4173

	};

4174
	function _format_float( f, num ) {
4175 4176 4177

		if ( f === undefined ) {

T
timk 已提交
4178
			var s = '0.';
4179 4180 4181

			while ( s.length < num + 2 ) {

T
timk 已提交
4182
				s += '0';
4183

T
timk 已提交
4184
			}
4185

T
timk 已提交
4186
			return s;
4187

T
timk 已提交
4188
		}
4189

T
timk 已提交
4190
		num = num || 2;
4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204

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

	};

4205
	function evaluateXPath( node, query ) {
4206

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

T
timk 已提交
4209 4210
		var inst = instances.iterateNext();
		var result = [];
4211 4212 4213 4214

		while ( inst ) {

			result.push( inst );
T
timk 已提交
4215
			inst = instances.iterateNext();
4216 4217 4218

		}

T
timk 已提交
4219
		return result;
4220 4221 4222

	};

4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242
	function extractDoubleSided( obj, element ) {

		obj.doubleSided = false;

		var node = COLLADA.evaluate( './/dae:extra//dae:double_sided', element, _nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );

		if ( node ) {

			node = node.iterateNext();

			if ( node && parseInt( node.textContent, 10 ) === 1 ) {

				obj.doubleSided = true;

			}

		}

	};

4243 4244
	// Up axis conversion

4245
	function setUpConversion() {
4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275

		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;

			}

		}

	};

4276
	function fixCoords( data, sign ) {
4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333

		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;

		}

	};

4334
	function getConvertedVec3( data, offset ) {
4335 4336 4337 4338 4339 4340 4341

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

	};

4342
	function getConvertedMat4( data ) {
4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398

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

	};

4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411
	function getConvertedIndex( index ) {

		if ( index > -1 && index < 3 ) {

			var members = ['X', 'Y', 'Z'],
				indices = { X: 0, Y: 1, Z: 2 };

			index = getConvertedMember( members[ index ] );
			index = indices[ index ];

		}

		return index;
4412

4413 4414
	};

4415
	function getConvertedMember( member ) {
4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490

		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 已提交
4491
	return {
4492

T
timk 已提交
4493
		load: load,
4494
		parse: parse,
T
timk 已提交
4495
		setPreferredShading: setPreferredShading,
T
timk 已提交
4496
		applySkin: applySkin,
4497 4498
		geometries : geometries,
		options: options
4499

T
timk 已提交
4500
	};
4501

4502
};