Code viewer for World: New Infinite World with Ph...
// These 3 have default values, so this section is optional:

AB.clockTick       = 50;    

	// Speed of run: Step every n milliseconds. Default 100.
	
AB.maxSteps        = 1000000;    

	// Length of run: Maximum length of run in steps. Default 1000.

AB.screenshotStep  = 50;   
  
	// Take screenshot on this step. (All resources should have finished loading.) Default 50.


const SKYCOLOR 	= 0x000000;			 	// a number, not a string 
const CURSORCOLOR  = "magenta";

const  LIGHTCOLOR 	= 0xffffff ;


const MODELLENGTH 		= 6200;	

 
const objectsize = 3 ;

const MAXPOS                = 4000 ;                                 
const startRadiusConst	 	= MAXPOS * 0.5 ;		// distance from centre to start the camera at
const maxRadiusConst 		= MAXPOS * 5 ;		// maximum distance from camera we will render things  
const velocitySpeed         = 4;
const dimWorld = 500;
const vision = 4; // determinate the maximum distance to see ground (3 * objectSize * groundMultiplier)
const groundMultiplier = 31; // Put an odd number or there will be some bugs. derterminate how much the ground is bigger than basic object

const PATHTEXTURES = "/uploads/meak/";
const ARRAYTEXTURES = ["tree1"];
const PLAYEROBJ = "Wall-e";


// friction and restitution between 0 and 1: 

const GROUND_FRICTION 		= 0.1;
const GROUND_RESTITUTION 	= 0.95;

const TREE_FRICTION 		= 0.1;
const TREE_RESTITUTION 		= 0.95;

const PLAYER_FRICTION 		= 0.1;
const PLAYER_RESTITUTION 	= 0.95;

// define gravity along x,y,z dimensions:
var gravity = new THREE.Vector3 ( 0, -50, 0 );

//--- change threeworld defaults: -------------------------------

threehandler.MAXCAMERAPOS = MAXPOS * 10 ;			// allow camera go far away 

function randomfloatAtoB ( A, B )			 
{
 return ( A + ( Math.random() * (B-A) ) );
}

function randomintAtoB ( A, B )			 
{
 return  ( Math.round ( randomfloatAtoB ( A, B ) ) );
}

