OSC control, tweaking

rob
Jurij Podgoršek 2021-08-14 15:15:16 +02:00
parent 8f061b4f06
commit 62b1a077a2
10 changed files with 3257 additions and 573 deletions

View File

@ -1,116 +0,0 @@
const express = require('express')
const http = require('http')
const WebSocket = require('ws')
const osc = require('osc')
const port = 6676
// Vzemi iz argumenta
const tty = process.argv[2]
const include_files = [
'/anim.js',
'/control.js',
'/test.js',
'/node_modules/three/build/three.min.js',
'/node_modules/nouislider/distribute/nouislider.min.js',
'/node_modules/nouislider/distribute/nouislider.min.css',
'/node_modules/osc/dist/osc-browser.js'
];
const app = express();
const server = http.Server(app);
// Odprti serijski OSC link
const scon = new osc.SerialPort({
devicePath: tty,
bitrate: 115200
})
scon.on('error', e => {
console.log('tty error', e)
})
scon.open()
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
app.get('/ctl', (req, res) => {
res.sendFile(__dirname + '/control.html');
});
app.get('/test', (req, res) => {
res.sendFile(__dirname + '/test.html');
});
let settings = {};
app.get('/settings', function(req, res) {
res.send(settings);
});
include_files.map(function(file) {
app.get(file, function(req, res){
res.sendFile(__dirname + file);
});
});
server.listen(port, () => console.log('listening on *:' + port))
// Websocket init
const wss = new WebSocket.Server({ server })
const sendAll = (msg, wss, ws = null) => {
wss.clients.forEach( client => {
if (client != ws) {
client.send(msg)
}
})
}
// Debug osc
/*
scon.on('osc', msg => {
console.log('tty osc', msg.address, ...msg.args.map(val => Math.round(val * 1000) / 1000))
})
*/
wss.on('connection', function (ws) {
const oscWS = new osc.WebSocketPort({
socket: ws,
metadata: true
});
// Arduino OSC gre v web
scon.on('osc', msg => {
switch(msg.address) {
case '/gyro/':
const [gx, gy, gz] = msg.args
sendAll('adjust:rotx:' + gx, wss)
sendAll('adjust:roty:' + gy, wss)
sendAll('adjust:rotz:' + gz, wss)
break;
case '/quaternion/':
const [qw, qx, qy, qz] = msg.args
sendAll('adjust:quaternion:' + [qw, qx, qy, qz].join(':'), wss)
break;
case '/accel/':
const [ax, ay, az] = msg.args
sendAll('adjust:posx:' + ax, wss)
sendAll('adjust:posy:' + ay, wss)
sendAll('adjust:posz:' + az, wss)
break;
}
})
ws.on('message', (msg) => {
//console.log('got msg', msg)
const parts = msg.split(":")
const cmd = parts[0]
// Broadcast adjust msg
switch (cmd) {
case 'adjust':
sendAll(msg, wss, ws)
}
})
})

View File

@ -1 +0,0 @@
g1smo@dbn.20170:1628540355

119
anim.js
View File

