13-map.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"/>
	<link rel="stylesheet" type="text/css" href="../css/ui.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.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 src="../core/world/nature_v01.js" defer></script>
	<script src="../core/entities/template3D_v01.js" defer></script>
	<script src="../core/entities/entity3D_v01.js" defer></script>

<script>

$(document).ready(function () {
	$WORLD.distance = 130;
	$WORLD.init3D({}, function () {
		$RG.templates={
			"castle_wall_a": {"model" : "../data/models/castle/wall_a.obj"},
			"castle_wall_b": {"model" : "../data/models/castle/wall_b.obj"},
			"castle_wall_c": {"model" : "../data/models/castle/wall_c.obj"},
			"castle_gate_wall": {"model" : "../data/models/castle/gate_wall.obj"},
			"castle_metal_gate": {"model" : "../data/models/castle/metal_gate.obj"},
			"castle_tower1": {"model" : "../data/models/castle/tower1.obj"},
			"castle_tower2": {"model" : "../data/models/castle/tower2.obj"},
			"castle_tower3": {"model" : "../data/models/castle/tower3.obj"},
			"house1": {"model": "../data/models/houses01/house1-01.obj"},
			"house2": {"model": "../data/models/houses01/house1-02.obj"},
			"house3": {"model": "../data/models/houses01/house1-03.obj"},
			"house4": {"model": "../data/models/houses01/house1-04.obj"},
			"well1": {"model": "../data/models/houses01/well-01.obj"},
			"bench1": {"model": "../data/models/houses01/bench-01.obj"},
			"house17": {"model": "../data/models/houses05/house5-01.obj"},
			"house18": {"model": "../data/models/houses05/house5-02.obj"},
			"house19": {"model": "../data/models/houses05/house5-03.obj"},
			"house20": {"model": "../data/models/houses05/house5-04.obj"},
			"house21": {"model": "../data/models/houses05/house5-05.obj"},
			"house22": {"model": "../data/models/houses06/house6-01.obj"},
			"house23": {"model": "../data/models/houses06/house6-02.obj"},
			"house25": {"model": "../data/models/houses06/house6-03.obj"},
			
			"tree07": {"model": "../data/graphics/textures/vegetation/tree07.png","width":10.2,"height":14.53,"type":3}

		}
		$WORLD.map = {
		"x":256,
		"z":256,
		"startPosX":126,
		"startPosZ":145,
		"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(225, 225, 225)",
			"fogNear":70,
			"fogFar":130
		},
			
		"nature": {
				"type":"basic",
				"patterns": {
					"bushes":{
						"freqX":5,
						"freqZ":5,
						"elements":[
							{"object":"../data/graphics/textures/vegetation/grass.png","width":1.5,"height":1.5},
							{"object":"../data/graphics/textures/vegetation/struik.png","width":1.5,"height":1.5}
						]
					},
					"forest":{
						"freqX":10,
						"freqZ":10,
						"elements":[
							{"object":"../data/graphics/textures/vegetation/tree01.png","width":8.75,"height":8.91},
							{"object":"../data/graphics/textures/vegetation/tree02.png","width":10,"height":9.84},
							{"object":"../data/graphics/textures/vegetation/tree03.png","width":9.59,"height":8.65},
							{"object":"../data/graphics/textures/vegetation/tree04.png","width":6.1,"height":8.65},
							{"object":"../data/graphics/textures/vegetation/tree05.png","width":10,"height":7.66},
							{"object":"../data/graphics/textures/vegetation/tree06.png","width":8.94,"height":13.9},
							{"object":"../data/graphics/textures/vegetation/tree07.png","width":10.2,"height":14.53}
						]
					},
					"hightTrees":{
						"freqX":12,
						"freqZ":12,
						"elements":[
							{"object":"../data/graphics/textures/vegetation/tree06.png","width":10,"height":20.68},
							{"object":"../data/graphics/textures/vegetation/tree07.png","width":12,"height":22.43}
						]
					}
					
				},
				"zones": [
					{"pattern":"forest","minX":0,"minZ":50,"maxZ":260,"maxX":114},
					{"pattern":"bushes","minX":20,"minZ":50,"maxZ":260,"maxX":117},
					
					{"pattern":"hightTrees","minX":110,"minZ":40,"maxZ":110,"maxX":200},
					{"pattern":"bushes","minX":110,"minZ":80,"maxZ":113,"maxX":140},
					
					{"pattern":"hightTrees","minX":0,"minZ":217,"maxZ":280,"maxX":230}
				]
			
		 }, 
		
		 "map3D": [
			{ "template": "castle_wall_c", "x": 214, "z": 110, "rY": -90 , "coment":"Size X:120-230, z:110-215"},
			{ "template": "castle_tower2", "x": 210, "z": 110 },
			{ "template": "castle_wall_a", "x": 199, "z": 110, "rY": -90 },
			{ "template": "castle_tower1", "x": 188, "z": 110, "rY": -90  },
			{ "template": "castle_gate_wall", "x": 177, "z": 110, "rY": -90 },
			{ "template": "castle_metal_gate", "x": 177, "z": 110, "rY": -90 },
			{ "template": "castle_tower1", "x": 166, "z": 110, "rY": -90  },
			{ "template": "castle_wall_a", "x": 155, "z": 110, "rY": -90 },
			{ "template": "castle_tower2", "x": 143, "z": 110 },

			{ "template": "castle_wall_c", "x": 120, "z": 129},
			{ "template": "castle_tower1", "x": 120, "z": 134},
			{ "template": "castle_gate_wall", "x": 120, "z": 145},
			{ "template": "castle_metal_gate", "x": 120, "z": 145, "y":2.5},
			{ "template": "castle_tower1", "x": 120, "z": 156},
			{ "template": "castle_wall_b", "x": 120, "z": 173},
			{ "template": "castle_tower3", "x": 120, "z": 192},
			{ "template": "castle_wall_c", "x": 140, "z": 215, "rY": 90},

			{ "template": "castle_tower2", "x": 144, "z": 215},
			{ "template": "castle_wall_b", "x": 157, "z": 215, "rY": 90 },
			{ "template": "castle_tower2", "x": 176, "z": 215},
			{ "template": "castle_wall_b", "x": 190, "z": 215, "rY": 90 },
			{ "template": "castle_tower2", "x": 210, "z": 215},
			{ "template": "castle_wall_c", "x": 233, "z": 199, "rY": 180 },
	
			{ "template": "castle_tower2", "x": 233, "z": 132},
			{ "template": "castle_wall_b", "x": 233, "z": 150, "rY": 180 },
			{ "template": "castle_tower2", "x": 233, "z": 165},
			{ "template": "castle_wall_b", "x": 233, "z": 185, "rY": 180 },
			{ "template": "castle_tower2", "x": 233, "z": 199},

			{ "template": "house1", "x": 155, "z": 150, "rY": -25,  "comment" : "houses01" },
			{ "template": "well1", "x": 135, "z": 146, "rY": -45  },
			{ "template": "bench1", "x": 145, "z": 153, "rY": -25 },
			{ "template": "house22", "x": 134, "z": 130,"rY": 110 },
			{ "template": "house23", "x": 150, "z": 125,"rY": 45 },
			{ "template": "house4", "x": 170, "z": 132, "rY": -25},

			{ "template": "house17", "x": 135, "z": 162, "rY": -100,  "comment" : "houses05" },
			{ "template": "house18", "x": 154, "z": 172,"rY": -45},
			{ "template": "house19", "x": 170, "z": 170,"rY": -55 },
			{ "template": "house20", "x": 174, "z": 155,"rY": -35 },
			{ "template": "house21", "x": 178, "z": 142,"rY": 45 },

			{ "template": "house22", "x": 133, "z": 180,"rY": 200, "comment" : "houses06" },
			{ "template": "house3", "x": 148, "z": 190, "rY": -15 },
			{ "template": "house2", "x": 168, "z": 190, "rY": 20 },
			{ "template": "house25", "x": 185, "z": 190, "rY": -5 },
			
			{ "template": "tree07", "x": 145, "z": 141 },
			{ "template": "tree07", "x": 146, "z": 166 },
			{ "template": "tree07", "x": 135, "z": 196 }

		]
	};
		
	$WORLD.showStats();		
	$WORLD.drawGround();
	$WORLD.drawSky();
	$WORLD.drawNature();
		
	$RG.loadTemplates( function() {

		for (var i=0;i<$WORLD.map.map3D.length;i++){
			var props=$WORLD.map.map3D[i];
			var ent=new $RG.Entity3D(props);
			ent.addToWorld();
		};
			
		var path=new THREE.CatmullRomCurve3([
            new THREE.Vector3(96, 2, 131), new THREE.Vector3(102, 2, 142), new THREE.Vector3(108, 2, 145), 
			new THREE.Vector3(120, 2, 145), new THREE.Vector3(126, 2, 144), new THREE.Vector3(134, 2, 140),
            new THREE.Vector3(143, 2, 136), new THREE.Vector3(148, 2, 136), new THREE.Vector3(150, 2, 136),
            new THREE.Vector3(150, 2, 140), new THREE.Vector3(143, 2, 148), new THREE.Vector3(139, 2, 153), 
            new THREE.Vector3(141, 2, 156), new THREE.Vector3(144, 2, 159), new THREE.Vector3(145, 2, 162), 
			new THREE.Vector3(143, 2, 160), new THREE.Vector3(142, 2, 182), new THREE.Vector3(134, 2, 195),
			new THREE.Vector3(127, 2, 187), new THREE.Vector3(124, 2, 178), new THREE.Vector3(127, 2, 171), 
			new THREE.Vector3(128, 2, 169), new THREE.Vector3(126, 2, 167), new THREE.Vector3(127, 2, 150), 
			new THREE.Vector3(124, 2, 146), new THREE.Vector3(121, 2, 146), new THREE.Vector3(114, 2, 145), 
			new THREE.Vector3(94, 2, 133), new THREE.Vector3(96, 2, 131)
		]);
		$WORLD.controls = new $CONTROLS.PathControls ($WORLD.camera, path, {"velocity":3});
		$WORLD.addToListUpdate ($WORLD.controls);

		$WORLD.startAnimation();
	});
  });
})
			
