Compare commits

...

27 Commits
main ... kegel

Author SHA1 Message Date
Jurij Podgoršek b898c51bb5 Dodan serial library 2024-06-16 18:27:25 +02:00
Jurij Podgoršek 5e402c1168 guile chickadee verzija (WIP) 2024-05-01 03:20:12 +02:00
Jurij Podgoršek 6f403bc7c5 Posreduj midi naprej, vec info v kalibraciji 2023-06-11 18:35:04 +02:00
Jurij Podgoršek 1e49d7811c Manjsi popravki kegelnega kadra, testiranje scheme verzije 2023-06-10 20:10:30 +02:00
Jurij Podgoršek 4d34baade5 Popravi za evalvacijo iz guila 2023-05-11 19:03:54 +02:00
Jurij Podgoršek 90efd9a13c Lagan razvoj chickadee varjante dalje 2023-03-04 16:34:00 +01:00
Jurij Podgoršek 246391c4e1 Skupaj s tlemi 2022-12-14 01:13:25 +01:00
Jurij Podgoršek 870d909845 Se zadnje pedenanje - sinhronizacija enih parametrov med razlicnimi okni 2022-12-01 13:16:48 +01:00
Jurij Podgoršek 1c4463c007 Zoom na touchpadu, barvne palete za zogice in kegle 2022-11-30 18:20:57 +01:00
Jurij Podgoršek cb0f516da4 Zacetni polozaj, zogice na midi 2022-11-30 17:21:03 +01:00
Jurij Podgoršek 83e7b42ce9 Nekaj dodatnih funkcij 2022-11-30 16:25:09 +01:00
Jurij Podgoršek 7053531f40 Kalibracija, zogice 2022-11-30 12:55:09 +01:00
Jurij Podgoršek ec796bafab Referencna rotacija, kalibracija 2022-11-28 14:28:45 +01:00
Jurij Podgoršek 726a7ededb rotacija iz sredine kegla 2022-11-28 14:01:32 +01:00
Jurij Podgoršek 1eff20bf21 Posodobitve modulov, drugacno kegel moduliranje 2022-11-28 13:54:29 +01:00
Jurij Podgoršek f1b5b69850 WIP kegel v kalibraciji, rotacija skatle v schemu 2022-11-27 09:45:23 +01:00
Jurij Podgoršek d784c6dd81 popravek test animacije za vec naprav 2022-11-25 12:36:15 +01:00
Jurij Podgoršek e968814b45 zelen kvadrat ki se vrti 2022-11-23 08:32:45 +01:00
Jurij Podgoršek 0e34584679 Okej mamo kocko! 2022-11-23 07:31:55 +01:00
Jurij Podgoršek 3bf7daabc2 WIP chickadee port 2022-11-23 04:14:31 +01:00
Jurij Podgoršek 2851a67eca Nekaj popravkov 2022-09-24 14:09:46 +02:00
Jurij Podgoršek 7c1fc1b321 Lovi le prvi kontroler 2022-09-17 15:25:19 +02:00
Jurij Podgoršek c35c231c10 porpavek midi in 2022-06-28 18:43:14 +02:00
Jurij Podgoršek 4407c45184 midi -> OSC 2022-06-28 18:40:16 +02:00
Jurij Podgoršek 413900467c Midi input (console log za zdaj) 2022-06-28 18:34:54 +02:00
Jurij Podgoršek 5be48cffe7 Lepsi serial debug 2022-06-17 16:10:59 +02:00
Jurij Podgoršek c5d19367f8 Podpri vec naprav (nekoliko grdo) 2022-05-27 12:34:22 +02:00
13 changed files with 1875 additions and 2931 deletions

View File

@ -1,24 +0,0 @@
<html >
<head>
<meta charset="UTF-8">
<title>cancerainbow test</title>
<style type="text/css">
body {
margin: 0
}
.noUi-target {
width: 500px;
}
table tr td {
padding-top: 1rem;
}
</style>
</head>
<body>
<h1>TEST</h1>
<script src="control.js"></script>
<script src="test.js"></script>
</body>
</html>

73
anim.js
View File

