418 lines
10 KiB
JavaScript
418 lines
10 KiB
JavaScript
console.log("Hello, Sky!");
|
|
|
|
/**** ☭☭☭☭☭☭☭☭☭☭☭☭ ******
|
|
/☭☭☭☭ Parametri razni ☭☭☭☭ *
|
|
******☭☭☭☭☭☭☭☭☭☭☭☭******/
|
|
|
|
// Odmik kamere
|
|
var odmik_kamere = 80;
|
|
|
|
// Rotacija kamere
|
|
var cam_rot_offset = 0;
|
|
|
|
// Vidni kot
|
|
var FOV = 90;
|
|
|
|
// Sirina in visina objektov
|
|
var width = 6;
|
|
|
|
// Limit stevila objektov
|
|
var obj_limit = 10;
|
|
|
|
// Prvotno prazno polje objektov. Lahko bi kak buffer to bil pozneje
|
|
var objekti = [];
|
|
|
|
// Stevec, za razno animiranje
|
|
var stevec = 0;
|
|
|
|
var gostota_obj = 1;
|
|
|
|
|
|
|
|
// Parametri animacije
|
|
var drotacijaX = 0.000;
|
|
var drotacijaY = 0.000;
|
|
var drotacijaZ = 0.000;
|
|
|
|
var rotacijaX = 0;
|
|
var rotacijaY = 0;
|
|
var rotacijaZ = 0;
|
|
|
|
// Premik obstojecih barv
|
|
var zamikBarve = 0.01;
|
|
|
|
// Zamik pri novem objektu
|
|
var barva_mod = 0.003;
|
|
var saturacija = 1;
|
|
var svetlost = 0.4;
|
|
|
|
// Rotiranje kamere
|
|
var kameraX = 0;
|
|
var kameraY = 0;
|
|
var kameraZ = 0;
|
|
|
|
// Quaternioni za rotacijo in kalibracijo
|
|
var qWW = new THREE.Quaternion(-1, 0, 0, 0);
|
|
var qWWo = new THREE.Quaternion(-1, 0, 0, 0);
|
|
var qWWd = new THREE.Quaternion(-1, 0, 0, 0);
|
|
var qObj = new THREE.Quaternion(-1, 0, 0, 0);
|
|
var qStart = new THREE.Quaternion(-1, 0, 0, 0);
|
|
var calibrate = true;
|
|
var reset = false;
|
|
|
|
// Razlika v eulerjih
|
|
var dqX = 0;
|
|
var dqY = 0;
|
|
var dqZ = 0;
|
|
|
|
// Gumbi in pa pospesek
|
|
var keysPressed = [0, 0, 0, 0];
|
|
var accel = [0, 0, 0];
|
|
|
|
// Scena, kamera in render
|
|
scene = new THREE.Scene;
|
|
|
|
camera = new THREE.PerspectiveCamera(FOV, window.innerWidth / window.innerHeight, 1, 10000);
|
|
camera.position.z = odmik_kamere;
|
|
|
|
renderer = new THREE.WebGLRenderer({
|
|
alpha: true
|
|
});
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
|
|
// Belo ozadje
|
|
//renderer.setClearColor(0xFFFFFF, 1);
|
|
// Črno ozadje
|
|
renderer.setClearColor(0x000000, 1);
|
|
|
|
|
|
|
|
|
|
|
|
function render () {
|
|
requestAnimationFrame(render);
|
|
stevec += 1;
|
|
|
|
// Dodaj objekt vcasih
|
|
if (stevec % gostota_obj === 0) {
|
|
addObj(width, width);
|
|
}
|
|
renderer.render(scene, camera);
|
|
|
|
modulirajParametre();
|
|
objAnim();
|
|
camRotate();
|
|
};
|
|
|
|
function modulirajParametre() {
|
|
// Vsi gumbi? => RESET
|
|
if ((keysPressed[0] + keysPressed[1] + keysPressed[2] + keysPressed[3]) === 4 && !reset) {
|
|
reset = true;
|
|
window.location.reload()
|
|
}
|
|
|
|
// Posodobi kvaternion polozaja kontrolerja
|
|
|
|
if (calibrate) {
|
|
qStart = qWW.clone();
|
|
qStart.conjugate();
|
|
calibrate = false;
|
|
console.log("RESET!");
|
|
}
|
|
|
|
// Rotiranje manualno (z rocnimi gibi "iz sredine")
|
|
if (keysPressed[3]) {
|
|
var k = objekti.slice(-1)[0];
|
|
qObj.multiply(qWWd);
|
|
k.quaternion.multiply(qWWd);
|
|
}
|
|
if (keysPressed[2]) {
|
|
drotacijaX += qWWd.x / 10;
|
|
drotacijaY += qWWd.y / 10;
|
|
drotacijaZ += qWWd.z / 10;
|
|
}
|
|
if (keysPressed[0]) {
|
|
width *= 1 + (dqY / 3);
|
|
barva_mod += (dqX / 30);
|
|
obj_limit *= 1 + (dqZ / 3);
|
|
}
|
|
}
|
|
|
|
// Funkcija za animacijo objektov
|
|
function objAnim() {
|
|
objekti.map(function (obj) {
|
|
obj.rotation.x += drotacijaX;
|
|
obj.rotation.y += drotacijaY;
|
|
obj.rotation.z += drotacijaZ;
|
|
|
|
obj.scale.z += width / 4;
|
|
obj.scale.y += width / 4;
|
|
obj.scale.x += width / 4;
|
|
|
|
obj.material.color.offsetHSL(zamikBarve, 0, 0);
|
|
});
|
|
};
|
|
|
|
// Funkcija za dodajanje novih objektov
|
|
function addObj(w, h) {
|
|
var col = new THREE.Color();
|
|
col.setHSL(stevec * barva_mod, saturacija, svetlost);
|
|
|
|
var mat = new THREE.LineBasicMaterial({
|
|
color: col
|
|
});
|
|
|
|
var geo = new THREE.BufferGeometry();
|
|
|
|
var offset = h / 2;
|
|
|
|
// Karo
|
|
var vertices = new Float32Array([
|
|
-offset, 0, 0, 0, offset, 0,
|
|
-offset, 0, 0, 0, -offset, 0,
|
|
offset, 0, 0, 0, offset, 0,
|
|
offset, 0, 0, 0, -offset, 0
|
|
]);
|
|
|
|
// 3d objekt (3 komponente na vertex)
|
|
geo.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
|
|
|
|
var obj = new THREE.Line(geo, mat, THREE.LineSegments);
|
|
|
|
scene.add(obj);
|
|
obj.setRotationFromQuaternion(qObj);
|
|
|
|
// Pocisti za seboj
|
|
if (objekti.push(obj) > obj_limit) {
|
|
while (objekti.length > obj_limit) {
|
|
scene.remove(objekti[0]);
|
|
objekti.shift();
|
|
}
|
|
}
|
|
};
|
|
|
|
var xAksa = new THREE.Vector3(0, 1, 0);
|
|
function camRotate () {
|
|
// rotiraj po z osi
|
|
camera.translateX(kameraX);
|
|
camera.translateZ(odmik_kamere - Math.sqrt(Math.pow(odmik_kamere, 2) + Math.pow(kameraX, 2)));
|
|
|
|
/*
|
|
camera.translateY(kameraY);
|
|
camera.translateX(odmik_kamere - Math.sqrt(Math.pow(odmik_kamere, 2) + Math.pow(kameraY, 2)));
|
|
|
|
camera.translateZ(kameraZ);
|
|
camera.translateX(odmik_kamere - Math.sqrt(Math.pow(odmik_kamere, 2) + Math.pow(kameraZ, 2)));
|
|
|
|
*/
|
|
/*
|
|
camera.position.x = Math.sin((stevec % 10) / 10) * cam_rot_offset;
|
|
camera.position.y = Math.cos((stevec % 10) / 10) * cam_rot_offset;
|
|
*/
|
|
|
|
camera.lookAt(scene.position);
|
|
};
|
|
|
|
// Inicializiraj
|
|
document.onreadystatechange = function () {
|
|
if (document.readyState === 'complete') {
|
|
document.getElementById("anim-container").appendChild(renderer.domElement);
|
|
|
|
render();
|
|
}
|
|
};
|
|
|
|
// Lep risajz
|
|
function onWindowResize() {
|
|
camera.aspect = window.innerWidth / window.innerHeight;
|
|
camera.updateProjectionMatrix();
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
}
|
|
window.addEventListener('resize', onWindowResize, false);
|
|
|
|
|
|
function getVal(msg) {
|
|
return msg.value;
|
|
}
|
|
|
|
kbdPressed = {
|
|
a: false,
|
|
s: false,
|
|
d: false,
|
|
f: false
|
|
};
|
|
|
|
window.addEventListener('keydown', (e) => {
|
|
kbdPressed[e.key] = true;
|
|
})
|
|
|
|
window.addEventListener('keyup', (e) => {
|
|
if (e.key in kbdPressed) {
|
|
kbdPressed[e.key] = false;
|
|
}
|
|
})
|
|
|
|
function eulerFromQuaternion( quaternion, order ) {
|
|
// Quaternion to matrix.
|
|
const w = quaternion[0], x = quaternion[1], y = quaternion[2], z = quaternion[3];
|
|
const x2 = x + x, y2 = y + y, z2 = z + z;
|
|
const xx = x * x2, xy = x * y2, xz = x * z2;
|
|
const yy = y * y2, yz = y * z2, zz = z * z2;
|
|
const wx = w * x2, wy = w * y2, wz = w * z2;
|
|
const matrix = [
|
|
1 - ( yy + zz ),
|
|
xy + wz,
|
|
xz - wy,
|
|
0,
|
|
xy - wz,
|
|
1 - ( xx + zz ),
|
|
yz + wx,
|
|
0,
|
|
xz + wy,
|
|
yz - wx,
|
|
1 - ( xx + yy ),
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
1
|
|
];
|
|
// Matrix to euler
|
|
function clamp( value, min, max ) {
|
|
return Math.max( min, Math.min( max, value ) );
|
|
}
|
|
const m11 = matrix[ 0 ], m12 = matrix[ 4 ], m13 = matrix[ 8 ];
|
|
const m21 = matrix[ 1 ], m22 = matrix[ 5 ], m23 = matrix[ 9 ];
|
|
const m31 = matrix[ 2 ], m32 = matrix[ 6 ], m33 = matrix[ 10 ];
|
|
var euler = [ 0, 0, 0 ];
|
|
switch ( order ) {
|
|
case "XYZ":
|
|
euler[1] = Math.asin( clamp( m13, - 1, 1 ) );
|
|
if ( Math.abs( m13 ) < 0.9999999 ) {
|
|
euler[0] = Math.atan2( - m23, m33 );
|
|
euler[2] = Math.atan2( - m12, m11 );
|
|
} else {
|
|
euler[0] = Math.atan2( m32, m22 );
|
|
euler[2] = 0;
|
|
}
|
|
break;
|
|
case "YXZ":
|
|
euler[0] = Math.asin( - clamp( m23, - 1, 1 ) );
|
|
if ( Math.abs( m23 ) < 0.9999999 ) {
|
|
euler[1] = Math.atan2( m13, m33 );
|
|
euler[2] = Math.atan2( m21, m22 );
|
|
} else {
|
|
euler[1] = Math.atan2( - m31, m11 );
|
|
euler[2] = 0;
|
|
}
|
|
break;
|
|
case "ZXY":
|
|
euler[0] = Math.asin( clamp( m32, - 1, 1 ) );
|
|
if ( Math.abs( m32 ) < 0.9999999 ) {
|
|
euler[1] = Math.atan2( - m31, m33 );
|
|
euler[2] = Math.atan2( - m12, m22 );
|
|
} else {
|
|
euler[1] = 0;
|
|
euler[2] = Math.atan2( m21, m11 );
|
|
}
|
|
break;
|
|
case "ZYX":
|
|
euler[1] = Math.asin( - clamp( m31, - 1, 1 ) );
|
|
if ( Math.abs( m31 ) < 0.9999999 ) {
|
|
euler[0] = Math.atan2( m32, m33 );
|
|
euler[2] = Math.atan2( m21, m11 );
|
|
} else {
|
|
euler[0] = 0;
|
|
euler[2] = Math.atan2( - m12, m22 );
|
|
}
|
|
break;
|
|
case "YZX":
|
|
euler[2] = Math.asin( clamp( m21, - 1, 1 ) );
|
|
if ( Math.abs( m21 ) < 0.9999999 ) {
|
|
euler[0] = Math.atan2( - m23, m22 );
|
|
euler[1] = Math.atan2( - m31, m11 );
|
|
} else {
|
|
euler[0] = 0;
|
|
euler[1] = Math.atan2( m13, m33 );
|
|
}
|
|
break;
|
|
case "XZY":
|
|
euler[2] = Math.asin( - clamp( m12, - 1, 1 ) );
|
|
if ( Math.abs( m12 ) < 0.9999999 ) {
|
|
euler[0] = Math.atan2( m32, m22 );
|
|
euler[1] = Math.atan2( m13, m11 );
|
|
} else {
|
|
euler[0] = Math.atan2( - m23, m33 );
|
|
euler[1] = 0;
|
|
}
|
|
break;
|
|
}
|
|
return euler;
|
|
}
|
|
|
|
var oscCallbacks = {
|
|
'/keys/': [
|
|
function(args) {
|
|
keysPressed = args.map(getVal);
|
|
keysPressed[0] |= kbdPressed['a'];
|
|
keysPressed[1] |= kbdPressed['s'];
|
|
keysPressed[2] |= kbdPressed['d'];
|
|
keysPressed[3] |= kbdPressed['f'];
|
|
//console.log(keysPressed, kbdPressed);
|
|
}
|
|
],
|
|
'/quaternion/': [
|
|
function (args) {
|
|
// Popravimo osi (w x y z po defaultu HMM)
|
|
qWWo = qWW.clone();
|
|
[qWW.w, qWW.z, qWW.x, qWW.y] = args.map(getVal);
|
|
// Dve sta obratno :)
|
|
qWW.x *= -1;
|
|
qWW.z *= -1;
|
|
qWWd = qWW.clone();
|
|
qWWd.conjugate();
|
|
qWWd.multiply(qWWo);
|
|
|
|
var euler = eulerFromQuaternion([qWWd.w, qWWd.z, qWWd.x, qWWd.y], 'XYZ');
|
|
dqX = euler[0];
|
|
dqY = euler[1];
|
|
dqZ = euler[2];
|
|
}
|
|
],
|
|
/*
|
|
'/gyro/': [
|
|
function (args) {
|
|
var [gx, gy, gz] = args.map(getVal);
|
|
console.log(keysPressed)
|
|
|
|
|
|
if (keysPressed[2]) {
|
|
rotacijaX += gyro[0] - gx
|
|
rotacijaY += gyro[1] - gy
|
|
rotacijaZ += gyro[2] - gz
|
|
}
|
|
if (keysPressed[3]) {
|
|
drotacijaX += gyro[0] - gx
|
|
drotacijaY += gyro[1] - gy
|
|
drotacijaZ += gyro[2] - gz
|
|
}
|
|
|
|
if (keysPressed[1]) {
|
|
kameraX += gyro[0] - gx
|
|
FOV *= 1 + (gy - gyro[1])
|
|
//kameraY += gyro[1] - gy
|
|
//kameraZ += gyro[2] - gz
|
|
}
|
|
|
|
if (keysPressed[0]) {
|
|
zamikBarve *= 1 + (gx - gyro[0])
|
|
obj_limit *= 1 + (gy - gyro[1])
|
|
width *= 1 + (gz - gyro[2])
|
|
}
|
|
|
|
gyro = [gx, gy, gz]
|
|
}
|
|
],
|
|
*/
|
|
}
|