diff --git a/controllerApp/BallWave.pde b/controllerApp/BallWave.pde new file mode 100644 index 0000000000000000000000000000000000000000..55d1e55e2c9f242b575b05dabea625eb86567b00 --- /dev/null +++ b/controllerApp/BallWave.pde @@ -0,0 +1,40 @@ +class BallWave +{ + PVector location; + PVector plocation; + String mText=""; + float life = frameRate * 2; + + public BallWave(String _text, float x, float y) + { + mText = _text; + location = new PVector(x, y); + } + + public BallWave(String _text, float x, float y, float px, float py) + { + mText = _text; + location = new PVector(x, y); + plocation = new PVector(px, py); + } + + public void draw() + { + pushStyle(); + stroke(0); + if (life > 0) + noFill(); + strokeWeight(map(life,frameRate*2,0,20,width/5)); + circle(location.x,location.y,map(life,frameRate*2,0,width/20,4*width)); + + if (plocation != null) + line(location.x, location.y, plocation.x, plocation.y); + popStyle(); + life--; + } + + public boolean isDead() + { + return(life <= 0); + } +} diff --git a/controllerApp/Net.pde b/controllerApp/Net.pde new file mode 100644 index 0000000000000000000000000000000000000000..5d6077d983484e1b4b1969c4ba84b6613c1d2128 --- /dev/null +++ b/controllerApp/Net.pde @@ -0,0 +1,127 @@ +import java.io.*; +import java.net.*; +import java.util.UUID; + +class Net +{ + JSONObject jsonParam; + String uuid; + + public Net() + { + this.uuid = UUID.randomUUID().toString(); + } + public void sendTap(float x, float y){ + jsonParam = new JSONObject(); + jsonParam.put("evnType", "Tap"); + jsonParam.put("x", y); + jsonParam.put("y", x); + jsonParam.put("id", uuid); + sendPost(); + } + public void sendLongPress(float x, float y){ + jsonParam = new JSONObject(); + jsonParam.put("evnType", "Long Press"); + jsonParam.put("x", y); + jsonParam.put("y", x); + jsonParam.put("id", uuid); + sendPost(); + } + public void sendRotation(float x, float y,float angle){ + jsonParam = new JSONObject(); + jsonParam.put("evnType", "Rotation"); + jsonParam.put("x", y); + jsonParam.put("y", x); + jsonParam.put("angle", angle); + jsonParam.put("id", uuid); + sendPost(); + } + public void sendPinch(float x, float y,float d){ + jsonParam = new JSONObject(); + jsonParam.put("evnType", "Pinch"); + jsonParam.put("x", y); + jsonParam.put("y", x); + jsonParam.put("d", d); + jsonParam.put("id", uuid); + sendPost(); + } + public void sendAccelerometer(float ax, float ay,float az){ + jsonParam = new JSONObject(); + jsonParam.put("evnType", "Accelerometer"); + jsonParam.put("ax", ay); + jsonParam.put("ay", ax); + jsonParam.put("az", az); + jsonParam.put("id", uuid); + sendPost(); + } + public void sendGyroscope(float gx, float gy,float gz){ + jsonParam = new JSONObject(); + jsonParam.put("evnType", "Gyroscope"); + jsonParam.put("gx", gx); + jsonParam.put("gy", gy); + jsonParam.put("gz", gz); + jsonParam.put("id", uuid); + sendPost(); + } + public void sendDoubleTap(float x, float y){ + jsonParam = new JSONObject(); + jsonParam.put("evnType", "Double Tap"); + jsonParam.put("x", y); + jsonParam.put("y", x); + jsonParam.put("id", uuid); + sendPost(); + } + public void sendFlick(float x, float y,float px, float py,float v){ + jsonParam = new JSONObject(); + jsonParam.put("evnType", "Flick"); + jsonParam.put("x", y); + jsonParam.put("y", x); + jsonParam.put("px", px); + jsonParam.put("py", py); + jsonParam.put("v", v); + jsonParam.put("id", uuid); + sendPost(); + } + public void sendText(String text_){ + jsonParam = new JSONObject(); + jsonParam.put("evnType", "Text"); + jsonParam.put("text", text_); + jsonParam.put("id", uuid); + sendPost(); + } + private void sendPost() { + + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + try { + URL url = new URL("http://controller.viarezo.fr/multicast/"+code); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8"); + conn.setRequestProperty("Accept", "application/json"); + conn.setDoOutput(true); + conn.setDoInput(true); + + println("JSON", jsonParam.toString()); + DataOutputStream os = new DataOutputStream(conn.getOutputStream()); + os.writeBytes(jsonParam.toString()); + + os.flush(); + os.close(); + + println("STATUS", String.valueOf(conn.getResponseCode())); + println("MSG", conn.getResponseMessage()); + + conn.disconnect(); + } + catch (Exception e) { + e.printStackTrace(); + } + } + } + ); + + thread.start(); + } +} diff --git a/controllerApp/Thing.pde b/controllerApp/Thing.pde new file mode 100644 index 0000000000000000000000000000000000000000..33e293cd9fc6a9d781449cb243bcf55145ae8955 --- /dev/null +++ b/controllerApp/Thing.pde @@ -0,0 +1,30 @@ +class Thing +{ + PVector location; + PVector plocation; + float life = frameRate * 0.5; + + public Thing(float x, float y,float px, float py) + { + location = new PVector(x, y); + plocation = new PVector(px, py); + } + + + public void draw() + { + pushStyle(); + strokeWeight(map(life, frameRate/2, 0, 40, 0)); + stroke(255); + life--; + if (life > 0) + line(location.x,location.y,plocation.x,plocation.y); + + popStyle(); + } + + public boolean isDead() + { + return(life <= 0); + } +} diff --git a/controllerApp/UI.pde b/controllerApp/UI.pde new file mode 100644 index 0000000000000000000000000000000000000000..9440a79d902a4538643d1e252090468d66acda40 --- /dev/null +++ b/controllerApp/UI.pde @@ -0,0 +1,84 @@ +class UI +{ + color mColor; + PVector plocation; + String mText=""; + float life = frameRate * 3; + + public UI() + { + mColor = color(0, 0, 0); + } + + private void fade() + { + color black = color(0,0,0); + mColor = lerpColor(mColor, black, 1/frameRate,1); + } + private void axis() + { + pushStyle(); + pushMatrix(); + translate(0.90*width,height-0.1*width); + strokeWeight(4/50.0); + scale(width/16); + //x*cos()-y*sin(),x*sin()+y*cos() + //cx,cy,cz + //cy/sqrt(cx*cx+cy*cy),-cx/sqrt(cx*cx+cy*cy),0 + // + + float n = sqrt(1+cy*cy/(cx*cx)+(cx*cx*cx*cx+cx*cx*cy*cy+cy*cy*cy*cy)/(cx*cx*cz*cz)); + stroke(255,0,0); + line(0,0,cx*cos(Angle)-cy*sin(Angle),cx*sin(Angle)+cy*cos(Angle)); + stroke(0,255,0); + line(0,0,(cy/sqrt(cx*cx+cy*cy))*cos(Angle)+(cx/sqrt(cx*cx+cy*cy))*sin(Angle),(cy/sqrt(cx*cx+cy*cy))*sin(Angle)-(cx/sqrt(cx*cx+cy*cy))*cos(Angle)); + stroke(0,0,255); + line(0,0,(1/n)*cos(Angle)-(cy/(n*cx))*sin(Angle),(1/n)*sin(Angle)+(cy/(n*cx))*cos(Angle)); + popStyle(); + popMatrix(); + + } + public void draw() + { + pushStyle(); + background(mColor); + fade(); + axis(); + //text("Accelerometer: \n" + + // "x: " + nfp(accelerometerX, 1, 3) + "\n" + + // "y: " + nfp(accelerometerY, 1, 3) + "\n" + + // "z: " + nfp(accelerometerZ, 1, 3), 0, 0, width, height); + + pushMatrix(); + translate(width/2, height/2); + rotate(Angle); + fill(255, 0, 0); + noStroke(); + rect( -Size/2, -Size/2, Size, Size); + popMatrix(); + //if we have things lets reverse through them + // so we can delete dead ones and draw live ones + if (things.size() > 0) { + for (int i = things.size()-1; i >= 0; i--) + { + Thing t = things.get(i); + if (t.isDead()) + things.remove(t); + else + t.draw(); + } + } + if (ball_waves.size() > 0) { + for (int i = ball_waves.size()-1; i >= 0; i--) + { + BallWave b = ball_waves.get(i); + if (b.isDead()) + ball_waves.remove(b); + else + b.draw(); + } + } + popStyle(); + + } +} diff --git a/controllerApp/controllerApp.pde b/controllerApp/controllerApp.pde new file mode 100644 index 0000000000000000000000000000000000000000..d182893a37b7ba834a9f955787c2e8f2aabb5e93 --- /dev/null +++ b/controllerApp/controllerApp.pde @@ -0,0 +1,219 @@ +import ketai.sensors.*; +import android.view.MotionEvent; +import ketai.ui.*; + +KetaiVibrate vibe; +KetaiGesture gesture; +KetaiSensor sensor; +KetaiKeyboard keyboard; +UI ui; +Net net; + +int DELAY = 200; + +float accelerometerX = 0; +float accelerometerY = 0; +float accelerometerZ = 0; +float rotation = 0; +float rotationX = 0; +float rotationY = 0; +float rotationZ = 0; + +float last_rotation = 0; +float last_accelerometer = 0; +float last_gyroscope = 0; +float last_keyboard = 0; + +float cx, cy, cz; +float Size = 400; +float Angle = 3.5; +PImage img; +String code = "a1b2c3"; +String text = ""; +Boolean keyboard_flag = false; +ArrayList<Thing> things = new ArrayList<Thing>(); +ArrayList<BallWave> ball_waves = new ArrayList<BallWave>(); + + +void onDoubleTap(float x, float y) +{ + if (!keyboard_flag) { + net.sendDoubleTap(x, y); + } +} + +void onTap(float x, float y) +{ + if (!keyboard_flag) { + ball_waves.add(new BallWave("SINGLE", x, y)); + ui.mColor = color(random(255), random(255), random(255)); + net.sendTap(x, y); + } +} + +void onLongPress(float x, float y) +{ + if (!keyboard_flag) { + ball_waves.add(new BallWave("LONG", x, y)); + ui.mColor = color(random(255), random(255), random(255)); + vibe.vibrate(50); + net.sendLongPress(x, y); + } +} + +//the coordinates of the start of the gesture, +// end of gesture and velocity in pixels/sec +void onFlick( float x, float y, float px, float py, float v) +{ + //things.add(new Thing("FLICK:"+v, x, y, px, py)); + if (!keyboard_flag) { + net.sendFlick(x, y, px, py, v); + } +} + +void onPinch(float x, float y, float d) +{ + if (d != 0) { + Size = constrain(Size+d, 1, 2000); + net.sendPinch(x, y, d); + } +} + +void onRotate(float x, float y, float ang) +{ + rotation += ang; + Angle += ang; + if (millis() - last_rotation > DELAY) { + last_rotation = millis(); + net.sendRotation(x, y, rotation); + rotation = 0; + } +} + +//these still work if we forward MotionEvents below +void mouseDragged() +{ + things.add(new Thing(mouseX, mouseY, pmouseX, pmouseY)); +} + +void mousePressed() +{ +} +void keyPressed() { + last_keyboard = millis(); + if (key == CODED) { + if (keyCode == BACKSPACE) { + if (mouseY<0.3*height) { + if (code.length()>0) { + code = code.substring(0, code.length() - 1); + } + } else { + if (text.length()>0) { + text = text.substring(0, text.length() - 1); + } + } + } + } else { + if (mouseY<0.15*height) { + code += str(key); + code = code.substring(0, min(6, code.length())); + } else { + text += str(key); + } + } +} + + +public boolean surfaceTouchEvent(MotionEvent event) { + + //call to keep mouseX, mouseY, etc updated + super.surfaceTouchEvent(event); + + //forward event to class for processing + return gesture.surfaceTouchEvent(event); +} + + + +void setup() +{ + net = new Net(); + sensor = new KetaiSensor(this); + gesture = new KetaiGesture(this); + vibe = new KetaiVibrate(this); + keyboard = new KetaiKeyboard(); + ui = new UI(); + sensor.start(); + orientation(PORTRAIT); + imageMode(CENTER); +} + +void draw() +{ + ui.draw(); + if (Size<=2 && !keyboard_flag) { + keyboard.show(this); + keyboard_flag = true; + text = ""; + } else if (Size>2 && keyboard_flag) { + keyboard.hide(this); + keyboard_flag = false; + } + if (keyboard_flag) { + if (mouseY<0.15*height) { + stroke(0,255,0); + } else { + stroke(150,150,150); + } + noFill(); + strokeWeight(3); + rect(width*0.72, width*0.02, width*0.24, width*0.08, width*0.08); + textSize(height*0.03); + textAlign(LEFT, CENTER); + fill(255); + text("code", 0.56*width, 0.06*width); + textAlign(CENTER, CENTER); + text(code, 0.84*width, 0.06*width); + textSize(height*0.06); + fill(200, 200, 200); + textAlign(CENTER, CENTER); + fill(0, max(0, 255-int((millis()-last_keyboard)/8.0)), 0); + if (255-int((millis()-last_keyboard)/8.0)<0 && text.length()>0) { + net.sendText(text); + text = ""; + } + text(text, 0.5*width, 0.35*height); + } +} + +void onAccelerometerEvent(float x, float y, float z) +{ + accelerometerX = x; + accelerometerY = y; + accelerometerZ = z; + float n = sqrt(x*x+y*y+z*z); + cx = x/n; + cy = y/n; + cz = z/n; + + if (millis()-last_accelerometer > DELAY) { + last_accelerometer = millis(); + net.sendAccelerometer(accelerometerX, accelerometerY, accelerometerZ); + accelerometerX = 0; + accelerometerY = 0; + accelerometerZ = 0; + } +} +void onGyroscopeEvent(float x, float y, float z) +{ + rotationX += x; + rotationY += y; + rotationZ += z; + if (millis()-last_gyroscope > DELAY) { + last_gyroscope = millis(); + net.sendGyroscope(rotationX, rotationY, rotationZ); + rotationX = 0; + rotationY = 0; + rotationZ = 0; + } +}