Advertisement
 
Tutorial
  1 <!-- ------------------------------------- 
  2 NeHe Tutorial 10 
  3 Original: http://nehe.gamedev.net/tutorial/loading_and_moving_through_a_3d_world/22003/ 
  4 @author: rkwright@geofx.com 
  5 -------------------------------------- --> 
  6 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
  7 <html xmlns="http://www.w3.org/1999/xhtml"> 
  8     <head>
  9         <title>Three.js/NEHE Tutorial #10</title> 
 10         <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
 11         <!-- The following meta line optimizes the site for mobile devices. It sets the viewport size 
 12         to the screen size, so it will be displayed maximized, but unscaled. --> 
 13         <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1"/> 
 14         <link rel="stylesheet" type="text/css" href="NEHE.css" /> 
 15         <!-- Include two libraries from THREE.js: Core and the Detector for WebGL --> 
 16         <script src="../js/r69/three.js" type="text/javascript"></script> 
 17         <script src="../js/r69/Detector.js" type="text/javascript"></script> 
 18         <script src="../js/r69/OrbitControls.js" type="text/javascript"></script> 
 19         <script src="Scene.js" type="text/javascript"></script> 
 20         <script src="Data/World.js" type="text/javascript"></script> 
 21     </head> 
 22     <body>
 23         <!-- This JavaScript block encloses the Three.js commands --> 
 24         <script> 
 25             // set up the THREE.js scene 
 26             initializeScene(); 
 27             // request the orbitControls be created and enabled 
 28             orbitControls(); 
 29             // then initialize our demo's stuff 
 30             initializeDemo(); 
 31             // Animate the scene 
 32             animateScene(); 
 33  
 34             /** 
 35              * Initialize the scene. 
 36              */ 
 37             function initializeDemo() { 
 38                 // draw some 3D axes to orient the user
 39                 drawAxes(10); 
 40                 // then read the data and create the objects 
 41                 createWorld(); 
 42             } 
 43  
 44             function createWorld() { 
 45                 // Load an image as texture 
 46                 var texture = new THREE.ImageUtils.loadTexture("Data/Mud.png"); 
 47                 // create the material by mapping our texture onto it. Note that we map 
 48                 // the texture onto both sides of each object 
 49                 var material = new THREE.MeshBasicMaterial( { map: texture, side:THREE.DoubleSide } ); 
 50                 // loop through all the triangles in our "world" 
 51                 for ( i=0; i<nTriangles; i++ ) { 
 52                     // fetch three rows at a time, being the three vertices 
 53                     var i1 = i * 3; 
 54                     var i2 = i * 3 + 1; 
 55                     var i3 = i * 3 + 2; 
 56                     // create a plain Geometry and push the vertices into it 
 57                     var triGeom = new THREE.Geometry(); 
 58                     triGeom.vertices.push(new THREE.Vector3(world[i1][V_X],world[i1][V_Y],world[i1][V_Z])); 
 59                     triGeom.vertices.push(new THREE.Vector3(world[i2][V_X],world[i2][V_Y],world[i2][V_Z])); 
 60                     triGeom.vertices.push(new THREE.Vector3(world[i3][V_X],world[i3][V_Y],world[i3][V_Z])); 
 61                     // now need to create the mapping between our texture and the two triangles that 
 62                     // comprise the faces. For a good intro into UV mapping, see 
 63                     // http://solutiondesign.com/webgl-and-three-js-texture-mapping/ 
 64                     var uvs = []; 
 65                     // need to see which triangle we are on so we map the correct half of the 
 66                     // texture. Otherwise we end up mapping the same half twice. 
 67                     if ((i & 1) == 1) { 
 68                     uvs.push( new THREE.Vector2( 0.0, 1.0 ) ); 
 69                     uvs.push( new THREE.Vector2( 1.0, 1.0 ) ); 
 70                     uvs.push( new THREE.Vector2( 1.0, 0.0 ) ); 
 71                     } 
 72                     else { 
 73                     uvs.push( new THREE.Vector2( 0.0, 1.0 ) ); 
 74                     uvs.push( new THREE.Vector2( 0.0, 0.0 ) ); 
 75                     uvs.push( new THREE.Vector2( 1.0, 0.0 ) ); 
 76                     } 
 77                     // create a new Face, whose indices point into the vertices we created above 
 78                     triGeom.faces.push( new THREE.Face3( 0, 1, 2 ) ); 
 79                     // then set corresponding UV vertices 
 80                     triGeom.faceVertexUvs[ 0 ].push( [ uvs[0], uvs[1], uvs[2] ] ); 
 81                     // re-compute the normals for both the faces and vertexes 
 82                     triGeom.computeFaceNormals(); 
 83                     triGeom.computeVertexNormals(); 
 84                     // and create the actual mesh 
 85                     var mesh = new THREE.Mesh( triGeom, material); 
 86                     // and add it to the scene 
 87                     scene.add(mesh); 
 88                 } 
 89             } 
 90  
 91             /** 
 92              * Animate the scene and call rendering. 
 93              */ 
 94             function animateScene() { 
 95                 // Tell the browser to call this function when page is visible 
 96                 requestAnimationFrame(animateScene); 
 97                 // Map the 3D scene down to the 2D screen (render the frame) 
 98                 renderer.render(scene, camera); 
 99                 // the orbit controls, if used, have to be updated as well 
100                 if (controls != null && typeof controls != 'undefined') 
101                     controls.update(); 
102             } 
103         </script> 
104 </body> 
105 </html>
Scene.js
  1 /* 
  2  * @author rkwright   /  www.geofx.com 
  3  */ 
  4  
  5 var scene;                    // THREE.js objects     
  6 var renderer;             
  7 var camera;     
  8 var controls; 
  9  
 10 var ambientLight; 
 11 var directionalLight; 
 12  
 13  
 14 /** 
 15  * Initialize the THREE.js scene. 
 16  */ 
 17 function initializeScene( containerID ) { 
 18  
 19     // Check whether the browser supports WebGL.  
 20     if ( !Detector.webgl ) Detector.addGetWebGLMessage(); 
 21  
 22     // Create the scene, in which all objects are stored (e. g. camera, lights, geometries, ...) 
 23     scene = new THREE.Scene(); 
 24  
 25     // Get the size of the inner window (content area) 
 26     canvasWidth = window.innerWidth; 
 27     canvasHeight = window.innerHeight; 
 28  
 29     // if the caller supplied the container elm ID try to find it 
 30     var container; 
 31     if (containerID != null && typeof containerID != 'undefined') 
 32         container = document.getElementById(containerID); 
 33      
 34     // couldn't find it, so create it ourselves 
 35     if (container == null || typeof container == 'undefined') { 
 36         container = document.createElement( 'div' ); 
 37         document.body.appendChild( container ); 
 38     } 
 39     else { 
 40         canvasWidth = container.clientWidth; 
 41         canvasHeight = container.clientHeight; 
 42     } 
 43  
 44     // set up the camera 
 45     camera = new THREE.PerspectiveCamera(45, canvasWidth / canvasHeight, 0.1, 1000); 
 46     camera.position.set(0, 6, 6); 
 47     camera.lookAt(scene.position); 
 48     scene.add(camera); 
 49  
 50     // allocate the THREE.js renderer 
 51     renderer = new THREE.WebGLRenderer({antialias:true}); 
 52  
 53     // Set the background color of the renderer to black, with full opacity 
 54     renderer.setClearColor(0x000000, 1); 
 55  
 56     // Set the renderers size to the content areas size 
 57     renderer.setSize(canvasWidth, canvasHeight); 
 58  
 59     // Get the DIV element from the HTML document by its ID and append the renderer's DOM object 
 60     container.appendChild(renderer.domElement); 
 61      
 62     // Ambient light has no direction, it illuminates every object with the same 
 63     // intensity. If only ambient light is used, no shading effects will occur. 
 64     ambientLight = new THREE.AmbientLight(0x404040); 
 65     scene.add(ambientLight); 
 66  
 67     // Directional light has a source and shines in all directions, like the sun. 
 68     // This behaviour creates shading effects. 
 69     directionalLight = new THREE.PointLight(0xffffff); 
 70     directionalLight.position.set(250,250,250);  
 71     scene.add(directionalLight); 
 72 } 
 73  
 74 function orbitControls() { 
 75     // add the controls 
 76     controls = new THREE.OrbitControls( camera, renderer.domElement ); 
 77 } 
 78  
 79 //some constants 
 80 var        X_AXIS = 0; 
 81 var        Y_AXIS = 1; 
 82 var        Z_AXIS = 2; 
 83  
 84 console.log("X_AXIS " + X_AXIS); 
 85  
 86 // draw some axes 
 87 function drawAxis( axis, axisColor, axisHeight ) 
 88 { 
 89     var        AXIS_RADIUS   =    axisHeight/200.0; 
 90     var        AXIS_HEIGHT   =    axisHeight; 
 91     var        AXIS_STEP     =    axisHeight/20.0; 
 92     var        AXIS_SEGMENTS = 32; 
 93     var        AXIS_GRAY     = 0x777777; 
 94     var        AXIS_WHITE    = 0xEEEEEE; 
 95      
 96     //console.log("drawAxis " + axis + " ht: " +  AXIS_HEIGHT + ", " + AXIS_STEP + " color: " + axisColor); 
 97  
 98     for ( i=0; i<(AXIS_HEIGHT/AXIS_STEP); i++ ) 
 99     { 
100         //console.log("loop " +  i); 
101          
102         var pos = -AXIS_HEIGHT / 2 + i * AXIS_STEP; 
103  
104         if ((i & 1) == 0) 
105             curColor = axisColor; 
106         else if (pos < 0) 
107             curColor = AXIS_GRAY; 
108         else 
109             curColor = AXIS_WHITE; 
110          
111         //console.log(i + " pos: " + pos + " color: " + curColor); 
112          
113         var geometry = new THREE.CylinderGeometry( AXIS_RADIUS, AXIS_RADIUS, AXIS_STEP, AXIS_SEGMENTS );  
114         var material = new THREE.MeshLambertMaterial( {color: curColor} );  
115         var cylinder = new THREE.Mesh( geometry, material );  
116          
117         pos += AXIS_STEP/2.0; 
118         if (axis == X_AXIS) 
119         { 
120             cylinder.position.x = pos; 
121             cylinder.rotation.z = Math.PI/2; 
122         } 
123         else if (axis == Y_AXIS) 
124         { 
125             cylinder.rotation.y = Math.PI/2; 
126             cylinder.position.y = pos; 
127         } 
128         else 
129         {     
130             cylinder.position.z = pos; 
131             cylinder.rotation.x = Math.PI/2; 
132         } 
133          
134         scene.add( cylinder ); 
135     }; 
136 } 
137  
138 function drawAxes( height ) 
139 {     
140     console.log("X_AXIS: " + X_AXIS); 
141      
142     drawAxis(X_AXIS, 0xff0000, height); 
143     drawAxis(Y_AXIS, 0x00ff00, height); 
144     drawAxis(Z_AXIS, 0x0000ff, height); 
145 }
NEHE.css
  1 /* 
  2  * @author rkwright   /  www.geofx.com 
  3  */ 
  4   
  5  body { 
  6     /* Set the background color of the HTML page to black */ 
  7     background-color: #000000; 
  8  
  9     /* Hide oversized content. This prevents the scroll bars. */ 
 10     overflow: hidden; 
 11  
 12     /* Define the font and the color for the usage, which is an ordinary HTML overlay. */ 
 13     font-family: Monospace; 
 14     color: white; 
 15 }
Live example