|
@@ -0,0 +1,301 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="en">
|
|
|
+ <head>
|
|
|
+ <title>three.js webgl - geometry - minecraft - Oculus Rift</title>
|
|
|
+ <meta charset="utf-8">
|
|
|
+ <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
|
|
|
+ <style>
|
|
|
+ body {
|
|
|
+ color: rgb(168, 148, 0);
|
|
|
+ font-family:Monospace;
|
|
|
+ font-size:13px;
|
|
|
+ text-align:center;
|
|
|
+
|
|
|
+ background-color: #bfd1e5;
|
|
|
+ margin: 0px;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ #info {
|
|
|
+ position: absolute;
|
|
|
+ top: 0px; width: 100%;
|
|
|
+ padding: 5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ a {
|
|
|
+
|
|
|
+ color: #a06851;
|
|
|
+ }
|
|
|
+
|
|
|
+ #oldie {
|
|
|
+ background:rgb(100,0,0) !important;
|
|
|
+ color:#fff !important;
|
|
|
+ margin-top:10em !important;
|
|
|
+ }
|
|
|
+ #oldie a { color:#fff }
|
|
|
+
|
|
|
+ </style>
|
|
|
+ </head>
|
|
|
+ <body>
|
|
|
+
|
|
|
+ <div id="container"><br /><br /><br /><br /><br />Generating world...</div>
|
|
|
+ <div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - <a href="http://www.minecraft.net/" target="_blank">minecraft</a> demo [oculus rift]. featuring <a href="http://painterlypack.net/" target="_blank">painterly pack</a><br />(left click: forward, right click: backward, o,p: distortion [<span id='distVal'>0</span>], k,l; eye separation [<span id='sepVal'>0</span>], n,m; fov [<span id='fovVal'>0</span>])</div>
|
|
|
+
|
|
|
+ <script src="../build/three.min.js"></script>
|
|
|
+
|
|
|
+ <script src="js/controls/FirstPersonControls.js"></script>
|
|
|
+
|
|
|
+ <script src="js/ImprovedNoise.js"></script>
|
|
|
+ <script src="js/Detector.js"></script>
|
|
|
+ <script src="js/effects/OculusRiftEffect.js"></script>
|
|
|
+ <script src="js/libs/stats.min.js"></script>
|
|
|
+
|
|
|
+ <script>
|
|
|
+
|
|
|
+ if ( ! Detector.webgl ) {
|
|
|
+
|
|
|
+ Detector.addGetWebGLMessage();
|
|
|
+ document.getElementById( 'container' ).innerHTML = "";
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ var container, stats;
|
|
|
+
|
|
|
+ var camera, controls, scene, renderer;
|
|
|
+
|
|
|
+ var mesh;
|
|
|
+
|
|
|
+ var worldWidth = 128, worldDepth = 128,
|
|
|
+ worldHalfWidth = worldWidth / 2, worldHalfDepth = worldDepth / 2,
|
|
|
+ data = generateHeight( worldWidth, worldDepth );
|
|
|
+
|
|
|
+ var clock = new THREE.Clock();
|
|
|
+
|
|
|
+ init();
|
|
|
+ animate();
|
|
|
+
|
|
|
+ function init() {
|
|
|
+
|
|
|
+ container = document.getElementById( 'container' );
|
|
|
+
|
|
|
+ camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 20000 );
|
|
|
+ camera.position.y = getY( worldHalfWidth, worldHalfDepth ) * 100 + 100;
|
|
|
+
|
|
|
+ controls = new THREE.FirstPersonControls( camera );
|
|
|
+
|
|
|
+ controls.movementSpeed = 1000;
|
|
|
+ controls.lookSpeed = 0.125;
|
|
|
+ controls.lookVertical = true;
|
|
|
+
|
|
|
+ scene = new THREE.Scene();
|
|
|
+
|
|
|
+ // sides
|
|
|
+
|
|
|
+ var matrix = new THREE.Matrix4();
|
|
|
+
|
|
|
+ var pxGeometry = new THREE.PlaneGeometry( 100, 100 );
|
|
|
+ pxGeometry.faces[ 0 ].materialIndex = 1;
|
|
|
+ pxGeometry.applyMatrix( matrix.makeRotationY( Math.PI / 2 ) );
|
|
|
+ pxGeometry.applyMatrix( matrix.makeTranslation( 50, 0, 0 ) );
|
|
|
+
|
|
|
+ var nxGeometry = new THREE.PlaneGeometry( 100, 100 );
|
|
|
+ nxGeometry.faces[ 0 ].materialIndex = 1;
|
|
|
+ nxGeometry.applyMatrix( matrix.makeRotationY( - Math.PI / 2 ) );
|
|
|
+ nxGeometry.applyMatrix( matrix.makeTranslation( - 50, 0, 0 ) );
|
|
|
+
|
|
|
+ var pyGeometry = new THREE.PlaneGeometry( 100, 100 );
|
|
|
+ pyGeometry.faces[ 0 ].materialIndex = 0;
|
|
|
+ pyGeometry.applyMatrix( matrix.makeRotationX( - Math.PI / 2 ) );
|
|
|
+ pyGeometry.applyMatrix( matrix.makeTranslation( 0, 50, 0 ) );
|
|
|
+
|
|
|
+ var pzGeometry = new THREE.PlaneGeometry( 100, 100 );
|
|
|
+ pzGeometry.faces[ 0 ].materialIndex = 1;
|
|
|
+ pzGeometry.applyMatrix( matrix.makeTranslation( 0, 0, 50 ) );
|
|
|
+
|
|
|
+ var nzGeometry = new THREE.PlaneGeometry( 100, 100 );
|
|
|
+ nzGeometry.faces[ 0 ].materialIndex = 1;
|
|
|
+ nzGeometry.applyMatrix( matrix.makeRotationY( Math.PI ) );
|
|
|
+ nzGeometry.applyMatrix( matrix.makeTranslation( 0, 0, -50 ) );
|
|
|
+ //
|
|
|
+
|
|
|
+ var geometry = new THREE.Geometry();
|
|
|
+ var dummy = new THREE.Mesh();
|
|
|
+
|
|
|
+ for ( var z = 0; z < worldDepth; z ++ ) {
|
|
|
+
|
|
|
+ for ( var x = 0; x < worldWidth; x ++ ) {
|
|
|
+
|
|
|
+ var h = getY( x, z );
|
|
|
+
|
|
|
+ dummy.position.x = x * 100 - worldHalfWidth * 100;
|
|
|
+ dummy.position.y = h * 100;
|
|
|
+ dummy.position.z = z * 100 - worldHalfDepth * 100;
|
|
|
+
|
|
|
+ var px = getY( x + 1, z );
|
|
|
+ var nx = getY( x - 1, z );
|
|
|
+ var pz = getY( x, z + 1 );
|
|
|
+ var nz = getY( x, z - 1 );
|
|
|
+
|
|
|
+ dummy.geometry = pyGeometry;
|
|
|
+ THREE.GeometryUtils.merge( geometry, dummy );
|
|
|
+
|
|
|
+ if ( ( px != h && px != h + 1 ) || x == 0 ) {
|
|
|
+
|
|
|
+ dummy.geometry = pxGeometry;
|
|
|
+ THREE.GeometryUtils.merge( geometry, dummy );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ( nx != h && nx != h + 1 ) || x == worldWidth - 1 ) {
|
|
|
+
|
|
|
+ dummy.geometry = nxGeometry;
|
|
|
+ THREE.GeometryUtils.merge( geometry, dummy );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ( pz != h && pz != h + 1 ) || z == worldDepth - 1 ) {
|
|
|
+
|
|
|
+ dummy.geometry = pzGeometry;
|
|
|
+ THREE.GeometryUtils.merge( geometry, dummy );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ( nz != h && nz != h + 1 ) || z == 0 ) {
|
|
|
+
|
|
|
+ dummy.geometry = nzGeometry;
|
|
|
+ THREE.GeometryUtils.merge( geometry, dummy );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ var textureGrass = THREE.ImageUtils.loadTexture( 'textures/minecraft/grass.png' );
|
|
|
+ textureGrass.magFilter = THREE.NearestFilter;
|
|
|
+ textureGrass.minFilter = THREE.LinearMipMapLinearFilter;
|
|
|
+
|
|
|
+ var textureGrassDirt = THREE.ImageUtils.loadTexture( 'textures/minecraft/grass_dirt.png' );
|
|
|
+ textureGrassDirt.magFilter = THREE.NearestFilter;
|
|
|
+ textureGrassDirt.minFilter = THREE.LinearMipMapLinearFilter;
|
|
|
+
|
|
|
+ var material1 = new THREE.MeshLambertMaterial( { map: textureGrass, ambient: 0xbbbbbb } );
|
|
|
+ var material2 = new THREE.MeshLambertMaterial( { map: textureGrassDirt, ambient: 0xbbbbbb } );
|
|
|
+
|
|
|
+ var mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( [ material1, material2 ] ) );
|
|
|
+ scene.add( mesh );
|
|
|
+
|
|
|
+ var ambientLight = new THREE.AmbientLight( 0xcccccc );
|
|
|
+ scene.add( ambientLight );
|
|
|
+
|
|
|
+ var directionalLight = new THREE.DirectionalLight( 0xffffff, 2 );
|
|
|
+ directionalLight.position.set( 1, 1, 0.5 ).normalize();
|
|
|
+ scene.add( directionalLight );
|
|
|
+
|
|
|
+ renderer = new THREE.WebGLRenderer();
|
|
|
+ renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
+ effect = new THREE.OculusRiftEffect( renderer );
|
|
|
+ effect.setSize( window.innerWidth, window.innerHeight );
|
|
|
+
|
|
|
+ // Right Oculus Parameters are yet to be determined
|
|
|
+ effect.separation = 20;
|
|
|
+ effect.distortion = 0.1;
|
|
|
+ effect.fov = 110;
|
|
|
+
|
|
|
+
|
|
|
+ document.getElementById( 'distVal' ).innerHTML = effect.distortion.toFixed(2);
|
|
|
+ document.getElementById( 'sepVal' ).innerHTML = effect.separation;
|
|
|
+ document.getElementById( 'fovVal' ).innerHTML = effect.fov;
|
|
|
+
|
|
|
+
|
|
|
+ container.innerHTML = "";
|
|
|
+
|
|
|
+ container.appendChild( renderer.domElement );
|
|
|
+
|
|
|
+ stats = new Stats();
|
|
|
+ stats.domElement.style.position = 'absolute';
|
|
|
+ stats.domElement.style.top = '0px';
|
|
|
+ container.appendChild( stats.domElement );
|
|
|
+
|
|
|
+ // GUI
|
|
|
+ window.addEventListener( 'resize', onWindowResize, false );
|
|
|
+ document.addEventListener( 'keydown', keyPressed, false );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function onWindowResize() {
|
|
|
+
|
|
|
+ camera.aspect = window.innerWidth / window.innerHeight;
|
|
|
+ camera.updateProjectionMatrix();
|
|
|
+
|
|
|
+ effect.setSize( window.innerWidth, window.innerHeight );
|
|
|
+
|
|
|
+ controls.handleResize();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function keyPressed (event) {
|
|
|
+ switch ( event.keyCode ) {
|
|
|
+ case 79: /*O*/ effect.distortion -= 0.01; document.getElementById( 'distVal' ).innerHTML = effect.distortion.toFixed(2); break;
|
|
|
+ case 80: /*P*/ effect.distortion += 0.01; document.getElementById( 'distVal' ).innerHTML = effect.distortion.toFixed(2); break;
|
|
|
+ case 75: /*K*/ effect.separation -= 1; document.getElementById( 'sepVal' ).innerHTML = effect.separation; break;
|
|
|
+ case 76: /*L*/ effect.separation += 1; document.getElementById( 'sepVal' ).innerHTML = effect.separation; break;
|
|
|
+ case 78: /*N*/ effect.fov -= 1; document.getElementById( 'fovVal' ).innerHTML = effect.fov; break;
|
|
|
+ case 77: /*M*/ effect.fov += 1; document.getElementById( 'fovVal' ).innerHTML = effect.fov; break;
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function generateHeight( width, height ) {
|
|
|
+
|
|
|
+ var data = [], perlin = new ImprovedNoise(),
|
|
|
+ size = width * height, quality = 2, z = Math.random() * 100;
|
|
|
+
|
|
|
+ for ( var j = 0; j < 4; j ++ ) {
|
|
|
+
|
|
|
+ if ( j == 0 ) for ( var i = 0; i < size; i ++ ) data[ i ] = 0;
|
|
|
+
|
|
|
+ for ( var i = 0; i < size; i ++ ) {
|
|
|
+
|
|
|
+ var x = i % width, y = ( i / width ) | 0;
|
|
|
+ data[ i ] += perlin.noise( x / quality, y / quality, z ) * quality;
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ quality *= 4
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return data;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function getY( x, z ) {
|
|
|
+
|
|
|
+ return ( data[ x + z * worldWidth ] * 0.2 ) | 0;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
+ function animate() {
|
|
|
+
|
|
|
+ requestAnimationFrame( animate );
|
|
|
+
|
|
|
+ render();
|
|
|
+ stats.update();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function render() {
|
|
|
+
|
|
|
+ controls.update( clock.getDelta() );
|
|
|
+ effect.render( scene, camera );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ </script>
|
|
|
+
|
|
|
+ </body>
|
|
|
+</html>
|