Browse Source

Added simple scene format loader.

This is very much work in progress - expect things to change and to be broken.
alteredq 14 years ago
parent
commit
8faa18b620
5 changed files with 781 additions and 123 deletions
  1. 128 122
      build/ThreeExtras.js
  2. 124 0
      examples/scene_test.html
  3. 287 0
      examples/scenes/test_scene.js
  4. 239 0
      src/extras/SceneUtils.js
  5. 3 1
      utils/build.py

File diff suppressed because it is too large
+ 128 - 122
build/ThreeExtras.js


+ 124 - 0
examples/scene_test.html

@@ -0,0 +1,124 @@
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+		<title>three.js - scene loader test</title>
+		<meta charset="utf-8">
+		<style type="text/css">
+			body {
+				background:#fff;
+				padding:0;
+				margin:0;
+				overflow:hidden;
+				font-family:georgia;
+				text-align:center;
+			}
+			
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				color: #000;
+				padding: 5px;
+				font-family: Monospace;
+				font-size: 13px;
+				text-align: center;
+			}
+			
+			a { color:skyblue }
+			canvas { pointer-events:none; z-index:10; }
+			#log { position:absolute; top:0; display:block; text-align:left; z-index:1000; pointer-events:none; }
+		</style>
+	</head>
+
+	<body>
+		<div id="info">
+			<a href="http://github.com/mrdoob/three.js">three.js</a> - scene loader test
+		</div>
+
+		<pre id="log"></pre>
+
+		<script type="text/javascript" src="../build/ThreeExtras.js"></script>
+		<script type="text/javascript" src="js/Stats.js"></script>
+
+		<script type="text/javascript">
+
+			var SCREEN_WIDTH = window.innerWidth;
+			var SCREEN_HEIGHT = window.innerHeight;
+
+			var container,stats;
+
+			var camera, scene;
+			var renderer;
+
+			var mesh, zmesh, geometry;
+
+			var mouseX = 0, mouseY = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+			document.addEventListener('mousemove', onDocumentMouseMove, false);
+
+			init();
+
+
+			function init() {
+
+				container = document.createElement('div');
+				document.body.appendChild(container);
+
+				var callback = function( result ) {
+				
+					scene = result.scene;
+					camera = result.currentCamera;
+					
+					camera.aspect = window.innerWidth / window.innerHeight;
+					camera.updateProjectionMatrix();
+
+					setInterval(loop, 1000/60);
+
+				}
+				
+				SceneUtils.loadScene( "scenes/test_scene.js", callback );
+				
+				renderer = new THREE.WebGLRenderer();
+				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
+				renderer.domElement.style.position = "relative";
+				container.appendChild( renderer.domElement );
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				stats.domElement.style.zIndex = 100;
+				container.appendChild( stats.domElement );
+
+			}
+
+			function onDocumentMouseMove(event) {
+
+				mouseX = ( event.clientX - windowHalfX );
+				mouseY = ( event.clientY - windowHalfY );
+
+			}
+
+			function loop() {
+
+				camera.position.x += ( mouseX - camera.position.x ) * .001;
+				camera.position.y += ( - mouseY - camera.position.y ) * .001;
+
+				renderer.render( scene, camera );
+
+				stats.update();
+
+			}
+
+			function log( text ) {
+
+				var e = document.getElementById("log");
+				e.innerHTML = text + "<br/>" + e.innerHTML;
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 287 - 0
examples/scenes/test_scene.js

@@ -0,0 +1,287 @@
+var scene = {
+	
+"objects": 
+{	
+	"cube1" : {
+		"geometry" : "cube",
+		"materials": [ "lambert_red" ],
+		"position" : [ 0, 0, 0 ],
+		"rotation" : [ 0, -0.3, 0 ],
+		"scale"	   : [ 1, 1, 1 ],
+		"visible"  : true
+	},
+
+	"cube2" : {
+		"geometry" : "cube",
+		"materials": [ "basic_black" ],
+		"position" : [ 0, 0, 0 ],
+		"rotation" : [ 0, -0.3, 0 ],
+		"scale"	   : [ 2, 2, 2 ],
+		"visible"  : true
+	},
+
+	"sphere" : {
+		"geometry" : "sphere",
+		"materials": [ "lambert_green" ],
+		"position" : [ -20, -5, 15 ],
+		"rotation" : [ 0, 0, 0 ],
+		"scale"	   : [ 1, 1, 1 ],
+		"visible"  : true
+	},
+
+	"torus" : {
+		"geometry" : "torus",
+		"materials": [ "phong_orange" ],
+		"position" : [ 0, 5, -50 ],
+		"rotation" : [ 0, 0, 0 ],
+		"scale"	   : [ 2, 2, 2 ],
+		"visible"  : true
+	},
+
+	"cone" : {
+		"geometry" : "cone",
+		"materials": [ "lambert_blue" ],
+		"position" : [ -50, 40, -50 ],
+		"rotation" : [ 1.57, 0, 0 ],
+		"scale"	   : [ 1, 1, 1 ],
+		"visible"  : true
+	},
+
+	"cylinder" : {
+		"geometry" : "cylinder",
+		"materials": [ "lambert_blue" ],
+		"position" : [ 50, 40, -50 ],
+		"rotation" : [ 1.57, 0, 0 ],
+		"scale"	   : [ 1, 1, 1 ],
+		"visible"  : true
+	},
+	
+	"veyron" : {
+		"geometry" : "veyron",
+		"materials": [ "face" ],
+		"position" : [ 40, -1, 0 ],
+		"rotation" : [ 0, 0.3, 0 ],
+		"scale"	   : [ 0.25, 0.25, 0.25 ],
+		"visible"  : true
+	},
+
+	"walt" : {
+		"geometry" : "WaltHead",
+		"materials": [ "phong_white" ],
+		"position" : [ -45, 10, 0 ],
+		"rotation" : [ 0, 0, 0 ],
+		"scale"	   : [ 0.5, 0.5, 0.5 ],
+		"visible"  : true
+	},
+	
+	"ground" : {
+		"geometry" : "plane",
+		"materials": [ "basic_gray" ],
+		"position" : [ 0, -10, 0 ],
+		"rotation" : [ 1.57, 0, 0 ],
+		"scale"	   : [ 100, 100, 100 ],
+		"visible"  : true
+	}	
+	
+},
+	
+"geometries":
+{
+	"cube": {
+		"type"  : "cube",
+		"width" : 10, 
+		"height": 10,
+		"depth" : 10, 
+		"segments_width"  : 1, 
+		"segments_height" : 1,
+		"flipped" : false, 
+		"sides"   : { "px": true, "nx": true, "py": true, "ny": true, "pz": true, "nz": true }
+	},
+
+	"plane": {
+		"type"   : "plane",
+		"width"  : 10, 
+		"height" : 10,
+		"segments_width"  : 50, 
+		"segments_height" : 50
+	},	
+
+	"sphere": {
+		"type"    : "sphere",
+		"radius"  : 5, 
+		"segments_width"  : 32, 
+		"segments_height" : 16
+	},
+ 
+	"torus": {
+		"type"    : "torus",
+		"radius"  : 5,
+		"tube"	  : 2,
+		"segmentsR" : 16, 
+		"segmentsT" : 32
+	},
+	
+	"cylinder": {
+		"type"    : "cylinder",
+		"numSegs"  : 32, 
+		"topRad"   : 5, 
+		"botRad"   : 5,
+		"height"   : 50,
+		"topOffset": 0,
+		"botOffset": 0
+	},
+
+	"cone": {
+		"type"    : "cylinder",
+		"numSegs"  : 32, 
+		"topRad"   : 0, 
+		"botRad"   : 5,
+		"height"   : 50,
+		"topOffset": 0,
+		"botOffset": 0
+	},
+	
+	"WaltHead": {
+		"type": "bin_mesh",
+		"url" : "obj/walt/WaltHead_bin.js"
+	},
+
+	"veyron": {
+		"type": "bin_mesh",
+		"url" : "obj/veyron/VeyronNoUv_bin.js"
+	},
+
+	"TextureCube": {
+		"type": "ascii_mesh",
+		"url" : "obj/textureTest/textureTest_baked.js"
+	},
+	
+	
+},
+	
+"materials":
+{
+	"basic_red": {
+		"type": "MeshBasicMaterial",
+		"parameters": { color: 0xff0000, wireframe: true } 
+	},
+
+	"basic_green": {
+		"type": "MeshBasicMaterial",
+		"parameters": { color: 0x007711, wireframe: true } 
+	},
+
+	"basic_gray": {
+		"type": "MeshBasicMaterial",
+		"parameters": { color: 0x666666, wireframe: true } 
+	},
+
+	"basic_black": {
+		"type": "MeshBasicMaterial",
+		"parameters": { color: 0x000000, wireframe: true } 
+	},
+	
+	"basic_blue": {
+		"type": "MeshBasicMaterial",
+		"parameters": { color: 0x0000ff, wireframe: true } 
+	},
+	
+	"lambert_red": {
+		"type": "MeshLambertMaterial",
+		"parameters": { color: 0xff0000 } 
+	},
+	
+	"lambert_green": {
+		"type": "MeshLambertMaterial",
+		"parameters": { color: 0x007711 } 
+	},
+
+	"lambert_blue": {
+		"type": "MeshLambertMaterial",
+		"parameters": { color: 0x0055aa } 
+	},
+	
+	"phong_white": {
+		"type": "MeshPhongMaterial",
+		"parameters": { color: 0xaaaaaa } 
+	},
+
+	"phong_orange": {
+		"type": "MeshPhongMaterial",
+		"parameters": { color:0x000000, specular: 0xaa5500 } 
+	},
+	
+	"face": {
+		"type": "MeshFaceMaterial",
+		"parameters": {}
+	}
+	
+},
+
+"cameras":
+{
+	"cam1": {
+		"type"  : "perspective",
+		"fov"   : 50,
+		"aspect": 1.33333,
+		"near"  : 1,
+		"far"   : 1000,
+		"position": [0,0,100],
+		"target"  : [0,0,0]
+	},
+
+	"cam2": {
+		"type"  : "ortho",
+		"left"  : 0,
+		"right" : 1024,
+		"top"   : 0,
+		"bottom": 1024,
+		"near"  : 1,
+		"far"   : 1000,
+		"position": [0,0,0],
+		"target"  : [0,0,0]
+	}
+
+},
+
+"lights":
+{
+	"light1": {
+		"type"		 : "directional",
+		"direction"	 : [0,1,1],
+		"color" 	 : [1,1,1]
+	},
+
+	"light2": {
+		"type"	  : "point",
+		"position": [0,0,0],
+		"color"   : [1,1,1]
+	}
+	
+},
+
+"fogs":
+{
+	"basic": {
+		"type" : "linear",
+		"color": [1,0,0],
+		"near" : 1,
+		"far"  : 1000
+	},
+	
+	"exponential": {
+		"type"    : "exp2",
+		"color"   : [1,1,1],
+		"density" : 0.005,
+	}
+},
+	
+"defaults" : 
+{
+	"camera": "cam1",
+	"fog"	: "exponential"
+}
+
+};
+
+postMessage( scene );

+ 239 - 0
src/extras/SceneUtils.js

@@ -1,4 +1,243 @@
 var SceneUtils = {
+	
+	loadScene : function( url, callback ) {
+
+		var dg, dm, dd, dl, dc, df, f,
+			g, o, m, l, p, c, t,
+			geometry, material, camera, fog, materials,
+			loader, callback_model,
+			worker = new Worker( url );
+
+		worker.onmessage = function( event ) {
+
+			function handle_objects() {
+				
+				for( dd in data.objects ) {
+					
+					if ( !result.objects[ dd ] ) {
+						
+						o = data.objects[ dd ];
+						
+						geometry = result.geometries[ o.geometry ];
+						
+						if ( geometry ) {
+							
+							materials = [];
+							for( i = 0; i < o.materials.length; i++ ) {
+								
+								materials[ i ] = result.materials[ o.materials[i] ];
+								
+							}
+							
+							p = o.position;
+							r = o.rotation;
+							s = o.scale;
+							
+							object = new THREE.Mesh( geometry, materials );
+							object.position.set( p[0], p[1], p[2] );
+							object.rotation.set( r[0], r[1], r[2] );
+							object.scale.set( s[0], s[1], s[2] );
+							object.visible = o.visible;
+							
+							result.scene.addObject( object );
+							
+							result.objects[ dd ] = object;
+							
+						}
+						
+					}
+					
+				}
+			};
+			
+			function handle_mesh( geo, id ) {
+				
+				result.geometries[ id ] = geo; 
+				handle_objects();
+				
+			};
+			
+			function create_callback( id ) {
+				
+				return function( geo ) { handle_mesh( geo, id ); }
+				
+			}
+			
+			var data = event.data;
+			
+			var result = {
+				
+				scene: new THREE.Scene(),
+				geometries: {},
+				materials: {},
+				objects: {},
+				cameras: {},
+				lights: {},
+				fogs: {}
+			
+			};
+			
+			loader = new THREE.Loader();
+			
+			// geometries	
+			
+			for( dg in data.geometries ) {
+				
+				g = data.geometries[ dg ];
+				
+				if ( g.type == "cube" ) {
+					
+					geometry = new Cube( g.width, g.height, g.depth, g.segments_width, g.segments_height, null, g.flipped, g.sides );
+					result.geometries[ dg ] = geometry;
+					
+				} else if ( g.type == "plane" ) {
+					
+					geometry = new Plane( g.width, g.height, g.segments_width, g.segments_height );
+					result.geometries[ dg ] = geometry;
+					
+				} else if ( g.type == "sphere" ) {
+					
+					geometry = new Sphere( g.radius, g.segments_width, g.segments_height );
+					result.geometries[ dg ] = geometry;
+					
+				} else if ( g.type == "cylinder" ) {
+					
+					geometry = new Cylinder( g.numSegs, g.topRad, g.botRad, g.height, g.topOffset, g.botOffset );
+					result.geometries[ dg ] = geometry;
+
+				} else if ( g.type == "torus" ) {
+					
+					geometry = new Torus( g.radius, g.tube, g.segmentsR, g.segmentsT );
+					result.geometries[ dg ] = geometry;
+					
+				} else if ( g.type == "bin_mesh" ) {
+					
+					loader.loadBinary( { model: g.url, 
+										 callback: create_callback( dg )
+										} );
+					
+				} else if ( g.type == "ascii_mesh" ) {
+					
+					loader.loadAscii( { model: g.url, 
+										callback: create_callback( dg )
+										} );
+					
+				}
+				
+			}
+
+			// materials
+			
+			for( dm in data.materials ) {
+				
+				m = data.materials[ dm ];
+				
+				material = new THREE[ m.type ]( m.parameters );
+				result.materials[ dm ] = material;
+				
+			}
+			
+			// objects
+			
+			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;
+				light.color.setRGB( c[0], c[1], c[2] );
+				
+				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;
+				
+			}
+			
+			result.currentCamera = result.cameras[ data.defaults.camera ];
+			
+			if ( result.fogs && data.defaults.fog ) {
+			
+				result.scene.fog = result.fogs[ data.defaults.fog ];
+				
+			}
+			
+			callback( result );
+
+		};
+
+		worker.postMessage( 0 );
+		
+	},
 
 	addMesh: function ( scene, geometry, scale, x, y, z, rx, ry, rz, material ) {
 

+ 3 - 1
utils/build.py

@@ -80,7 +80,9 @@ EXTRAS_FILES = [
 'extras/primitives/Cube.js',
 'extras/primitives/Cylinder.js',
 'extras/primitives/Plane.js',
-'extras/primitives/Sphere.js','extras/primitives/LathedObject.js',
+'extras/primitives/Sphere.js',
+'extras/primitives/Torus.js',
+'extras/primitives/LathedObject.js',
 'extras/io/Loader.js'
 ]
 

Some files were not shown because too many files changed in this diff