Refaktoriranje, fraktalni objekti, pedalka 3d modeli, WIP kontrole

main
Jurij Podgoršek 2023-06-16 16:32:28 +02:00
parent 61adbf6b60
commit 73d79ccf3e
43 changed files with 93245 additions and 750 deletions

View File

@ -1,5 +1,5 @@
1. FFT noise od blizu, ni rotacije + ko pridejo zogice pulziranje
2. dodamo vrtenjek
2. dodamo vrtenje
Ideje:

BIN
3d/fedre.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
3d/pedalka-Body.stl 100644

Binary file not shown.

BIN
3d/pedalka.FCStd 100644

Binary file not shown.

BIN
3d/pedalka.FCStd1 100644

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Example OpenOCD configuration file for ESP32-WROVER-KIT board.
#
# For example, OpenOCD can be started for ESP32 debugging on
#
# openocd -f board/esp32-wrover-kit-3.3v.cfg
#
# Source the JTAG interface configuration file
source [find interface/ftdi/esp32_devkitj_v1.cfg]
set ESP32_FLASH_VOLTAGE 3.3
# Source the ESP32 configuration file
source [find target/esp32.cfg]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
{
"name":"Arduino on ESP32",
"toolchainPrefix":"xtensa-esp32-elf",
"svdFile":"debug.svd",
"request":"attach",
"postAttachCommands":[
"set remote hardware-watchpoint-limit 2",
"monitor reset halt",
"monitor gdb_sync",
"thb setup",
"c"
],
"overrideRestartCommands":[
"monitor reset halt",
"monitor gdb_sync",
"thb setup",
"c"
]
}

View File

@ -1,21 +1,26 @@
# kegel
# Glasbena miza
Mere:
Najdaljši premer: 82mm
Špica: 15mm
Ta zbirka vsebuje kodo, s pomočjo katere lahko kegle spremenimo v inštrumente. To dosežemo z vgradnjo ESP32 mikrokrmilnikov in MPU9255 gibalnih senzorjev.
## Mere
Najdaljši premer - 82mm
Špica - 15mm
32mm je lahko dolg vstavek
27mm je široka spodnja odprtina (blizu držalu)
Zapečemo ga s strani (izrez + prispajk nazaj)
## TODO
- Li-poly baterije
- konektorji za baterije
- gumbi za vklop
- še en kegel sestaviva
- napajanje za rock pi X (QC3.0)
- mikrofon naredit v kegel
- wifi na tablico ALI drug displej
- pedalko sprintat in povezat
- bluetooth; je stabilen?
- senzorji včasih ne odštejejo gravitacije
## Kako?
## Razno
Problem s flashanjem:
```
esp_core_dump_flash: Core dump flash config is corrupted! CRC=0x7bd5c66f instead of 0x0
```
V arduino IDE nastaviš `Flash mode` na "DIO" namesto "QIO".

View File

@ -34,7 +34,7 @@ oscWS.on('ready', () => {
*/
})
const zaznava = [2, 2.5, 2, 2, 2, 2]
const zaznava = [2, 2, 2, 2, 2, 2]
const utisaj_vse = 0.2
let utisaj_c = [0, 0, 0, 0, 0, 0]
let cakaj = [false, false, false, false, false, false]

720
kegli.js
View File