</script>
</head>
<body>
</body>
</html>

core/world/template3D_v01.js


var $RG = $RG || {};
$RG.templates=[];

$RG.Types = $RG.Types || {};
$RG.Types.type3D = { "OBJ": 0, "DAE":1, "JSON":2, "SPRITE":3 };

$RG.loadTemplates = function(fSuc, fFail, fProgress) {
	var i=0;
	var list=Object.keys($RG.templates);
	var _load = function () {
		if (list.length==i) {
			fSuc();
			return;
		}
		var ent=$RG.templates[list[i]].template3D=new $RG.Template3D(list[i]);
		if (fProgress) {fProgress(list[i],i+1,list.length);}
		i++;
		ent.load({},_load, fFail);
	}
	_load();
};

//CLASSE: Template3D    
$RG.Template3D = function (id) {
        this.id = id;
		this._template=$RG.templates[id];
        this.isReady = false;
        this.mesh = null; 
};

$RG.Template3D.prototype.load = function (oPars, fSuc, fFail) {
	var temp=this._template;
	if (!("type" in temp)) temp.type = $RG.Types.type3D.OBJ;
	if (temp.type == $RG.Types.type3D.OBJ) {
		this._loadOBJ(oPars,fSuc,fFail);
	} else if (temp.type == $RG.Types.type3D.DAE) {
		this._loadDAE(oPars,fSuc,fFail);
	} else if (temp.type == $RG.Types.type3D.SPRITE) {
		this._loadSPRITE(oPars,fSuc,fFail);
	} else {
		fFail();
	}
}

