Browse Source

Merge remote branch 'alteredq/master'

Mr.doob 14 years ago
parent
commit
ad0a8a7446
4 changed files with 380 additions and 146 deletions
  1. 207 6
      examples/scene_test.html
  2. 26 14
      examples/scenes/test_scene.js
  3. 129 111
      src/extras/SceneUtils.js
  4. 18 15
      src/renderers/WebGLRenderer.js

+ 207 - 6
examples/scene_test.html

@@ -44,13 +44,26 @@
 				padding:0.1em 0.3em;
 				width:3em;
 				text-align: center;
-				/*
-				font-size:0.8em;
+				display:none;
+			}
+			
+			.shadow {
 				-moz-box-shadow: 0px 0px 5px #000;
 				-webkit-box-shadow: 0px 0px 5px #000;
 				box-shadow: 0px 0px 5px #000;
-				*/
-				display:none;
+			}
+			
+			#progressbar {
+				text-align: center;
+				background: white;
+				width: 250px;
+				height: 10px;
+			}
+			
+			#bar {
+				background:#d00;
+				width:50px;
+				height:10px;
 			}
 			
 			.enabled {
@@ -70,6 +83,48 @@
 			a { color:red }
 			canvas { pointer-events:none; z-index:10; }
 			#log { position:absolute; top:0; display:block; text-align:left; z-index:1000; pointer-events:none; }
+			
+			#scene_explorer {
+				background:transparent;
+				color:#fff;
+				width:200px;
+				position:absolute;
+				text-align:left;
+				top:0px;
+				z-index:200;
+				overflow:auto;
+			}
+			
+			#section_exp {
+				background:rgba(0,0,50,0.5);
+				padding:0.5em 0;
+				display:none;
+			}
+			
+			#scene_explorer h3 { 
+				font-size:1em;
+				padding:0;
+				margin:0;
+				color:orange;
+			}
+			
+			#scene_explorer a {
+				color:#555;
+				font-weight:bold;
+				text-decoration:none;
+				font-size:1.2em;
+				font-family:Monospace;
+			}
+			#scene_explorer a:hover {
+				background:#555;
+				color:rgba(0,0,50,1);
+			}
+			
+			.part {
+				display:none;
+				padding:0 0 0.5em 2em;
+			}
+			
 		</style>
 	</head>
 
@@ -77,10 +132,19 @@
 		<div id="info">
 			<a href="http://github.com/mrdoob/three.js">three.js</a> - scene loader test
 		</div>
+		
+		<div id="scene_explorer">
+			<a id="plus_exp" href="#">[+]</a>
+			<div id="section_exp"></div>
+		</div>
 
 		<div id="progress">
 			<span id="message">Loading ...</span>
-			<center><div id="start" class="disabled">Start</div></center>
+			
+			<center>
+				<div id="progressbar" class="shadow"><div id="bar" class="shadow"></div></div>
+				<div id="start" class="disabled">Start</div>
+			</center>
 		</div>
 		
 		<pre id="log"></pre>
@@ -115,6 +179,39 @@
 				
 			}
 			