@ -1,720 +0,0 @@
console.log("Hello, Sky!");
/**** ******
/ Test skripta *
************/
// Ker kegel imamo?
var izbranKegel = 1;
if (window.location.hash.indexOf('kegel') > -1) {
izbranKegel = window.location.hash.split('=')[1];
console.log('definiran kegel!');
}
console.log('izbran kegel: ', izbranKegel);
// Vidni kot
var FOV = 90;
// Parametri rotacije (euler)
var rotacijaX = 0.000;
var rotacijaY = 0.000;
var rotacijaZ = 0.000;
// Parametri pospeska
var accX = 0.000;
var accY = 0.000;
var accZ = 0.000;
var deformiraj = 0;
// Analiza zvoka
const fftSize = 64
const bufferSize = 32
const stolpicki = new Uint8Array(bufferSize)
let analyser = null
// "Napihni" kegle?
let napihni = 1
// Scena, kamera in render
var scene = new THREE.Scene;
window.scene = scene;
/*
const axesHelper = new THREE.AxesHelper( 5 );
scene.add( axesHelper );
*/
var camera = new THREE.PerspectiveCamera(FOV, window.innerWidth / window.innerHeight, 0.1, 2000);
window.camera = camera;
// Polozaj kamere
camera.position.z = 10;
var renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
// Belo ozadje
renderer.setClearColor(0xFFFFFF, 1);
// Črno ozadje
//renderer.setClearColor(0x000000, 1);
//var skupina = new THREE.Group();
/********
* KEGEL *
*********/
// Sirina in visina test objekta
var width = 16;
var height = 128;
var radialnihSegmentov = 4;
var visinskihSegmentov = 128;
var geo = new THREE.BufferGeometry();
var offset = width;
var polozaji = [];
// visina: 128 segmentov
// sirina: 9 segmentov
var sirinaSegmentov = 9;
// Najprej "spodnja buba"
var faktor = [
2/sirinaSegmentov, 2/sirinaSegmentov
];
// Pol rocaj (1.4 do 2.8 segmenta, dolgo 62 segmentov)
var rocajSegmentov = 46;
for (var i = 0; i <= rocajSegmentov; i++) {
faktor.push((1.4 + i / rocajSegmentov * 1.4) / sirinaSegmentov);
}
// pol stresica dol (2.8 do 7.4 segmenta)
var stresicaSegmentov = 48;
for (i = 0; i <= stresicaSegmentov; i++) {
faktor.push((2.8 + i / stresicaSegmentov * 4.6) / sirinaSegmentov);
}
// Pa se zadnji naklon (7.4 do 3 segmente)
var konecSegmentov = 30;
for (i = 0; i <= konecSegmentov; i++) {
faktor.push((7.4 - i / konecSegmentov * 4.4) / sirinaSegmentov);
}
// spodnji krog
for (var s = 0; s < radialnihSegmentov; s++) {
polozaji.push(
0.0,
0.0,
0.0,
Math.sin(2 * Math.PI * s / radialnihSegmentov) * width * faktor[0],
Math.cos(2 * Math.PI * s / radialnihSegmentov) * width * faktor[0],
0.0,
Math.sin(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[0],
Math.cos(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[0],
0.0
);
}
// vmesni segmenti
for (var h = 0; h < visinskihSegmentov; h++) {
for (s = 0; s < radialnihSegmentov; s++) {
polozaji.push(
Math.sin(2 * Math.PI * s / radialnihSegmentov) * width * faktor[h],
Math.cos(2 * Math.PI * s / radialnihSegmentov) * width * faktor[h],
h * height / visinskihSegmentov,
Math.sin(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[h],
Math.cos(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[h],
h * height / visinskihSegmentov,
Math.sin(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[h],
Math.cos(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[h],
(h + 1) * height / visinskihSegmentov,
);
}
}
// zgornji krog
for (s = 0; s < radialnihSegmentov; s++) {
polozaji.push(
0,
0,
height,
Math.sin(2 * Math.PI * s / radialnihSegmentov) * width * faktor[31],
Math.cos(2 * Math.PI * s / radialnihSegmentov) * width * faktor[31],
height,
Math.sin(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[31],
Math.cos(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[31],
height
);
}
for (i = 0; i < polozaji.length; i++) {
if (i % 3 == 2) {
polozaji[i] -= height / 2;
}
}
// Spremeni v vertexe
var vertices = new Float32Array(polozaji);
geo.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
window.geo = geo;
var barva = new THREE.Color(0, 0, 0);
var barvaDodatni = new THREE.Color();
barvaDodatni.setHSL(0.6, 1.0, 0.5);
var mat = new THREE.MeshBasicMaterial({
//color: 0xff00ff,
color: barva,
wireframe: true,
transparent: true
});
window.mat = mat;
//var mat = new THREE.LineBasicMaterial({ color: 0xff00ff });
var kegel = new THREE.Mesh(geo.clone(), mat);
kegel.position.z = 20; // gor / dol
kegel.position.y = -30; // levo / desno
kegel.position.x = 12; // levo / desno drugic
if (izbranKegel == 1) {
kegel.position.x -= 10;
kegel.position.y += 8;
kegel.position.z += 3;
}
var barvnePalete = [
[0x0a2d2e, 0x1c4e4f, 0x436e6f, 0x6a8e8f, 0x879693, 0xa49e97, 0xdeae9f, 0xefd7cf, 0xf7ebe7, 0xffffff],
// https://colorkit.co/palette/0a2d2e-1c4e4f-436e6f-6a8e8f-879693-a49e97-deae9f-efd7cf-f7ebe7-ffffff/
[0x80558c, 0xaf7ab3, 0xcba0ae, 0xd8b9a0, 0xe4d192],
// https://colorkit.co/palette/80558c-af7ab3-cba0ae-d8b9a0-e4d192/
[0xf68aa2, 0xcf6d93, 0xa85183, 0x813474, 0x5a1765],
// https://colorkit.co/palette/f68aa2-cf6d93-a85183-813474-5a1765/
[0x03071e, 0x211c1b, 0x3d3019, 0x594417, 0x745814, 0x906b12, 0xac7f0f, 0xc8930d, 0xe3a60a, 0xffba08]
// https://colorkit.co/palette/03071e-211c1b-3d3019-594417-745814-906b12-ac7f0f-c8930d-e3a60a-ffba08/
]
var barvnePaleteIdx = [0, 0, 0, 0]
/*********
* ZOGICE *
*********/
var zogice = false
var kegli = false
/*
var barvnaPaleta = [
new THREE.Color(0x003F5C),
new THREE.Color(0x58508D),
new THREE.Color(0xBC5090),
new THREE.Color(0xFF6361),
new THREE.Color(0xFFA600),
// Simetrija
new THREE.Color(0xFF6361),
new THREE.Color(0xBC5090),
new THREE.Color(0x58508D),
];
console.log(barvnaPaleta);
var barvnaPaletaIdx = 0;
*/
var barvaKrogleO = new THREE.Color();
barvaKrogleO.setHSL(Math.random(), 0.8, 0.5);
function novaKrogla () {
//var barvaKrogle = barvaKrogleO.clone();
var bId = izbranKegel == 0 ? 2 : 3
console.log('id barve:', bId);
var barvaKrogle = new THREE.Color(barvnePalete[bId][barvnePaleteIdx[bId]]);
var mat = new THREE.MeshBasicMaterial({
color: barvaKrogle,
wireframe: true,
transparent: true
});
var velikost = 1 + Math.random() * 5;
var kroglaGeo = new THREE.SphereGeometry(velikost, 12, 12);
var krogla = new THREE.Mesh(kroglaGeo, mat);
krogla.position.x = (Math.random() - 1) * 200;
krogla.position.y = (Math.random() - 1) * 10;
krogla.position.z = (Math.random() - 1) * 300;
krogla.position.y -= 100;
krogla.position.x += 150;
krogla.position.z += 230; // gor/dol
//krogla.position.y += 200;
scene.add(krogla);
krogle.push(krogla);
}
function spremeniZoom (kolicina) {
const noviZum = camera.position.z * (1 + kolicina / 25)
console.log(noviZum)
if ((noviZum > 0.1) && (noviZum < 300)) {
camera.position.z = noviZum
}
}
function spremeniDeformiraj (kolicina) {
const noviDeformiraj = deformiraj + (kolicina / 2)
//console.log('deform', noviDeformiraj)
if (noviDeformiraj > 0) {
deformiraj = noviDeformiraj
} else {
deformiraj = 0
}
}
//skupina.add(kegel);
// Za pospeskomer - os X
var gAX = new THREE.CylinderGeometry(10, 10, 10, 16);
var mAX = new THREE.MeshBasicMaterial({ color: 0xff000055 });
var AX = new THREE.Mesh(gAX, mAX);
//skupina.add(AX);
// Damo vse skupaj v kader
// scene.add(skupina);
scene.add(kegel);
// Quaternioni za rotacijo in kalibracijo
var qWW = new THREE.Quaternion();
var qPrej = new THREE.Quaternion();
var qObj = new THREE.Quaternion();
var qStart = new THREE.Quaternion();
var reset = false;
var calibrate = true;
var objekti = [kegel];
var dodatniObjekti = [];
var krogle = [];
var stevec = 0;
// Zacetna orientacija kegla
scene.rotation.x = 90;
scene.rotation.z = 270;
//skupina.position.z = 32;
//skupina.position.y = -100;
var cakajDeformiraj = false
var cakajZogice = false
var cakajKegli = false
let analiziramZvok = false
function inputHandle () {
if (kbdPressed.c) {
calibrate = true;
sendAll('/ww/calibrate');
}
if (kbdPressed['-']) {
sendAll('/ww/reload');
window.location.reload();
}
/*
if (kbdPressed.d && !cakajDeformiraj) {
deformiraj = !deformiraj
cakajDeformiraj = true
const args = [{
type: "f",
value: deformiraj
}];
sendAll('/ww/zoom', args)
setTimeout(() => cakajDeformiraj = false, 200)
}
*/
if (kbdPressed.g && !cakajZogice) {
zogice = !zogice
cakajZogice = true
const args = [{
type: "i",
value: zogice ? 1 : 0
}];
sendAll('/ww/zogice', args)
setTimeout(() => cakajZogice = false, 200)
}
if (kbdPressed['l'] && !cakajKegli) {
kegli = !kegli
console.log('sprememba kegli', kegli)
cakajKegli = true
const args = [{
type: "i",
value: kegli ? 1 : 0
}];
sendAll('/ww/kegli', args)
setTimeout(() => cakajKegli = false, 200)
}
}
function render () {
requestAnimationFrame(render);
renderer.render(scene, camera);
stevec += 1;
objAnim();
inputHandle();
while (krogle.length > 50) {
scene.remove(krogle[0]);
krogle.shift();
}
};
var cakajDodatni = false
// Funkcija za animacijo objektov
function objAnim() {
// Rotacija kegla
objekti.map(function (obj) {
// Apliciramo rotacijo (po quaternionih - eulerji zajebavajo.)
qObj = qWW.clone();
qObj.multiply(qStart);
obj.setRotationFromQuaternion(qObj);
AX.scale.x = accX / 1000;
if (analyser) {
analyser.getByteFrequencyData(stolpicki)
deformiraj = (stolpicki[3] + stolpicki[4] + stolpicki[5]) / 30
//console.log('FFT!', stolpicki)
//napihni = 1 + stolpicki[0] / 10
}
obj.scale.z = napihni
if (napihni > 1) {
obj.scale.x = napihni * 2
obj.scale.y = napihni * 2
napihni = Math.max(napihni * 0.9, 1)
} else {
obj.scale.x = 1
obj.scale.y = 1
}
// Deformiranje kegla!
// Random 500 zamaknemo
var koti = obj.geometry.attributes.position.array;
var faktorD = 5;
/*
// Random deformacija
for (var i = 0; i < 500; i++) {
koti[Math.floor(Math.random() * koti.length)] += (Math.random() - 1) * deformiraj;
}
*/
// Deformacija po stolpickih FFT
for (var i = 0; i < koti.length / 10; i += 1) {
const stolpLen = 10;
const stolpOffset = 0;
const offset = Math.floor(Math.random() * 3)
const vrednost = stolpicki[Math.floor(i * 10 / koti.length * stolpLen) + stolpOffset]
/*
if (i % 1000 == 0) {
console.log('+', i, vrednost)
}
*/
const neg = (Math.random() > 0.5) ? 1 : -1
//console.log(offset, vrednost, neg)
koti[koti.length - (i * 10 + offset)] += vrednost / 50 * neg
}
// In priblizamo osnovni geometriji
for (var i = 0; i < koti.length; i++) {
// Tole zamika cel kegel stran @TODO
//koti[i] = (geo.attributes.position.array[i] - koti[i]) * 0.75;
koti[i] = (geo.attributes.position.array[i] - koti[i]) * 0.75;
}
obj.geometry.attributes.position.needsUpdate = true;
});
// Ce jih je prevec, pucaj
while (dodatniObjekti.length > 100) {
scene.remove(dodatniObjekti[0]);
dodatniObjekti.shift();
}
dodatniObjekti.map(function (obj) {
// Apliciramo rotacijo (po quaternionih - eulerji zajebavajo.)
qObj = qWW.clone();
//qObj.multiply(obj.qStart).multiply(qStart);
//obj.setRotationFromQuaternion(qObj);
obj.translateOnAxis(obj.premakniAxis, obj.premakniKolicina);
// obj.material.color.offsetHSL(0, 0, 0.003);
obj.material.opacity *= 0.998;
obj.premakniKolicina *= 0.98;
var dQ = obj.quaternion.multiply(obj.rotirajQ);
/*
dQ.multiply(obj.rotirajQ);
obj.setRotationFromQuaternion(dQ);
*/
/*
obj.premakni.x *= 1.1;
obj.premakni.y *= 1.1;
obj.premakni.z *= 1.1;
*/
obj.material.opacity *= 0.98;
});
barvaKrogleO.offsetHSL(-(2/1000), 0, 0);
krogle.map(function (obj) {
obj.material.opacity *= 0.98;
var scaleF = 0.05;
obj.scale.x += scaleF;
obj.scale.y += scaleF;
obj.scale.z += scaleF;
});
// Kalibracija rotacije kegla
if (calibrate) {
qStart = qWW.clone();
qStart.conjugate();
calibrate = false;
console.log("RESET!");
}
// rotiramo skupino da se vidi
//skupina.rotation.x += 0.003;
//skupina.rotation.y += 0.005;
//skupina.rotation.z += 0.007;
if (kegel.scale.x > 1) {
kegel.scale.x *= 0.95;
}
if (kegel.scale.z > 1) {
kegel.scale.z *= 0.95;
}
// kegel.material.color.offsetHSL(2 / 1000, 0, 0);
// Dupliranje keglov
if (kegli) {
var vsota = Math.abs(accX) + Math.abs(accZ)
if (vsota > 2 && !cakajDodatni) {
cakajDodatni = true
var dodatni = kegel.clone();
dodatni.renderOrder = stevec;
var dodatniMat = kegel.material.clone();
//var dodatniBarva = barvaDodatni.clone();
var bId = izbranKegel == 0 ? 0 : 1
var dodatniBarva = new THREE.Color(barvnePalete[bId][barvnePaleteIdx[bId]])
dodatniMat.color = dodatniBarva;
dodatni.material = dodatniMat;
dodatni.premakniAxis = new THREE.Vector3(
Math.random(),
Math.random(),
Math.random()
);
dodatni.premakniKolicina = vsota;
var rQ = qWW.clone();
rQ.invert();
rQ.multiply(qPrej);
dodatni.rotirajQ = rQ;
//dodatni.qStart = kegel.quaternion.clone();
dodatniObjekti.push(dodatni);
scene.add(dodatni);
barvnePaleteIdx[bId] = (barvnePaleteIdx[bId] + 1) % barvnePalete[bId].length;
}
if (cakajDodatni && vsota < 1) {
cakajDodatni = false
}
}
};
// 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);
// Poslusaj OSC evente
var keysPressed = [0, 0, 0, 0];
const getVal = function (msg) {
return msg.value;
}
var prepend = `/ww/0/ww/${izbranKegel}`;
console.log('prepend!', prepend);
var oscCallbacks = {};
oscCallbacks[`${prepend}'/keys`] = function(args) {
keysPressed = args.map(getVal);
};
oscCallbacks[`${prepend}/quaternion`] = function (args) {
// Popravimo osi (w x y z po defaultu HMM)
[qPrej.w, qPrej.x, qPrej.y, qPrej.z] = [qWW.w, qWW.x, qWW.y, qWW.z];
[qWW.w, qWW.x, qWW.y, qWW.z] = args.map(getVal);
};
oscCallbacks[`${prepend}/accel`] = function (args) {
[accX, accY, accZ] = args.map(getVal);
};
oscCallbacks[`${prepend}/gyro`] = function (args) {
[rotacijaX, rotacijaY, rotacijaZ] = args.map(getVal);
};
oscCallbacks['/ww/calibrate'] = function () {
calibrate = true;
};
oscCallbacks['/ww/reload'] = function () {
window.location.reload();
};
oscCallbacks['/ww/zoom'] = args => {
const [kolicina] = args.map(getVal)
spremeniZoom(kolicina)
}
oscCallbacks['/ww/deformiraj'] = args => {
const [kolicina] = args.map(getVal)
spremeniDeformiraj(kolicina)
}
oscCallbacks['/ww/kegli'] = args => {
const [ali] = args.map(getVal)
kegli = ali
}
oscCallbacks['/ww/zogice'] = args => {
const [ali] = args.map(getVal)
zogice = ali
}
function zogicaCB(args) {
console.log("MAMOMO MIDI!", args[0].value, args[1].value, args[2].value);
var minus = (izbranKegel == 1) ? -1 : 1;
// kegel.material.color.offsetHSL(minus * args[2].value / 1000, 0, 0);
barvaDodatni.offsetHSL(minus * args[2].value / 1000, 0, 0);
if (Math.random() < 0.5) {
kegel.scale.x *= 2;
} else {
kegel.scale.z *= 2;
}
//kegel.scale.y *= 1 + (args[2] / 100000);
//kegel.scale.z *= 1 + (args[2] / 100000);
if (zogice) {
novaKrogla();
var bId = izbranKegel == 0 ? 2 : 3
console.log('id barve:', bId)
barvnePaleteIdx[bId] = (barvnePaleteIdx[bId] + 1) % barvnePalete[bId].length;
}
napihni = 3
}
oscCallbacks['/midi-in/0'] = zogicaCB
const kbdPressed = {
a: false,
s: false,
d: false,
f: false,
c: false
};
window.addEventListener('keydown', e => {
kbdPressed[e.key] = true
})
window.addEventListener('keyup', e => {
if (e.key in kbdPressed) {
kbdPressed[e.key] = false
}
})
window.addEventListener('mousedown', e => {
e.preventDefault()
switch (e.button) {
case 0:
kbdPressed['miska'] = true
if (!analiziramZvok) {
zacniAnalizo()
}
break;
case 2:
kbdPressed['miskaD'] = true
}
return false
})
window.addEventListener('mouseup', e => {
if ('miska' in kbdPressed) {
kbdPressed['miska'] = false
}
if ('miskaD' in kbdPressed) {
kbdPressed['miskaD'] = false
}
})
var skrolam = false;
var zadnjiSkrol = 0;
window.addEventListener('mousemove', e => {
if (kbdPressed['miska']) {
const sprememba = (e.movementX + e.movementY) / 10
spremeniZoom(sprememba)
const args = [{
type: "f",
value: sprememba
}];
sendAll('/ww/zoom', args)
}
if (kbdPressed['miskaD']) {
const sprememba = (e.movementX + e.movementY) / 10
spremeniDeformiraj(sprememba)
const args = [{
type: "f",
value: sprememba
}];
sendAll('/ww/deformiraj', args)
}
})
// Zacni audio analizo
function zacniAnalizo() {
if (!analiziramZvok) {
// Analiza zvoka
const audioCtx = new AudioContext()
const mikrofon = navigator.mediaDevices.getUserMedia({ audio: true }).then(
(stream) => {
const source = audioCtx.createMediaStreamSource(stream)
analyser = audioCtx.createAnalyser()
analyser.minDecibels = -90;
analyser.maxDecibels = -10;
analyser.smoothingTimeConstant = 0.85;
analyser.fftSize = fftSize
source.connect(analyser)
//analyser.connect(audioCtx.destination)
},
() => {
console.log('napaka nalaganja mikrofona', arguments)
analiziramZvok = false
}
)
analiziramZvok = true
}
}

View File

@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Example OpenOCD configuration file for ESP32-WROVER-KIT board.
#
# For example, OpenOCD can be started for ESP32 debugging on
#
# openocd -f board/esp32-wrover-kit-3.3v.cfg
#
# Source the JTAG interface configuration file
source [find interface/ftdi/esp32_devkitj_v1.cfg]
set ESP32_FLASH_VOLTAGE 3.3
# Source the ESP32 configuration file
source [find target/esp32.cfg]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
{
"name":"Arduino on ESP32",
"toolchainPrefix":"xtensa-esp32-elf",
"svdFile":"debug.svd",
"request":"attach",
"postAttachCommands":[
"set remote hardware-watchpoint-limit 2",
"monitor reset halt",
"monitor gdb_sync",
"thb setup",
"c"
],
"overrideRestartCommands":[
"monitor reset halt",
"monitor gdb_sync",
"thb setup",
"c"
]
}

View File

@ -3,7 +3,7 @@
#include <Wire.h>
// ID kegla mora bit unikaten za vsakega! (se poslje poleg parametrov)
#define KEGEL_ID 2
#define KEGEL_ID 1
// IMU libraries
#include "I2Cdev.h"
@ -100,8 +100,6 @@ void setup() {
return;
}
//esp_now_register_send_cb(paketPoslan);
memcpy(peerInfo.peer_addr, sprejemnikMac, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
@ -112,15 +110,6 @@ void setup() {
}
}
void paketPoslan(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nStanje poslanega paketa:\t");
if (status == ESP_NOW_SEND_SUCCESS) {
Serial.println("Uspesno poslano!");
} else {
Serial.println("Napaka pri posiljanju...");
}
}
void loop() {
unsigned long now = millis();
unsigned long delta;

11
package-lock.json generated
View File

@ -11,6 +11,7 @@
"midi": "^2.0.0",
"nodemon": "^2.0.16",
"osc": "^2.4.2",
"three": "0.135.0",
"ws": "^7.3.1"
}
},
@ -1329,6 +1330,11 @@
"node": ">=4"
}
},
"node_modules/three": {
"version": "0.135.0",
"resolved": "https://registry.npmjs.org/three/-/three-0.135.0.tgz",
"integrity": "sha512-kuEpuuxRzLv0MDsXai9huCxOSQPZ4vje6y0gn80SRmQvgz6/+rI0NAvCRAw56zYaWKMGMfqKWsxF9Qa2Z9xymQ=="
},
"node_modules/to-readable-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
@ -2468,6 +2474,11 @@
"has-flag": "^3.0.0"
}
},
"three": {
"version": "0.135.0",
"resolved": "https://registry.npmjs.org/three/-/three-0.135.0.tgz",
"integrity": "sha512-kuEpuuxRzLv0MDsXai9huCxOSQPZ4vje6y0gn80SRmQvgz6/+rI0NAvCRAw56zYaWKMGMfqKWsxF9Qa2Z9xymQ=="
},
"to-readable-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",

View File

@ -6,6 +6,7 @@
"midi": "^2.0.0",
"nodemon": "^2.0.16",
"osc": "^2.4.2",
"three": "0.135.0",
"ws": "^7.3.1"
},
"scripts": {

BIN
tik.wav 100644

Binary file not shown.

13
web/config.js 100644
View File

@ -0,0 +1,13 @@
const SERVER_IP = '192.168.1.101'
const SERVER_PORT = 6676
const PROTO = 'ws'
// Ker kegel imamo?
const IZBRAN = (window.location.hash.indexOf('kegel') > -1)
? parseInt(window.location.hash.split('=')[1])
: 0
console.log('izbran kegel: ', IZBRAN);
const ST_KEGLOV = 2
const PREPEND = `/ww/0/ww/`
console.log('OSC predpona', PREPEND);

28
web/ctl.css 100644
View File

@ -0,0 +1,28 @@
body { margin: 0; }
.container {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
table {
margin-left: auto;
margin-right: auto;
border: 1px solid black;
}
button {
width: 100%;
height: 100%;
}
#scene {
display: flex;
flex-direction: row;
}
.gumb {
width: 5rem;
}

40
web/ctl.html 100644
View File

@ -0,0 +1,40 @@
<html>
<head>
<meta charset="UTF-8">
<title>nastavitve &gt;&lt; glasbena miza</title>
<link rel="stylesheet" href="ctl.css">
</head>
<body>
<section class="container">
<table id="ctl">
<tr>
<th colspan="3">SCENE</th>
</tr>
<tr><td><div id="scene"></div></td></tr>
<tr>
<th colspan="3">
NASTAVITVE
</th>
</tr>
<tr>
<td>šum 1</td>
<td class="gumb">
<button id="sum1">&nbsp;</button>
</td>
</tr>
<tr>
<td>šum 2</td>
<td class="gumb">
<button id="sum1">&nbsp;</button>
</td>
</tr>
</table>
</section>
<script src="node_modules/osc/dist/osc-browser.js"></script>
<script src="config.js"></script>
<script src="osctl.js"></script>
<script src="ctl.js"></script>
</body>
</html>

56
web/ctl.js 100644
View File

@ -0,0 +1,56 @@
const scene = {
'scena 1': () => {
},
'scena 2': () => {
},
'scena 3': () => {
}
}
const gumbi = {
'kalibriraj': () => {
console.log('kalibriram')
sendAll('/ww/calibrate')
}
}
const qs = s => document.querySelector(s)
const qsa = s => document.querySelectorAll(s)
const ce = e => document.createElement(e)
window.addEventListener('DOMContentLoaded', () => {
// Dodaj scene
const sceneTD = qs('#scene')
Object.keys(scene).forEach(ime => {
const b = ce('button')
b.innerHTML = ime
b.onclick = () => {
console.log('izbiram ', ime)
scene[ime]()
}
sceneTD.append(b)
})
// Dodaj gumbe
const gumbiT = qs('#ctl')
Object.keys(gumbi).forEach(ime => {
const v = ce('tr')
const ic = ce('td')
ic.append(ime)
v.append(ic)
const g = ce('button')
g.id = 'gumb_' + ime
g.innerHTML = '&nbsp;'
const gc = ce('td')
gc.append(g)
v.append(gc)
g.onclick = () => {
console.log('spreminjam', ime)
gumbi[ime]()
}
gumbiT.append(v)
})
})

34
web/fft.js 100644
View File

@ -0,0 +1,34 @@
// Analiza zvoka
let analiziramZvok = false
let analyser = null
const fftSize = 64
const bufferSize = 32
const stolpicki = new Uint8Array(bufferSize)
// Zacni audio analizo
function zacniAnalizo() {
if (!analiziramZvok) {
// Analiza zvoka
const audioCtx = new AudioContext()
const mikrofon = navigator.mediaDevices.getUserMedia({ audio: true }).then(
(stream) => {
const source = audioCtx.createMediaStreamSource(stream)
analyser = audioCtx.createAnalyser()
analyser.minDecibels = -90;
analyser.maxDecibels = -10;
analyser.smoothingTimeConstant = 0.85;
analyser.fftSize = fftSize
source.connect(analyser)
},
() => {
console.log('napaka nalaganja mikrofona', arguments)
analiziramZvok = false
}
)
analiziramZvok = true
}
}

View File

@ -11,7 +11,13 @@
<script src="node_modules/three/build/three.min.js"></script>
<script src="node_modules/osc/dist/osc-browser.js"></script>
<script src="kegli.js"></script>
<script src="config.js"></script>
<script src="osctl.js"></script>
<script src="osc_callbacks.js"></script>
<script src="kegel.js"></script>
<script src="zoga.js"></script>
<script src="fft.js"></script>
<script src="izris.js"></script>
<script src="input.js"></script>
</body>
</html>

110
web/input.js 100644
View File

@ -0,0 +1,110 @@
const kbdPressed = {
a: false,
s: false,
d: false,
f: false,
c: false
};
function inputHandle () {
if (kbdPressed.c) {
calibrate = true;
sendAll('/ww/calibrate');
}
if (kbdPressed['-']) {
sendAll('/ww/reload');
window.location.reload();
}
/*
if (kbdPressed.d && !cakajDeformiraj) {
deformiraj = !deformiraj
cakajDeformiraj = true
const args = [{
type: "f",
value: deformiraj
}];
sendAll('/ww/zoom', args)
setTimeout(() => cakajDeformiraj = false, 200)
}
*/
if (kbdPressed.g && !cakajZogice) {
zogice = !zogice
cakajZogice = true
const args = [{
type: "i",
value: zogice ? 1 : 0
}];
sendAll('/ww/zogice', args)
setTimeout(() => cakajZogice = false, 200)
}
if (kbdPressed['l'] && !cakajDodatniKegli) {
dodatniKegli = !dodatniKegli
console.log('sprememba kegli', dodatniKegli)
cakajDodatniKegli = true
const args = [{
type: "i",
value: dodatniKegli ? 1 : 0
}];
sendAll('/ww/kegli', args)
setTimeout(() => cakajDodatniKegli = false, 200)
}
}
window.addEventListener('keydown', e => {
kbdPressed[e.key] = true
})
window.addEventListener('keyup', e => {
if (e.key in kbdPressed) {
kbdPressed[e.key] = false
}
})
window.addEventListener('mousedown', e => {
e.preventDefault()
switch (e.button) {
case 0:
kbdPressed['miska'] = true
if (!analiziramZvok) {
zacniAnalizo()
}
break;
case 2:
kbdPressed['miskaD'] = true
}
return false
})
window.addEventListener('mouseup', e => {
if ('miska' in kbdPressed) {
kbdPressed['miska'] = false
}
if ('miskaD' in kbdPressed) {
kbdPressed['miskaD'] = false
}
})
var skrolam = false;
var zadnjiSkrol = 0;
window.addEventListener('mousemove', e => {
if (kbdPressed['miska']) {
const sprememba = (e.movementX + e.movementY) / 10
spremeniZoom(sprememba)
const args = [{
type: "f",
value: sprememba
}];
sendAll('/ww/zoom', args)
}
if (kbdPressed['miskaD']) {
const sprememba = (e.movementX + e.movementY) / 10
spremeniDeformiraj(sprememba)
const args = [{
type: "f",
value: sprememba
}];
sendAll('/ww/deformiraj', args)
}
})

332
web/izris.js 100644
View File

@ -0,0 +1,332 @@
console.log("Hello, Sky!");
/**** ******
/ KEGLI *
************/
// Vidni kot
var FOV = 90;
var deformiraj = 0;
const izbraniStolpicki = [0, 4, 8, 12]
// "Napihni" kegle?
let napihni = 1
// Scena, kamera in render
var scene = new THREE.Scene;
window.scene = scene;
/*
const axesHelper = new THREE.AxesHelper( 5 );
scene.add( axesHelper );
*/
var camera = new THREE.PerspectiveCamera(FOV, window.innerWidth / window.innerHeight, 0.1, 2000);
window.camera = camera;
// Polozaj kamere
camera.position.z = 30;
var renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
// Belo ozadje
renderer.setClearColor(0xFFFFFF, 1);
// Črno ozadje
//renderer.setClearColor(0x000000, 1);
var barvnePalete = [
[0x0a2d2e, 0x1c4e4f, 0x436e6f, 0x6a8e8f, 0x879693, 0xa49e97, 0xdeae9f, 0xefd7cf, 0xf7ebe7, 0xffffff],
// https://colorkit.co/palette/0a2d2e-1c4e4f-436e6f-6a8e8f-879693-a49e97-deae9f-efd7cf-f7ebe7-ffffff/
[0x80558c, 0xaf7ab3, 0xcba0ae, 0xd8b9a0, 0xe4d192],
// https://colorkit.co/palette/80558c-af7ab3-cba0ae-d8b9a0-e4d192/
[0xf68aa2, 0xcf6d93, 0xa85183, 0x813474, 0x5a1765],
// https://colorkit.co/palette/f68aa2-cf6d93-a85183-813474-5a1765/
[0x03071e, 0x211c1b, 0x3d3019, 0x594417, 0x745814, 0x906b12, 0xac7f0f, 0xc8930d, 0xe3a60a, 0xffba08]
// https://colorkit.co/palette/03071e-211c1b-3d3019-594417-745814-906b12-ac7f0f-c8930d-e3a60a-ffba08/
]
var barvnePaleteIdx = [0, 0, 0, 0]
let zogice = false
let dodatniKegli = false
/*
var barvnaPaleta = [
new THREE.Color(0x003F5C),
new THREE.Color(0x58508D),
new THREE.Color(0xBC5090),
new THREE.Color(0xFF6361),
new THREE.Color(0xFFA600),
// Simetrija
new THREE.Color(0xFF6361),
new THREE.Color(0xBC5090),
new THREE.Color(0x58508D),
];
console.log(barvnaPaleta);
var barvnaPaletaIdx = 0;
*/
var objekti = [getKegel(), getKegel()];
for (let i = 0; i < ST_KEGLOV; i++) {
//objekti[i].rotation = qWW[i]
}
// "Zunanji" kegel
objekti[1].scale.x = 10
objekti[1].scale.z = 10
objekti[1].scale.y = 10
var dodatniObjekti = []
var krogle = []
var stevec = 0
// Fraktaliziraj (kegel znotraj kegla manjsanje)
let fraktaliziraj = 1
let fraktal_meje = [
new THREE.Vector3(0.1, 0.1, 0.1),
new THREE.Vector3(10, 10, 10)
]
let fraktal_sprememba = new THREE.Vector3(0.98, 0.98, 0.98)
let fraktal_interval = 2500
let fraktal_stevec = 0
const fraktal_limit = 100
let fraktalni_objekti = []
let fraktalni_timer = null;
function dodajFraktal() {
const i = fraktal_stevec % ST_KEGLOV
const fract = objekti[i].clone()
//fract.scale = fraktal_meje[1].clone()
fract.scale.x = fraktal_meje[1].x
fract.scale.y = fraktal_meje[1].x
fract.scale.z = fraktal_meje[1].x
fract.material.opacity = 0.05
fract.i = i
fract.qStart = objekti[i].quaternion.clone()
fract.qStart.conjugate()
//console.log('dodajam fract', fract, fraktal_stevec)
fraktalni_objekti.push(fract)
scene.add(fract)
// Odstrani odvecne
while (fraktalni_objekti.length > fraktal_limit) {
scene.remove(fraktalni_objekti[0])
fraktalni_objekti.shift()
}
fraktal_stevec += 1
}
function fraktalInit() {
for (let i = 0; i < ST_KEGLOV; i++) {
fraktalni_objekti = []
//objekti[i].material.opacity = 0
scene.remove(objekti[i])
}
fraktal_interval = setInterval(() => dodajFraktal(), fraktal_interval)
}
fraktalInit()
// Zacetna orientacija kegla
scene.rotation.x = 90
scene.rotation.z = 270
var cakajDeformiraj = false
var cakajZogice = false
var cakajDodatniKegli = false
function render () {
requestAnimationFrame(render)
renderer.render(scene, camera)
stevec += 1
objAnim()
inputHandle()
while (krogle.length > 50) {
scene.remove(krogle[0])
krogle.shift()
}
// Fraktaliziraj?
if (fraktaliziraj) {
fraktalni_objekti.forEach(f => {
// Pomanjsaj
f.scale.multiply(fraktal_sprememba)
// Vidnost (fade in)
if (f.material.opacity < 1) {
f.material.opacity *= 1.02
}
// Rotacija
const qF = qWW[f.i].clone()
qF.multiply(f.qStart)
f.setRotationFromQuaternion(qF)
})
}
}
var cakajDodatni = false
// Funkcija za animacijo objektov
function objAnim() {
// FFT
if (analyser) {
analyser.getByteFrequencyData(stolpicki)
deformiraj = (stolpicki[3] + stolpicki[4] + stolpicki[5]) / 30
//console.log('FFT!', stolpicki)
//napihni = 1 + stolpicki[0] / 10
}
// Kalibracija rotacije kegla
if (calibrate) {
for (let i = 0; i < ST_KEGLOV; i++) {
qStart[i] = qWW[i].clone();
qStart[i].conjugate();
}
calibrate = false;
console.log("RESET!");
}
// Apliciramo rotacijo (po quaternionih - eulerji zajebavajo.)
for (let i = 0; i < ST_KEGLOV; i++) {
qObj[i] = qWW[i].clone()
qObj[i].multiply(qStart[i])
objekti[i].setRotationFromQuaternion(qObj[i]);
deformirajKegel(objekti[i], izbraniStolpicki)
objekti[i].geometry.attributes.position.needsUpdate = true;
}
// Rotacija kegla
//const obj = objekti[IZBRAN]
/*
//obj.scale.z = napihni
// Utripanje ob zogicah
if (napihni > 1) {
obj.scale.x = napihni * 2
obj.scale.y = napihni * 2
napihni = Math.max(napihni * 0.9, 1)
} else {
obj.scale.x = 1
obj.scale.y = 1
}
*/
// Ce je dodatnih objektov prevec, pucaj
while (dodatniObjekti.length > 100) {
scene.remove(dodatniObjekti[0]);
dodatniObjekti.shift();
}
dodatniObjekti.map(function (obj) {
// Apliciramo rotacijo (po quaternionih - eulerji zajebavajo.)
qObj[i] = qWW.clone();
//qObj.multiply(obj.qStart).multiply(qStart);
//obj.setRotationFromQuaternion(qObj);
obj.translateOnAxis(obj.premakniAxis, obj.premakniKolicina);
// obj.material.color.offsetHSL(0, 0, 0.003);
obj.material.opacity *= 0.998;
obj.premakniKolicina *= 0.98;
var dQ = obj.quaternion.multiply(obj.rotirajQ);
/*
dQ.multiply(obj.rotirajQ);
obj.setRotationFromQuaternion(dQ);
*/
/*
obj.premakni.x *= 1.1;
obj.premakni.y *= 1.1;
obj.premakni.z *= 1.1;
*/
obj.material.opacity *= 0.98;
});
barvaKrogleO.offsetHSL(-(2/1000), 0, 0);
krogle.map(function (obj) {
obj.material.opacity *= 0.98;
var scaleF = 0.05;
obj.scale.x += scaleF;
obj.scale.y += scaleF;
obj.scale.z += scaleF;
});
/* ?????
if (objekti[IZBRAN].scale.x > 1) {
objekti[IZBRAN].scale.x *= 0.95;
}
if (objekti[IZBRAN].scale.z > 1) {
objekti[IZBRAN].scale.z *= 0.95;
}
*/
// kegel.material.color.offsetHSL(2 / 1000, 0, 0);
// Dupliranje keglov
if (dodatniKegli) {
var vsota = Math.abs(acc[IZBRAN].x) + Math.abs(acc[IZBRAN].z)
if (vsota > 2 && !cakajDodatni) {
cakajDodatni = true
var dodatni = obj.clone();
dodatni.renderOrder = stevec;
var dodatniMat = objekti[IZBRAN].material.clone();
//var dodatniBarva = barvaDodatni.clone();
var bId = IZBRAN == 0 ? 0 : 1
var dodatniBarva = new THREE.Color(barvnePalete[bId][barvnePaleteIdx[bId]])
dodatniMat.color = dodatniBarva;
dodatni.material = dodatniMat;
dodatni.premakniAxis = new THREE.Vector3(
Math.random(),
Math.random(),
Math.random()
);
dodatni.premakniKolicina = vsota;
var rQ = qWW.clone();
rQ.invert();
rQ.multiply(qPrej);
dodatni.rotirajQ = rQ;
//dodatni.qStart = kegel.quaternion.clone();
dodatniObjekti.push(dodatni);
scene.add(dodatni);
barvnePaleteIdx[bId] = (barvnePaleteIdx[bId] + 1) % barvnePalete[bId].length;
}
if (cakajDodatni && vsota < 1) {
cakajDodatni = false
}
}
}
// 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);

166
web/kegel.js 100644
View File

@ -0,0 +1,166 @@
/********
* KEGEL *
*********/
// Sirina in visina kegla
var width = 16;
var height = 128;
var radialnihSegmentov = 4;
var visinskihSegmentov = 128;
var sirinaSegmentov = 9;
function getKegelGeo() {
const geo = new THREE.BufferGeometry()
const polozaji = [];
// Najprej "spodnja buba"
var faktor = [
2/sirinaSegmentov, 2/sirinaSegmentov
];
// Pol rocaj (1.4 do 2.8 segmenta, dolgo 62 segmentov)
var rocajSegmentov = 46;
for (var i = 0; i <= rocajSegmentov; i++) {
faktor.push((1.4 + i / rocajSegmentov * 1.4) / sirinaSegmentov);
}
// pol stresica dol (2.8 do 7.4 segmenta)
var stresicaSegmentov = 48;
for (i = 0; i <= stresicaSegmentov; i++) {
faktor.push((2.8 + i / stresicaSegmentov * 4.6) / sirinaSegmentov);
}
// Pa se zadnji naklon (7.4 do 3 segmente)
var konecSegmentov = 30;
for (i = 0; i <= konecSegmentov; i++) {
faktor.push((7.4 - i / konecSegmentov * 4.4) / sirinaSegmentov);
}
// spodnji krog
for (var s = 0; s < radialnihSegmentov; s++) {
polozaji.push(
0.0,
0.0,
0.0,
Math.sin(2 * Math.PI * s / radialnihSegmentov) * width * faktor[0],
Math.cos(2 * Math.PI * s / radialnihSegmentov) * width * faktor[0],
0.0,
Math.sin(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[0],
Math.cos(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[0],
0.0
);
}
// vmesni segmenti
for (var h = 0; h < visinskihSegmentov; h++) {
for (s = 0; s < radialnihSegmentov; s++) {
polozaji.push(
Math.sin(2 * Math.PI * s / radialnihSegmentov) * width * faktor[h],
Math.cos(2 * Math.PI * s / radialnihSegmentov) * width * faktor[h],
h * height / visinskihSegmentov,
Math.sin(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[h],
Math.cos(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[h],
h * height / visinskihSegmentov,
Math.sin(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[h],
Math.cos(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[h],
(h + 1) * height / visinskihSegmentov,
);
}
}
// zgornji krog
for (s = 0; s < radialnihSegmentov; s++) {
polozaji.push(
0,
0,
height,
Math.sin(2 * Math.PI * s / radialnihSegmentov) * width * faktor[31],
Math.cos(2 * Math.PI * s / radialnihSegmentov) * width * faktor[31],
height,
Math.sin(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[31],
Math.cos(2 * Math.PI * (s + 1) / radialnihSegmentov) * width * faktor[31],
height
);
}
for (i = 0; i < polozaji.length; i++) {
if (i % 3 == 2) {
polozaji[i] -= height / 2;
}
}
// Spremeni v vertexe
var vertices = new Float32Array(polozaji)
geo.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
return geo
}
const refKegelGeo = getKegelGeo()
function getKegel() {
const geo = getKegelGeo();
var barva = new THREE.Color(0, 0, 0);
var barvaDodatni = new THREE.Color();
barvaDodatni.setHSL(0.6, 1.0, 0.5);
var mat = new THREE.MeshBasicMaterial({
//color: 0xff00ff,
color: barva,
wireframe: true,
transparent: true
});
window.mat = mat;
//var mat = new THREE.LineBasicMaterial({ color: 0xff00ff });
var kegel = new THREE.Mesh(geo.clone(), mat);
kegel.position.z = 20; // gor / dol
kegel.position.y = -30; // levo / desno
kegel.position.x = 12; // levo / desno drugic
if (IZBRAN == 1) {
kegel.position.x -= 10;
kegel.position.y += 8;
kegel.position.z += 3;
}
scene.add(kegel);
return kegel;
}
// Deformiranje kegla!
function deformirajKegel(obj, fft) {
const koti = obj.geometry.attributes.position.array;
/*
// Random 500 zamaknemo
for (var i = 0; i < 500; i++) {
koti[Math.floor(Math.random() * koti.length)] += (Math.random() - 1) * deformiraj;
}
*/
// Deformacija po stolpickih FFT
const kotov = koti.length / 3
for (let k = 0; k < kotov; k += 1) {
const zamik = Math.floor(Math.random() * 3)
//const neg = (Math.random() > 0.5) ? 1 : -1
const vrednost = stolpicki[Math.floor(k / kotov * fft.length) + zamik] /* * neg*/ / 30
const kot = koti.length - (k * 3 + zamik)
/*
if (k % 30 == 0) {
console.log(stolpicki)
console.log(kot, vrednost)
}
*/
koti[kot] += vrednost
}
// In priblizamo osnovni geometriji
for (var i = 0; i < koti.length; i++) {
// Tole zamika cel kegel stran @TODO
//koti[i] = (geo.attributes.position.array[i] - koti[i]) * 0.75;
koti[i] = (refKegelGeo.attributes.position.array[i] + koti[i]) / 2;
}
obj.geometry.attributes.position.needsUpdate = true;
}

View File

@ -0,0 +1,128 @@
const oscCallbacks = {}
// Quaternioni za rotacijo in kalibracijo
var calibrate = true
const qWW = []
const qPrej = []
const qObj = []
const qStart = []
// Parametri rotacije (euler)
const rotacija = []
// Parametri pospeska
const acc = []
for (let i = 0; i < ST_KEGLOV; i++) {
qWW[i] = new THREE.Quaternion()
qPrej[i] = new THREE.Quaternion()
qObj[i] = new THREE.Quaternion()
qStart[i] = new THREE.Quaternion()
rotacija[i] = new THREE.Vector3()
acc[i] = new THREE.Vector3()
}
// rotacije in pospeski keglov
for (let i = 0; i < ST_KEGLOV; i++) {
oscCallbacks[`${PREPEND}${i}/quaternion`] = function (args) {
// Popravimo osi (w x y z po defaultu HMM)
qPrej[i].copy(qWW[i])
const vals = args.map(getVal)
qWW[i].set(vals[0], vals[1], vals[2], vals[3])
}
oscCallbacks[`${PREPEND}${i}/accel`] = function (args) {
[acc[i].x, acc[i].y, acc[i].z] = args.map(getVal)
}
oscCallbacks[`${PREPEND}${i}/gyro`] = function (args) {
[rotacija[i].x, rotacija[i].y, rotacija[i].z] = args.map(getVal)
}
}
// Parametri animacije
oscCallbacks['/ww/calibrate'] = function () {
calibrate = true
}
oscCallbacks['/ww/reload'] = function () {
window.location.reload()
}
oscCallbacks['/ww/zoom'] = args => {
const [kolicina] = args.map(getVal)
spremeniZoom(kolicina)
}
oscCallbacks['/ww/deformiraj'] = args => {
const [kolicina] = args.map(getVal)
spremeniDeformiraj(kolicina)
}
oscCallbacks['/ww/kegli'] = args => {
const [ali] = args.map(getVal)
kegli = ali
}
oscCallbacks['/ww/zogice'] = args => {
const [ali] = args.map(getVal)
zogice = ali
}
// Poslusaj OSC evente
const getVal = function (msg) {
return msg.value;
}
function spremeniDeformiraj (kolicina) {
const noviDeformiraj = deformiraj + (kolicina / 2)
//console.log('deform', noviDeformiraj)
if (noviDeformiraj > 0) {
deformiraj = noviDeformiraj
} else {
deformiraj = 0
}
}
function spremeniZoom (kolicina) {
const noviZum = camera.position.z * (1 + kolicina / 25)
console.log(noviZum)
if ((noviZum > 0.1) && (noviZum < 300)) {
camera.position.z = noviZum
}
}
// Zogice
function zogicaCB(args) {
console.log("MAMOMO MIDI!", args[0].value, args[1].value, args[2].value);
var minus = (IZBRAN == 1) ? -1 : 1;
// kegel.material.color.offsetHSL(minus * args[2].value / 1000, 0, 0);
barvaDodatni.offsetHSL(minus * args[2].value / 1000, 0, 0);
/*
if (Math.random() < 0.5) {
kegel.scale.x *= 2;
} else {
kegel.scale.z *= 2;
}
*/
//kegel.scale.y *= 1 + (args[2] / 100000);
//kegel.scale.z *= 1 + (args[2] / 100000);
if (zogice) {
novaKrogla();
var bId = IZBRAN == 0 ? 2 : 3
console.log('id barve:', bId)
barvnePaleteIdx[bId] = (barvnePaleteIdx[bId] + 1) % barvnePalete[bId].length;
}
napihni = 3
}
oscCallbacks['/midi-in/0'] = zogicaCB
oscCallbacks['/midi-in/1'] = zogicaCB
oscCallbacks['/midi-in/2'] = zogicaCB

22
web/osctl.js 100644
View File

@ -0,0 +1,22 @@
const oscPort = new osc.WebSocketPort({
url: `${PROTO}://${SERVER_IP}:${SERVER_PORT}/`,
metadata: true
})
function sendAll (address, args) {
//console.log('posiljam', address, args)
oscPort.send({ address, args })
}
oscPort.on("ready", function () {
console.log("OSC listening!")
oscPort.on("message", function (msg) {
//console.log('msg!', msg);
var cb = oscCallbacks[msg.address]
if (cb) {
cb(msg.args)
}
})
})
oscPort.open()

34
web/zoga.js 100644
View File

@ -0,0 +1,34 @@
/*********
* ZOGICE *
*********/
var barvaKrogleO = new THREE.Color();
barvaKrogleO.setHSL(Math.random(), 0.8, 0.5);
function novaKrogla () {
//var barvaKrogle = barvaKrogleO.clone();
var bId = IZBRAN == 0 ? 2 : 3
console.log('id barve:', bId);
var barvaKrogle = new THREE.Color(barvnePalete[bId][barvnePaleteIdx[bId]]);
var mat = new THREE.MeshBasicMaterial({
color: barvaKrogle,
wireframe: true,
transparent: true
});
var velikost = 1 + Math.random() * 5;
var kroglaGeo = new THREE.SphereGeometry(velikost, 12, 12);
var krogla = new THREE.Mesh(kroglaGeo, mat);
krogla.position.x = (Math.random() - 1) * 200;
krogla.position.y = (Math.random() - 1) * 10;
krogla.position.z = (Math.random() - 1) * 300;
krogla.position.y -= 100;
krogla.position.x += 150;
krogla.position.z += 230; // gor/dol
//krogla.position.y += 200;
scene.add(krogla);
krogle.push(krogla);
}