12-vegetation-planes.html


<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>The Five Planets</title>
	<meta http-equiv="content-type" content="text/html;charset=utf-8" />
	<style>
        body {
			width:100%;
			height:100%;
			padding:0;
            margin:0;
            overflow:hidden;
        }
    </style>
	<link rel="stylesheet" type="text/css" href="../css/screen.css"/>
	
	<!-- LOAD JQUERY & REQUIERE -->
	<script src="../frameworks/require.min.js"></script>
    <script src="../frameworks/jquery-2.0.3.min.js"></script>
	
	<!-- LOAD THREE.JS -->
    <script src="../frameworks/three.min.js" defer></script>
	<script src="../frameworks/renders/projector.js" defer></script>
    <script src="../frameworks/loaders/DDSLoader.js" defer></script>
	<script src="../frameworks/loaders/MTLLoader.js" defer></script>
	<script src="../frameworks/loaders/OBJLoader.js" defer></script>
	<script src="../frameworks/loaders/ColladaLoader.js" defer></script>
	<script src="../frameworks/loaders/collada/Animation.js" defer></script>
	<script src="../frameworks/loaders/collada/AnimationHandler.js" defer></script>
	<script src="../frameworks/loaders/collada/KeyFrameAnimation.js" defer></script>
	
	<!-- LOAD DAT.GUI & STATS-->
    <script src="../frameworks/dat.gui.min.js" defer></script>
	<script src="../frameworks/stats.js" defer></script>
	
	<!-- GAME FILES-->
	<script src="../core/controls/controls_path_v01.js" defer></script>
    <script src="../core/world/world_v01.js" defer></script>
	<script src="../core/world/ground_v01.js" defer></script>
	<script src="../core/world/sky_v01.js" defer></script>

<script>

$(document).ready(function () {
	$WORLD.distance = 140;
	$WORLD.init3D({}, function () {
		$WORLD.map = {
		"x":256,
		"z":256,
		"ground": {
			"type":"basic",
			"texture":"../data/graphics/textures/terrain/grass1.jpg",
			"resX":2,
			"resY":2
		},
		"sky": {
			"type":"skysphere",
			"colorAmbient" : "rgb(90, 90, 90)",
			"intensityAmbient" : 0.5,
			"sunlightcolor" : "rgb(255, 255, 255)",
			"sunlightposition": {"x":10, "y":20, "z":0},
			"sunlightintensity" : 1,
			"texture":"../data/graphics/textures/sky/skydome.jpg",
			"fogColor": "rgb(255, 255, 255)",
			"fogNear":6,
			"fogFar":70
		} 
	};
	
	$WORLD.showStats();	
	$WORLD.drawGround();
	$WORLD.drawSky();


	var  scene=$WORLD.scene;

	var grassMeshes = [], grassGeometry, grassMaterial;

	var worldWidth = 50, worldDepth = 50,
	worldHalfWidth = worldWidth / 2, worldHalfDepth = worldDepth / 2;

	var grassHeight = 5, grassWidth = 2;

	var grassCount = 3000;
			
	grassGeometry = new THREE.PlaneGeometry( 2, 2, 1, 1 );
				
	var textureLoader= new THREE.TextureLoader();
	var grassMap = textureLoader.load("../data/graphics/textures/vegetation/grass.png");

	grassMaterial = new THREE.MeshBasicMaterial( { map: grassMap, alphaTest: 0.8, side: THREE.DoubleSide} );

	for ( var i = 0, l = grassCount; i < l; i=i+3 ) {
					grassMeshes[i] = new THREE.Mesh( grassGeometry, grassMaterial );
					grassMeshes[i].position.x = Math.random() * worldWidth;// - worldHalfWidth;
					grassMeshes[i].position.z = Math.random() * worldDepth;// - worldHalfDepth;
					grassMeshes[i].position.y = 1;
					grassMeshes[i].rotation.y = Math.random() * Math.PI;
					scene.add( grassMeshes[i] );
					grassMeshes[i+1] = new THREE.Mesh( grassGeometry, grassMaterial );
					grassMeshes[i+1].position.x = grassMeshes[i].position.x;
					grassMeshes[i+1].position.z = grassMeshes[i].position.z;
					grassMeshes[i+1].position.y = 1;
					grassMeshes[i+1].rotation.y = grassMeshes[i].rotation.y + Math.PI/3;
					scene.add( grassMeshes[i+1] );	
					grassMeshes[i+2] = new THREE.Mesh( grassGeometry, grassMaterial );
					grassMeshes[i+2].position.x = grassMeshes[i].position.x;
					grassMeshes[i+2].position.z = grassMeshes[i].position.z;
					grassMeshes[i+2].position.y = 1;
					grassMeshes[i+2].rotation.y = grassMeshes[i].rotation.y + Math.PI*2/3;
					scene.add( grassMeshes[i+2] );	
	}
	
	var path=new THREE.CatmullRomCurve3([
		new THREE.Vector3(0, 2, 25),
		new THREE.Vector3(25, 2, 50),
		new THREE.Vector3(25, 2, 25),
		new THREE.Vector3(25, 2, 0)
		])
	$WORLD.controls = new $CONTROLS.PathControls ($WORLD.camera, path, {"velocity":2});
	$WORLD.controls.showPath();
	$WORLD.addToListUpdate ($WORLD.controls);
	$WORLD.startAnimation();
	});
})
</script>
</head>
<body>
</body>
</html>