@ -179,17 +179,17 @@ function objAnim() {
function addObj(w, h) {
var col = new THREE.Color();
//col.setHSL(stevec * barva_mod, saturacija, svetlost);
col.setHSL(stevec * barva_mod, saturacija, (Math.sin(stevec/barvapuls) / 6) + 0.3);
col.setHSL(stevec * barva_mod, saturacija, (Math.sin(stevec/barvapuls) / 6) + 0.5);
var mat = new THREE.LineBasicMaterial({
color: col
});
var geo = new THREE.BufferGeometry();
var offset = h / 2;
// Karo
var geo = new THREE.BufferGeometry();
var vertices = new Float32Array([
-offset, 0, 0, 0, offset, 0,
-offset, 0, 0, 0, -offset, 0,
@ -207,11 +207,10 @@ function addObj(w, h) {
obj.setRotationFromQuaternion(qObj);
// Pocisti za seboj
if (objekti.push(obj) > obj_limit) {
while (objekti.length > obj_limit) {
scene.remove(objekti[0]);
objekti.shift();
}
objekti.push(obj);
while (objekti.length > obj_limit) {
scene.remove(objekti[0]);
objekti.shift();
}
};
@ -219,16 +218,15 @@ qK = new THREE.Quaternion()
function camRotate () {
//scene.setRotationFromQuaternion(qKamera)
scene.rotation.x += crotacijaX
scene.rotation.y += crotacijaY
scene.rotation.z += crotacijaZ
scene.rotation.x += crotacijaX;
scene.rotation.y += crotacijaY;
scene.rotation.z += crotacijaZ;
}
// Inicializiraj
document.onreadystatechange = function () {
if (document.readyState === 'complete') {
document.getElementById("anim-container").appendChild(renderer.domElement);
render();
}
};
@ -256,41 +254,35 @@ const kbdPressed = {
window.addEventListener('keydown', (e) => {
kbdPressed[e.key] = true;
})
});
window.addEventListener('keyup', (e) => {
if (e.key in kbdPressed) {
kbdPressed[e.key] = false;
}
})
});
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)
[qWW.w, qWW.z, qWW.x, qWW.y] = args.map(getVal);
}
],
'/quaternionDiff': [
function (args) {
[qWWd.w, qWWd.x, qWWd.y, qWWd.z] = args.map(getVal);
}
],
'/eulerDiff': [
function (args) {
[dqX, dqY, dqZ] = args.map(getVal);
}
],
var prepend = '/ww/0';
var oscCallbacks = {};
oscCallbacks[prepend + '/keys'] = function(args) {
keysPressed = args.map(getVal);
keysPressed[0] |= kbdPressed['a'];
keysPressed[1] |= kbdPressed['s'];
keysPressed[2] |= kbdPressed['d'];
keysPressed[3] |= kbdPressed['f'];
};
oscCallbacks[prepend + '/quaternion'] = function (args) {
// Popravimo osi (w x y z po defaultu HMM)
[qWW.w, qWW.z, qWW.x, qWW.y] = args.map(getVal);
};
oscCallbacks[prepend + '/quaternionDiff'] = function (args) {
[qWWd.w, qWWd.x, qWWd.y, qWWd.z] = args.map(getVal);
};
oscCallbacks[prepend + '/eulerDiff'] = function (args) {
[dqX, dqY, dqZ] = args.map(getVal);
};
/* Ne uporabljamo vec
'/gyro/': [
@ -327,4 +319,3 @@ var oscCallbacks = {
}
],
*/
}

3
guile/Makefile 100644
View File

@ -0,0 +1,3 @@
play:
chickadee play ww.scm --repl-server

View File

@ -0,0 +1,7 @@
(use-modules (guix packages)
(gnu packages base)
(gnu packages guile)
(gnu packages game-development)
(gnu packages guile-xyz))
(packages->manifest (list guile-next guile-chickadee guile-ares-rs guile-websocket gnu-make))

156
guile/ww.scm 100644
View File