@ -11,17 +11,13 @@ var odmik_kamere = 100;
var cam_rot_offset = 1; var cam_rot_offset = 1;
// Vidni kot // Vidni kot
var FOV = 140; var FOV = 90;
// Sirina in visina objektov // Sirina in visina objektov
var width = 2; var width = 6;
var height = 2;
// Limit stevila objektov // Limit stevila objektov
var obj_limit = 1000; var obj_limit = 600;
// Prvotno prazno polje objektov. Lahko bi kak buffer to bil pozneje // Prvotno prazno polje objektov. Lahko bi kak buffer to bil pozneje
var objekti = []; var objekti = [];
@ -29,24 +25,30 @@ var objekti = [];
// Stevec, za razno animiranje // Stevec, za razno animiranje
var stevec = 0; var stevec = 0;
var gostota_obj = 1;
// Parametri animacije // Parametri animacije
var rotacijaX = 0.006; var drotacijaX = 0.006;
var rotacijaY = 0.001; var drotacijaY = 0.001;
var rotacijaZ = 0.003; var drotacijaZ = 0.003;
var rotacijaX = 0;
var rotacijaY = 0;
var rotacijaZ = 0;
// Premik obstojecih barv // Premik obstojecih barv
var zamikBarve = 0.0000666; var zamikBarve = 1;
// Zamik pri novem objektu // Zamik pri novem objektu
var barva_mod = 0.333; var barva_mod = 0.333;
var saturacija = 1; var saturacija = 1;
var svetlost = 0.4; var svetlost = 0.4;
var wDiff = 0.5; var kameraX = 0;
var hDiff = 0.5; var kameraY = 0;
var kameraZ = 0;
// Scena, kamera in render // Scena, kamera in render
@ -71,31 +73,28 @@ renderer.setClearColor(0x000000, 1);
function render () { function render () {
requestAnimationFrame(render); requestAnimationFrame(render);
stevec += 1; stevec += 1;
// Dodaj objekt vcasih // Dodaj objekt vcasih
if (stevec % gostota_obj === 0) { if (stevec % gostota_obj === 0) {
addObj(width, height); addObj(width, width);
} }
renderer.render(scene, camera); renderer.render(scene, camera);
objAnim(); objAnim();
camRotate(); camRotate();
}; };
// Funkcija za animacijo objektov // Funkcija za animacijo objektov
function objAnim() { function objAnim() {
objekti.map(function (obj) { objekti.map(function (obj) {
obj.rotation.y += rotacijaY; obj.rotation.x += drotacijaX / 100;
obj.rotation.z += rotacijaZ; obj.rotation.y += drotacijaY / 100;
obj.rotation.x += rotacijaX; obj.rotation.z += drotacijaZ / 100;
obj.scale.z += wDiff; obj.scale.z += width / 4;
obj.scale.y += wDiff; obj.scale.y += width / 4;
obj.scale.x += wDiff; obj.scale.x += width / 4;
obj.material.color.offsetHSL(zamikBarve, 0, 0); obj.material.color.offsetHSL(zamikBarve, 0, 0);
}); });
@ -122,6 +121,9 @@ function addObj(w, h) {
var obj = new THREE.Line(geo, mat, THREE.LineSegments); var obj = new THREE.Line(geo, mat, THREE.LineSegments);
scene.add(obj); scene.add(obj);
obj.rotation.x = rotacijaX;
obj.rotation.y = rotacijaY;
obj.rotation.z = rotacijaZ;
// Pocisti za seboj // Pocisti za seboj
if (objekti.push(obj) > obj_limit) { if (objekti.push(obj) > obj_limit) {
@ -135,18 +137,18 @@ function addObj(w, h) {
var xAksa = new THREE.Vector3(0, 1, 0); var xAksa = new THREE.Vector3(0, 1, 0);
function camRotate () { function camRotate () {
// rotiraj po z osi // rotiraj po z osi
camera.translateX(cam_rot_offset); camera.translateX(kameraX);
camera.translateZ(odmik_kamere - Math.sqrt(Math.pow(odmik_kamere, 2) + Math.pow(cam_rot_offset, 2))); camera.translateZ(odmik_kamere - Math.sqrt(Math.pow(odmik_kamere, 2) + Math.pow(kameraX, 2)));
/* /*
camera.translateY(cam_rot_offset); camera.translateY(kameraY);
camera.translateX(odmik_kamere - Math.sqrt(Math.pow(odmik_kamere, 2) + Math.pow(cam_rot_offset, 2))); camera.translateX(odmik_kamere - Math.sqrt(Math.pow(odmik_kamere, 2) + Math.pow(kameraY, 2)));
camera.translateY(cam_rot_offset);
camera.translateX(odmik_kamere - Math.sqrt(Math.pow(odmik_kamere, 2) + Math.pow(cam_rot_offset, 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.x = Math.sin((stevec % 10) / 10) * cam_rot_offset;
camera.position.y = Math.cos((stevec % 10) / 10) * cam_rot_offset; camera.position.y = Math.cos((stevec % 10) / 10) * cam_rot_offset;
*/ */
@ -170,3 +172,56 @@ function onWindowResize() {
renderer.setSize(window.innerWidth, window.innerHeight); renderer.setSize(window.innerWidth, window.innerHeight);
} }
window.addEventListener('resize', onWindowResize, false); window.addEventListener('resize', onWindowResize, false);
var keysPressed = [0, 0, 0, 0];
var gyro = [0, 0, 0];
var accel = [0, 0, 0];
const getVal = function (msg) {
return msg.value;
}
oscCallbacks = {
'/keys/': [
function(args) {
keysPressed = args.map(getVal);
}
],
'/gyro/': [
function (args) {
var [gx, gy, gz] = args.map(getVal);
console.log(keysPressed)
if (keysPressed[0] && keysPressed[1] && keysPressed[2] && keysPressed[3]) {
window.location.reload()
}
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 += (gyro[1] - gy) * 10
//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]
}
]
}

View File

@ -13,7 +13,8 @@
<div id="anim-container"> <div id="anim-container">
</div> </div>
<script src="node_modules/three/build/three.min.js"></script> <script src="node_modules/three/build/three.min.js"></script>
<script src="node_modules/osc/dist/osc-browser.js"></script>
<script src="anim.js"></script> <script src="anim.js"></script>
<script src="control.js"></script> <script src="osctl.js"></script>
</body> </body>
</html> </html>

View File

@ -6,6 +6,7 @@ var oscPort = new osc.WebSocketPort({
oscPort.open(); oscPort.open();
oscPort.on("ready", function () { oscPort.on("ready", function () {
console.log("OSC listening!")
// Example send // Example send
/* /*
oscPort.send({ oscPort.send({
@ -19,6 +20,7 @@ oscPort.on("ready", function () {
}); });
*/ */
oscPort.on("message", function (msg) { oscPort.on("message", function (msg) {
console.log("OSC message", msg); //console.log("OSC message", msg.address, oscCallbacks);
}); oscCallbacks[msg.address].forEach(cb => cb(msg.args))
});
}); });

3392
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,15 +4,14 @@
"description": "epilepsija", "description": "epilepsija",
"dependencies": { "dependencies": {
"express": "^4.17.1", "express": "^4.17.1",
"nodemon": "^2.0.12",
"nouislider": "14.6.2", "nouislider": "14.6.2",
"osc": "^2.4.2", "osc": "^2.4.2",
"pm2": "^5.1.0",
"three": "0.120.1", "three": "0.120.1",
"ws": "^7.3.1" "ws": "^7.3.1"
}, },
"scripts": { "scripts": {
"start": "npx nodemon server.js" "start": "npx nodemon server.js /dev/ttyUSB0"
},
"devDependencies": {
"nodemon": "^2.0.12"
} }
} }

109
server.js
View File

@ -1,7 +1,6 @@
const express = require('express') const express = require('express')
const http = require('http') const http = require('http')
const WebSocket = require('ws') const WebSocket = require('ws')
const osc = require('osc') const osc = require('osc')
const port = 6676 const port = 6676
@ -11,24 +10,61 @@ const tty = process.argv[2]
const include_files = [ const include_files = [
'/anim.js', '/anim.js',
'/control.js', '/control.js',
'/osctl.js',
'/test.js', '/test.js',
'/node_modules/three/build/three.min.js', '/node_modules/three/build/three.min.js',
'/node_modules/nouislider/distribute/nouislider.min.js', '/node_modules/nouislider/distribute/nouislider.min.js',
'/node_modules/nouislider/distribute/nouislider.min.css', '/node_modules/nouislider/distribute/nouislider.min.css',
'/node_modules/osc/dist/osc-browser.js'
]; ];
const app = express(); const app = express();
const server = http.Server(app); const server = http.Server(app);
// Odprti serijski OSC link // Odprti serijski OSC link
const scon = new osc.SerialPort({ let scon = null
function openSerial() {
console.log('opening ', tty)
scon = new osc.SerialPort({
devicePath: tty, devicePath: tty,
bitrate: 115200 bitrate: 115200,
}) autoOpen: true
scon.on('error', e => { })
console.log('tty error', e) scon.open()
}) scon.on('open', e => {
scon.open() console.log('scon opened', e)
console.log(scon)
})
scon.on('error', e => {
console.error('tty error', e)
/*
if (e.match(/cannot open/)) {
scon = null
setTimeout(openSerial, 1000)
}
*/
})
scon.on('close', e => {
console.warn('serial connection closed, restarting in 1 second')
setTimeout(openSerial, 1000)
scon = null
})
// Arduino OSC gre v web
scon.on('osc', msg => {
// Debug incoming osc
//console.log('tty osc', msg.address, ...msg.args.map(val => Math.round(val * 1000) / 1000))
sendAll(msg, null, null, osclients)
})
if (scon._closeCode) {
scon = null
setTimeout(openSerial, 1000)
}
}
openSerial()
app.get('/', (req, res) => { app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html'); res.sendFile(__dirname + '/index.html');
@ -58,58 +94,35 @@ server.listen(port, () => console.log('listening on *:' + port))
// Websocket init // Websocket init
const wss = new WebSocket.Server({ server }) const wss = new WebSocket.Server({ server })
const sendAll = (msg, wss, ws = null) => { const sendAll = (msg, info, oscWS, osclients) => {
wss.clients.forEach( client => { osclients.forEach( client => {
if (client != ws) { if (client && oscWS != client) {
//console.log("sending", msg, info)
client.send(msg) client.send(msg)
} }
}) })
} }
// Debug osc const osclients = []
/*
scon.on('osc', msg => {
console.log('tty osc', msg.address, ...msg.args.map(val => Math.round(val * 1000) / 1000))
})
*/
wss.on('connection', function (ws) { wss.on('connection', function (ws) {
console.log('client connection', ws)
const oscWS = new osc.WebSocketPort({ const oscWS = new osc.WebSocketPort({
socket: ws, socket: ws,
metadata: true metadata: false
}); });
// Arduino OSC gre v web // Vsi OSC sem grejo naprej na kliente OSC
scon.on('osc', msg => { oscWS.on('packet', (packet, info) => {
switch(msg.address) {
case '/gyro/':
const [gx, gy, gz] = msg.args
sendAll('adjust:rotx:' + gx, wss)
sendAll('adjust:roty:' + gy, wss)
sendAll('adjust:rotz:' + gz, wss)
break;
case '/quaternion/':
const [qw, qx, qy, qz] = msg.args
sendAll('adjust:quaternion:' + [qw, qx, qy, qz].join(':'), wss)
break;
case '/accel/':
const [ax, ay, az] = msg.args
sendAll('adjust:posx:' + ax, wss)
sendAll('adjust:posy:' + ay, wss)
sendAll('adjust:posz:' + az, wss)
break;
}
})
ws.on('message', (msg) => {
//console.log('got msg', msg) //console.log('got msg', msg)
const parts = msg.split(":")
const cmd = parts[0]
// Broadcast adjust msg // Broadcast adjust msg
switch (cmd) { const [address, args] = packet
case 'adjust': sendAll({ address, args}, info, oscWS, osclients)
sendAll(msg, wss, ws)
}
}) })
oscWS.on('error', error => {
console.warn('Ignoring invalid OSC')
console.warn(error)
})
osclients.push(oscWS)
}) })

View File

@ -3,17 +3,15 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>wavey wind test</title> <title>wavey wind test</title>
<style type="text/css"> <style type="text/css">
body { body { margin: 0; }
margin: 0
}
</style> </style>
</head> </head>
<body> <body>
<div id="anim-container"></div> <div id="anim-container"></div>
<script src="node_modules/three/build/three.min.js"></script> <script src="node_modules/three/build/three.min.js"></script>
<script src="node_modules/osc/dist/osc-browser.js"></script>
<script src="test.js"></script> <script src="test.js"></script>
<script src="control.js"></script> <script src="osctl.js"></script>
</body> </body>
</html> </html>

33
test.js
View File

@ -61,6 +61,8 @@ var mat = new THREE.MeshBasicMaterial({
color: 0xff00ff, color: 0xff00ff,
wireframe: true wireframe: true
}); });
//quaternion = new THREE.Quaternion();
quaternion = null;
var cube = new THREE.Mesh(geo, mat); var cube = new THREE.Mesh(geo, mat);
scene.add(cube); // scene.add(cube); //
@ -79,7 +81,12 @@ function render () {
// Funkcija za animacijo objektov // Funkcija za animacijo objektov
function objAnim() { function objAnim() {
objekti.map(function (obj) { objekti.map(function (obj) {
obj.setRotationFromEuler(new THREE.Euler(rotacijaX, rotacijaY, rotacijaZ, 'XYZ')); obj.setRotationFromEuler(new THREE.Euler(rotacijaY, -rotacijaX, rotacijaZ, 'XYZ'));
/*
if (quaternion) {
obj.setRotationFromQuaternion(new THREE.Quaternion(...quaternion));
}
*/
/* /*
obj.rotation.y = -rotacijaX; obj.rotation.y = -rotacijaX;
@ -138,3 +145,27 @@ function onWindowResize() {
renderer.setSize(window.innerWidth, window.innerHeight); renderer.setSize(window.innerWidth, window.innerHeight);
} }
window.addEventListener('resize', onWindowResize, false); window.addEventListener('resize', onWindowResize, false);
// Poslusaj OSC evente
keysPressed = [0, 0, 0, 0];
oscCallbacks = {
'/keys/': [
function(args) {
keysPressed = [...args];
}
],
/*
'/quaternion/': [
function (args) {
quaternion = args.map(function (a) { return a.value; });
}
]
*/
'/gyro/': [
function (args) {
[rotacijaX, rotacijaY, rotacijaZ] = args.map(function (a) { return a.value; });
}
]
}