// nikatlas -- Solar System
(function() {
var MAX_CAM = 300;
PouchDB.debug.disable('*');
var ZEROVECTOR = new THREE.Vector2(0,0);
var X_AXIS = new THREE.Vector3(1,0,0);
var Y_AXIS = new THREE.Vector3(0,1,0);
var Z_AXIS = new THREE.Vector3(0,0,1);
var ZERO_ROT_QUAT = new THREE.Quaternion(0,0,0,1);
var controls;
var manager;
var loader;
var _textures = {};
var Game = window.GameInstance = new window.Game();
var GameBox = new window.GameBox(5,14,5);
var moveVector = new THREE.Vector2(0,0);
var lookVector = new THREE.Vector3(0,0,1);
var paused = false;
var db = new PouchDB('tetris3d');
window.remoteDB = new PouchDB('http://tetrisuser:tetrispass@couchdb.onarbooks.com:80/tetris3d');
function init() {
Game.init();
addLights(Game.scene);
window.scene = Game.scene; // DEBUG
manager = new THREE.LoadingManager();
loader = new THREE.TextureLoader(manager);
createScene(Game.scene);
// controls
controls = new THREE.OrbitControls(Game.camera, Game.renderer.domElement);
controls.minPolarAngle = Math.PI * 0.28;
controls.maxPolarAngle = Math.PI * 0.48;
controls.minDistance = 30;
controls.maxDistance = MAX_CAM;
controls.target.copy(new THREE.Vector3(0,5.5,0));
Game.camera.lookAt(new THREE.Vector3(0,5.5,0));
GameBox.init(Game.scene);
GameBox.drop(new window.Shapes.Box(0x00ff20));
Game.animate();
var lasttime = 0,movelasttime=0;
var oldLookVector = new THREE.Vector3(0,0,1);
Game.addLoopFn(function(time){
if(time - lasttime > GameBox.getSpeed() && !paused ){ //////////////////////////////////////////////// TIME .....
GameBox.progress();
lasttime = time;
}
if(time - movelasttime > 0.05){
if(!moveVector.equals(ZEROVECTOR) || !lookVector.equals(oldLookVector)){
var move = rotateToCamera(moveVector);
var look = rotateToCamera(lookVector);
look = vectorToLook(look);
GameBox.move(move.x,move.z, look.axis, look.degrees);
oldLookVector.copy(lookVector);
movelasttime = time;
}
}
restoreUI();
});
function fixData(){
db.allDocs({
include_docs: true,
descending : true,
limit : 5
}).then(function(res){
var data = res.rows;
var s = "";
for(var i=0;i< data.length;i++){
s += ' \
\
'+data[i].doc.name+'
\
'+data[i].doc.score+'
\
';
}
var scores = getit("scores");
scores.innerHTML = s;
});
}
window.getFromDB = function(){
db.changes().on('change', function() {
fixData();
});
remoteDB.login('nikatlas', 'Nikos0349').then(function (user) {
db.info();
})
.then(function (info) {
console.log(info);
db.sync(remoteDB);
});
};
getFromDB();
window.saveToDB = function(){
var name = getit("name").value;
if(!name)return;
var mid = pad(GameBox.score,100) + name;
db.put({
_id : mid,
name : name,
score : GameBox.score
}).then(function (result) {
console.log(result);
fixData();
}).catch(function (err) {
console.log(err);
});;
};
}
function pad(num, size) {var s = num+"";while (s.length < size) s = "0" + s;return s;}
function getit(id){return document.getElementById(id);};
function restoreUI(){
var score = getit("highscore");
score.innerHTML = GameBox.score || 0;
if(GameBox.finished){
var lost = getit("lost");
lost.style.display = "block";
var mscore = getit("myscore");
mscore.innerHTML = GameBox.score || 0;
}
};
window.restartGame = function(){
if(GameBox.finished){
var lost = getit("lost");
lost.style.display = "none";
GameBox.restart();
}
}
function rotateToCamera(v){
var mat4 = new THREE.Matrix4();
mat4.makeRotationFromQuaternion(Game.camera);
var rot;
if(v.z == undefined){
rot = new THREE.Vector3(v.x,0,v.y);
}
else{
rot = new THREE.Vector3(v.x,v.y,v.z);
}
rot.applyQuaternion(Game.camera.getWorldQuaternion());
var x = rot.x;
var y = rot.y;
var z = rot.z;
var ax = Math.abs(x) > Math.abs(z) && Math.abs(x) > Math.abs(y);
var ay = Math.abs(y) > Math.abs(x) && Math.abs(y) > Math.abs(z);
var az = Math.abs(z) > Math.abs(x) && Math.abs(z) > Math.abs(y);
var sx = x > 0 ? 1 : -1;
var sy = y > 0 ? 1 : -1;
var sz = z > 0 ? 1 : -1;
rot.set(sx * ax, sy * ay,sz * az);
return rot;
}
function getRotationOf(u, v)
{
if( u.equals(v) )return ZERO_ROT_QUAT;
// It is important that the inputs are of equal length when
// calculating the half-way vector.
u = u.clone().normalize();
v = v.clone().normalize();
var k_cos_theta = u.clone().dot(v);
var k = Math.sqrt(u.length() * v.length());
// Unfortunately, we have to check for when u == -v, as u + v
// in this case will be (0, 0, 0), which cannot be normalized.
// if (u.equals(v.clone().multiplyScalar(-1)))
if (k_cos_theta / k == -1)
{
// 180 degree rotation around any orthogonal vector
var orthv = Y_AXIS;
orthv.normalize();
return new THREE.Quaternion(orthv.x , orthv.y , orthv.z , 0);
}
var cross = u.cross(v);
return new THREE.Quaternion(cross.x , cross.y , cross.z , k_cos_theta + k ).normalize();
}
function vectorToLook(v){
var q = getRotationOf(Z_AXIS, v);
var qw = q.w;
var angle = 2 * Math.acos(qw)
var x = q.x / Math.sqrt(1-qw*qw)
var y = q.y / Math.sqrt(1-qw*qw)
var z = q.z / Math.sqrt(1-qw*qw)
var look = {
axis : new THREE.Vector3(x,y,z),
degrees : angle
};
return look;
}
// Create Scene
function createScene(scene){
box = createBox(5,5,5,0x11ff20);
box.receiveShadow = true;
box.castShadow = true;
box.position.copy(new THREE.Vector3( -4 , 7 , 4 ));
//console.log(box.position);
//scene.add(box);
box = createBox(4,1,4,0x00ff20);
box.receiveShadow = true;
box.castShadow = true;
box.position.copy(new THREE.Vector3( 1 , 4 , 0 ));
//console.log(box.position);
//scene.add(box);
plane = createTerrain(2025,2025,0x7f8f6f);
plane.rotation.x = Math.PI / 2;
plane.receiveShadow = true;
scene.add(plane);
target = scene;
createSkybox(scene);
}
// Lights
function createDLight(color, intensity) {
var l = new THREE.DirectionalLight( color, intensity );
l.castShadow = true;
l.shadowCameraRight = 30;
l.shadowCameraLeft = -30;
l.shadowCameraTop = 30;
l.shadowCameraBottom = -30;
l.shadow.mapSize.width = 1024;
l.shadow.mapSize.height = 1024;
l.shadow.map = null;
return l;
}
function addLights(scene) {
scene.add(new THREE.AmbientLight(0x111111)); // Ambient light
// White directional light at half intensity shining from the top.
var directionalLight = createDLight( 0xffffff, 0.55 );
directionalLight.position.copy(new THREE.Vector3( 0 , 50, 0));
directionalLight.castShadow = true;
// var directionalLight2 = createDLight( 0xffffff, 0.15 );
// directionalLight2.position.copy(new THREE.Vector3( -100 , 100, -45 ));
// directionalLight2.castShadow = true;
// var directionalLight3 = createDLight( 0xffffff, 0.15 );
// directionalLight3.position.copy(new THREE.Vector3( 0 , 100 , 65 ));
// directionalLight3.castShadow = true;
//scene.add( directionalLight );
// scene.add( directionalLight2 );
// scene.add( directionalLight3 );
}
function load(k,path) {
_textures[k] = loader.load(path, THREE.SphericalRefractionMapping);
}
function loadTextures() {
manager.onProgress = function () {
console.log("Progress");
}
manager.onLoad = function(){
console.log("[-] Textures Loaded!")
computeGraph();
}
//load('sun','textures/planets/sun.jpg');
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
var earth,moon,sun,europa;
function computeGraph() {
return true;
}
// Input Handling
var axis = X_AXIS;
var degrees = 0;
window.onkeydown = function (e) {
if(e.keyCode == 65){ // a
moveVector.x = -1;
}
else if(e.keyCode == 87){ // w
moveVector.y = -1;
}
else if(e.keyCode == 68){ // d
moveVector.x = 1;
}
else if(e.keyCode == 83){ // s
moveVector.y = 1;
}
if(e.keyCode == 73){
lookVector.z = -1;
lookVector.x = 0;
lookVector.y = 0;
}
else if(e.keyCode == 75){
lookVector.z = 1;
lookVector.x = 0;
lookVector.y = 0;
}
if(e.keyCode == 74){
lookVector.x = -1;
lookVector.y = 0;
lookVector.z = 0;
}
else if(e.keyCode == 76){
lookVector.x = 1;
lookVector.y = 0;
lookVector.z = 0;
}
if(e.keyCode == 79){ //o
lookVector.y = 1;
lookVector.z = 0;
lookVector.x = 0;
}
else if(e.keyCode == 85){ //u
lookVector.y = -1;
lookVector.z = 0;
lookVector.x = 0;
}
if(e.keyCode == 32){
GameBox.progressToNext();
}
console.log(e.keyCode);
};
window.onkeyup = function (e) {
if(e.keyCode == 65){ // a
moveVector.x = 0;
}
else if(e.keyCode == 87){ // w
moveVector.y = 0;
}
else if(e.keyCode == 68){ // d
moveVector.x = 0;
}
else if(e.keyCode == 83){ // s
moveVector.y = 0;
}
// if(e.keyCode == 73){
// lookVector.y = 0;
// }
// else if(e.keyCode == 75){
// lookVector.y = 0;
// }
// if(e.keyCode == 74){
// lookVector.x = 0;
// }
// else if(e.keyCode == 76){
// lookVector.x = 0;
// }
if(e.keyCode == 80){
paused = !paused;
}
};
var raycaster = new THREE.Raycaster();
var dragging = false;
window.onmousedown = function (event) {
// var mx = ( event.clientX / window.innerWidth ) * 2 - 1;
// var my = - ( event.clientY / window.innerHeight ) * 2 + 1;
// var mouse = new THREE.Vector2(mx,my);
// // update the picking ray with the camera and mouse position
// raycaster.setFromCamera( mouse, Game.camera );
// // calculate objects intersecting the picking ray
// var intersects = raycaster.intersectObjects( Game.scene.children, true );
// if(intersects.length){
// dragging = intersects[0].object;
// }
};
window.onmouseup = function (event) {
dragging = false;
};
var lastmx=0,lastmy=0;
window.onmousemove = function (event) {
if(dragging){
var mx = ( event.clientX / window.innerWidth ) * 2 - 1;
var my = - ( event.clientY / window.innerHeight ) * 2 + 1;
var dx = (mx - lastmx)*30;
var dy = (my - lastmy)*30;
lastmx = mx;
lastmy = my;
if(typeof dx != "number" || typeof dy != "number" )return;
switch(axis){
case 1 :
dragging.position.x += dx;
break;
case 2 :
dragging.position.y += dy;
break;
case 3 :
dragging.position.z += dx;
break;
}
}
};
///////////////////////// HELPERS /////////////////////////////////
function createSkybox(scene) {
/////////////////////////////////////////////////////////////////////
///// SKYBOX
var urlPrefix = "textures/skybox/Daylight Box_";
var urls = [ "Left.bmp", "Right.bmp",
"Top.bmp", "Bottom.bmp",
"Back.bmp", "Front.bmp" ];
scene.background = new THREE.CubeTextureLoader()
.setPath( urlPrefix )
.load(urls);
return;
}
function createBox(x,y,z,color){
// This is where introtowebgl uses CubeGeometry
var geometry = new THREE.BoxGeometry(x,y,z);
//var material = new THREE.MeshBasicMaterial({ color: color, shading : THREE.SmoothShading });
var material = new THREE.MeshPhongMaterial( {
color: color,
specular: 0x050505,
shininess: 100
} );
var cube = new THREE.Mesh(geometry,material);
return cube;
}
function generateHeight( width, height ) {
var size = width * height, data = new Uint8Array( size ),
perlin = new ImprovedNoise(), quality = 1, z = Math.random() * 100;
for ( var j = 0; j < 4; j ++ ) {
for ( var i = 0; i < size; i ++ ) {
var x = i % width, y = ~~ ( i / width );
data[ i ] += Math.abs( perlin.noise( x / quality, y / quality, z ) * quality * 1.75 );
}
quality *= 5;
}
return data;
}
function createTerrain(w,h,color){
var geometry = new THREE.PlaneGeometry( w, h, w/8, h/8);
var vertices = geometry.vertices;
var NOISE = generateHeight(w/8+1,h/8+1);
for ( var i = 0, l = vertices.length; i < l; i ++) {
vertices[ i ].z = NOISE[ i ] + 10;
}
var texture = new THREE.TextureLoader().load( "textures/terrains/desertrock.jpg" );
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( w/64, w/64 );
//var material = new THREE.MeshBasicMaterial( {color: color, side: THREE.DoubleSide} );
var material = new THREE.MeshPhongMaterial({
specular: 0x030303,
map : texture,
color : color,
alphaTest: 0.8,
shininess: 2,
side: THREE.DoubleSide,
shading : THREE.SmoothShading
});
var plane = new THREE.Mesh( geometry, material );
return plane;
}
init();
})();