$RG.Template3D.prototype._loadOBJ = function (oPars, fSuc, fFail) {
        var $O = this;
        var onProgress = function (xhr) {    };
        var onError = function (xhr) { if (fFail) { fFail($O); } };
        var mtlLoader = new THREE.MTLLoader();
        var pathArray = $O._template.model.split('/');
        var mP = '';
        for (var i = 0; i < pathArray.length-1; i++) {
            mP += pathArray[i];
            mP += "/";
        }
        var model = pathArray[pathArray.length - 1];
        mtlLoader.setPath(mP);
		model=model.substr(0,model.length - 4)
        mtlLoader.load(model + '.mtl', function (materials) {
            materials.preload();
            var objLoader = new THREE.OBJLoader();
            objLoader.setMaterials(materials);
            objLoader.setPath(mP);
            objLoader.load(model + '.obj', function (object) {
                object.traverse(function (child) {
                    if (child instanceof THREE.Mesh) {
                        child.castShadow = true;
                    }
                });
                $O.mesh = object;
				$O.mesh.castShadow = true;
                $O.isReady = true;
                if (fSuc) { fSuc($O); }

            }, onProgress, onError);

        }, onProgress, onError);
};

$RG.Template3D.prototype._loadDAE = function (oPars, fSuc, fFail) {
	var $O = this;
	var temp=$O._template;
    var loader = new THREE.ColladaLoader();
	var onProgress = function (xhr) {    };
    var onError = function (xhr) { if (fFail) { fFail($O); } };
    loader.load(temp.model, function (collada) {
		var object = collada.scene;
		var mesh=null;
		object.traverse(function (child) {
			if (child instanceof THREE.Mesh) {
				child.castShadow = true;
				mesh=child;
               }
		});

		if (temp.scale) {
			mesh.scale.x = temp.scale.x;
			mesh.scale.y = temp.scale.y;
			mesh.scale.z = temp.scale.z; //Corregir escala
		}
		if (temp.rotate) {
			if (temp.rotate.x) {
				mesh.rotateX (temp.rotate.x * Math.PI / 180);
			};
			if (temp.rotate.y) {
				mesh.rotateY (temp.rotate.y * Math.PI / 180);
			};
			if (temp.rotate.z) {
				mesh.rotateZ (temp.rotate.z * Math.PI / 180);
			}//Corregir rotación
		}
		$O.mesh = object;
		$O.isReady = true;
		fSuc(mesh);
    }, onProgress, onError);
};

