2
0
Эх сурвалжийг харах

Merge remote-tracking branch 'alteredq/dev' into dev

Mr.doob 12 жил өмнө
parent
commit
bec5849df7

+ 75 - 20
build/three.js

@@ -2965,8 +2965,9 @@ THREE.Frustum.__v1 = new THREE.Vector3();
 			var geometry = object.geometry;
 			var geometry = object.geometry;
 			var vertices = geometry.vertices;
 			var vertices = geometry.vertices;
 
 
-			var geometryMaterials = object.geometry.materials;
 			var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
 			var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
+			var geometryMaterials = ( isFaceMaterial && object.material.materials.length > 0 ) ? object.material.materials : object.geometry.materials;
+
 			var side = object.material.side;
 			var side = object.material.side;
 
 
 			var a, b, c, d;
 			var a, b, c, d;
@@ -3983,7 +3984,7 @@ THREE.Projector = function() {
 
 
 		_renderData = projectGraph( scene, sortObjects );
 		_renderData = projectGraph( scene, sortObjects );
 
 
-		for ( o = 0, ol = _renderData.objects.length; o < ol; o++ ) {
+		for ( o = 0, ol = _renderData.objects.length; o < ol; o ++ ) {
 
 
 			object = _renderData.objects[ o ].object;
 			object = _renderData.objects[ o ].object;
 
 
@@ -3994,7 +3995,7 @@ THREE.Projector = function() {
 			if ( object instanceof THREE.Mesh ) {
 			if ( object instanceof THREE.Mesh ) {
 
 
 				geometry = object.geometry;
 				geometry = object.geometry;
-				geometryMaterials = object.geometry.materials;
+
 				vertices = geometry.vertices;
 				vertices = geometry.vertices;
 				faces = geometry.faces;
 				faces = geometry.faces;
 				faceVertexUvs = geometry.faceVertexUvs;
 				faceVertexUvs = geometry.faceVertexUvs;
@@ -4003,6 +4004,8 @@ THREE.Projector = function() {
 				_normalMatrix.transpose();
 				_normalMatrix.transpose();
 
 
 				isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
 				isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
+				geometryMaterials = ( isFaceMaterial && object.material.materials.length > 0 ) ? object.material.materials : object.geometry.materials;
+
 				side = object.material.side;
 				side = object.material.side;
 
 
 				for ( v = 0, vl = vertices.length; v < vl; v ++ ) {
 				for ( v = 0, vl = vertices.length; v < vl; v ++ ) {
@@ -11051,7 +11054,11 @@ THREE.MeshNormalMaterial.prototype.clone = function () {
  * @author mrdoob / http://mrdoob.com/
  * @author mrdoob / http://mrdoob.com/
  */
  */
 
 
-THREE.MeshFaceMaterial = function () {};
+THREE.MeshFaceMaterial = function ( materials ) {
+
+	this.materials = materials instanceof Array ? materials : [];
+
+};
 
 
 THREE.MeshFaceMaterial.prototype.clone = function () {
 THREE.MeshFaceMaterial.prototype.clone = function () {
 
 
@@ -15619,7 +15626,7 @@ THREE.ShaderLib = {
 			"void main() {",
 			"void main() {",
 
 
 				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
 				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
-				"vNormal = normalMatrix * normal;",
+				"vNormal = normalize( normalMatrix * normal );",
 
 
 				"gl_Position = projectionMatrix * mvPosition;",
 				"gl_Position = projectionMatrix * mvPosition;",
 
 
@@ -15893,7 +15900,7 @@ THREE.ShaderLib = {
 				THREE.ShaderChunk[ "skinnormal_vertex" ],
 				THREE.ShaderChunk[ "skinnormal_vertex" ],
 				THREE.ShaderChunk[ "defaultnormal_vertex" ],
 				THREE.ShaderChunk[ "defaultnormal_vertex" ],
 
 
-				"vNormal = transformedNormal;",
+				"vNormal = normalize( transformedNormal );",
 
 
 				THREE.ShaderChunk[ "morphtarget_vertex" ],
 				THREE.ShaderChunk[ "morphtarget_vertex" ],
 				THREE.ShaderChunk[ "skinning_vertex" ],
 				THREE.ShaderChunk[ "skinning_vertex" ],
@@ -17037,13 +17044,21 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	function getBufferMaterial( object, geometryGroup ) {
 	function getBufferMaterial( object, geometryGroup ) {
 
 
-		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
+		if ( object.material instanceof THREE.MeshFaceMaterial ) {
 
 
-			return object.material;
+			if ( object.material.materials.length > 0 ) {
+
+				return object.material.materials[ geometryGroup.materialIndex ];
+
+			} else {
+
+				return object.geometry.materials[ geometryGroup.materialIndex ];
+
+			}
 
 
-		} else if ( geometryGroup.materialIndex >= 0 ) {
+		} else {
 
 
-			return object.geometry.materials[ geometryGroup.materialIndex ];
+			return object.material;
 
 
 		}
 		}
 
 
@@ -20307,7 +20322,15 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 			if ( materialIndex >= 0 ) {
 			if ( materialIndex >= 0 ) {
 
 
-				material = object.geometry.materials[ materialIndex ];
+				if ( meshMaterial.materials.length > 0 ) {
+
+					material = meshMaterial.materials[ materialIndex ];
+
+				} else {
+
+					material = object.geometry.materials[ materialIndex ];
+
+				}
 
 
 				if ( material.transparent ) {
 				if ( material.transparent ) {
 
 
@@ -25731,19 +25754,19 @@ THREE.ShaderUtils = {
 
 
 					"#ifdef USE_SKINNING",
 					"#ifdef USE_SKINNING",
 
 
-						"vNormal = normalMatrix * skinnedNormal.xyz;",
+						"vNormal = normalize( normalMatrix * skinnedNormal.xyz );",
 
 
 						"vec4 skinnedTangent = skinMatrix * vec4( tangent.xyz, 0.0 );",
 						"vec4 skinnedTangent = skinMatrix * vec4( tangent.xyz, 0.0 );",
-						"vTangent = normalMatrix * skinnedTangent.xyz;",
+						"vTangent = normalize( normalMatrix * skinnedTangent.xyz );",
 
 
 					"#else",
 					"#else",
 
 
-						"vNormal = normalMatrix * normal;",
-						"vTangent = normalMatrix * tangent.xyz;",
+						"vNormal = normalize( normalMatrix * normal );",
+						"vTangent = normalize( normalMatrix * tangent.xyz );",
 
 
 					"#endif",
 					"#endif",
 
 
-					"vBinormal = cross( vNormal, vTangent ) * tangent.w;",
+					"vBinormal = normalize( cross( vNormal, vTangent ) * tangent.w );",
 
 
 					"vUv = uv * uRepeat + uOffset;",
 					"vUv = uv * uRepeat + uOffset;",
 
 
@@ -35154,9 +35177,25 @@ THREE.ShadowMapPlugin = function ( ) {
 
 
 	function getObjectMaterial( object ) {
 	function getObjectMaterial( object ) {
 
 
-		return object.material instanceof THREE.MeshFaceMaterial ? object.geometry.materials[ 0 ] : object.material;
+		if ( object.material instanceof THREE.MeshFaceMaterial ) {
 
 
-	}
+			if ( object.material.materials.length > 0 ) {
+
+				return object.material.materials[ 0 ];
+
+			} else {
+
+				return object.geometry.materials[ 0 ];
+
+			}
+
+		} else {
+
+			return object.material;
+
+		}
+
+	};
 
 
 };
 };
 
 
@@ -35670,9 +35709,25 @@ THREE.DepthPassPlugin = function ( ) {
 
 
 	function getObjectMaterial( object ) {
 	function getObjectMaterial( object ) {
 
 
-		return object.material instanceof THREE.MeshFaceMaterial ? object.geometry.materials[ 0 ] : object.material;
+		if ( object.material instanceof THREE.MeshFaceMaterial ) {
 
 
-	}
+			if ( object.material.materials.length > 0 ) {
+
+				return object.material.materials[ 0 ];
+
+			} else {
+
+				return object.geometry.materials[ 0 ];
+
+			}
+
+		} else {
+
+			return object.material;
+
+		}
+
+	};
 
 
 };
 };
 
 

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 197 - 197
build/three.min.js


+ 13 - 16
editor/index.html

@@ -66,7 +66,7 @@
 
 
 				// notifications
 				// notifications
 
 
-				sceneCreated: new SIGNALS.Signal(),
+				sceneAdded: new SIGNALS.Signal(),
 				sceneChanged: new SIGNALS.Signal(),
 				sceneChanged: new SIGNALS.Signal(),
 				objectAdded: new SIGNALS.Signal(),
 				objectAdded: new SIGNALS.Signal(),
 				objectSelected: new SIGNALS.Signal(),
 				objectSelected: new SIGNALS.Signal(),
@@ -139,7 +139,7 @@
 								geometry.sourceType = "ctm";
 								geometry.sourceType = "ctm";
 								geometry.sourceFile = file.name;
 								geometry.sourceFile = file.name;
 
 
-								var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
+								var mesh = new THREE.Mesh( geometry, createDummyMaterial() );
 								mesh.name = filename;
 								mesh.name = filename;
 
 
 								signals.objectAdded.dispatch( mesh );
 								signals.objectAdded.dispatch( mesh );
@@ -228,7 +228,7 @@
 								geometry.sourceType = "ascii";
 								geometry.sourceType = "ascii";
 								geometry.sourceFile = file.name;
 								geometry.sourceFile = file.name;
 
 
-								var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
+								var mesh = new THREE.Mesh( geometry, createDummyMaterial() );
 								mesh.name = filename;
 								mesh.name = filename;
 
 
 								signals.objectAdded.dispatch( mesh );
 								signals.objectAdded.dispatch( mesh );
@@ -244,7 +244,7 @@
 
 
 									if ( resetScene ) {
 									if ( resetScene ) {
 
 
-										signals.resetScene.dispatch( result.scene, result.currentCamera, result.bgColor );
+										signals.sceneAdded.dispatch( result.scene, result.currentCamera, result.bgColor );
 
 
 									} else {
 									} else {
 
 
@@ -291,7 +291,7 @@
 							geometry.sourceType = "stl";
 							geometry.sourceType = "stl";
 							geometry.sourceFile = file.name;
 							geometry.sourceFile = file.name;
 
 
-							var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
+							var mesh = new THREE.Mesh( geometry, createDummyMaterial() );
 							mesh.name = filename;
 							mesh.name = filename;
 
 
 							signals.objectAdded.dispatch( mesh );
 							signals.objectAdded.dispatch( mesh );
@@ -335,7 +335,7 @@
 							geometry.sourceType = "vtk";
 							geometry.sourceType = "vtk";
 							geometry.sourceFile = file.name;
 							geometry.sourceFile = file.name;
 
 
-							var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
+							var mesh = new THREE.Mesh( geometry, createDummyMaterial() );
 							mesh.name = filename;
 							mesh.name = filename;
 
 
 							signals.objectAdded.dispatch( mesh );
 							signals.objectAdded.dispatch( mesh );
@@ -350,16 +350,11 @@
 
 
 			}
 			}
 
 
-			var geometry = new THREE.SphereGeometry( 75, 25, 15 );
+			// create default scene
 
 
-			var material = new THREE.MeshPhongMaterial();
-			material.color.setHSV( Math.random(), Math.random(), 1 );
+			signals.resetScene.dispatch();
 
 
-			var mesh = new THREE.Mesh( geometry, material );
-			mesh.name = "Sphere";
-
-			signals.objectAdded.dispatch( mesh );
-			signals.objectSelected.dispatch( mesh );
+			//
 
 
 			var onWindowResize = function ( event ) {
 			var onWindowResize = function ( event ) {
 
 
@@ -367,12 +362,14 @@
 
 
 			};
 			};
 
 
-			var createDummyMaterial = function ( geometry ) {
+			var createDummyMaterial = function () {
 
 
-				return new THREE.MeshLambertMaterial();
+				return new THREE.MeshPhongMaterial();
 
 
 			};
 			};
 
 
+			//
+
 			onWindowResize();
 			onWindowResize();
 
 
 			window.addEventListener( 'resize', onWindowResize, false );
 			window.addEventListener( 'resize', onWindowResize, false );

+ 137 - 7
editor/js/ui/Menubar.Add.js

@@ -19,25 +19,155 @@ Menubar.Add = function ( signals ) {
 	var options = new UI.Panel();
 	var options = new UI.Panel();
 	options.setWidth( '140px' );
 	options.setWidth( '140px' );
 	options.setBackgroundColor( '#ddd' );
 	options.setBackgroundColor( '#ddd' );
-	options.setPadding( '10px' );
+	options.setPadding( '0px' );
+	options.setBorderTop( 'solid 1px #ccc' );
+	options.setStyle( 'box-shadow', [ '0 3px 6px rgba(0,0,0,0.1), 3px 3px 6px rgba(0,0,0,0.2)' ] );
 	options.setDisplay( 'none' );
 	options.setDisplay( 'none' );
 	container.add( options );
 	container.add( options );
 
 
+	// add sphere
+
 	var option = new UI.Panel();
 	var option = new UI.Panel();
-	option.setTextContent( 'Sphere' ).setColor( '#666' );
-	option.onClick( function () { alert( 'Sphere' ) } );
+	option.setTextContent( 'Sphere' ).setColor( '#666' ).setPadding( '6px 12px' );
+	option.onClick( function () {
+
+		var radius = 75;
+		var widthSegments = 32;
+		var heightSegments = 16;
+
+		var geometry = new THREE.SphereGeometry( radius, widthSegments, heightSegments );
+		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
+		mesh.name = 'Sphere ' + mesh.id;
+
+		signals.objectAdded.dispatch( mesh );
+
+	} );
 	options.add( option );
 	options.add( option );
 
 
+	addHoverStyle( option );
+
+	// add cube
+
 	var option = new UI.Panel();
 	var option = new UI.Panel();
-	option.setTextContent( 'Cube' ).setColor( '#666' );
-	option.onClick( function () { alert( 'Cube' ) } );
+	option.setTextContent( 'Cube' ).setColor( '#666' ).setPadding( '6px 12px' );
+	option.onClick( function () {
+
+		var width = 100;
+		var height = 100;
+		var depth = 100;
+
+		var widthSegments = 1;
+		var heightSegments = 1;
+		var depthSegments = 1;
+
+		var geometry = new THREE.CubeGeometry( width, height, depth, widthSegments, heightSegments, depthSegments );
+		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
+		mesh.name = 'Cube ' + mesh.id;
+
+		signals.objectAdded.dispatch( mesh );
+
+
+	} );
 	options.add( option );
 	options.add( option );
 
 
+	addHoverStyle( option );
+
+	// add plane
+
 	var option = new UI.Panel();
 	var option = new UI.Panel();
-	option.setTextContent( 'Plane' ).setColor( '#666' );
-	option.onClick( function () { alert( 'Plane' ) } );
+	option.setTextContent( 'Plane' ).setColor( '#666' ).setPadding( '6px 12px' );
+	option.onClick( function () {
+
+		var width = 200;
+		var height = 200;
+
+		var widthSegments = 1;
+		var heightSegments = 1;
+
+		var geometry = new THREE.PlaneGeometry( width, height, widthSegments, heightSegments );
+		var mesh = new THREE.Mesh( geometry, createDummyMaterial( geometry ) );
+		mesh.name = 'Plane ' + mesh.id;
+
+		mesh.rotation.x = - Math.PI/2;
+
+		signals.objectAdded.dispatch( mesh );
+
+	} );
+	options.add( option );
+
+	addHoverStyle( option );
+
+	// divider
+
+	var option = new UI.Panel();
+	option.setBackgroundColor( '#ccc' ).setPadding( '1px 12px' );
 	options.add( option );
 	options.add( option );
 
 
+	// add directional light
+
+	var option = new UI.Panel();
+	option.setTextContent( 'Directional light' ).setColor( '#666' ).setPadding( '6px 12px' );
+	option.onClick( function () {
+
+		var color = 0xffffff;
+		var intensity = 1;
+
+		var light = new THREE.DirectionalLight( color, intensity );
+		light.name = 'Light ' + light.id;
+		light.target.name = 'Light ' + light.id + ' target';
+
+		light.target.properties.targetInverse = light;
+
+		light.position.set( 1, 1, 1 ).multiplyScalar( 200 );
+
+		signals.objectAdded.dispatch( light );
+
+	} );
+	options.add( option );
+
+	addHoverStyle( option );
+
+	// add point light
+
+	var option = new UI.Panel();
+	option.setTextContent( 'Point light' ).setColor( '#666' ).setPadding( '6px 12px' );
+	option.onClick( function () {
+
+		var color = 0xffffff;
+		var intensity = 1;
+		var distance = 0;
+
+		var light = new THREE.PointLight( color, intensity, distance );
+		light.name = 'Light ' + light.id;
+
+		signals.objectAdded.dispatch( light );
+
+	} );
+	options.add( option );
+
+	addHoverStyle( option );
+
+	// add spot light
+
+	// add hemisphere light
+
+	// add ambient light
+
+	//
+
+	function addHoverStyle( element ) {
+
+		element.onMouseOver( function () { element.setBackgroundColor( '#356' ).setColor( '#eee' ); } );
+		element.onMouseOut( function () { element.setBackgroundColor( 'transparent' ).setColor( '#666' ) } );
+
+	}
+
+	function createDummyMaterial() {
+
+		return new THREE.MeshPhongMaterial();
+
+	};
+
 	return container;
 	return container;
 
 
 }
 }

+ 18 - 3
editor/js/ui/Menubar.Edit.js

@@ -19,15 +19,30 @@ Menubar.Edit = function ( signals ) {
 	var options = new UI.Panel();
 	var options = new UI.Panel();
 	options.setWidth( '140px' );
 	options.setWidth( '140px' );
 	options.setBackgroundColor( '#ddd' );
 	options.setBackgroundColor( '#ddd' );
-	options.setPadding( '10px' );
+	options.setPadding( '0px' );
+	options.setBorderTop( 'solid 1px #ccc' );
+	options.setStyle( 'box-shadow', [ '0 3px 6px rgba(0,0,0,0.1), 3px 3px 6px rgba(0,0,0,0.2)' ] );
 	options.setDisplay( 'none' );
 	options.setDisplay( 'none' );
 	container.add( options );
 	container.add( options );
 
 
+	// delete
+
 	var option = new UI.Panel();
 	var option = new UI.Panel();
-	option.setTextContent( 'Delete' ).setColor( '#666' );
-	option.onClick( function () { alert( 'Delete' ) } );
+	option.setTextContent( 'Delete' ).setColor( '#666' ).setPadding( '6px 12px' );
+	option.onClick( function () { signals.removeSelectedObject.dispatch(); } );
 	options.add( option );
 	options.add( option );
 
 
+	addHoverStyle( option );
+
+	//
+
+	function addHoverStyle( element ) {
+
+		element.onMouseOver( function () { element.setBackgroundColor( '#356' ).setColor( '#eee' ); } );
+		element.onMouseOut( function () { element.setBackgroundColor( 'transparent' ).setColor( '#666' ) } );
+
+	}
+
 	return container;
 	return container;
 
 
 }
 }

+ 38 - 7
editor/js/ui/Menubar.File.js

@@ -19,35 +19,66 @@ Menubar.File = function ( signals ) {
 	var options = new UI.Panel();
 	var options = new UI.Panel();
 	options.setWidth( '140px' );
 	options.setWidth( '140px' );
 	options.setBackgroundColor( '#ddd' );
 	options.setBackgroundColor( '#ddd' );
-	options.setPadding( '10px' );
+	options.setPadding( '0px' );
+	options.setBorderTop( 'solid 1px #ccc' );
+	options.setStyle( 'box-shadow', [ '0 3px 6px rgba(0,0,0,0.1), 3px 3px 6px rgba(0,0,0,0.2)' ] );
 	options.setDisplay( 'none' );
 	options.setDisplay( 'none' );
 	container.add( options );
 	container.add( options );
 
 
+	// open
+
 	var option = new UI.Panel();
 	var option = new UI.Panel();
-	option.setTextContent( 'Open' ).setColor( '#666' );
+	option.setTextContent( 'Open' ).setColor( '#666' ).setPadding( '6px 12px' );
 	option.onClick( function () { alert( 'Open' ) } );
 	option.onClick( function () { alert( 'Open' ) } );
 	options.add( option );
 	options.add( option );
 
 
+	addHoverStyle( option );
+
+	// reset scene
+
 	var option = new UI.Panel();
 	var option = new UI.Panel();
-	option.setTextContent( 'Reset' ).setColor( '#666' );
-	option.onClick( function () { alert( 'Reset' ) } );
+	option.setTextContent( 'Reset' ).setColor( '#666' ).setPadding( '6px 12px' );
+	option.onClick( function () { signals.resetScene.dispatch(); } );
 	options.add( option );
 	options.add( option );
 
 
+	addHoverStyle( option );
+
+	// export geometry
+
 	var option = new UI.Panel();
 	var option = new UI.Panel();
-	option.setTextContent( 'Export Geometry' ).setColor( '#666' );
+	option.setTextContent( 'Export Geometry' ).setColor( '#666' ).setPadding( '6px 12px' );
 	option.onClick( function () { signals.exportGeometry.dispatch(); } );
 	option.onClick( function () { signals.exportGeometry.dispatch(); } );
 	options.add( option );
 	options.add( option );
 
 
+	addHoverStyle( option );
+
+	// export scene
+
 	var option = new UI.Panel();
 	var option = new UI.Panel();
-	option.setTextContent( 'Export Scene' ).setColor( '#666' );
+	option.setTextContent( 'Export Scene' ).setColor( '#666' ).setPadding( '6px 12px' );
 	option.onClick( function () { signals.exportScene.dispatch(); } );
 	option.onClick( function () { signals.exportScene.dispatch(); } );
 	options.add( option );
 	options.add( option );
 
 
+	addHoverStyle( option );
+
+	// export OBJ
+
 	var option = new UI.Panel();
 	var option = new UI.Panel();
-	option.setTextContent( 'Export OBJ' ).setColor( '#666' );
+	option.setTextContent( 'Export OBJ' ).setColor( '#666' ).setPadding( '6px 12px' );
 	option.onClick( function () { alert( 'Export OBJ' ) } );
 	option.onClick( function () { alert( 'Export OBJ' ) } );
 	options.add( option );
 	options.add( option );
 
 
+	addHoverStyle( option );
+
+	//
+
+	function addHoverStyle( element ) {
+
+		element.onMouseOver( function () { element.setBackgroundColor( '#356' ).setColor( '#eee' ); } );
+		element.onMouseOut( function () { element.setBackgroundColor( 'transparent' ).setColor( '#666' ) } );
+
+	}
+
 	return container;
 	return container;
 
 
 }
 }

+ 17 - 2
editor/js/ui/Menubar.Help.js

@@ -19,15 +19,30 @@ Menubar.Help = function ( signals ) {
 	var options = new UI.Panel();
 	var options = new UI.Panel();
 	options.setWidth( '140px' );
 	options.setWidth( '140px' );
 	options.setBackgroundColor( '#ddd' );
 	options.setBackgroundColor( '#ddd' );
-	options.setPadding( '10px' );
+	options.setPadding( '0px' );
+	options.setBorderTop( 'solid 1px #ccc' );
+	options.setStyle( 'box-shadow', [ '0 3px 7px rgba(0,0,0,0.05), 3px 3px 7px rgba(0,0,0,0.1)' ] );
 	options.setDisplay( 'none' );
 	options.setDisplay( 'none' );
 	container.add( options );
 	container.add( options );
 
 
+	// about
+
 	var option = new UI.Panel();
 	var option = new UI.Panel();
-	option.setTextContent( 'About' ).setColor( '#666' );
+	option.setTextContent( 'About' ).setColor( '#666' ).setPadding( '6px 12px' );
 	option.onClick( function () { alert( 'About' ) } );
 	option.onClick( function () { alert( 'About' ) } );
 	options.add( option );
 	options.add( option );
 
 
+	addHoverStyle( option );
+
+	//
+
+	function addHoverStyle( element ) {
+
+		element.onMouseOver( function () { element.setBackgroundColor( '#356' ).setColor( '#eee' ); } );
+		element.onMouseOut( function () { element.setBackgroundColor( 'transparent' ).setColor( '#666' ) } );
+
+	}
+
 	return container;
 	return container;
 
 
 }
 }

+ 0 - 6
editor/js/ui/Sidebar.Scene.js

@@ -224,12 +224,6 @@ Sidebar.Scene = function ( signals ) {
 
 
 	// events
 	// events
 
 
-	signals.sceneCreated.add( function ( object ) {
-
-		scene = object;
-
-	} );
-
 	signals.sceneChanged.add( function ( object ) {
 	signals.sceneChanged.add( function ( object ) {
 
 
 		scene = object;
 		scene = object;

+ 1 - 0
editor/js/ui/Sidebar.js

@@ -3,6 +3,7 @@ var Sidebar = function ( signals ) {
 	var container = new UI.Panel( 'absolute' );
 	var container = new UI.Panel( 'absolute' );
 	container.setWidth( '300px' ).setHeight( '100%' );
 	container.setWidth( '300px' ).setHeight( '100%' );
 	container.setBackgroundColor( '#eee' );
 	container.setBackgroundColor( '#eee' );
+	container.setBorderLeft( 'solid 1px #ccc' );
 	container.setOverflow( 'auto' );
 	container.setOverflow( 'auto' );
 
 
 	container.add( new Sidebar.Scene( signals ) );
 	container.add( new Sidebar.Scene( signals ) );

+ 166 - 49
editor/js/ui/Viewport.js

@@ -2,6 +2,7 @@ var Viewport = function ( signals ) {
 
 
 	var container = new UI.Panel( 'absolute' );
 	var container = new UI.Panel( 'absolute' );
 	container.setBackgroundColor( '#aaa' );
 	container.setBackgroundColor( '#aaa' );
+	container.setBorderTop( 'solid 1px #ccc' );
 
 
 	// settings
 	// settings
 
 
@@ -47,30 +48,10 @@ var Viewport = function ( signals ) {
 	selectionAxis.visible = false;
 	selectionAxis.visible = false;
 	sceneHelpers.add( selectionAxis );
 	sceneHelpers.add( selectionAxis );
 
 
-	//
+	// default dummy scene and camera
 
 
 	var scene = new THREE.Scene();
 	var scene = new THREE.Scene();
-
-	var camera = new THREE.PerspectiveCamera( 50, 1, 1, 5000 );
-	camera.position.set( 500, 250, 500 );
-	camera.lookAt( scene.position );
-	scene.add( camera );
-
-	var light1 = new THREE.DirectionalLight( 0xffffff, 0.8 );
-	light1.position.set( 1, 0.5, 0 ).multiplyScalar( 400 );
-
-	var light2 = new THREE.SpotLight( 0xffffff, 1.5, 500, Math.PI * 0.025 );
-	light2.position.set( - 1, 0.5, 1 ).multiplyScalar( 300 );
-
-	light1.target.properties.targetInverse = light1;
-	light2.target.properties.targetInverse = light2;
-
-	var light3 = new THREE.PointLight( 0xffaa00, 0.75 );
-	light3.position.set( -250, 200, -200 );
-
-	//var light4 = new THREE.AmbientLight( 0x111111 );
-	var light4 = new THREE.HemisphereLight( 0x00aaff, 0xff0000, 0.75 );
-	light4.position.y = 250;
+	var camera = new THREE.Camera();
 
 
 	// fog
 	// fog
 
 
@@ -80,24 +61,6 @@ var Viewport = function ( signals ) {
 	var oldFogFar = 5000;
 	var oldFogFar = 5000;
 	var oldFogDensity = 0.00025;
 	var oldFogDensity = 0.00025;
 
 
-	// default objects names
-
-	camera.name = "Camera";
-
-	light1.name = "Light 1";
-	light1.target.name = "Light 1 Target";
-
-	light2.name = "Light 2";
-	light2.target.name = "Light 2 Target";
-
-	light3.name = "Light 3";
-
-	light4.name = "Light 4";
-
-	// active objects
-
-	camera.properties.active = true;
-
 	// object picking
 	// object picking
 
 
 	var intersectionPlane = new THREE.Mesh( new THREE.PlaneGeometry( 10000, 10000, 8, 8 ) );
 	var intersectionPlane = new THREE.Mesh( new THREE.PlaneGeometry( 10000, 10000, 8, 8 ) );
@@ -390,6 +353,13 @@ var Viewport = function ( signals ) {
 		object.traverse( handleAddition );
 		object.traverse( handleAddition );
 
 
 		scene.add( object );
 		scene.add( object );
+
+		if ( object instanceof THREE.Light && ! ( object instanceof THREE.AmbientLight ) )  {
+
+			updateMaterials( scene );
+
+		}
+
 		render();
 		render();
 
 
 		signals.sceneChanged.dispatch( scene );
 		signals.sceneChanged.dispatch( scene );
@@ -431,16 +401,28 @@ var Viewport = function ( signals ) {
 
 
 		}
 		}
 
 
-		// remove from picking list
+		// remove proxies from picking list
 
 
 		var toRemove = {};
 		var toRemove = {};
 
 
-		selected.traverse( function ( child ) {
+		var proxyObject = selected.properties.pickingProxy ? selected.properties.pickingProxy : selected;
+
+		proxyObject.traverse( function ( child ) {
 
 
 			toRemove[ child.id ] = true;
 			toRemove[ child.id ] = true;
 
 
 		} );
 		} );
 
 
+		// remove eventual pure Object3D target proxies from picking list
+
+		if ( selected.target && !selected.target.geometry ) {
+
+			toRemove[ selected.target.properties.pickingProxy.id ] = true;
+
+		}
+
+		//
+
 		var newObjects = [];
 		var newObjects = [];
 
 
 		for ( var i = 0; i < objects.length; i ++ ) {
 		for ( var i = 0; i < objects.length; i ++ ) {
@@ -457,17 +439,61 @@ var Viewport = function ( signals ) {
 
 
 		objects = newObjects;
 		objects = newObjects;
 
 
-		//
+		// clean selection highlight
 
 
 		selectionBox.visible = false;
 		selectionBox.visible = false;
 		selectionAxis.visible = false;
 		selectionAxis.visible = false;
 
 
+		// remove selected object from the scene
+
 		scene.traverse( function( node ) {
 		scene.traverse( function( node ) {
 
 
 			node.remove( selected );
 			node.remove( selected );
 
 
 		} );
 		} );
 
 
+		// remove eventual pure Object3D targets from the scene
+
+		if ( selected.target && !selected.target.geometry ) {
+
+			scene.traverse( function( node ) {
+
+				node.remove( selected.target );
+
+			} );
+
+		}
+
+		// remove eventual helpers for the object from helpers scene
+
+		var helpersToRemove = [];
+
+		if ( selected.properties.helper ) {
+
+			helpersToRemove.push( selected.properties.helper );
+
+			if ( selected.properties.helper.targetLine ) helpersToRemove.push( selected.properties.helper.targetLine );
+			if ( selected.target && !selected.target.geometry ) helpersToRemove.push( selected.properties.helper.targetSphere );
+
+
+		}
+
+		sceneHelpers.traverse( function( node ) {
+
+			for ( var i = 0; i < helpersToRemove.length; i ++ ) {
+
+				node.remove( helpersToRemove[ i ] );
+
+			}
+
+		} );
+
+		if ( selected instanceof THREE.Light && ! ( selected instanceof THREE.AmbientLight ) )  {
+
+			updateMaterials( scene );
+
+		}
+
 		render();
 		render();
 
 
 		signals.sceneChanged.dispatch( scene );
 		signals.sceneChanged.dispatch( scene );
@@ -647,6 +673,13 @@ var Viewport = function ( signals ) {
 
 
 	signals.exportGeometry.add( function () {
 	signals.exportGeometry.add( function () {
 
 
+		if ( !selected.geometry ) {
+
+			console.warn( "Selected object doesn't have any geometry" );
+			return;
+
+		}
+
 		var output = new THREE.GeometryExporter().parse( selected.geometry );
 		var output = new THREE.GeometryExporter().parse( selected.geometry );
 
 
 		var blob = new Blob( [ output ], { type: 'text/plain' } );
 		var blob = new Blob( [ output ], { type: 'text/plain' } );
@@ -679,7 +712,21 @@ var Viewport = function ( signals ) {
 
 
 	} );
 	} );
 
 
-	signals.resetScene.add( function ( newScene, newCamera, newClearColor ) {
+	signals.resetScene.add( function () {
+
+		var defaultScene = createDefaultScene();
+		var defaultCamera = createDefaultCamera();
+		var defaultBgColor = new THREE.Color( 0xaaaaaa );
+
+		defaultCamera.lookAt( defaultScene.position );
+		defaultScene.add( defaultCamera );
+
+		signals.sceneAdded.dispatch( defaultScene, defaultCamera, defaultBgColor );
+		signals.objectSelected.dispatch( defaultScene.properties.defaultSelection );
+
+	} );
+
+	signals.sceneAdded.add( function ( newScene, newCamera, newClearColor ) {
 
 
 		scene = newScene;
 		scene = newScene;
 
 
@@ -787,11 +834,6 @@ var Viewport = function ( signals ) {
 
 
 	signals.sceneChanged.dispatch( scene );
 	signals.sceneChanged.dispatch( scene );
 
 
-	signals.objectAdded.dispatch( light1 );
-	signals.objectAdded.dispatch( light2 );
-	signals.objectAdded.dispatch( light3 );
-	signals.objectAdded.dispatch( light4 );
-
 	//
 	//
 
 
 	function updateMaterials( root ) {
 	function updateMaterials( root ) {
@@ -832,6 +874,81 @@ var Viewport = function ( signals ) {
 
 
 	}
 	}
 
 
+	function createDefaultScene() {
+
+		// create scene
+
+		var scene = new THREE.Scene();
+
+		// create lights
+
+		var light1 = new THREE.DirectionalLight( 0xffffff, 0.8 );
+		light1.position.set( 1, 0.5, 0 ).multiplyScalar( 400 );
+
+		var light2 = new THREE.SpotLight( 0xffffff, 1.5, 500, Math.PI * 0.025 );
+		light2.position.set( - 1, 0.5, 1 ).multiplyScalar( 300 );
+
+		var light3 = new THREE.PointLight( 0xffaa00, 0.75 );
+		light3.position.set( -250, 200, -200 );
+
+		//var light4 = new THREE.AmbientLight( 0x111111 );
+		var light4 = new THREE.HemisphereLight( 0x00aaff, 0xff0000, 0.75 );
+		light4.position.y = 250;
+
+		light1.target.properties.targetInverse = light1;
+		light2.target.properties.targetInverse = light2;
+
+		// create objects
+
+		var geometry = new THREE.SphereGeometry( 75, 25, 15 );
+
+		var material = new THREE.MeshPhongMaterial();
+		material.color.setHSV( Math.random(), Math.random(), 1 );
+
+		var mesh = new THREE.Mesh( geometry, material );
+
+		// set default names
+
+		light1.name = "Light 1";
+		light1.target.name = "Light 1 Target";
+
+		light2.name = "Light 2";
+		light2.target.name = "Light 2 Target";
+
+		light3.name = "Light 3";
+
+		light4.name = "Light 4";
+
+		mesh.name = "Sphere";
+
+		// set default selection
+
+		scene.properties.defaultSelection = mesh;
+
+		// add to scene
+
+		scene.add( light1 );
+		scene.add( light2 );
+		scene.add( light3 );
+		scene.add( light4 );
+		scene.add( mesh );
+
+		return scene;
+
+	}
+
+	function createDefaultCamera() {
+
+		var camera = new THREE.PerspectiveCamera( 50, 1, 1, 5000 );
+		camera.position.set( 500, 250, 500 );
+
+		camera.name = "Camera";
+		camera.properties.active = true;
+
+		return camera;
+
+	}
+
 	function animate() {
 	function animate() {
 
 
 		requestAnimationFrame( animate );
 		requestAnimationFrame( animate );

+ 1 - 1
examples/js/ShaderSkin.js

@@ -323,7 +323,7 @@ THREE.ShaderSkin = {
 
 
 				"vViewPosition = -mvPosition.xyz;",
 				"vViewPosition = -mvPosition.xyz;",
 
 
-				"vNormal = normalMatrix * normal;",
+				"vNormal = normalize( normalMatrix * normal );",
 
 
 				"vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",
 				"vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",
 
 

+ 4 - 2
src/core/Projector.js

@@ -196,7 +196,7 @@ THREE.Projector = function() {
 
 
 		_renderData = projectGraph( scene, sortObjects );
 		_renderData = projectGraph( scene, sortObjects );
 
 
-		for ( o = 0, ol = _renderData.objects.length; o < ol; o++ ) {
+		for ( o = 0, ol = _renderData.objects.length; o < ol; o ++ ) {
 
 
 			object = _renderData.objects[ o ].object;
 			object = _renderData.objects[ o ].object;
 
 
@@ -207,7 +207,7 @@ THREE.Projector = function() {
 			if ( object instanceof THREE.Mesh ) {
 			if ( object instanceof THREE.Mesh ) {
 
 
 				geometry = object.geometry;
 				geometry = object.geometry;
-				geometryMaterials = object.geometry.materials;
+
 				vertices = geometry.vertices;
 				vertices = geometry.vertices;
 				faces = geometry.faces;
 				faces = geometry.faces;
 				faceVertexUvs = geometry.faceVertexUvs;
 				faceVertexUvs = geometry.faceVertexUvs;
@@ -216,6 +216,8 @@ THREE.Projector = function() {
 				_normalMatrix.transpose();
 				_normalMatrix.transpose();
 
 
 				isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
 				isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
+				geometryMaterials = ( isFaceMaterial && object.material.materials.length > 0 ) ? object.material.materials : object.geometry.materials;
+
 				side = object.material.side;
 				side = object.material.side;
 
 
 				for ( v = 0, vl = vertices.length; v < vl; v ++ ) {
 				for ( v = 0, vl = vertices.length; v < vl; v ++ ) {

+ 2 - 1
src/core/Ray.js

@@ -109,8 +109,9 @@
 			var geometry = object.geometry;
 			var geometry = object.geometry;
 			var vertices = geometry.vertices;
 			var vertices = geometry.vertices;
 
 
-			var geometryMaterials = object.geometry.materials;
 			var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
 			var isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
+			var geometryMaterials = ( isFaceMaterial && object.material.materials.length > 0 ) ? object.material.materials : object.geometry.materials;
+
 			var side = object.material.side;
 			var side = object.material.side;
 
 
 			var a, b, c, d;
 			var a, b, c, d;

+ 5 - 5
src/extras/ShaderUtils.js

@@ -635,19 +635,19 @@ THREE.ShaderUtils = {
 
 
 					"#ifdef USE_SKINNING",
 					"#ifdef USE_SKINNING",
 
 
-						"vNormal = normalMatrix * skinnedNormal.xyz;",
+						"vNormal = normalize( normalMatrix * skinnedNormal.xyz );",
 
 
 						"vec4 skinnedTangent = skinMatrix * vec4( tangent.xyz, 0.0 );",
 						"vec4 skinnedTangent = skinMatrix * vec4( tangent.xyz, 0.0 );",
-						"vTangent = normalMatrix * skinnedTangent.xyz;",
+						"vTangent = normalize( normalMatrix * skinnedTangent.xyz );",
 
 
 					"#else",
 					"#else",
 
 
-						"vNormal = normalMatrix * normal;",
-						"vTangent = normalMatrix * tangent.xyz;",
+						"vNormal = normalize( normalMatrix * normal );",
+						"vTangent = normalize( normalMatrix * tangent.xyz );",
 
 
 					"#endif",
 					"#endif",
 
 
-					"vBinormal = cross( vNormal, vTangent ) * tangent.w;",
+					"vBinormal = normalize( cross( vNormal, vTangent ) * tangent.w );",
 
 
 					"vUv = uv * uRepeat + uOffset;",
 					"vUv = uv * uRepeat + uOffset;",
 
 

+ 18 - 2
src/extras/renderers/plugins/DepthPassPlugin.js

@@ -196,9 +196,25 @@ THREE.DepthPassPlugin = function ( ) {
 
 
 	function getObjectMaterial( object ) {
 	function getObjectMaterial( object ) {
 
 
-		return object.material instanceof THREE.MeshFaceMaterial ? object.geometry.materials[ 0 ] : object.material;
+		if ( object.material instanceof THREE.MeshFaceMaterial ) {
 
 
-	}
+			if ( object.material.materials.length > 0 ) {
+
+				return object.material.materials[ 0 ];
+
+			} else {
+
+				return object.geometry.materials[ 0 ];
+
+			}
+
+		} else {
+
+			return object.material;
+
+		}
+
+	};
 
 
 };
 };
 
 

+ 18 - 2
src/extras/renderers/plugins/ShadowMapPlugin.js

@@ -480,9 +480,25 @@ THREE.ShadowMapPlugin = function ( ) {
 
 
 	function getObjectMaterial( object ) {
 	function getObjectMaterial( object ) {
 
 
-		return object.material instanceof THREE.MeshFaceMaterial ? object.geometry.materials[ 0 ] : object.material;
+		if ( object.material instanceof THREE.MeshFaceMaterial ) {
 
 
-	}
+			if ( object.material.materials.length > 0 ) {
+
+				return object.material.materials[ 0 ];
+
+			} else {
+
+				return object.geometry.materials[ 0 ];
+
+			}
+
+		} else {
+
+			return object.material;
+
+		}
+
+	};
 
 
 };
 };
 
 

+ 5 - 1
src/materials/MeshFaceMaterial.js

@@ -2,7 +2,11 @@
  * @author mrdoob / http://mrdoob.com/
  * @author mrdoob / http://mrdoob.com/
  */
  */
 
 
-THREE.MeshFaceMaterial = function () {};
+THREE.MeshFaceMaterial = function ( materials ) {
+
+	this.materials = materials instanceof Array ? materials : [];
+
+};
 
 
 THREE.MeshFaceMaterial.prototype.clone = function () {
 THREE.MeshFaceMaterial.prototype.clone = function () {
 
 

+ 21 - 5
src/renderers/WebGLRenderer.js

@@ -890,13 +890,21 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	function getBufferMaterial( object, geometryGroup ) {
 	function getBufferMaterial( object, geometryGroup ) {
 
 
-		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
+		if ( object.material instanceof THREE.MeshFaceMaterial ) {
 
 
-			return object.material;
+			if ( object.material.materials.length > 0 ) {
+
+				return object.material.materials[ geometryGroup.materialIndex ];
+
+			} else {
 
 
-		} else if ( geometryGroup.materialIndex >= 0 ) {
+				return object.geometry.materials[ geometryGroup.materialIndex ];
 
 
-			return object.geometry.materials[ geometryGroup.materialIndex ];
+			}
+
+		} else {
+
+			return object.material;
 
 
 		}
 		}
 
 
@@ -4160,7 +4168,15 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 			if ( materialIndex >= 0 ) {
 			if ( materialIndex >= 0 ) {
 
 
-				material = object.geometry.materials[ materialIndex ];
+				if ( meshMaterial.materials.length > 0 ) {
+
+					material = meshMaterial.materials[ materialIndex ];
+
+				} else {
+
+					material = object.geometry.materials[ materialIndex ];
+
+				}
 
 
 				if ( material.transparent ) {
 				if ( material.transparent ) {
 
 

+ 2 - 2
src/renderers/WebGLShaders.js

@@ -1937,7 +1937,7 @@ THREE.ShaderLib = {
 			"void main() {",
 			"void main() {",
 
 
 				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
 				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
-				"vNormal = normalMatrix * normal;",
+				"vNormal = normalize( normalMatrix * normal );",
 
 
 				"gl_Position = projectionMatrix * mvPosition;",
 				"gl_Position = projectionMatrix * mvPosition;",
 
 
@@ -2211,7 +2211,7 @@ THREE.ShaderLib = {
 				THREE.ShaderChunk[ "skinnormal_vertex" ],
 				THREE.ShaderChunk[ "skinnormal_vertex" ],
 				THREE.ShaderChunk[ "defaultnormal_vertex" ],
 				THREE.ShaderChunk[ "defaultnormal_vertex" ],
 
 
-				"vNormal = transformedNormal;",
+				"vNormal = normalize( transformedNormal );",
 
 
 				THREE.ShaderChunk[ "morphtarget_vertex" ],
 				THREE.ShaderChunk[ "morphtarget_vertex" ],
 				THREE.ShaderChunk[ "skinning_vertex" ],
 				THREE.ShaderChunk[ "skinning_vertex" ],

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно