Browse Source

Merge branch 'dev' of github.com:mrdoob/three.js into Editor_ShaderMaterial

tschw 10 years ago
parent
commit
6def65f414

+ 3 - 3
editor/index.html

@@ -113,12 +113,12 @@
 			var viewport = new Viewport( editor );
 			document.body.appendChild( viewport.dom );
 
-			var script = new Script( editor );
-			document.body.appendChild( script.dom );
-
 			var player = new Player( editor );
 			document.body.appendChild( player.dom );
 
+			var script = new Script( editor );
+			document.body.appendChild( script.dom );
+
 			var toolbar = new Toolbar( editor );
 			document.body.appendChild( toolbar.dom );
 

+ 1 - 0
examples/index.html

@@ -271,6 +271,7 @@
 				"webgl_loader_utf8",
 				"webgl_loader_vrml",
 				"webgl_loader_vtk",
+				"webgl_exporter_obj",
 				"webgl_lod",
 				"webgl_marchingcubes",
 				"webgl_materials",

+ 16 - 18
examples/js/exporters/OBJExporter.js

@@ -45,17 +45,17 @@ THREE.OBJExporter.prototype = {
 
 				var faces = geometry.faces;
 				var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
+				var hasVertexUvs = faces.length === faceVertexUvs.length;
 
-				if ( faces.length === faceVertexUvs.length ) {
+				if ( hasVertexUvs ) {
 
 					for ( var i = 0, l = faceVertexUvs.length; i < l; i ++ ) {
 
 						var vertexUvs = faceVertexUvs[ i ];
 
-						for ( var j = 0; j < vertexUvs.length; j ++ ) {
+						for ( var j = 0, jl = vertexUvs.length; j < jl; j ++ ) {
 
 							var uv = vertexUvs[ j ];
-							vertex.applyMatrix4( mesh.matrixWorld );
 
 							output += 'vt ' + uv.x + ' ' + uv.y + '\n';
 
@@ -65,19 +65,13 @@ THREE.OBJExporter.prototype = {
 
 					}
 
-				} else {
-
-					for ( var i = 0, l = faces.length * 3; i < l; i ++ ) {
-
-						output += 'vt 0 0\n';
-						nbVertexUvs ++;
-
-					}
-
 				}
 
 				// normals
 
+				var normalMatrixWorld = new THREE.Matrix3();
+				normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
+
 				for ( var i = 0, l = faces.length; i < l; i ++ ) {
 
 					var face = faces[ i ];
@@ -85,9 +79,11 @@ THREE.OBJExporter.prototype = {
 
 					if ( vertexNormals.length === 3 ) {
 
-						for ( var j = 0; j < vertexNormals.length; j ++ ) {
+						for ( var j = 0, jl = vertexNormals.length; j < jl; j ++ ) {
+
+							var normal = vertexNormals[ j ].clone();
+							normal.applyMatrix3( normalMatrixWorld );
 
-							var normal = vertexNormals[ j ];
 							output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';
 
 							nbNormals ++;
@@ -96,7 +92,8 @@ THREE.OBJExporter.prototype = {
 
 					} else {
 
-						var normal = face.normal;
+						var normal = face.normal.clone();
+						normal.applyMatrix3( normalMatrixWorld );
 
 						for ( var j = 0; j < 3; j ++ ) {
 
@@ -112,14 +109,15 @@ THREE.OBJExporter.prototype = {
 
 				// faces
 
+
 				for ( var i = 0, j = 1, l = faces.length; i < l; i ++, j += 3 ) {
 
 					var face = faces[ i ];
 
 					output += 'f ';
-					output += ( indexVertex + face.a + 1 ) + '/' + ( indexVertexUvs + j ) + '/' + ( indexNormals + j ) + ' ';
-					output += ( indexVertex + face.b + 1 ) + '/' + ( indexVertexUvs + j + 1 ) + '/' + ( indexNormals + j + 1 ) + ' ';
-					output += ( indexVertex + face.c + 1 ) + '/' + ( indexVertexUvs + j + 2 ) + '/' + ( indexNormals + j + 2 ) + '\n';
+					output += ( indexVertex + face.a + 1 ) + '/' + ( hasVertexUvs ? ( indexVertexUvs + j     ) : '' ) + '/' + ( indexNormals + j     ) + ' ';
+					output += ( indexVertex + face.b + 1 ) + '/' + ( hasVertexUvs ? ( indexVertexUvs + j + 1 ) : '' ) + '/' + ( indexNormals + j + 1 ) + ' ';
+					output += ( indexVertex + face.c + 1 ) + '/' + ( hasVertexUvs ? ( indexVertexUvs + j + 2 ) : '' ) + '/' + ( indexNormals + j + 2 ) + '\n';
 
 				}
 

+ 5 - 4
examples/webgl_buffergeometry_rawshader.html

@@ -113,9 +113,9 @@
 
 				var geometry = new THREE.BufferGeometry();
 
-				var vertices = new THREE.BufferAttribute( new Float32Array( triangles * 3 * 3 ), 3 );
+				var vertices = new THREE.Float32Attribute( triangles * 3 * 3, 3 );
 
-				for ( var i = 0; i < vertices.length; i ++ ) {
+				for ( var i = 0, l = vertices.count; i < l; i ++ ) {
 
 					vertices.setXYZ( i, Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5 );
 
@@ -123,9 +123,9 @@
 
 				geometry.addAttribute( 'position', vertices );
 
-				var colors = new THREE.BufferAttribute(new Float32Array( triangles * 3 * 4 ), 4 );
+				var colors = new THREE.Float32Attribute( triangles * 3 * 4, 4 );
 
-				for ( var i = 0; i < colors.length; i ++ ) {
+				for ( var i = 0, l = colors.count; i < l; i ++ ) {
 
 					colors.setXYZW( i, Math.random(), Math.random(), Math.random(), Math.random() );
 
@@ -140,6 +140,7 @@
 					uniforms: {
 						time: { type: "f", value: 1.0 }
 					},
+					attributes: [ 'position', 'color' ],
 					vertexShader: document.getElementById( 'vertexShader' ).textContent,
 					fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
 					side: THREE.DoubleSide,

+ 19 - 28
examples/webgl_custom_attributes.html

@@ -88,29 +88,20 @@
 
 		var renderer, scene, camera, stats;
 
-		var sphere, uniforms, attributes;
+		var sphere, uniforms;
 
-		var noise = [];
-
-		var WIDTH = window.innerWidth,
-			HEIGHT = window.innerHeight;
+		var displacement, noise;
 
 		init();
 		animate();
 
 		function init() {
 
-			camera = new THREE.PerspectiveCamera( 30, WIDTH / HEIGHT, 1, 10000 );
+			camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 1, 10000 );
 			camera.position.z = 300;
 
 			scene = new THREE.Scene();
 
-			attributes = {
-
-				displacement: {	type: 'f', value: [] }
-
-			};
-
 			uniforms = {
 
 				amplitude: { type: "f", value: 1.0 },
@@ -123,36 +114,36 @@
 
 			var shaderMaterial = new THREE.ShaderMaterial( {
 
-				uniforms: 		uniforms,
-				attributes:     attributes,
-				vertexShader:   document.getElementById( 'vertexshader' ).textContent,
+				uniforms: uniforms,
+				attributes: [ 'displacement' ],
+				vertexShader:document.getElementById( 'vertexshader' ).textContent,
 				fragmentShader: document.getElementById( 'fragmentshader' ).textContent
 
 			});
 
 
 			var radius = 50, segments = 128, rings = 64;
-			var geometry = new THREE.SphereGeometry( radius, segments, rings );
-			geometry.dynamic = true;
 
-			sphere = new THREE.Mesh( geometry, shaderMaterial );
+			var geometry = new THREE.SphereBufferGeometry( radius, segments, rings );
 
-			var vertices = sphere.geometry.vertices;
-			var values = attributes.displacement.value;
+			displacement = new Float32Array( geometry.attributes.position.count );
+			noise = new Float32Array( geometry.attributes.position.count );
 
-			for ( var v = 0; v < vertices.length; v++ ) {
+			for ( var i = 0; i < displacement.length; i ++ ) {
 
-				values[ v ] = 0;
-				noise[ v ] = Math.random() * 5;
+				noise[ i ] = Math.random() * 5;
 
 			}
 
+			geometry.addAttribute( 'displacement', new THREE.BufferAttribute( displacement, 1 ) );
+
+			sphere = new THREE.Mesh( geometry, shaderMaterial );
 			scene.add( sphere );
 
 			renderer = new THREE.WebGLRenderer();
 			renderer.setClearColor( 0x050505 );
 			renderer.setPixelRatio( window.devicePixelRatio );
-			renderer.setSize( WIDTH, HEIGHT );
+			renderer.setSize( window.innerWidth, window.innerHeight );
 
 			var container = document.getElementById( 'container' );
 			container.appendChild( renderer.domElement );
@@ -195,18 +186,18 @@
 			uniforms.amplitude.value = 2.5 * Math.sin( sphere.rotation.y * 0.125 );
 			uniforms.color.value.offsetHSL( 0.0005, 0, 0 );
 
-			for ( var i = 0; i < attributes.displacement.value.length; i ++ ) {
+			for ( var i = 0; i < displacement.length; i ++ ) {
 
-				attributes.displacement.value[ i ] = Math.sin( 0.1 * i + time );
+				displacement[ i ] = Math.sin( 0.1 * i + time );
 
 				noise[ i ] += 0.5 * ( 0.5 - Math.random() );
 				noise[ i ] = THREE.Math.clamp( noise[ i ], -5, 5 );
 
-				attributes.displacement.value[ i ] += noise[ i ];
+				displacement[ i ] += noise[ i ];
 
 			}
 
-			attributes.displacement.needsUpdate = true;
+			sphere.geometry.attributes.displacement.needsUpdate = true;
 
 			renderer.render( scene, camera );
 

+ 17 - 3
examples/webgl_exporter_obj.html

@@ -55,7 +55,8 @@
 			<span class="link" id="triangle">triangle</span>,
 			<span class="link" id="cube">cube</span>,
 			<span class="link" id="cylinder">cylinder</span>,
-			<span class="link" id="both">both</span>
+			<span class="link" id="both">both</span>,
+			<span class="link" id="transformed">transformed</span>
 			- <span class="link" id="export">export to obj</span>
 		</div>
 		
@@ -81,10 +82,13 @@
 				for (var i = 0; i < scene.children.length; i++) {
 					var current = scene.children[i];
 					if (current instanceof THREE.Mesh) {
+						current.geometry.dispose ();
 						scene.remove (current);
 						i--;
 					}
 				}
+				
+				console.log (renderer.info);
 	
 				if (type == 1) {
 					var material = new THREE.MeshLambertMaterial ( { color : 0x00cc00 } );
@@ -104,7 +108,7 @@
 					var material = new THREE.MeshLambertMaterial ( { color : 0x00cc00 } );
 					var geometry = new THREE.CylinderGeometry( 50, 50, 100, 30, 1 );
 					scene.add( new THREE.Mesh( geometry, material ) );
-				} else if (type == 4) {
+				} else if (type == 4 || type == 5) {
 					var material = new THREE.MeshLambertMaterial ( { color : 0x00cc00 } );
 
 					var geometry = new THREE.Geometry ();
@@ -115,14 +119,23 @@
 					geometry.computeFaceNormals ();
 					var mesh = new THREE.Mesh( geometry, material );
 					mesh.position.x = -200;
+					if (type == 5) {
+						mesh.rotation.y = Math.PI / 4.0;
+					}
 					scene.add( mesh );
 
 					var geometry2 = new THREE.BoxGeometry( 100, 100, 100 );
 					var mesh2 = new THREE.Mesh( geometry2, material );
+					if (type == 5) {
+						mesh2.rotation.y = Math.PI / 4.0;
+					}
 					scene.add( mesh2 );
 
 					var geometry3 = new THREE.CylinderGeometry( 50, 50, 100, 30, 1 );
 					var mesh3 = new THREE.Mesh( geometry3, material );
+					if (type == 5) {
+						mesh3.rotation.y = Math.PI / 4.0;
+					}
 					mesh3.position.x = 200;
 
 					scene.add( mesh3 );
@@ -155,6 +168,7 @@
 				document.getElementById( 'cube' ).addEventListener( 'click', function() { addGeometry (2); });
 				document.getElementById( 'cylinder' ).addEventListener( 'click', function() { addGeometry (3); });
 				document.getElementById( 'both' ).addEventListener( 'click', function() { addGeometry (4); });
+				document.getElementById( 'transformed' ).addEventListener( 'click', function() { addGeometry (5); });
 				
 				exportButton = document.getElementById( 'export' );
 				exportButton.addEventListener( 'click', function() { exportToObj (); });
@@ -206,7 +220,7 @@
 
 				camera.position.x += ( mouseX - camera.position.x ) * .05;
 				camera.position.y += ( -mouseY - camera.position.y ) * .05;
-				camera.lookAt( new THREE.Vector3 (0.0, 0.0, 0.0) );
+				camera.lookAt( scene.position );
 
 				light.position.set( camera.position.x, camera.position.y, camera.position.z ).normalize ();
 				renderer.render( scene, camera );

+ 0 - 74
src/core/BufferGeometry.js

@@ -174,7 +174,6 @@ THREE.BufferGeometry.prototype = {
 				this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );
 				this.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );
 
-
 			}
 
 			if ( geometry instanceof THREE.DynamicGeometry ) {
@@ -189,41 +188,6 @@ THREE.BufferGeometry.prototype = {
 
 		}
 
-		if ( material.attributes !== undefined ) {
-
-			var attributes = material.attributes;
-
-			for ( var name in attributes ) {
-
-				var attribute = attributes[ name ];
-
-				var type = attribute.type;
-				var array = attribute.value;
-
-				switch ( type ) {
-
-					case "f":
-						this.addAttribute( name, new THREE.Float32Attribute( array.length, 1 ).copyArray( array ) );
-						break;
-
-					case "c":
-						this.addAttribute( name, new THREE.Float32Attribute( array.length * 3, 3 ).copyColorsArray( array ) );
-						break;
-
-					case "v3":
-						this.addAttribute( name, new THREE.Float32Attribute( array.length * 3, 3 ).copyVector3sArray( array ) );
-						break;
-
-					default:
-						console.warn( 'THREE.BufferGeometry.setFromObject(). TODO: attribute unsupported', type );
-						break;
-
-				}
-
-			}
-
-		}
-
 		return this;
 
 	},
@@ -264,44 +228,6 @@ THREE.BufferGeometry.prototype = {
 
 	},
 
-	updateFromMaterial: function ( material ) {
-
-		if ( material.attributes !== undefined ) {
-
-			var attributes = material.attributes;
-
-			for ( var name in attributes ) {
-
-				var attribute = attributes[ name ];
-
-				var type = attribute.type;
-				var array = attribute.value;
-
-				switch ( type ) {
-
-					case "f":
-						this.attributes[ name ].copyArray( array );
-						this.attributes[ name ].needsUpdate = true;
-						break;
-
-					case "c":
-						this.attributes[ name ].copyColorsArray( array );
-						this.attributes[ name ].needsUpdate = true;
-						break;
-
-					case "v3":
-						this.attributes[ name ].copyVector3sArray( array );
-						this.attributes[ name ].needsUpdate = true;
-						break;
-
-				}
-
-			}
-
-		}
-
-	},
-
 	fromGeometry: function ( geometry, material ) {
 
 		material = material || { 'vertexColors': THREE.NoColors };

+ 2 - 2
src/loaders/ImageLoader.js

@@ -59,10 +59,10 @@ THREE.ImageLoader.prototype = {
 
 		if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;
 
-		image.src = url;
-
 		scope.manager.itemStart( url );
 
+		image.src = url;
+
 		return image;
 
 	},

+ 1 - 0
src/loaders/MaterialLoader.js

@@ -41,6 +41,7 @@ THREE.MaterialLoader.prototype = {
 		if ( json.specular !== undefined ) material.specular.setHex( json.specular );
 		if ( json.shininess !== undefined ) material.shininess = json.shininess;
 		if ( json.uniforms !== undefined ) material.uniforms = json.uniforms;
+		if ( json.attributes !== undefined ) material.attributes = json.attributes;
 		if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;
 		if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;
 		if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;

+ 15 - 5
src/loaders/ObjectLoader.js

@@ -332,6 +332,16 @@ THREE.ObjectLoader.prototype = {
 
 	parseTextures: function ( json, images ) {
 
+		function parseConstant( value ) {
+
+			if ( typeof( value ) === 'number' ) return value;
+
+			console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );
+
+			return THREE[ value ];
+
+		}
+
 		var textures = {};
 
 		if ( json !== undefined ) {
@@ -358,15 +368,15 @@ THREE.ObjectLoader.prototype = {
 				texture.uuid = data.uuid;
 
 				if ( data.name !== undefined ) texture.name = data.name;
-				if ( data.mapping !== undefined ) texture.mapping = data.mapping;
+				if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping );
 				if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2( data.repeat[ 0 ], data.repeat[ 1 ] );
-				if ( data.minFilter !== undefined ) texture.minFilter = THREE[ data.minFilter ];
-				if ( data.magFilter !== undefined ) texture.magFilter = THREE[ data.magFilter ];
+				if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter );
+				if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter );
 				if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;
 				if ( data.wrap instanceof Array ) {
 
-					texture.wrapS = THREE[ data.wrap[ 0 ] ];
-					texture.wrapT = THREE[ data.wrap[ 1 ] ];
+					texture.wrapS = parseConstant( data.wrap[ 0 ] );
+					texture.wrapT = parseConstant( data.wrap[ 1 ] );
 
 				}
 

+ 10 - 3
src/materials/ShaderMaterial.js

@@ -36,7 +36,14 @@ THREE.ShaderMaterial = function ( parameters ) {
 
 	this.defines = {};
 	this.uniforms = {};
-	this.attributes = null;
+	this.attributes = [];
+
+	if ( parameters.attributes !== undefined && Array.isArray( parameters.attributes ) === false ) {
+
+		console.warn( 'THREE.ShaderMaterial: attributes should now be an array of attribute names.' );
+		parameters.attributes = Object.keys( parameters.attributes );
+
+	}
 
 	this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}';
 	this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}';
@@ -112,9 +119,9 @@ THREE.ShaderMaterial.prototype.clone = function ( material ) {
 
 };
 
-THREE.ShaderMaterial.prototype.toJSON = function () {
+THREE.ShaderMaterial.prototype.toJSON = function ( meta ) {
 
-	var data = THREE.Material.prototype.toJSON.call( this );
+	var data = THREE.Material.prototype.toJSON.call( this, meta );
 
 	data.uniforms = this.uniforms;
 	data.attributes = this.attributes;

+ 8 - 3
src/renderers/WebGLRenderer.js

@@ -1146,7 +1146,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 				}
 
-				var position = geometry.attributes['position'];
+				var position = geometry.attributes.position;
 
 				// render non-indexed triangles
 
@@ -2092,9 +2092,14 @@ THREE.WebGLRenderer = function ( parameters ) {
 			// changed glsl or parameters
 			deallocateMaterial( material );
 
-		} else {
+		} else if ( shaderID !== undefined ) {
+
+			// same glsl
+			return;
+
+		} else if ( material.__webglShader.uniforms === material.uniforms ) {
 
-			// same glsl and parameters
+			// same uniforms (container object)
 			return;
 
 		}

+ 0 - 5
src/renderers/webgl/WebGLObjects.js

@@ -114,11 +114,6 @@ THREE.WebGLObjects = function ( gl, info ) {
 		if ( object.geometry instanceof THREE.DynamicGeometry ) {
 
 			geometry.updateFromObject( object );
-			geometry.updateFromMaterial( object.material );
-
-		} else if ( object.geometry instanceof THREE.Geometry ) {
-
-			geometry.updateFromMaterial( object.material );
 
 		}
 

+ 36 - 25
src/renderers/webgl/WebGLProgram.js

@@ -4,15 +4,15 @@ THREE.WebGLProgram = ( function () {
 
 	function generateDefines( defines ) {
 
-		var value, chunk, chunks = [];
+		var chunks = [];
 
-		for ( var d in defines ) {
+		for ( var name in defines ) {
+
+			var value = defines[ name ];
 
-			value = defines[ d ];
 			if ( value === false ) continue;
 
-			chunk = '#define ' + d + ' ' + value;
-			chunks.push( chunk );
+			chunks.push( '#define ' + name + ' ' + value );
 
 		}
 
@@ -50,7 +50,7 @@ THREE.WebGLProgram = ( function () {
 
 	}
 
-	function programArrayToString ( previousValue, currentValue, index, array ) {
+	function programArrayToString( previousValue, currentValue, index, array ) {
 
 		if ( currentValue !== '' && currentValue !== undefined && currentValue !== null ) {
 
@@ -59,6 +59,7 @@ THREE.WebGLProgram = ( function () {
 		}
 
 		return previousValue;
+
 	}
 
 	return function ( renderer, code, material, parameters ) {
@@ -414,35 +415,45 @@ THREE.WebGLProgram = ( function () {
 
 		// cache attributes locations
 
-		identifiers = [
+		if ( material instanceof THREE.RawShaderMaterial ) {
 
-			'position',
-			'normal',
-			'uv',
-			'uv2',
-			'tangent',
-			'color',
-			'skinIndex',
-			'skinWeight',
-			'lineDistance'
+			identifiers = attributes;
 
-		];
+		} else {
 
-		for ( var i = 0; i < parameters.maxMorphTargets; i ++ ) {
+			identifiers = [
 
-			identifiers.push( 'morphTarget' + i );
+				'position',
+				'normal',
+				'uv',
+				'uv2',
+				'tangent',
+				'color',
+				'skinIndex',
+				'skinWeight',
+				'lineDistance'
 
-		}
+			];
 
-		for ( var i = 0; i < parameters.maxMorphNormals; i ++ ) {
+			for ( var i = 0; i < parameters.maxMorphTargets; i ++ ) {
 
-			identifiers.push( 'morphNormal' + i );
+				identifiers.push( 'morphTarget' + i );
 
-		}
+			}
 
-		for ( var a in attributes ) {
+			for ( var i = 0; i < parameters.maxMorphNormals; i ++ ) {
 
-			identifiers.push( a );
+				identifiers.push( 'morphNormal' + i );
+
+			}
+
+			// ShaderMaterial attributes
+
+			if ( Array.isArray( attributes ) ) {
+
+				identifiers = identifiers.concat( attributes );
+
+			}
 
 		}
 

+ 12 - 1
src/textures/Texture.js

@@ -109,8 +109,19 @@ THREE.Texture.prototype = {
 				type: 'Texture',
 				generator: 'Texture.toJSON'
 			},
+
 			uuid: this.uuid,
-			mapping: this.mapping
+			name: this.name,
+
+			mapping: this.mapping,
+
+			repeat: [ this.repeat.x, this.repeat.y ],
+			offset: [ this.offset.x, this.offset.y ],
+			wrap: [ this.wrapS, this.wrapT ],
+
+			minFilter: this.minFilter,
+			magFilter: this.magFilter,
+			anisotropy: this.anisotropy
 		};
 
 		if ( this.image !== undefined ) {