$RG.Template3D.prototype._loadSPRITE = function (oPars, fSuc, fFail) {
	var $O = this;
	var onProgress = function (xhr) {    };
    var onError = function (xhr) { if (fFail) { fFail($O); } };
    $WORLD.textureLoader.load($O._template.model, function (texture) {
		var mat = new THREE.SpriteMaterial( { map: texture, useScreenCoordinates: false, transparent: true,fog:true} );
		var object =new THREE.Sprite(mat);
		object.scale.y=$O._template.height;
		object.scale.x=$O._template.width;
		$O.mesh = object;
		$O.isReady = true;
		fSuc($O.mesh);
    }, onProgress, onError);
};

core/world/entity3D_v01.js


var $RG = $RG || {};
$RG.entities=[];

$RG.Entity3D = function (properties) {
	this.template=properties.template
	this.prop=properties;
	this.mesh=null;
	$RG.entities.push(this)
}

$RG.Entity3D.prototype.addToWorld = function () {
	var prop=this.prop;
	var templ=$RG.templates[prop.template];

	//Clonar la figura 3D, posicionar y rotar
	var mesh=templ.template3D.mesh.clone();
	var y=0
	mesh.position.set(prop.x, ((prop.y)?prop.y:0), prop.z);
	if (!(prop.rY)) prop.rY=0;
	if (templ.type=3) {
		mesh.translateY(templ.height/2-0.05);
	}
	mesh.rotateY(prop.rY * Math.PI / 180);
	this.mesh=mesh;

	$WORLD.scene.add(mesh);
	return mesh;
};

core/world/nature_v01.js


//****************************
// CREA LA NATURALEZA
//****************************

$WORLD.drawNature = function () {

        var nat=$WORLD.map.nature;
        //CARGAR EN MEMORIA TODOS LOS SPRITES
        var list=Object.keys(nat.patterns);
        for (var i=0;i<list.length;i++) {
            var pat=nat.patterns[list[i]];
            for (var n=0;n<pat.elements.length;n++) {
                var el=pat.elements[n];
                var mat = new THREE.SpriteMaterial( { map: $WORLD.textureLoader.load(el.object), useScreenCoordinates: false, transparent: true,fog:true} );
                var obj =new THREE.Sprite(mat);
                obj.scale.y=el.height;
                obj.scale.x=el.width;
                el._sprite = obj;
            }
        }
        //PARA CADA ZONA AÑADIR LOSaerboles
        for (var j=0;j<nat.zones.length;j++) {
            var zon=nat.zones[j];
            var pat=nat.patterns[zon.pattern];
            for (var x=zon.minX;x<zon.maxX-pat.freqX;x+=pat.freqX) {
                for (var z=zon.minZ;z<zon.maxZ-pat.freqZ;z+=pat.freqZ) {
                    var i=Math.round(Math.random()*(pat.elements.length-1));
                    var el=pat.elements[i];
                    var obj2=el._sprite.clone();z
                    obj2.position.set(x+(Math.random()*pat.freqX), el.height/2-0.05, z+(Math.random()*pat.freqZ));
                    $WORLD.scene.add(obj2);
                }
            }
        }
};

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;
}