+			function handle_update( result, pieces ) {
+				
+				refreshSceneView( result );
+				renderer.initWebGLObjects( result.scene );
+				
+				var m, material, count = 0;
+				
+				for ( m in result.materials ) {
+				
+					material = result.materials[ m ];
+					if ( ! ( material instanceof THREE.MeshFaceMaterial ) ) {
+						
+						if( !material.program ) {
+						
+							console.log(m);
+							renderer.initMaterial( material, result.scene.lights, result.scene.fog );
+							
+							count += 1;
+							if( count > pieces ) {
+								
+								//console.log("xxxxxxxxx");
+								break;
+							
+							}
+							
+						}
+						
+					}
+					
+				}
+				
+			}
+			
 			function init() {
 
 				container = document.createElement( 'div' );
@@ -133,9 +230,30 @@
 
 				setInterval( loop, 1000/60 );
 
+				var callback_progress = function( progress, result ) {
+				
+					var bar = 250, 
+						total = progress.total_models + progress.total_textures,
+						loaded = progress.loaded_models + progress.loaded_textures;
+					
+					if ( total )
+						bar = Math.floor( bar * loaded / total );
+					
+					$( "bar" ).style.width = bar + "px";
+					
+					count = 0;
+					for ( var m in result.materials ) count++;
+
+					handle_update( result, Math.floor( count/total ) );
+					
+				}
+				
 				var callback_sync = function( result ) {
 				
 					/*
+					
+					// uncomment to see progressive scene loading
+					
 					scene = result.scene;
 					camera = result.currentCamera;
 					
@@ -146,6 +264,8 @@
 					
 					*/
 
+					//handle_update( result, 1 );
+					
 				}
 				
 				var callback_async = function( result ) {
@@ -160,21 +280,29 @@
 					mat_veyron[ 3 ][ 0 ] = result.materials[ "glass" ];
 					mat_veyron[ 4 ][ 0 ] = result.materials[ "chrome" ];
 					mat_veyron[ 5 ][ 0 ] = result.materials[ "chrome" ];
+					mat_veyron[ 6 ][ 0 ] = result.materials[ "backlights" ];
+					mat_veyron[ 7 ][ 0 ] = result.materials[ "backsignals" ];
 					
 					$( "message" ).style.display = "none";
+					$( "progressbar" ).style.display = "none";
 					$( "start" ).style.display = "block";
 					$( "start" ).className = "enabled";
 					
+					handle_update( result, 1 );
+					
 				}
 				
 				$( "progress" ).style.display = "block";
-				SceneUtils.loadScene( "scenes/test_scene.js", callback_sync, callback_async );
+				SceneUtils.loadScene( "scenes/test_scene.js", callback_sync, callback_async, callback_progress );
 
 				stats = new Stats();
 				stats.domElement.style.position = 'absolute';
 				stats.domElement.style.top = '0px';
+				stats.domElement.style.right = '0px';
 				stats.domElement.style.zIndex = 100;
 				container.appendChild( stats.domElement );
+				
+				$( "plus_exp" ).addEventListener( 'click', createToggle( "exp" ), false );
 
 			}
 
@@ -263,6 +391,79 @@
 
 			}
 
+			// Scene explorer user interface
+			
+			function toggle( id ) {
+				
+				var scn = $( "section_" + id ).style,
+					btn = $( "plus_" + id );
+				
+				if ( scn.display == "block" ) {
+				
+					scn.display = "none";
+					btn.innerHTML = "[+]";
+					
+				}
+				else {
+					
+					scn.display = "block";
+					btn.innerHTML = "[-]";
+					
+				}
+					
+			}
+			
+			function createToggle( label ) { return function() { toggle( label ) } };
+			
+			function refreshSceneView( result ) {
+				
+				$( "section_exp" ).innerHTML = generateSceneView( result );
+
+				var config = [ "obj", "geo", "mat", "tex", "lit", "cam" ];
+				
+				for ( var i = 0; i < config.length; i++ )
+					$( "plus_" + config[i] ).addEventListener( 'click', createToggle( config[i] ), false );
+
+			}
+			
+			function generateSection( label, id, objects ) {
+				
+				var html = "";
+				
+				html += "<h3><a id='plus_" + id + "' href='#'>[+]</a> " + label + "</h3>";
+				html += "<div id='section_" + id + "' class='part'>";
+				
+				for( var o in objects ) {
+				
+					html += o + "<br/>";
+					
+				}
+				html += "</div>";
+				
+				return html;
+			
+			}
+			
+			function generateSceneView( result ) {
+				
+				var config = [
+				[ "Objects",    "obj", result.objects ],
+				[ "Geometries", "geo", result.geometries ],
+				[ "Materials",  "mat", result.materials ],
+				[ "Textures",   "tex", result.textures ],
+				[ "Lights",     "lit", result.lights ],
+				[ "Cameras",    "cam", result.cameras ]
+				];
+				
+				var html = "";
+				
+				for ( var i = 0; i < config.length; i++ )
+					html += generateSection( config[i][0], config[i][1], config[i][2] );
+
+				return html;
+				
+			}
+
 		</script>
 
 	</body>

+ 26 - 14
examples/scenes/test_scene.js