core/world/sky_v01.js


//****************************
// CREA EL CIELO, Y LAS LUCES
//****************************

$WORLD.sky= {
    update:function(delta){
        var p = $WORLD.controls.getPosition();
        $WORLD.sky.skyBox.position.set(p.x, 0, p.z);
    }    
};

$WORLD.drawSky = function () {
    var sky = $WORLD.map.sky;
    if (sky.type=="skybox"){
        $WORLD.drawSkybox(sky);
    } else if (sky.type=="skysphere" && sky.texture!="") {
        $WORLD.drawSkysphere(sky);
    } else {
        $WORLD.drawSkysphereNoImg(sky);
    }

    //CREAR LA LUZ DE AMBIENTE
    $WORLD.ambientLight.color = new THREE.Color(sky.colorAmbient);
    $WORLD.ambientLight.intensity = sky.intensityAmbient;

    //CREAR LA LUZ DEL SOL
    var light = new THREE.DirectionalLight(sky.sunlightcolor, sky.sunlightintensity);
    light.castShadow = true;
    light.shadow.mapSize.width = 2 * 512; 
    light.shadow.mapSize.height = 2 * 512;
    light.shadow.camera.near = 0;
    light.shadow.camera.far = 50; //ALTURA DEL CUBO

    //DES DEL PUNTO CENTRAL INDICAN EL CUADRADO.
    light.shadow.camera.top = 25; //X
    light.shadow.camera.right = 25;
    light.shadow.camera.left = -25;
    light.shadow.camera.bottom = -25;

    light.shadow.camera.visible = true;
    $WORLD.sky.skyBox.add(light);
    
    light.position.set(sky.sunlightposition.x, sky.sunlightposition.y, sky.sunlightposition.z); 
    light.target = $WORLD.sky.skyBox;
    
    $WORLD.scene.fog.near = sky.fogNear;
    if (sky.fogFar > 0 && ($WORLD.distance - $WORLD.distance / 4) > sky.fogFar) {
        $WORLD.scene.fog.far = sky.fogFar;
    }
    $WORLD.scene.fog.color = new THREE.Color(sky.fogColor);
    $WORLD.renderer.setClearColor($WORLD.scene.fog.color, 1);
    
    $WORLD.addToListUpdate ($WORLD.sky);
};

$WORLD.drawSkybox=function (sky){
    var cubemap = new THREE.CubeTextureLoader().load( sky.texture );
    cubemap.format = THREE.RGBFormat;
        
    var shader = THREE.ShaderLib['cube']; 
    shader.uniforms['tCube'].value = cubemap; 

    var skyBoxMaterial = new THREE.ShaderMaterial( {
    fragmentShader: shader.fragmentShader,
    vertexShader: shader.vertexShader,
    uniforms: shader.uniforms,
    depthWrite: false,
    side: THREE.BackSide
    });
    
    var distance=($WORLD.distance*2-20);
    var c = Math.pow ((distance*distance)/2,0.5);
    var skyBox = new THREE.Mesh(  new THREE.BoxGeometry(c, c, c),  skyBoxMaterial);
    $WORLD.scene.add(skyBox);
    $WORLD.sky.skyBox = skyBox;

};