@ -0,0 +1,156 @@
(use-modules (chickadee)
(chickadee config)
(chickadee graphics text)
(chickadee graphics phong)
(chickadee graphics engine)
(chickadee graphics model)
(chickadee graphics mesh)
(chickadee graphics light)
(chickadee graphics shader)
(chickadee graphics buffer)
(chickadee graphics polygon)
(chickadee math)
(chickadee math vector)
(chickadee math matrix)
(system repl coop-server)
(ww init)
(ww kamera)
(ww obj))
;; Hitra pomoc:
;;
;; chickadee play anim.scm --repl-server
;; ^ pozene fajl z repl serverjem v ozadju
;;
;;
(define repl (spawn-coop-repl-server))
(define stevec 0)
(define (input-handle)
(cond ((key-pressed? 'h)
(set! dX (+ dX 0.1)))
((key-pressed? 'l)
(set! dX (- dX 0.1)))))
(define (update dt)
;; REPL!
(poll-coop-repl-server repl)
;; Stevec gor
(set! stevec (+ stevec 1))
(display (string-append (number->string stevec) "\n"))
(input-handle)
(obj-anim dt))
(define rotX 0)
(define rotY 0)
(define rotZ 0)
(define dX 0)
(define dY 0)
(define dZ 0)
(define (obj-anim dt)
(set! rotX (+ rotX (/ dt 0.2) (* dt dX)))
(set! rotY (+ rotY (/ dt 0.1)))
(set! rotZ (+ rotZ (/ dt 0.5)))
(matrix4-copy! (matrix4* (matrix4-scale stevec)
(matrix4-rotate-x rotX)
(matrix4-rotate-y rotY)
(matrix4-rotate-z rotZ))
model-matrix)
(matrix4-copy! (matrix4* (matrix4-scale stevec)
(matrix4-rotate-x rotY)
(matrix4-rotate-y rotZ)
(matrix4-rotate-z rotX))
tla-matrix)
;(matrix4-scale! model-matrix stevec)
;(matrix4-mult! model-matrix model-matrix (matrix4-scale stevec))
;(matrix4-rotate-x! model-matrix rotX)
;(matrix4-rotate-y! model-matrix rotY)
;(matrix4-rotate-z! model-matrix rotZ))
)
(define (key-press key modifiers repeat?)
(cond
((eq? key 'q)
(abort-game))
((eq? key 'k)
(set! obj (cons (ustvari-objekt stevec) obj)))
((eq? key 'r)
(load))))
(define (reset-stevec!)
(set! stevec 1))
(define tla-matrix (make-identity-matrix4))
(define position (vec3 0.0 0.0 -4.0))
(define obj #f)
(define tla #f)
(define nebo #f)
(define wireframe-shader
(load-shader (scope-datadir "shaders/path-stroke-vert.glsl")
(scope-datadir "shaders/path-stroke-frag.glsl")))
(define (draw alpha)
(with-graphics-state
((g:polygon-mode line-polygon-mode))
(with-projection
projection
;; objekti
(map (lambda (o)
(draw-mesh o
#:model-matrix model-matrix
#:view-matrix view-matrix
#:camera-position position
#:lights (list (ustvari-luc))))
obj)
;; "tla"
(draw-mesh tla
#:model-matrix tla-matrix
#:view-matrix view-matrix
#:camera-position position
#:lights (list (ustvari-luc)))
;; wireframe test?
(map
(lambda (p)
(shader-apply
my-shader
(primitive-vertex-array p)))
(mesh-primitives tla)))))
;; :( ne dela?
(define (load)
;; Moramo pogledat model
(poglej! position)
(reset-stevec!)
(ustvari-luc)
(set! obj (list (ustvari-objekt stevec)))
(set! tla (ustvari-tla))
(set! nebo (ustvari-nebo)))
(run-game
#:draw draw
#:update update
#:key-press key-press
#:load load
;; Okno init
#:window-resizable? #t
#:window-title "wavey wind"
#:clear-color (rgb #xFFFFFF))
;(reset-stevec!)

35
guile/ww/init.scm 100644
View File

@ -0,0 +1,35 @@
(define-module (ww init)
#:use-module (chickadee math vector)
#:use-module (chickadee graphics color)
#:use-module (chickadee graphics mesh)
#:use-module (chickadee graphics light)
#:use-module (chickadee graphics pbr)
#:use-module (chickadee graphics polygon)
#:use-module (chickadee graphics skybox)
#:use-module (chickadee graphics texture)
#:export (ustvari-tla
ustvari-nebo
ustvari-luc))
(define (ustvari-tla)
(make-plane 0.002
0.002
(make-pbr-material #:base-color-factor (vec3 1.0 0 0)
#:polygon-mode line-polygon-mode)))
;; (define (ustvari-kvadrat sirina)
;; (build-mesh
;; "kvadrat"
;; (let* ((polovica (/ sirina 2.0))
;; (levo-zgoraj (vec3 (- polovica) 0.0 (- polovica))
;; (vec2 )))
;; (list (vertex (vec3 (- sirina)))))))
(define (ustvari-nebo)
(default-skybox))
(define (ustvari-luc)
(make-directional-light
#:direction (vec3 1 1 1)
#:color white
#:intensity 10))

View File

@ -0,0 +1,14 @@
(define-module (ww kamera)
#:use-module (chickadee math)
#:use-module (chickadee math vector)
#:use-module (chickadee math matrix)
#:export (poglej! view-matrix projection))
(define projection (perspective-projection (/ pi 3.0) (/ 4.0 3.0) 0.1 10.0))
(define view-matrix (make-identity-matrix4))
(define (poglej! position)
(look-at! view-matrix
position
(vec3+ position (vec3 0.0 0.0 1.0))
(vec3 0.0 1.0 0.0)))

23
guile/ww/obj.scm 100644
View File

@ -0,0 +1,23 @@
(define-module (ww obj)
#:use-module (chickadee math matrix)
#:use-module (chickadee math vector)
#:use-module (chickadee graphics mesh)
#:use-module (chickadee graphics pbr)
#:use-module (chickadee graphics phong)
#:use-module (chickadee graphics polygon)
#:export (ustvari-objekt model-matrix))
(define model-matrix (make-identity-matrix4))
(define (ustvari-objekt stevec)
(let ((velikost (/ stevec 2000.0))
(barva (vec3 0.2 0.8 0.4)))
(make-cube velikost
(make-pbr-material #:base-color-factor barva
#:polygon-mode line-polygon-mode
#:metallic-factor 0.1))
;(make-plane velikost
; velikost
; (make-pbr-material))
))

View File

@ -3,23 +3,20 @@ var oscPort = new osc.WebSocketPort({
metadata: true
});
oscPort.open();
function sendAll (address, args) {
//console.log('posiljam', address, args)
oscPort.send({ address, args })
}
oscPort.on("ready", function () {
console.log("OSC listening!")
// Example send
/*
oscPort.send({
address: "/carrier/frequency",
args: [
{
type: "f",
value: 440
}
]
});
*/
oscPort.on("message", function (msg) {
oscCallbacks[msg.address].forEach(cb => cb(msg.args))
//console.log('msg!', msg);
var cb = oscCallbacks[msg.address]
if (cb) {
cb(msg.args)
}
});
});
oscPort.open();

3733
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,8 +7,9 @@
"midi": "^2.0.0",
"nodemon": "^2.0.12",
"nouislider": "14.6.2",
"osc": "^2.4.2",
"osc": "^2.4.4",
"pm2": "^5.1.0",
"serialport": "^12.0.0",
"three": "0.135.0",
"ws": "^7.3.1"
},

106
server.js
View File

@ -14,6 +14,8 @@ const DEBUG = {
// MIDI out
const MIDI = true
// Serial baud rate
const BAUDRATE = 115200
@ -22,6 +24,7 @@ const MIDI = true
require('serialport')
const express = require('express')
const http = require('http')
const WebSocket = require('ws')
@ -31,16 +34,11 @@ const fs = require('fs')
const midi = require('midi')
// Vzemi iz argumenta
const tty = process.argv[2]
// Seznam povezanih tty naprav
const tty = process.argv.splice(2)
let eulerRotation = [0, 0, 0]
let baudrate = parseInt(process.argv[3])
if (!baudrate) {
baudrate = 115200
}
const include_files = [
'/anim.js',
'/control.js',
@ -52,66 +50,87 @@ const include_files = [
'/node_modules/osc/dist/osc-browser.js'
];
function isFloat(value) {
if (
typeof value === 'number' &&
!Number.isNaN(value) &&
!Number.isInteger(value)
) {
return true;
}
return false;
}
const app = express();
const server = http.Server(app);
// Odprti serijski OSC link
let scon = null
// Odprti serijski OSC linki
let serijskePovezave = {}
let mo = null
let mi = null
if (MIDI) {
// Midi port
mo = new midi.Output()
mi = new midi.Input()
//mo.getPortCount()
//mo.getPortName(0)
//mo.openPort(0)
mo.openVirtualPort("kegel")
mi.openVirtualPort("ww-midi-in")
}
function openSerial() {
console.log('opening ', tty, baudrate)
function openSerial(ttyAddr) {
console.log('opening ', ttyAddr, BAUDRATE)
scon = new osc.SerialPort({
devicePath: tty,
bitrate: baudrate,
serijskePovezave[ttyAddr] = new osc.SerialPort({
devicePath: ttyAddr,
bitrate: BAUDRATE,
autoOpen: true,
useSLIP: true
})
const scon = serijskePovezave[ttyAddr]
scon.on('open', e => {
console.log('serial connection opened')
console.log(`serial connection ${ttyAddr} opened`)
//console.log(scon)
})
scon.on('error', e => {
console.error('tty error', e)
console.error(`tty ${ttyAddr} error`, e)
//scon.close()
})
scon.on('close', e => {
console.warn('serial connection closed, restarting in 1 second')
setTimeout(openSerial, 1000)
console.warn(`serial connection ${ttyAddr} closed, restarting in 1 second`)
setTimeout(() => { openSerial(ttyAddr) }, 1000)
})
// Arduino OSC gre v web
scon.on('message', msg => {
// Debug incoming osc
if (DEBUG.osc) {
console.log('osc msg', msg)
}
const index = Object.keys(serijskePovezave).indexOf(ttyAddr)
const prepend = `/ww/${index}`
sendAll(msg, null, null, osclients)
// Debug incoming serial osc
if (DEBUG.osc) {
console.log('osc SERIAL msg', msg.address, msg.args.map((a) => isFloat(a) ? a.toFixed(3) : a), ttyAddr, prepend)
}
sendAll(msg, null, null, osclients, prepend)
})
scon.open()
if (scon._closeCode) {
scon = null
console.log('restarting serial connection')
console.log('restarting serial connection ', ttyAddr)
setTimeout(openSerial, 1000)
}
}
if (tty) {
openSerial(baudrate)
if (tty.length > 0) {
tty.forEach((ttyAddr) => {
openSerial(ttyAddr);
});
}
app.get('/', (req, res) => {
@ -188,6 +207,22 @@ scudp.on('error', (e) => {
})
scudp.open()
if (MIDI) {
mi.on('message', (deltaTime, message) => {
// The message is an array of numbers corresponding to the MIDI bytes:
// [status, data1, data2]
// https://www.cs.cf.ac.uk/Dave/Multimedia/node158.html has some helpful
// information interpreting the messages.
console.log(`midi in: ${message} d: ${deltaTime}`);
mo.send(message)
sendAll({
address: '/midi-in',
args: message
}, null, null, osclients)
});
}
function eulerFromQuaternion(quaternion) {
// Quaternion to matrix.
const w = quaternion[0], x = quaternion[1], y = quaternion[2], z = quaternion[3];
@ -221,7 +256,7 @@ function eulerFromQuaternion(quaternion) {
return euler;
}
const sendAll = (msg, info, oscWS, osclients) => {
const sendAll = (msg, info, oscWS, osclients, prepend = '') => {
// Reset euler rotation to 0
if (msg.address == '/keys') {
if (msg.args[0] && msg.args[1] && msg.args[2] && msg.args[3]) {
@ -235,7 +270,7 @@ const sendAll = (msg, info, oscWS, osclients) => {
sendAll({
address: '/eulerDiff',
args: euler
}, info, oscWS, osclients)
}, info, oscWS, osclients, prepend)
eulerRotation[0] += euler[0]
eulerRotation[1] += euler[1]
@ -244,13 +279,20 @@ const sendAll = (msg, info, oscWS, osclients) => {
sendAll({
address: '/euler',
args: eulerRotation
}, info, oscWS, osclients)
}, info, oscWS, osclients, prepend)
}
// Add prepend
let sendMsg = {
address: `${prepend}${msg.address}`,
args: msg.args
}
// OSC relay
osclients.forEach( client => {
if (client && oscWS != client) {
// console.log("sending", msg, info)
client.send(msg)
// console.log("OSC RELAY", sendMsg, info, prepend)
client.send(sendMsg)
}
})
@ -258,7 +300,7 @@ const sendAll = (msg, info, oscWS, osclients) => {
if (DEBUG.udp) {
console.log("UDP SEND", msg)
}
scudp.send(msg)
scudp.send(sendMsg)
}
}

604
test.js
View File

@ -4,16 +4,16 @@ console.log("Hello, Sky!");
/ Test skripta *
************/
// Odmik kamere
var odmik_kamere = 100;
// 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 = 140;
// Sirina in visina test objekta
var width = 25;
var height = 150;
var depth = 50;
var FOV = 90;
// Parametri rotacije (euler)
var rotacijaX = 0.000;
@ -25,15 +25,23 @@ var accX = 0.000;
var accY = 0.000;
var accZ = 0.000;
var deformiraj = 0;
// Scena, kamera in render
scene = new THREE.Scene;
var scene = new THREE.Scene;
window.scene = scene;
camera = new THREE.PerspectiveCamera(FOV, window.innerWidth / window.innerHeight, 0.1, 2000);
camera.position.z = odmik_kamere;
/*
const axesHelper = new THREE.AxesHelper( 5 );
scene.add( axesHelper );
*/
renderer = new THREE.WebGLRenderer({
alpha: true
});
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
@ -41,81 +49,445 @@ renderer.setClearColor(0xFFFFFF, 1);
// Črno ozadje
//renderer.setClearColor(0x000000, 1);
var skupina = new THREE.Group();
//var skupina = new THREE.Group();
// Dodaj test skatlo
var geo = new THREE.BoxGeometry(width, height, depth);
/********
* 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
);
}
console.log(polozaji);
// 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,
wireframe: true
//color: 0xff00ff,
color: barva,
wireframe: true,
transparent: true
});
var cube = new THREE.Mesh(geo, mat);
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
skupina.add(cube);
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 > 10) && (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);
//skupina.add(AX);
// Damo vse skupaj v kader
scene.add(skupina);
// 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
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)
}
}
var objekti = [cube];
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) {
//obj.setRotationFromEuler(new THREE.Euler(rotacijaY, -rotacijaX, rotacijaZ, 'XYZ'));
// Apliciramo rotacijo (po quaternionih - eulerji zajebavajo.)
qObj = qWW.clone();
qObj.multiply(qStart);
obj.setRotationFromQuaternion(qObj);
AX.scale.x = accX / 1000;
// Deformiranje kegla!
// Random 500 zamaknemo
var koti = obj.geometry.attributes.position.array;
var faktorD = 5;
for (var i = 0; i < 500; i++) {
koti[Math.floor(Math.random() * koti.length)] += (Math.random() - 1) * deformiraj;
}
// In priblizamo osnovni geometriji
for (var i = 0; i < koti.length; i++) {
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;
});
// Drzimo vse stiri gumbe (reset)? - kalibracija!
if ((keysPressed[0] + keysPressed[1] + keysPressed[2] + keysPressed[3]) === 4) {
if (!reset) {
qStart = qWW.clone();
qStart.conjugate();
reset = true;
console.log("RESET!");
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;
}
} else {
if (reset) {
reset = false;
console.log("reset off....");
if (cakajDodatni && vsota < 1) {
cakajDodatni = false
}
}
};
// Inicializiraj
document.onreadystatechange = function () {
if (document.readyState === 'complete') {
document.getElementById("anim-container").appendChild(renderer.domElement);
render();
}
if (document.readyState === 'complete') {
document.getElementById("anim-container").appendChild(renderer.domElement);
render();
}
};
// Lep risajz
@ -128,32 +500,136 @@ window.addEventListener('resize', onWindowResize, false);
// Poslusaj OSC evente
keysPressed = [0, 0, 0, 0];
var keysPressed = [0, 0, 0, 0];
const getVal = function (msg) {
return msg.value;
}
var prepend = `/ww/0/ww/${izbranKegel}`;
console.log('prepend!', prepend);
oscCallbacks = {
'/keys': [
function(args) {
keysPressed = args.map(getVal);
}
],
'/quaternion': [
function (args) {
// Popravimo osi (w x y z po defaultu HMM)
[qWW.w, qWW.x, qWW.y, qWW.z] = args.map(getVal);
}
],
'/accel': [
function (args) {
[accX, accY, accZ] = args.map(getVal);
}
],
'/gyro': [
function (args) {
[rotacijaX, rotacijaY, rotacijaZ] = args.map(getVal);
}
]
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
}
oscCallbacks['/midi-in'] = function (args) {
//console.log("MAMOMO MIDI!", args);
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;
}
};
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
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)
}
})