function World() { 

var objects;
var groundTexture;
var loaded = false;
var player ; // Object with player
var velocity = 0;
var speedRotation = 0;
var grounds;
var ai, aj;
var pai, paj;
var numberElementsLoaded = 0;
var modeOfView = 0; //0 : first person --- 1 : third person
var timeRunning = 0;

class Cube
{
  constructor() 
  {
      this.size = 1;
      this.ground = createCube();
  }
}
class Grnd
{
  constructor(act, pos) 
  {
      this.active = act;
      this.ground = createGround(pos);
  }
}

class ObjectsConteneur
{
  constructor() 
  {
      this.tree = [];
      this.player;
  }
}

function createRandomElement()
{
    var a = objects.tree[randomintAtoB(0,objects.tree.length - 1)].clone();
    return a;
}

function createGround(pos) 
{

    var gr = new Physijs.PlaneMesh (
        new THREE.PlaneGeometry ( objectsize*groundMultiplier, objectsize*groundMultiplier ),
        groundTexture );
        
    gr.rotation.x = (Math.PI / 2) * 3;
    gr.position = pos;
    gr.receiveShadow = true;
    gr.collision = 0;
    
    threeworld.scene.add(gr);
    //add all elements to a group, 
    
    /*let tmp = new Array(groundMultiplier);
    for (let i = 0; i < groundMultiplier; i++) 
    {
        tmp[i] = new Array(groundMultiplier);
        for (let j = 0; j < groundMultiplier; j++) 
        {
            tmp[i][j] = null;
        }
    }
    
    let numberElement = randomintAtoB(0,3);
    while(numberElement > 0)
    {
        console.warn(numberElement);
        let randomX = randomintAtoB(0,groundMultiplier-1);
        let randomY = randomintAtoB(0,groundMultiplier-1);
        let wasPosed = false;
        while(!wasPosed)
        {
            if(tmp[randomX][randomY] === null)
            {
                var t = createRandomElement();
                t.position.set((randomX - parseInt(groundMultiplier/2)) * objectsize,objectsize,(randomY - parseInt(groundMultiplier/2)) * objectsize);
                gr.add(t);
                wasPosed = true;
                numberElement--;
            }
            else
            {
                randomX = randomintAtoB(0,groundMultiplier-1);
                randomY = randomintAtoB(0,groundMultiplier-1);
            }
        }
    }*/
    
    return gr;
}

function updateGround()
{
    for(let i = ai - vision-1; i < ai + vision+1; i++)
    {
        for(let j = aj - vision-1; j < aj + vision+1; j++)
        {
            if(i == ai - vision - 1 || j == aj - vision - 1 || i == ai + vision || j == aj + vision)
            {
                if(grounds[i][j] !== null && grounds[i][j].active)
                {
                    grounds[i][j].active = false;
                    threeworld.scene.remove(grounds[i][j].ground);
                } 
            }
            else
            {
               if(grounds[i][j] === null)
                {
                    console.warn("creation ground -----------||||" + i + "||||" + j);
                    grounds[i][j] = new Grnd(true, new THREE.Vector3(0,0,0));
                    grounds[i][j].ground.position.set((i- dimWorld/2) * objectsize*groundMultiplier,0, (j- dimWorld/2) * objectsize*groundMultiplier);
                    threeworld.scene.add(grounds[i][j].ground);
                }
                else if(!grounds[i][j].active)
                {
                    grounds[i][j].active = true;
                    threeworld.scene.add(grounds[i][j].ground);
                }
            }
        }
    }
    
}
function createPlayerCamera() 
{
    player.position.set(0,objectsize*20,0);
    
    //Position for camera follow and lookat at the first person
    var posCam = new THREE.Mesh();
    posCam.name = "followFirstPerson";
    posCam.position.set(0,objectsize*3,0);
    
    var focusCam = new THREE.Mesh();
    focusCam.name = "lookatFirstPerson";
    focusCam.position.set(0,objectsize*3,objectsize*3);

    player.add(posCam);
    player.add(focusCam);
    
    
    //Position for camera follow and lookat at the third person
    var posCam2 = new THREE.Mesh();
    posCam2.name = "followThirdPerson";
    posCam2.position.set(0,objectsize*10,-objectsize*20);
    
    var focusCam2 = new THREE.Mesh();
    focusCam2.name = "lookatThirdPerson";
    focusCam2.position.set(0,0,0);
    
    player.add(posCam2);
    player.add(focusCam2);
}

function loaderObjects()
{
    groundTexture = new THREE.MeshBasicMaterial( {map: new THREE.ImageUtils.loadTexture("/uploads/meak/grass.jpg")}, GROUND_FRICTION,GROUND_RESTITUTION  );
    /*groundTexture.map.wrapS = THREE.RepeatWrapping;
	groundTexture.map.wrapT = THREE.RepeatWrapping;
	groundTexture.map.repeat.set( 3, 3 );*/
	
    console.log("loading " + ARRAYTEXTURES.length + " elements ");
    for(let i = 0; i < ARRAYTEXTURES.length; i++)
    {
        let loaderMat = new THREE.MTLLoader();
        let loaderObj = new THREE.OBJLoader();
        loaderMat.setTexturePath(PATHTEXTURES);
        let pathMat = PATHTEXTURES + ARRAYTEXTURES[i] + '.mtl';
        let pathObj = PATHTEXTURES + ARRAYTEXTURES[i] + '.obj';
        console.log("loading " + pathMat + " and " + pathObj);
        loaderMat.load(
        	// resource URL
        	pathMat,
        	// called when resource is loaded
        	function ( materials ) {
        	    materials.preload();
        	    loaderObj.setMaterials(materials);
        	    // load a resource
                loaderObj.load(
                	// resource URL
                	pathObj,
                	// called when resource is loaded
                	function ( object ) {
                	    
                	    
                	    geometry = object.children[0].geometry;
                        geometry.computeBoundingBox();
                        
                        //var boundingBoxHelper = geometry.boundingBox.clone();
                        var mesh = new Physijs.CapsuleMesh(geometry, groundTexture, 0 );
                        object.add(mesh);  
                        //var box = new THREE.BoxHelper( object, 0xffff00 );
                        //threeworld.scene.add( box );
                	    objects.tree.push(object);
                        object.position.set(0,objectsize,0);
                        
                        numberElementsLoaded++;
                        console.log("already loaded " + numberElementsLoaded + " of " + ARRAYTEXTURES.length + " elements ");
                        if(numberElementsLoaded == ARRAYTEXTURES.length+1)
                        {
                            loaded = true;
                            init();
                        }
                	},
                );
        	},
        );
    }
    
    var player_material =    Physijs.createMaterial (
            new THREE.MeshLambertMaterial({ map:  new THREE.ImageUtils.loadTexture("/uploads/meak/grass.jpg")  }),  
            PLAYER_FRICTION,
		    PLAYER_RESTITUTION );
		    
    let loaderObj = new THREE.OBJLoader();
    let pathObj = PATHTEXTURES + PLAYEROBJ + '.obj';
    console.log("loading " + pathObj);

    // load a resource
    loaderObj.load(
        // resource URL
        pathObj,
        // called when resource is loaded
        function ( object ) {

            geometry = object.children[0].geometry;
            geometry.computeBoundingBox();
            
            var boundingBox = geometry.boundingBox.clone();
            
            object.position.set(0,objectsize,0);
            //*/new THREE.Box3().setFromObject(obj);
            //var bbox = new BoxSetFromObject(object);
            //object.computeBoundingBox();
            //
            var mesh = new Physijs.CapsuleMesh(geometry, player_material, 1 );
            mesh.collisions = 0;
	        mesh.castShadow = true;
            player = mesh;
            
            createPlayerCamera();
        
        	player.collisions = 0;
        	player.castShadow = true;
        	
            player.scale.multiplyScalar (0.5);
            numberElementsLoaded++;
            if(numberElementsLoaded == ARRAYTEXTURES.length+1)
            {
                loaded = true;
                init();
            }
        },
    );
}

function init()		 
{
    grounds = new Array(dimWorld);
    for (let i = 0; i < dimWorld; i++) 
    {
        grounds[i] = new Array(dimWorld);
        for (let j = 0; j < dimWorld; j++) 
        {
            grounds[i][j] = null;
        }
    }
    threeworld.scene.add(player);
    player.updateMatrixWorld();
    threeworld.follow = player.getObjectByName("followFirstPerson").getWorldPosition();
    threeworld.lookat = player.getObjectByName("lookatFirstPerson").getWorldPosition();
    ai = parseInt(dimWorld/2 + player.getWorldPosition().x/(objectsize*groundMultiplier) + 1);
    aj = parseInt(dimWorld/2 + player.getWorldPosition().z/(objectsize*groundMultiplier) + 1);
    pai = ai;
    paj = aj;
    updateGround();
}



function paintThis( object )        // paint objects with random textures 
{
    object.material =  new THREE.MeshBasicMaterial ( { transparent: true, opacity: 1, map:textureArray[currentTexture]  } ); 
}

function handleKeyUp (e)
{
    if((e.keyCode == 38) || (e.keyCode == 40))
    {
        player.setLinearVelocity(0);
        velocity = 0;
    }
    if(e.keyCode == 37 || e.keyCode == 39)
    {
        speedRotation = 0;
    }
    if(e.keyCode == 37 || e.keyCode == 39)
    {
        speedRotation = 0;
        modeOfView
    }
}

function shakePositionCamera(follow, lookat)
{
    if(velocity != 0)
    {
        follow.position.x += 0.6*Math.sin(timeRunning);
        lookat.position.x += 0.6*Math.sin(timeRunning);
        follow.position.y = objectsize*3 + Math.abs(Math.sin(timeRunning))*1.3;
        lookat.position.y = objectsize*3 + Math.abs(Math.sin(timeRunning))*1.3;
    }
    else
    {
        follow.position.y = objectsize*3;
        lookat.position.y = objectsize*3;
        follow.position.x = 0;
        lookat.position.x = 0;
    }
}
// the main key handling function:

function handleKeyDown (e)
{
    if (e.keyCode == 37)  speedRotation = Math.PI/70;//ACTION_LEFT
    if (e.keyCode == 38)  player.setLinearVelocity(new THREE.Vector3(0,0,1));//velocity = velocitySpeed;//ACTION_DOWN 
    if (e.keyCode == 39)  speedRotation = -Math.PI/70;//ACTION_RIGHT
    if (e.keyCode == 40)  player.setLinearVelocity(new THREE.Vector3(0,0,-1));//velocity = -velocitySpeed;//ACTION_UP
    
    // Change modeOfView for the player
    if (e.keyCode == 17)
    {
        if(modeOfView === 0)
        {
            modeOfView = 1;
        }
        else
        {
            modeOfView = 0;
        }
    }
    
    updateGround()
}

this.endCondition = false;

this.newRun = function() 
{
    
	threeworld.init3d ( startRadiusConst, maxRadiusConst, SKYCOLOR  ); 
	
	var thelight = new THREE.DirectionalLight ( LIGHTCOLOR, 2 );
    thelight.position.set ( startRadiusConst, startRadiusConst, startRadiusConst );
    thelight.castShadow = true;
    threeworld.scene.add(thelight);
    
     // can adjust renderer:
 
	threeworld.renderer.shadowMap.enabled = true;
 

    // scene is Physijs.Scene, not THREE.Scene
    // can adjust scene - change gravity from default:
 
	threeworld.scene.setGravity ( gravity );
	var s = "<p>   Use arrow keys, w (up) and s(down) to move. </p>";
 	$("#user_span2").html( s );
    
    objects = new ObjectsConteneur();
    
    
    
 	loaderObjects();
 	
 	threeworld.scene.simulate();
	// set up the main key handler:
	document.addEventListener( 'keydown', handleKeyDown);
	document.addEventListener( 'keyup', handleKeyUp);
	
	

};


this.nextStep = function()
{
    
    if(!loaded)
    {
        console.warn( 'Charging' );
    }
    else
    {
        player.rotateY(speedRotation);
        player.translateZ(velocity);
        player.updateMatrixWorld();
        if(modeOfView == 0) // First Person
        {
            timeRunning += 0.25;
            shakePositionCamera(player.getObjectByName("followFirstPerson"), player.getObjectByName("lookatFirstPerson"));
            threeworld.follow = player.getObjectByName("followFirstPerson").getWorldPosition();
            threeworld.lookat = player.getObjectByName("lookatFirstPerson").getWorldPosition();
        }
        else //Third person
        {
            threeworld.follow = player.getObjectByName("followThirdPerson").getWorldPosition();
            threeworld.lookat = player.getObjectByName("lookatThirdPerson").getWorldPosition();
        }
        
        ai = parseInt(dimWorld/2 + player.getWorldPosition().x/(objectsize*groundMultiplier)+1);
        aj = parseInt(dimWorld/2 + player.getWorldPosition().z/(objectsize*groundMultiplier)+1);

        if(ai != pai || aj != paj)
        {
            console.warn("creation grounds :");
            pai = ai;
            paj = aj;
            updateGround();
        }
    }
    
   
    
};


this.endRun = function()
{
};

}