$WORLD.drawSkysphere=function (sky){
    var skyTexture = $WORLD.textureLoader.load(sky.texture);
    var geometry = new THREE.SphereGeometry($WORLD.distance - 10, 30, 20);

    var uniforms = {
        texture: { type: 't', value: skyTexture }
    };
    var material = new THREE.ShaderMaterial({
        uniforms: uniforms,
        vertexShader: "varying vec2 vUV;" +
        "\n" +
        "void main() {  " +
        "    vUV = uv;" +
        "    vec4 pos = vec4(position, 1.0);" +
        "    gl_Position = projectionMatrix * modelViewMatrix * pos;" +
        "}",
        fragmentShader: "uniform sampler2D texture;" +
        "varying vec2 vUV;" +
        "" +
        "    void main() {" +
        "        vec4 sample = texture2D(texture, vUV);" +
        "        gl_FragColor = vec4(sample.xyz, sample.w);" +
        "    }"
    });

    var skyBox = new THREE.Mesh(geometry, material);
    skyBox.scale.set(-1, 1, 1);
    skyBox.rotation.order = 'XZY';
    skyBox.renderDepth = $WORLD.distance;
    $WORLD.scene.add(skyBox);
    $WORLD.sky.skyBox = skyBox;
};

$WORLD.drawSkysphereNoImg=function (sky){

    var vertexShader ="varying vec3 vWorldPosition;"+
    " "+
    "void main() {"+
    "    vec4 worldPosition = modelMatrix * vec4( position, 1.0 );"+
    "    vWorldPosition = worldPosition.xyz;"+ //xyz
    " "+
    "    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );"+
    "}";

    var fragmentShader ="uniform vec3 topColor;"+
    "uniform vec3 bottomColor;"+
    "uniform float offset;"+
    "uniform float exponent;"+
    " "+
    "varying vec3 vWorldPosition;"+
    " "+
    "void main() {"+
    "    float h = normalize( vWorldPosition + offset ).y;"+
    "    gl_FragColor = vec4( mix( bottomColor, topColor, max( pow( h, exponent ), 0.0 ) ), 1.0 );"+
    "}";

    var uniforms = {
            topColor: {type: "c", value: new THREE.Color(sky.topColor)}, bottomColor: {type: "c", value: new THREE.Color(sky.bottomColor)},
            offset: {type: "f", value: 0}, exponent: {type: "f", value: 0.5} 
    }
    var skyMaterial = new THREE.ShaderMaterial({vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: uniforms, side: THREE.BackSide, fog: false});
     
    var skyBox = new THREE.Mesh( new THREE.SphereGeometry($WORLD.distance - 10, 30, 20), skyMaterial);

    skyBox.rotation.order = 'XZY';
    skyBox.renderDepth = $WORLD.distance;
    
    $WORLD.scene.add(skyBox);
    $WORLD.sky.skyBox = skyBox;
}

core/world/ground_v01.js


//****************************
// CREA EL SUELO DEL MUNDO
//****************************

$WORLD.drawGround = function () {
    var map = $WORLD.map;
    var groundTexture = $WORLD.textureLoader.load(map.ground.texture);
    var x = $WORLD.distance * 2.25 + map.x
    var z = $WORLD.distance * 2.25 + map.z
    groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
    groundTexture.repeat.set(x / 2, z / 2); 
    groundTexture.anisotropy = 16;
    var groundMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff, map: groundTexture });
    var mesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(x, z), groundMaterial);
    mesh.position.y = 0;
    mesh.position.x = map.x / 2;
    mesh.position.z = map.z / 2;
    mesh.rotation.x = - Math.PI / 2;
    mesh.receiveShadow = true;
    $WORLD.scene.add(mesh);
}

