Code viewer for World:
Sun
// Cloned by Nathan Bonnard on 9 Aug 2018 from World "Infinite World" by Nathan Bonnard
// Please leave this clone trail here.
//==============================================================================
// Sun Prefab
//==============================================================================
//------------------------------ TWEAKER BOX ------------------------------//
const SKYDISTANCE = 3000; // Distance of stars and sun
const NBSTARS = 100; //number of stars
//------------------------------ END OF TWEAKER BOX ------------------------------//
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 SKYCOLOR = 0x6495ED;
const LIGHTCOLOR = 0xffffff ;
threehandler.MAXCAMERAPOS = MAXPOS * 10 ;// allow camera go far away
AB.clockTick = 20;
// 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.
/**
* A linear interpolator for hexadecimal colors
* @param {Int} a
* @param {Int} b
* @param {Number} amount
* @example
* // returns 0x7F7F7F
* lerpColor(0x000000, 0xffffff, 0.5)
* @returns {Int}
*/
function lerpColor(a, b, amount) {
let ah = a;
ar = ah >> 16, ag = ah >> 8 & 0xff, ab = ah & 0xff,
bh = b;
br = bh >> 16, bg = bh >> 8 & 0xff, bb = bh & 0xff,
rr = ar + amount * (br - ar),
rg = ag + amount * (bg - ag),
rb = ab + amount * (bb - ab);
return ((1 << 24) + (rr << 16) + (rg << 8) + rb | 0);
}
/**/
function map(n, start1, stop1, start2, stop2)
{
return ((n-start1)/(stop1-start1))*(stop2-start2)+start2;
}
//==============================================================================
// World Definition
//==============================================================================
function World() {
//==============================================================================
// All variables
//==============================================================================
var sun; //sun and all functions with it (also stars)
this.endCondition = false;
//==============================================================================
//==============================================================================
//==============================================================================
// Sun Class
//==============================================================================
function Sun(target)
{
this.angle = 0;
this.object = new THREE.DirectionalLight( 0xffffff, 0.1 );
this.object.position.set(0, Math.cos(this.angle)*3000, Math.sin(this.angle)*3000);
this.object.castShadow = true;
this.object.shadow.mapSize.width = 1024;
this.object.shadow.mapSize.height = 1024;
this.object.shadow.camera.near = 10;
this.object.shadow.camera.far = 4000;
let d = 1000;
this.object.shadow.camera.left = -d;
this.object.shadow.camera.right = d;
this.object.shadow.camera.top = d;
this.object.shadow.camera.bottom = -d;
this.object.shadow.bias = -0.0001;
this.object.target = target;
threeworld.scene.add(this.object);
this.stars = [];
this.starMaterial = new THREE.MeshBasicMaterial({color : "white", fog: false}) ;
this.starMaterial.transparent = true;
this.starMaterial.opacity = 0;
let sunball = new THREE.Mesh( new THREE.SphereGeometry(100,32,32), new THREE.MeshBasicMaterial({color : "yellow", fog: false}) );
this.object.add( sunball );
this.starGyroscope = new THREE.Mesh();
target.add( this.starGyroscope );
for (let i = 0; i<NBSTARS; i++)
{
let radius = AB.randomFloatAtoB ( 5, 20 );
let star = new THREE.Mesh( new THREE.SphereGeometry(radius,8,8), this.starMaterial);
let s = AB.randomFloatAtoB ( 0, Math.PI*2 );
let t = AB.randomFloatAtoB ( 0, Math.PI/2 );
star.position.set(SKYDISTANCE*Math.cos(s)*Math.sin(t), SKYDISTANCE*Math.cos(t), SKYDISTANCE*Math.sin(s)*Math.sin(t));
this.stars.push(star);
this.starGyroscope.add(star);
}
//Use this in nextStep to make the sun move
this.animate = function()
{
this.angle+=0.001;
//normalize angle between -PI and PI
while (this.angle <= -Math.PI) this.angle += Math.PI*2;
while (this.angle > Math.PI) this.angle -= Math.PI*2;
this.object.position.set(target.position.x, Math.cos(this.angle)*3000, Math.sin(this.angle)*3000 + target.position.z);
this.object.intensity = this.getSunIntensity();
let c = new THREE.Color(this.getSkyColor());
threeworld.scene.background = c;
threeworld.scene.fog.color = c;
this.setStarsOpacityAndFog();
this.starGyroscope.rotation.set(-target.rotation.x, -target.rotation.y, -target.rotation.z);
}
//change star opacity and fog depending of the position of the sun
this.setStarsOpacityAndFog = function()
{
if (this.angle > Math.PI/2 && this.angle < Math.PI*3/4)
{
soundManager.isNight = true;
soundManager.playCurrentSound();
this.starMaterial.opacity = map(this.angle, Math.PI/2, Math.PI*3/4, 0, 0.8);
threeworld.scene.fog.far = 1000 + SKYDISTANCE * (1 - map(this.angle, Math.PI/2, Math.PI*3/4, 0, 0.8));
}
else if (this.angle > -Math.PI*3/4 && this.angle < -Math.PI/2)
{
soundManager.isNight = false;
this.starMaterial.opacity = map(this.angle, -Math.PI*3/4, -Math.PI/2, 0.8, 0);
threeworld.scene.fog.far = 1000 + SKYDISTANCE * (1 - map(this.angle, -Math.PI*3/4, -Math.PI/2, 0.8, 0));
}
}
//return the color of the sky depending of the position of the sun (to get the sunrise)
this.getSkyColor = function()
{
if (this.angle > -Math.PI*3/8 && this.angle < Math.PI*3/8)
{
// console.log("day");
return 0x7ec0ee;
}
else if (this.angle > Math.PI*3/8 && this.angle < Math.PI/2)
{
// console.log("Sunset 1");
return lerpColor(0x7ec0ee, 0xfd5e53, map(this.angle, Math.PI*3/8,Math.PI/2,0,1));
}
else if (this.angle > Math.PI/2 && this.angle < Math.PI*5/8)
{
// console.log("Sunset 2");
return lerpColor(0xfd5e53, 0x0c3166, map(this.angle, Math.PI/2,Math.PI*5/8,0,1));
}
else if (this.angle > Math.PI*5/8 || this.angle < -Math.PI*3/4)
{
// console.log("night");
return 0x0c3166;
}
else if (this.angle > -Math.PI*3/4 && this.angle < -Math.PI/2)
{
// console.log("Sunrise 1");
return lerpColor(0x0c3166, 0xfd5e53, map(this.angle, -Math.PI*3/4,-Math.PI/2,0,1));
}
else if (this.angle > -Math.PI/2 && this.angle < -Math.PI*3/8)
{
// console.log("Sunrise 2");
return lerpColor(0xfd5e53, 0x7ec0ee, map(this.angle, -Math.PI/2, -Math.PI*3/8, 0, 1));
}
}
//return intensity of the sun
this.getSunIntensity = function()
{
if (this.angle > -Math.PI*3/8 && this.angle < Math.PI*3/8)
{
return 2;
}
else if (this.angle > Math.PI*3/8 && this.angle < Math.PI/2)
{
return map(this.angle, Math.PI*3/8,Math.PI/2,2,1);
}
else if (this.angle > Math.PI/2 && this.angle < Math.PI*3/4)
{
return map(this.angle, Math.PI/2,Math.PI*3/4,1,0);
}
else if (this.angle > Math.PI*3/4 || this.angle < -Math.PI*3/4)
{
return 0;
}
else if (this.angle > -Math.PI*3/4 && this.angle < -Math.PI/2)
{
return map(this.angle, -Math.PI*3/4,-Math.PI/2,0,1);
}
else if (this.angle > -Math.PI/2 && this.angle < -Math.PI*3/8)
{
return map(this.angle, -Math.PI/2, -Math.PI*3/8, 1, 2);
}
}
}
//==============================================================================
// Function newRun ,init and endRun
//==============================================================================
this.newRun = function()
{
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, SKYDISTANCE );
threeworld.camera = camera;
threeworld.init3d ( 0, 0, SKYCOLOR );
// can adjust renderer:
threeworld.renderer.shadowMap.enabled = true;
threeworld.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
threeworld.scene.fog = new THREE.Fog(SKYCOLOR, 0, SKYDISTANCE);
var geometry = new THREE.BoxGeometry( 10, 10, 10 );
var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
var cube = new THREE.Mesh( geometry, material );
threeworld.scene.add( cube );
sun = new Sun(cube);
};
this.nextStep = function()
{
sun.animate();
};
this.endRun = function()
{
};
}