@@ -206,6 +206,7 @@ var scene = {
 	
 "materials":
 {
+	/*
 	"basic_red": {
 		"type": "MeshBasicMaterial",
 		"parameters": { color: 0xff0000, wireframe: true } 
@@ -215,16 +216,27 @@ var scene = {
 		"type": "MeshBasicMaterial",
 		"parameters": { color: 0x007711, wireframe: true } 
 	},
-
-	"basic_gray": {
+	
+	"basic_blue": {
 		"type": "MeshBasicMaterial",
-		"parameters": { color: 0x666666, wireframe: true } 
+		"parameters": { color: 0x0000ff, wireframe: true } 
 	},
-
+		
 	"basic_black": {
 		"type": "MeshBasicMaterial",
 		"parameters": { color: 0x000000, wireframe: true } 
 	},
+	
+	"phong_white": {
+		"type": "MeshPhongMaterial",
+		"parameters": { color: 0xaaaaaa } 
+	},
+	*/
+	
+	"basic_gray": {
+		"type": "MeshBasicMaterial",
+		"parameters": { color: 0x666666, wireframe: true } 
+	},
 
 	"basic_white": {
 		"type": "MeshBasicMaterial",
@@ -236,11 +248,6 @@ var scene = {
 		"parameters": { color: 0xffffff, shading: "flat" } 
 	},
 	
-	"basic_blue": {
-		"type": "MeshBasicMaterial",
-		"parameters": { color: 0x0000ff, wireframe: true } 
-	},
-	
 	"lambert_red": {
 		"type": "MeshLambertMaterial",
 		"parameters": { color: 0xff0000 } 
@@ -256,11 +263,6 @@ var scene = {
 		"parameters": { color: 0x0055aa } 
 	},
 	
-	"phong_white": {
-		"type": "MeshPhongMaterial",
-		"parameters": { color: 0xaaaaaa } 
-	},
-
 	"phong_orange": {
 		"type": "MeshPhongMaterial",
 		"parameters": { color:0x000000, specular: 0xaa5500 } 
@@ -296,6 +298,16 @@ var scene = {
 		"parameters": { color: 0x050505 }
 	},
 	
+	"backlights": {	
+		"type": "MeshLambertMaterial",
+		"parameters": { color: 0xff0000, opacity: 0.5 }
+	},
+	
+	"backsignals": {
+		"type": "MeshLambertMaterial",
+		"parameters": { color: 0xffbb00, opacity: 0.5 }
+	},
+	
 	"textured_bg": {
 		"type": "MeshBasicMaterial",
 		"parameters": { color: 0xffffff, map: "texture_bg" } 

+ 129 - 111
src/extras/SceneUtils.js

@@ -1,6 +1,6 @@
 var SceneUtils = {
 	
-	loadScene : function( url, callback_sync, callback_async ) {
+	loadScene : function( url, callback_sync, callback_async, callback_progress ) {
 
 		var worker = new Worker( url );
 		worker.postMessage( 0 );
@@ -14,6 +14,7 @@ var SceneUtils = {
 				materials,
 				data, loader, 
 				counter_models, counter_textures,
+				total_models, total_textures,
 				result;
 
 			data = event.data;
@@ -90,7 +91,6 @@ var SceneUtils = {
 					handle_mesh( geo, id );
 					
 					counter_models -= 1;
-					//console.log( "models to load:", counter_models );
 					
 					async_callback_gate();
 					
@@ -100,6 +100,17 @@ var SceneUtils = {
 			
 			function async_callback_gate() {
 				
+				var progress = {
+					
+					total_models: total_models,
+					total_textures: total_textures,
+					loaded_models: total_models - counter_models,
+					loaded_textures: total_textures - counter_textures
+					
+				};
+				
+				callback_progress( progress, result );
+				
 				if( counter_models == 0 && counter_textures == 0 ) {
 					
 					callback_async( result );
@@ -108,6 +119,119 @@ var SceneUtils = {
 				
 			};
 			
+			var callback_texture = function( images ) {
+				
+				counter_textures -= 1;
+				async_callback_gate();  
+				
+			};
+			
+			// first go synchronous elements
+			
+			// cameras
+			
+			for( dc in data.cameras ) {
+				
+				c = data.cameras[ dc ];
+				
+				if ( c.type == "perspective" ) {
+					
+					camera = new THREE.Camera( c.fov, c.aspect, c.near, c.far );
+					
+				} else if ( c.type == "ortho" ) {
+					
+					camera = new THREE.Camera();
+					camera.projectionMatrix = THREE.Matrix4.makeOrtho( c.left, c.right, c.top, c.bottom, c.near, c.far );
+					
+				}
+				
+				p = c.position;
+				t = c.target;
+				camera.position.set( p[0], p[1], p[2] );
+				camera.target.position.set( t[0], t[1], t[2] );
+				
+				result.cameras[ dc ] = camera;
+				
+			}
+			
+			// lights
+			
+			for( dl in data.lights ) {
+				
+				l = data.lights[ dl ];
+				
+				if ( l.type == "directional" ) {
+				
+					p = l.direction;
+					
+					light = new THREE.DirectionalLight();
+					light.position.set( p[0], p[1], p[2] );
+					light.position.normalize();
+					
+				} else if ( l.type == "point" ) {
+				
+					p = l.position;
+					
+					light = new THREE.PointLight();
+					light.position.set( p[0], p[1], p[2] );
+					
+				}
+				
+				c = l.color;
+				i = l.intensity || 1;
+				light.color.setRGB( c[0] * i, c[1] * i, c[2] * i );
+				
+				result.scene.addLight( light );
+				
+				result.lights[ dl ] = light;
+				
+			}
+			
+			// fogs
+			
+			for( df in data.fogs ) {
+				
+				f = data.fogs[ df ];
+				
+				if ( f.type == "linear" ) {
+					
+					fog = new THREE.Fog( 0x000000, f.near, f.far );
+				
+				} else if ( f.type == "exp2" ) {
+					
+					fog = new THREE.FogExp2( 0x000000, f.density );
+					
+				}
+				
+				c = f.color;
+				fog.color.setRGB( c[0], c[1], c[2] );
+				
+				result.fogs[ df ] = fog;
+				
+			}
+			
+			// defaults
+			
+			if ( result.cameras && data.defaults.camera ) {
+				
+				result.currentCamera = result.cameras[ data.defaults.camera ];
+				
+			}
+			
+			if ( result.fogs && data.defaults.fog ) {
+			
+				result.scene.fog = result.fogs[ data.defaults.fog ];
+				
+			}
+			
+			c = data.defaults.bgcolor;
+			result.bgColor = new THREE.Color();
+			result.bgColor.setRGB( c[0], c[1], c[2] );
+			
+			result.bgColorAlpha = data.defaults.bgalpha;
+
+			// now come potentially asynchronous elements
+			
 			// geometries
 			
 			// count how many models will be loaded asynchronously
@@ -124,6 +248,8 @@ var SceneUtils = {
 				
 			}
 			
+			total_models = counter_models;
+			
 			for( dg in data.geometries ) {
 				
 				g = data.geometries[ dg ];
@@ -194,13 +320,7 @@ var SceneUtils = {
 				
 			}
 			
-			var callback_texture = function( images ) {
-				
-				counter_textures -= 1; 
-				//console.log( "textures to load:", counter_textures ); 
-				async_callback_gate();  
-				
-			};
+			total_textures = counter_textures;
 			
 			for( dt in data.textures ) {
 				
@@ -266,108 +386,6 @@ var SceneUtils = {
 			
 			handle_objects();
 			
-			// lights
-			
-			for( dl in data.lights ) {
-				
-				l = data.lights[ dl ];
-				
-				if ( l.type == "directional" ) {
-				
-					p = l.direction;
-					
-					light = new THREE.DirectionalLight();
-					light.position.set( p[0], p[1], p[2] );
-					light.position.normalize();
-					
-				} else if ( l.type == "point" ) {
-				
-					p = l.position;
-					
-					light = new THREE.PointLight();
-					light.position.set( p[0], p[1], p[2] );
-					
-				}
-				
-				c = l.color;
-				i = l.intensity || 1;
-				light.color.setRGB( c[0] * i, c[1] * i, c[2] * i );
-				
-				result.scene.addLight( light );
-				
-				result.lights[ dl ] = light;
-				
-			}
-			
-			// cameras
-			
-			for( dc in data.cameras ) {
-				
-				c = data.cameras[ dc ];
-				
-				if ( c.type == "perspective" ) {
-					
-					camera = new THREE.Camera( c.fov, c.aspect, c.near, c.far );
-					
-				} else if ( c.type == "ortho" ) {
-					
-					camera = new THREE.Camera();
-					camera.projectionMatrix = THREE.Matrix4.makeOrtho( c.left, c.right, c.top, c.bottom, c.near, c.far );
-					
-				}
-				
-				p = c.position;
-				t = c.target;
-				camera.position.set( p[0], p[1], p[2] );
-				camera.target.position.set( t[0], t[1], t[2] );
-				
-				result.cameras[ dc ] = camera;
-				
-			}
-
-			// fogs
-			
-			for( df in data.fogs ) {
-				
-				f = data.fogs[ df ];
-				
-				if ( f.type == "linear" ) {
-					
-					fog = new THREE.Fog( 0x000000, f.near, f.far );
-				
-				} else if ( f.type == "exp2" ) {
-					
-					fog = new THREE.FogExp2( 0x000000, f.density );
-					
-				}
-				
-				c = f.color;
-				fog.color.setRGB( c[0], c[1], c[2] );
-				
-				result.fogs[ df ] = fog;
-				
-			}
-			
-			// defaults
-			
-			if ( result.cameras && data.defaults.camera ) {
-				
-				result.currentCamera = result.cameras[ data.defaults.camera ];
-				
-			}
-			
-			if ( result.fogs && data.defaults.fog ) {
-			
-				result.scene.fog = result.fogs[ data.defaults.fog ];
-				
-			}
-			
-			c = data.defaults.bgcolor;
-			result.bgColor = new THREE.Color();
-			result.bgColor.setRGB( c[0], c[1], c[2] );
-			
-			result.bgColorAlpha = data.defaults.bgalpha;
-			
 			// synchronous callback
 			
 			callback_sync( result );

+ 18 - 15
src/renderers/WebGLRenderer.js

@@ -711,19 +711,16 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 
-	this.renderBuffer = function ( camera, lights, fog, material, geometryChunk, object ) {
-
-		var program, u, identifiers, attributes, parameters, maxLightCount, linewidth, primitives;
-
+	this.initMaterial = function( material, lights, fog ) {
+		
 		if ( !material.program ) {
 
+			var u, identifiers, parameters, maxLightCount;
+			
 			if ( material instanceof THREE.MeshDepthMaterial ) {
 
 				setMaterialShaders( material, THREE.ShaderLib[ 'depth' ] );
 
-				material.uniforms.mNear.value = camera.near;
-				material.uniforms.mFar.value = camera.far;
-
 			} else if ( material instanceof THREE.MeshNormalMaterial ) {
 
 				setMaterialShaders( material, THREE.ShaderLib[ 'normal' ] );
@@ -732,26 +729,18 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 				setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] );
 
-				refreshUniformsCommon( material, fog );
-
 			} else if ( material instanceof THREE.MeshLambertMaterial ) {
 
 				setMaterialShaders( material, THREE.ShaderLib[ 'lambert' ] );
 
-				refreshUniformsCommon( material, fog );
-
 			} else if ( material instanceof THREE.MeshPhongMaterial ) {
 
 				setMaterialShaders( material, THREE.ShaderLib[ 'phong' ] );
 
-				refreshUniformsCommon( material, fog );
-
 			} else if ( material instanceof THREE.LineBasicMaterial ) {
 
 				setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] );
 
-				refreshUniformsLine( material, fog );
-
 			}
 
 			// heuristics to create shader parameters according to lights in the scene
@@ -773,6 +762,14 @@ THREE.WebGLRenderer = function ( parameters ) {
 			cacheAttributeLocations( material.program, [ "position", "normal", "uv", "tangent" ] );
 
 		}
+		
+	};
+	
+	this.renderBuffer = function ( camera, lights, fog, material, geometryChunk, object ) {
+
+		var program, u, identifiers, attributes, parameters, maxLightCount, linewidth, primitives;
+
+		this.initMaterial( material, lights, fog );
 
 		program = material.program;
 
@@ -813,6 +810,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
+		if ( material instanceof THREE.MeshDepthMaterial ) {
+
+			material.uniforms.mNear.value = camera.near;
+			material.uniforms.mFar.value = camera.far;
+		}
+		
 		setUniforms( program, material.uniforms );
 
 		attributes = program.attributes;