core/world/world_v01.js


//*******************************
//DEFINIR EL MUNDO
//*******************************
var $WORLD = $WORLD || {};
$WORLD.distance = 80;
$WORLD.renderer = null;
$WORLD.scene = null;
$WORLD.clock = null;
$WORLD.map=null;
$WORLD.controls=null;
$WORLD._objUpdate = [];

$WORLD.init3D=function(oPars, fSuc, fFail) {

    var renderer = new THREE.WebGLRenderer();
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    $WORLD.renderer = renderer;
    $WORLD.scene = new THREE.Scene();
    
    $WORLD.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, $WORLD.distance);
    $WORLD.camera.position.set(0, 2, 0);
    $WORLD.camera.lookAt(new THREE.Vector3(0,2,0) );
    
    $WORLD.clock = new THREE.Clock();
    $WORLD.controls={
        getPosition: function(){
            return $WORLD.camera.position;
        }
    } 

    $WORLD.textureLoader = new THREE.TextureLoader();
    
    $WORLD.ambientLight = new THREE.AmbientLight(0xffffff,1);
    $WORLD.scene.add($WORLD.ambientLight);
 
    $WORLD.scene.fog = new THREE.Fog(0xffffff, 5, ($WORLD.distance - $WORLD.distance / 4)); //niebla
    $WORLD.renderer.setClearColor($WORLD.scene.fog.color, 1);
    
    window.addEventListener('resize', onWindowResize, false);
    THREE.Loader.Handlers.add(/\.dds$/i, new THREE.DDSLoader());
    fSuc();
}

$WORLD.showStats=function() {
    if (!($WORLD.stats)) {
        $WORLD.stats = new Stats();
        $WORLD.stats.setMode(0);
        document.body.appendChild($WORLD.stats.domElement);
        $WORLD.addToListUpdate($WORLD.stats);
    };

}

$WORLD.startAnimation = function () {
    $WORLD.animate();
}

$WORLD.pauseAnimation = function () {
    window.cancelAnimationFrame( $WORLD.idAnim );
}

$WORLD.addToListUpdate = function (obj) {
    $WORLD._objUpdate.push(obj);
}

$WORLD.animate = function () {
    $WORLD.idAnim = requestAnimationFrame($WORLD.animate);
    var delta = $WORLD.clock.getDelta();
    for (var i = 0; i < $WORLD._objUpdate.length; i++) {
        $WORLD._objUpdate[i].update(delta);
    };
    THREE.AnimationHandler.update(delta);
    $WORLD.renderer.render($WORLD.scene, $WORLD.camera);

};

function onWindowResize() {
    $WORLD.camera.aspect = window.innerWidth / window.innerHeight;
    $WORLD.camera.updateProjectionMatrix();
    $WORLD.renderer.setSize(window.innerWidth, window.innerHeight);
}

core/controls/controls_path_v01.js


var $CONTROLS = $CONTROLS || {};

$CONTROLS.PathControls = function (object, path, prop) {
    this.path=path;
    this._object=object;
    this._pos=0;
    this.velocity=1; //unidades por segundo
    if (prop && prop.velocity){
        this.velocity=prop.velocity;
    }
    this._factor=this.velocity/this.path.getLength();
};

$CONTROLS.PathControls.prototype.update = function ( delta ) {
    this._object.position.copy(this.path.getPointAt(this._pos));
    this._pos += (this._factor  * delta);
    if (this._pos > 1) {this._pos = 0;};
    this._object.lookAt(this.path.getPointAt(this._pos));
}

$CONTROLS.PathControls.prototype.showPath = function ( ) {
    var geometry = new THREE.Geometry();
    var points = this.path.getPoints(50);

    var material = new THREE.LineBasicMaterial({
        color: 0xff00f0
    });

    geometry.vertices = points;
    var line = new THREE.Line(geometry, material);
    line.position.set(0,0.25,0)
    $WORLD.scene.add(line);
}

$CONTROLS.PathControls.prototype.getPosition = function ( ) {
    return this._object.position;
}