Skip to content

Instantly share code, notes, and snippets.

@Fabax
Created November 22, 2012 12:03
Show Gist options
  • Save Fabax/4130808 to your computer and use it in GitHub Desktop.
Save Fabax/4130808 to your computer and use it in GitHub Desktop.
Processing : Class Wii
/* Wii Processing class
* (cc) 2009 Douglas Edric Stanley
* l'Atelier Hypermédia
* l'École supérieure d'art d'Aix-en-Provence
* http://www.ecole-art-aix.fr/
*
* Pour utiliser cette classe il faut :
*
+ Osculator : http://www.osculator.net/
+ Open Sound Control for Processing (OscP5) : http://www.sojamo.de/libraries/oscP5/
*
* La classe Wii permet de se connecter à Osculator via OSC et répartir les
* valeurs du Wiimote, du Nunchuck et du Classic Controller (tous les deux
* reliés au Wiimote) et enfin du Balance Board (Planche WiiFit) -- le tout
* dans sous une forme plus simple à manier dans Processing.
*
* Il y a un fichier de configuration d'Osculator inclus dans le dossier du sketch
* qui fait le gros du boulot pour configurer Osculator pour parler à Processing. Il faut
* juste "relier" Osculator et votre Wiimote/BalanceBoard (ouvrez le tiroir dans Osculator
* pour voir la liste de tous les appareils)
*
* On peut avoir jusqu'à 4 instances de n'importe quelle combinasion Wiimote/BalanceBoard.
* Il faut qu'Osculator soit démarré et emêt en OSC sur le port 9000 (configurable)
* avant de pouvoir recevoir les valeurs.
*
* Il suffit de copier ce fichier "wii.pde" dans le dossier de votre sketch et de
* re-ouvrir votre sketch (ou Processing, peu importe) pour voir apparaître l'onglet Wii :
~/Documents/
/Processing/
/NomDuSketch/
/data/
/NomDuSketch.pde
/Wii.pde
/wii.oscd
* Au début de votre sketch il faut déclarer l'objet qui contiendra les valeurs :
Wii wii = new Wii();
* Si vous voulez recevoir sur un autre port, mettez un int entre les parenthèses :
Wii wii = new Wii(666666);
* Si vous voulez voir/tester toutes les possibilités, demander à wii de tout déssiner :
void draw() {
background(255);
wii.draw();
}
* L'objet wii sera ensuite le seul 'accès' nécessaire pour avoir les valeurs
* du Wiimote/BalanceBoard. Par exemple, pour avoir la valeur de l'accéleromètre
* il suffit de le demander comme ceci:
background( wii.wiimote.accel.pitch * 255 );
* Notez que les valeurs arriveront toujours entre 0.0 et 1.0. Si on veut 0-255, il
* suffit de les multiplier par 255. Si on veut jusqu'à la taille du Sketch, il suffit
* de multiplier par 'width' ou par 'height' (ex: wii.accel.roll * width).
*
* Si on a plusieurs Wiimotes attachés, il faut indiquer lequel on veut :
// cette image bougera une image et l'agrandira suivant
float x = wii.wiimote[3].accel.pitch * width;
float y = wii.wiimote[3].accel.roll * width;
float largeur = wii.wiimote[3].accel.accel * monImage.width;
float hauteur = wii.wiimote[3].accel.accel * monImage.height;
* Pour faire vibrer un Wiimote, il faut lui demander de vibrer (0.0 = éteint / 1.0 allumé) :
wii.wiimotes[n].vibrate(1.0);
* Pour changer les lumières LED, on envoie la commande led(numéro_du_masquage) :
wii.wiimotes[n].led(15);
* Voici quelques examples de valeurs de masquage:
0 = 0000
1 = 0001
2 = 0010
3 = 0011
4 = 0100
8 = 1000
15= 1111
* Il y a aussi une commande pour allumer comme un indicateur de niveau (0.0 - 1.0)
wii.wiimotes[n].level(valeur);
* L'objet wii classifiera ensuite les valeurs suivant l'arborescence suivante :
wii
* (balance board)
wii.balanceBoard *raccourci vers le premier balanceBoards[n] qui arrive
wii.balanceBoards[n] *jusqu'à 4 wiimotes/balanceBoards (0/4, 1/3, 2/2, 3/1, 4/0)
wii.balanceBoards[n].values[n] *il y en a 4
wii.balanceBoards[n].someone *boolean (true/false) pour dire s'il y a quelqu'un dessus ou pas
wii.balanceBoards[n].top_left *raccourci vers .values[0]
wii.balanceBoards[n].top_right *raccourci vers .values[1]
wii.balanceBoards[n].bottom_right *raccourci vers .values[2]
wii.balanceBoards[n].bottom_left *raccourci vers .values[3]
wii.balanceBoards[n].sum *la somme des 4 valeurs (x 100 pour avoir les Kg)
* (wiimote)
wii.wiimote *raccourci vers le premier wiimotes[n] qui arrive
wii.wiimotes[n] *jusqu'à 4 wiimotes/balanceBoards (0/4, 1/3, 2/2, 3/1, 4/0)
wii.wiimotes[n].accel
wii.wiimotes[n].accel.pitch
wii.wiimotes[n].accel.roll
wii.wiimotes[n].accel.yaw
wii.wiimotes[n].accel.accel *l'ampleur des trois précédentes valeurs
wii.wiimotes[n].button
wii.wiimotes[n].button.a
wii.wiimotes[n].button.b
wii.wiimotes[n].button.one
wii.wiimotes[n].button.two
wii.wiimotes[n].button.left
wii.wiimotes[n].button.right
wii.wiimotes[n].button.up
wii.wiimotes[n].button.down
wii.wiimotes[n].button.minus
wii.wiimotes[n].button.home
wii.wiimotes[n].button.plus
wii.wiimotes[n].ir
wii.wiimotes[n].ir.x
wii.wiimotes[n].ir.y
wii.wiimotes[n].ir.xys[n] *x, y, rayon : jusqu'à 4 points
wii.wiimotes[n].ir.xys[n].x
wii.wiimotes[n].ir.xys[n].y
wii.wiimotes[n].ir.xys[n].r *la taille
* (nunchuk)
wii.wiimotes[n].nunchuk.accel
wii.wiimotes[n].nunchuk.accel.pitch
wii.wiimotes[n].nunchuk.accel.roll
wii.wiimotes[n].nunchuk.accel.yaw
wii.wiimotes[n].nunchuk.accel.accel *l'ampleur des trois précédentes valeurs
wii.wiimotes[n].nunchuk.joystick
wii.wiimotes[n].nunchuk.joystick.x
wii.wiimotes[n].nunchuk.joystick.y
wii.wiimotes[n].nunchuk.button
wii.wiimotes[n].nunchuk.button.c
wii.wiimotes[n].nunchuk.button.z
* (classic controller)
wii.wiimotes[n].classic.right
wii.wiimotes[n].classic.right.x
wii.wiimotes[n].classic.right.y
wii.wiimotes[n].classic.left
wii.wiimotes[n].classic.left.x
wii.wiimotes[n].classic.left.y
wii.wiimotes[n].classic.button
wii.wiimotes[n].classic.button.a
wii.wiimotes[n].classic.button.b
wii.wiimotes[n].classic.button.x
wii.wiimotes[n].classic.button.y
wii.wiimotes[n].classic.button.left
wii.wiimotes[n].classic.button.right
wii.wiimotes[n].classic.button.up
wii.wiimotes[n].classic.button.down
wii.wiimotes[n].classic.button.l * cette valeur est analogique 0.0 -> 1.0
wii.wiimotes[n].classic.button.zl
wii.wiimotes[n].classic.button.r * cette valeur est analogique 0.0 -> 1.0
wii.wiimotes[n].classic.button.zr
wii.wiimotes[n].classic.button.home
wii.wiimotes[n].classic.button.minus
wii.wiimotes[n].classic.button.plus
* Liste des TO-DO (pas encore implementé) :
*
+ un indicateur de mouvement sur la planche (avec un seuil) -- c'est pratique pour faire du son
+ des « call-backs » pour appeler une fonction dès les changements d'état (bouton / mouvement)
*
*/
import oscP5.*;
import netP5.*;
//////////////////////////////////////////////////////////////////
class Wii {
// connection à Open Sound Control
OscP5 osc;
NetAddress osculator;
// police pour le mode DEBUG
PFont debug_font;
// les wiimotes
Wiimote[] wiimotes = new Wiimote[4];
// le pointeur vers le premier wiimote à s'annoncer
Wiimote wiimote = new Wiimote();
// l'index du wiimote par défaut
int default_wiimote_index = -1;
// les balance boards
Balance[] balanceBoards = new Balance[4];
// le pointeur vers le premier board à s'annoncer
Balance balanceBoard = new Balance();
// l'index board par défaut
int default_board_index = -1;
Wii() {
// par défaut, écouter sur le port 9000 (celui par défaut d'Osculator)
this(9000);
}
Wii(int port) {
osc= new OscP5 (this, 9000);
osculator = new NetAddress("127.0.0.1",8000);
debug_font = createFont("Monospaced", 10);
}
void draw() {
color c = color(0);
textFont(debug_font);
for(int i=0; i<4; i++) {
switch(i) {
case(0):
c = color(255,0,0);
break;
case(1):
c = color(0,127,0);
break;
case(2):
c = color(0,0,255);
break;
case(3):
c = color(255,0,255);
break;
}
fill(c);
stroke(c);
if (balanceBoards[i] != null) balanceBoards[i].draw(i,c);
if (wiimotes[i] != null) wiimotes[i].draw(i,c);
}
}
void oscEvent(OscMessage message) {
// saucisonner l'identifiant du message
String[] pattern = split(message.addrPattern(), "/");
String typetag = message.typetag();
// si pas assez, on s'en fout du reste
if (pattern.length < 4) return;
// lequel des controlleurs ?
int index = (pattern[2].equals("1")) ? 0 :
(pattern[2].equals("2")) ? 1 :
(pattern[2].equals("3")) ? 2 :
(pattern[2].equals("4")) ? 3 : -1;
// si on n'a pas eu de controlleur correcte
if (-1 == index) return;
// vérifier que les array des balance board et wiimotes sont remplis correctement
// (pour ne pas avoir de null-pointer)
if (pattern[3].equals("balance")) checkBoardArray(index);
else if (pattern[3].equals("accel")) checkWiimoteArray(index);
else if (pattern[3].equals("button")) checkWiimoteArray(index);
else if (pattern[3].equals("ir")) checkWiimoteArray(index);
else if (pattern[3].equals("nunchuk")) checkWiimoteArray(index);
else if (pattern[3].equals("classic")) checkWiimoteArray(index);
// passer les évenements à leurs propriétaires
if (pattern[3].equals("accel") ) {
if (balanceBoards[index] != null) balanceBoards[index].deactivate();
wiimotes[index].message(pattern,typetag,message);
}
if (pattern[3].equals("button") ) {
if (balanceBoards[index] != null) balanceBoards[index].deactivate();
wiimotes[index].message(pattern,typetag,message);
}
if (pattern[3].equals("ir")) {
if (balanceBoards[index] != null) balanceBoards[index].deactivate();
wiimotes[index].message(pattern,typetag,message);
}
if (pattern[3].equals("balance")) {
if (wiimotes[index] != null && wiimotes[index].active) wiimotes[index].deactivate();
balanceBoards[index].message(pattern,typetag,message);
}
if (pattern[3].equals("nunchuk")) {
if (balanceBoards[index] != null) balanceBoards[index].deactivate();
if (wiimotes[index] != null) wiimotes[index].classic.active = false;
wiimotes[index].nunchuk.message(pattern,typetag,message);
}
if (pattern[3].equals("classic")) {
if (balanceBoards[index] != null) balanceBoards[index].deactivate();
if (wiimotes[index] != null) wiimotes[index].nunchuk.active = false;
wiimotes[index].classic.message(pattern,typetag,message);
}
}
void checkBoardArray(int index) {
// si on n'a pas encore attribué ce balance board
if (null == balanceBoards[index]) balanceBoards[index] = new Balance();
// si on n'a pas encore attribué le pointeur par défaut
if (-1 == default_board_index) {
balanceBoard = balanceBoards[index];
default_board_index = index;
}
}
void checkWiimoteArray(int index) {
// si on n'a pas encore attribué ce balance board
if (null == wiimotes[index]) wiimotes[index] = new Wiimote(index);
// si on n'a pas encore attribué le pointeur par défaut
if (-1 == default_wiimote_index) {
wiimote = wiimotes[index];
default_wiimote_index = index;
}
}
//////////////////////////////////////////////////////////////////////////////////
class Wiimote {
boolean active = false;
boolean vibration = false;
int object_index = 0;
Accel accel = new Accel();
Button button = new Button();
IR ir = new IR();
Nunchuk nunchuk = new Nunchuk();
Classic classic = new Classic();
Wiimote() {
}
Wiimote(int index) {
object_index = index;
}
void deactivate() {
active = false;
classic.active = false;
nunchuk.active = false;
// ir has to potentially turn off all the raw points (max. 4)
ir.deactivate();
}
void vibrate(float value) {
value = min(1.0,max(0.0,value));
// mémoriser si on vibre ou pas
if (value >= 0.5) vibration = true;
else vibration = false;
String header = "/vibrate/" + object_index;
OscMessage message = new OscMessage(header);
message.add(value);
osc.send(message, osculator);
}
void led(int light_mask) {
light_mask = min(15,max(0,light_mask));
String header = "/led/" + object_index;
OscMessage message = new OscMessage(header);
message.add((float)light_mask);
osc.send(message, osculator);
}
void level(float level_value) {
level_value = min(1.0,max(0.0,level_value));
String header = "/light/" + object_index;
OscMessage message = new OscMessage(header);
message.add(level_value);
osc.send(message, osculator);
}
void message(String[] pattern, String typetag, OscMessage message) {
active = true;
if (pattern[3].equals("accel")) accel.message(pattern,typetag,message);
else if (pattern[3].equals("button")) button.message(pattern,typetag,message);
else if (pattern[3].equals("ir")) ir.message(pattern,typetag,message);
}
void draw(int index, color c) {
if (!active) return;
float x_step = width/4;
float x_half_step = x_step/2;
float x = (index*x_step)+x_half_step;
// dessiner l'accéleration du wiimote
accel.draw(index, x, 20, c);
// dessiner les boutons
drawButtons(x, (height/2)-85, c);
// draw the infrared points
ir.draw(x, (height/2)+90, c);
// si le nunchuk est actif, dessinder l'accéleration du nunchuk
if (nunchuk.active) {
// dessiner l'accélerateur du nunchuk
nunchuk.accel.draw(index, x, height-75, c);
// dessiner les joysticks
nunchuk.joystick.draw(x, (height/2)+40, c);
}
// draw the two joysticks
if (classic.active) {
classic.left.draw(x-30, (height/2)+40, c);
classic.right.draw(x+30, (height/2)+40, c);
}
}
void drawButtons(float x, float y, color c) {
// draw buttons
pushMatrix();
translate(int(x), int(y));
stroke(c);
// wiimote
pushMatrix();
translate(20,-20);
// image of a wiimote
fill(c,0);
rect(-11,0,21,50);
// arrows
fill(c, button.left*255);
rect(-8,8,5,5);
fill(c, button.right*255);
rect(+2,8,5,5);
fill(c, button.up*255);
rect(-3,3,5,5);
fill(c, button.down*255);
rect(-3,13,5,5);
// triggers
fill(c, button.a*255);
rect(-3,21,5,5);
fill(c, button.b*255);
rect(5,21,5,5);
// reset
fill(c, button.minus*255);
rect(-8,30,5,5);
fill(c, button.home*255);
rect(-3,30,5,5);
fill(c, button.plus*255);
rect(+2,30,5,5);
// selection
fill(c, button.one*255);
rect(-3,38,5,5);
fill(c, button.two*255);
rect(-3,43,5,5);
popMatrix();
// nunchuk
pushMatrix();
translate(-20,-20);
fill(c,0);
triangle(-10,0,10,0,0,50);
fill(c, nunchuk.button.c*255);
rect(-3,3,5,5);
fill(c, nunchuk.button.z*255);
rect(-3,8,5,5);
fill(c,0);
ellipse(0,20,7,7);
popMatrix();
// classic controller
pushMatrix();
translate(0,50);
// draw the joystick frame
fill(c,0);
rect(-30,0,60,30);
// joystick holders
fill(c,0);
ellipse(-10,25,7,7);
ellipse(+10,25,7,7);
fill(c, classic.button.y*255);
rect(9,13,5,5);
fill(c, classic.button.x*255);
rect(16,8,5,5);
fill(c, classic.button.b*255);
rect(16,18,5,5);
fill(c, classic.button.a*255);
rect(23,13,5,5);
fill(c, classic.button.left*255);
rect(-28,13,5,5);
fill(c, classic.button.right*255);
rect(-18,13,5,5);
fill(c, classic.button.up*255);
rect(-23,8,5,5);
fill(c, classic.button.down*255);
rect(-23,18,5,5);
// left and right buttons
fill(c, classic.button.l*255);
rect(-30,0,20,5);
fill(c, classic.button.zl*255);
rect(-10,0,5,5);
fill(c, classic.button.zr*255);
rect(5,0,5,5);
fill(c, classic.button.r*255);
rect(10,0,20,5);
// show the right and left analog values
fill(c);
float h = 15*classic.analog.l;
rect(-30,0,h,5);
h = 15*classic.analog.r;
rect(30-h,0,h,5);
// reset buttons
fill(c, classic.button.minus*255);
rect(-9,10,5,5);
fill(c, classic.button.home*255);
rect(-4,10,5,5);
fill(c, classic.button.plus*255);
rect(1,10,5,5);
popMatrix(); // end controller matrix
popMatrix();
}
///////////////////////////////////////
class Accel {
float pitch, roll, yaw, accel;
void message(String[] pattern, String typetag, OscMessage message) {
if (!message.typetag().equals("ffff")) return;
pitch = message.get(0).floatValue();
roll = message.get(1).floatValue();
yaw = message.get(2).floatValue();
accel = message.get(3).floatValue();
}
void draw(int index, float x, float y, color c) {
noStroke();
fill(c);
float w = 20 + (40 * accel);
float h = w * 1.5;
pushMatrix();
translate((int)x,(int)y,0.0);
String value_string;
value_string = "no." + nf(index,0);
text(value_string, -textWidth(value_string)/2, 30);
value_string = "pitch:" + nf(pitch,1,5);
text(value_string, -textWidth(value_string)/2, 40);
value_string = " roll:" + nf(roll,1,5);
text(value_string, -textWidth(value_string)/2, 50);
value_string = " yaw:" + nf(yaw,1,5);
text(value_string, -textWidth(value_string)/2, 60);
value_string = "accel:" + nf(accel,1,5);
text(value_string, -textWidth(value_string)/2, 70);
rotateZ(PI);
rotateX(pitch*PI);
rotateY(roll*PI+PI/2);
rotateZ(yaw*PI+PI/2);
rect(-w/2,-h/2,w,h);
popMatrix();
}
}
///////////////////////////////////////
class Joystick {
float x = 0.5;
float y = 0.5;
Joystick() {
}
void message(String[] pattern, String typetag, OscMessage message) {
//
if ( !typetag.equals("ff") ) return;
//
x = message.get(0).floatValue();
y = message.get(1).floatValue();
}
void draw(float pos_x, float pos_y, color c) {
pushMatrix();
translate(pos_x,pos_y);
fill(c,0);
stroke(c,255);
ellipse(0,0,50,50);
ellipse( (x*50)-25, 25-(y*50), 15, 15 );
popMatrix();
}
}
///////////////////////////////////////
class Button {
boolean changed;
float a, b, c, z, x, y, l, r, zl, zr, left, down, up, right, one, two, plus, minus, home;
void message(String[] pattern, String typetag, OscMessage message) {
if (!typetag.equals("f")) return;
String name = pattern[pattern.length-1];
if (name.equals("1")) one = message.get(0).floatValue();
if (name.equals("2")) two = message.get(0).floatValue();
if (name.equals("A")) a = message.get(0).floatValue();
if (name.equals("B")) b = message.get(0).floatValue();
if (name.equals("Down")) down = message.get(0).floatValue();
if (name.equals("Home")) home = message.get(0).floatValue();
if (name.equals("Left")) left = message.get(0).floatValue();
if (name.equals("Minus")) minus = message.get(0).floatValue();
if (name.equals("Plus")) plus = message.get(0).floatValue();
if (name.equals("Right")) right = message.get(0).floatValue();
if (name.equals("Up")) up = message.get(0).floatValue();
if (name.equals("L")) l = message.get(0).floatValue();
if (name.equals("R")) r = message.get(0).floatValue();
if (name.equals("X")) x = message.get(0).floatValue();
if (name.equals("Y")) y = message.get(0).floatValue();
if (name.equals("C")) c = message.get(0).floatValue();
if (name.equals("Z")) z = message.get(0).floatValue();
if (name.equals("ZL")) zl = message.get(0).floatValue();
if (name.equals("ZR")) zr = message.get(0).floatValue();
changed = true;
}
}
///////////////////////////////////////
class IR {
boolean active;
float x,y;
IRRaw[] raws = new IRRaw[4];
IR() {
for(int i=0; i<raws.length; i++) raws[i] = new IRRaw();
}
void deactivate() {
active = false;
for(int i=0; i<raws.length; i++) raws[i] = new IRRaw();
}
void message(String[] pattern, String typetag, OscMessage message) {
active = true;
// if this is a simple infrared
if (typetag.equals("ff") && 4==pattern.length) {
x = message.get(0).floatValue();
y = message.get(1).floatValue();
}
else if (typetag.equals("fff") && 6==pattern.length && pattern[4].equals("xys")) {
// get the index of this point
int index = (pattern[5].equals("1")) ? 0 :
(pattern[5].equals("2")) ? 1 :
(pattern[5].equals("3")) ? 2 :
(pattern[5].equals("4")) ? 3 : -1;
// error
if (-1 == index) return;
raws[index].x = message.get(0).floatValue();
raws[index].y = message.get(1).floatValue();
raws[index].r = message.get(2).floatValue();
raws[index].active = true;
}
}
void draw(float pos_x, float pos_y, color c) {
if (!active) return;
//println("draw ir");
pushMatrix();
translate(pos_x, pos_y);
// draw the view rectangle
fill(c,0);
stroke(c);
rect(-30,0,60,40);
// draw the dot
pushMatrix();
translate(-30,0);
ellipse(x*60,40-(y*40),7,7);
popMatrix();
// draw the four dots
for(int i=0; i<4; i++) {
// ignore if not active
if (!raws[i].active) continue;
// chercher le rayon
float radius = 1 + (raws[i].r * 15);
// draw
pushMatrix();
translate(-30,0);
ellipse(raws[i].x*60,40-(raws[i].y*40),7,7);
popMatrix();
}
popMatrix();
}
}
///////////////////////////////////////
class IRRaw {
boolean active = false;
float x,y,r;
}
///////////////////////////////////////
class Nunchuk {
boolean active = false;
Joystick joystick = new Joystick();
Accel accel = new Accel();
Button button = new Button();
void message(String[] pattern, String typetag, OscMessage message) {
active = true;
if ( typetag.equals("ffff") && pattern.length == 6 && pattern[4].equals("accel") && pattern[5].equals("pry") ) {
accel.message(pattern,typetag,message);
}
else if (pattern[4].equals("button") ) {
button.message(pattern,typetag,message);
}
else if (pattern[4].equals("joy") ) {
joystick.message(pattern,typetag,message);
}
}
}
///////////////////////////////////////
class Classic {
boolean active;
Joystick left = new Joystick();
Joystick right = new Joystick();
Button button = new Button();
Analog analog = new Analog();
class Analog {
float l, r;
}
void message(String[] pattern, String typetag, OscMessage message) {
active = true;
if (pattern[4].equals("button") ) {
// weird bug
float value = message.get(0).floatValue();
if (value > 0.0 && value < 1.0) {
if (pattern[5].equals("L")) analog.l = message.get(0).floatValue();
else if (pattern[5].equals("R")) analog.r = message.get(0).floatValue();
return;
}
button.message(pattern,typetag,message);
}
else if (pattern[4].equals("analog") && typetag.equals("f")) {
if (pattern[5].equals("L")) analog.l = message.get(0).floatValue();
else if (pattern[5].equals("R")) analog.r = message.get(0).floatValue();
}
else if (pattern[4].equals("joyl") && typetag.equals("ff")) {
left.x = message.get(0).floatValue();
left.y = message.get(1).floatValue();
}
else if (pattern[4].equals("joyr") && typetag.equals("ff")) {
right.x = message.get(0).floatValue();
right.y = message.get(1).floatValue();
}
}
}
///////////////////////////////////////
} // fin de la classe Wiimote
///////////////////////////////////////////////////////////////////////////
class Balance {
boolean active = false;
// est-ce que quelqu'un est sur la planche
boolean someone = false;
// les cinq états réunis dans une liste de valeurs
float[] values = new float[5];
// ces listes avec des noms lisibles
float bottom_left, bottom_right, top_left, top_right;
// la somme
float sum = 0.0;
// centre de gravité
Center center = new Center();
// ciblage
Target target = new Target();
Balance() {
}
void deactivate() {
active = false;
target = new Target();
center = new Center();
}
void draw(int index, color c) {
if (!active) return;
String value_string;
float x_step = width/4;
float x_half_step = x_step/2;
float x = int((index*x_step)+x_half_step);
pushMatrix();
translate(x,44,0);
// l'index de la planche
value_string = "no." + nf(index,0);
text(value_string, int(-textWidth(value_string)/2), +6);
value_string = "bottom_left :" + nf(values[0],1,5);
text(value_string, int(-textWidth(value_string)/2), +16);
value_string = "bottom_right:" + nf(values[2],1,5);
text(value_string, int(-textWidth(value_string)/2), +26);
value_string = "top_left :" + nf(values[3],1,5);
text(value_string, int(-textWidth(value_string)/2), +36);
value_string = "top_right :" + nf(values[4],1,5);
text(value_string, int(-textWidth(value_string)/2), +46);
popMatrix();
pushMatrix();
translate(x,(height/2)-85);
// le rectangle de la planche
if (someone) noFill();
else fill(c);
rect(-50,0,100,50);
// la somme
float y = (sum * 50);
line(-50,y,50,y);
value_string = "somme:" + nf(sum,1,5) + " / " + nf( int(sum*100), 0) + "kg";
text(value_string, int(-textWidth(value_string)/2), +66);
if (someone) {
ellipse(-50, +50, values[0]*50, values[0]*50);
ellipse(+50, +50, values[1]*50, values[1]*50);
ellipse(-50, +0, values[2]*50, values[2]*50);
ellipse(+50, +0, values[3]*50, values[3]*50);
}
// draw the center
if (center.x > 0.0 && center.y > 0.0) {
pushMatrix();
translate((int)(center.x*100)-50, (int)(center.y*50),0);
line(-4,0,5,0);
line(0,-4,0,5);
popMatrix();
}
// do we draw the target?
if (target.active) {
pushMatrix();
// move to target position
translate((int)(target.x*100)-50, (int)(target.y*50),0);
// are we near the target?
if (center.near) {
// draw rectangle
fill(c);
rect(-4,-4,8,8);
}
else {
// otherwise, draw target
stroke(c);
line(-4,-4,-1,-4);
line(-4,-4,-4,-1);
line( 4,-4, 2,-4);
line( 4,-4, 4,-1);
line(-4, 4,-4, 2);
line(-4, 4,-1, 4);
line( 4, 4, 4, 2);
line( 2, 4, 5, 4);
}
popMatrix();
}
popMatrix();
} // fin du draw()
void message(String[] pattern, String typetag, OscMessage message) {
active = true;
if( pattern.length != 4 ) return;
if (!typetag.equals("fffff")) return;
setValues(message);
}
void setValues(OscMessage message) {
// regarder la somme pour voir si quelqu'un est sur la planche
if (message.get(4).floatValue() < 0.1) {
// personne
someone = false;
// turn of centering
center = new Center();
// pas la peine de continuer
return;
}
// chercher la somme
sum = values[4] = message.get(4).floatValue();
// il y a quelqu'un
someone = true;
// remplir les valeurs
for(int i=0; i<4; i++) {
values[i] = message.get(i).floatValue() / sum;
}
// mémoriser les nouvelles valeurs
bottom_left = values[0];
bottom_right = values[1];
top_left = values[2];
top_right = values[3];
// figure out the center
center.x = 1.0 - (((top_left+bottom_left) - (top_right+bottom_right) + 1) / 2);
center.y = 1.0 - (((top_left+top_right) - (bottom_left+bottom_right) + 1) / 2);
if (target.active) center.near = target.near(center.x, center.y);
}
// indiquer si quelquun est sur la planche
boolean someone() {
return someone;
}
class Target {
boolean active;
float x = -1.0, y = -1.0;
float tolerance = 0.05;
void deactivate() {
x = -1.0;
y = -1.0;
active = false;
}
void setXY(float new_x, float new_y) {
x = new_x;
y = new_y;
active = true;
}
void setTolerance(float new_tolerance) {
tolerance = new_tolerance;
}
boolean near(float new_x, float new_y) {
// if we're not even targeting within bounds return false
if (x < 0 || y < 0) return false;
//
if (new_x < 0 || new_y < 0) return false;
// if we're inactive return false
if (!active) return false;
// figure out the distances
float diff = dist(x, y, new_x, new_y);
// if the distance is greater than the tolerance, we're not close enough
if (diff > tolerance) return false;
// if all that is untrue, then we're near -- return true
return true;
}
} // fin de la classe Target
class Center {
boolean near = false;
float x = -1.0;
float y = -1.0;
}
} // fin de la classe Balance
} // fin de la classe Wii
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment