Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

changing directory name

  • Loading branch information...
commit 3ef38e21336b300f8458aaa4dfd7a001ca604cf2 1 parent b2cfd8d
@shiffman authored
Showing with 4,527 additions and 0 deletions.
  1. +25 −0 eclipse/MPEMessagingExamples/.classpath
  2. +17 −0 eclipse/MPEMessagingExamples/.project
  3. BIN  eclipse/MPEMessagingExamples/bin/feeds/Headline.class
  4. BIN  eclipse/MPEMessagingExamples/bin/feeds/Headlines.class
  5. BIN  eclipse/MPEMessagingExamples/bin/fourthclient/Ball.class
  6. BIN  eclipse/MPEMessagingExamples/bin/fourthclient/Messenger.class
  7. BIN  eclipse/MPEMessagingExamples/bin/fourthclient/Throwing.class
  8. BIN  eclipse/MPEMessagingExamples/bin/helloworld/HelloWorld.class
  9. BIN  eclipse/MPEMessagingExamples/bin/soundinput/Ball.class
  10. BIN  eclipse/MPEMessagingExamples/bin/soundinput/Threshold.class
  11. BIN  eclipse/MPEMessagingExamples/bin/soundinput/Volume.class
  12. BIN  eclipse/MPEMessagingExamples/bin/soundinput/WaveForm.class
  13. BIN  eclipse/MPEMessagingExamples/bin/twocameras/Jiggler.class
  14. BIN  eclipse/MPEMessagingExamples/bin/twocameras/OverallMotion.class
  15. BIN  eclipse/MPEMessagingExamples/bin/video/ColorTracking.class
  16. BIN  eclipse/MPEMessagingExamples/bin/video/Jiggler.class
  17. BIN  eclipse/MPEMessagingExamples/bin/video/OverallMotion.class
  18. BIN  eclipse/MPEMessagingExamples/lib/core/core.jar
  19. +41 −0 eclipse/MPEMessagingExamples/lib/minim/changelog.txt
  20. +1 −0  eclipse/MPEMessagingExamples/lib/minim/library/export.txt
  21. BIN  eclipse/MPEMessagingExamples/lib/minim/library/jl1.0.jar
  22. BIN  eclipse/MPEMessagingExamples/lib/minim/library/jsminim.jar
  23. BIN  eclipse/MPEMessagingExamples/lib/minim/library/minim-spi.jar
  24. BIN  eclipse/MPEMessagingExamples/lib/minim/library/minim.jar
  25. BIN  eclipse/MPEMessagingExamples/lib/minim/library/mp3spi1.9.4.jar
  26. BIN  eclipse/MPEMessagingExamples/lib/minim/library/tritonus_aos.jar
  27. BIN  eclipse/MPEMessagingExamples/lib/minim/library/tritonus_share.jar
  28. +165 −0 eclipse/MPEMessagingExamples/lib/minim/license.txt
  29. +1 −0  eclipse/MPEMessagingExamples/lib/minim/version.txt
  30. BIN  eclipse/MPEMessagingExamples/lib/simpleML.jar
  31. BIN  eclipse/MPEMessagingExamples/lib/video/video.jar
  32. BIN  eclipse/MPEMessagingExamples/mpe.jar
  33. +7 −0 eclipse/MPEMessagingExamples/mpefiles/mpe0.ini
  34. +7 −0 eclipse/MPEMessagingExamples/mpefiles/mpe1.ini
  35. +7 −0 eclipse/MPEMessagingExamples/mpefiles/mpe2.ini
  36. +59 −0 eclipse/MPEMessagingExamples/src/feeds/Headline.java
  37. +122 −0 eclipse/MPEMessagingExamples/src/feeds/Headlines.java
  38. +51 −0 eclipse/MPEMessagingExamples/src/fourthclient/Ball.java
  39. +64 −0 eclipse/MPEMessagingExamples/src/fourthclient/Messenger.java
  40. +88 −0 eclipse/MPEMessagingExamples/src/fourthclient/Throwing.java
  41. +66 −0 eclipse/MPEMessagingExamples/src/helloworld/HelloWorld.java
  42. +51 −0 eclipse/MPEMessagingExamples/src/soundinput/Ball.java
  43. +128 −0 eclipse/MPEMessagingExamples/src/soundinput/Threshold.java
  44. +100 −0 eclipse/MPEMessagingExamples/src/soundinput/Volume.java
  45. +111 −0 eclipse/MPEMessagingExamples/src/soundinput/WaveForm.java
  46. +74 −0 eclipse/MPEMessagingExamples/src/twocameras/Jiggler.java
  47. +151 −0 eclipse/MPEMessagingExamples/src/twocameras/OverallMotion.java
  48. +146 −0 eclipse/MPEMessagingExamples/src/video/ColorTracking.java
  49. +47 −0 eclipse/MPEMessagingExamples/src/video/Jiggler.java
  50. +141 −0 eclipse/MPEMessagingExamples/src/video/OverallMotion.java
  51. +8 −0 eclipse/MostPixelsEverTCP/.classpath
  52. +17 −0 eclipse/MostPixelsEverTCP/.project
  53. BIN  eclipse/MostPixelsEverTCP/core.jar
  54. BIN  eclipse/MostPixelsEverTCP/data/Arial-BoldMT-18.vlw
  55. BIN  eclipse/MostPixelsEverTCP/data/texture.gif
  56. +7 −0 eclipse/MostPixelsEverTCP/ini_quotes/mpeSc0.ini
  57. +7 −0 eclipse/MostPixelsEverTCP/ini_quotes/mpeSc1.ini
  58. +7 −0 eclipse/MostPixelsEverTCP/ini_threeD/mpe0.ini
  59. +7 −0 eclipse/MostPixelsEverTCP/ini_threeD/mpe1.ini
  60. +176 −0 eclipse/MostPixelsEverTCP/mpe/client/AsyncClient.java
  61. +11 −0 eclipse/MostPixelsEverTCP/mpe/client/MpeDataListener.java
  62. +849 −0 eclipse/MostPixelsEverTCP/mpe/client/TCPClient.java
  63. +207 −0 eclipse/MostPixelsEverTCP/mpe/config/FileParser.java
  64. +121 −0 eclipse/MostPixelsEverTCP/mpe/examples/AutoBalls.java
  65. +128 −0 eclipse/MostPixelsEverTCP/mpe/examples/BouncingBalls.java
  66. +123 −0 eclipse/MostPixelsEverTCP/mpe/examples/OptimizedBalls.java
  67. +63 −0 eclipse/MostPixelsEverTCP/mpe/examples/ThreeDTest.java
  68. +103 −0 eclipse/MostPixelsEverTCP/mpe/examples/VideoTest.java
  69. +109 −0 eclipse/MostPixelsEverTCP/mpe/examples/quotes/QuoteDisplay.java
  70. +121 −0 eclipse/MostPixelsEverTCP/mpe/examples/quotes/QuoteFetcher.java
  71. +218 −0 eclipse/MostPixelsEverTCP/mpe/server/Connection.java
  72. +85 −0 eclipse/MostPixelsEverTCP/mpe/server/ListenerConnection.java
  73. +23 −0 eclipse/MostPixelsEverTCP/mpe/server/MPEPrefs.java
  74. +351 −0 eclipse/MostPixelsEverTCP/mpe/server/MPEServer.java
  75. +48 −0 eclipse/MostPixelsEverTCP/mpe/tests/BackdoorServerTest.java
  76. +7 −0 eclipse/MostPixelsEverTCP/mpeSc0.ini
  77. +7 −0 eclipse/MostPixelsEverTCP/mpeSc1.ini
  78. +36 −0 eclipse/MostPixelsEverTCP/mpeScComments.ini
  79. +18 −0 eclipse/MostPixelsEverTCP/notes.txt
  80. BIN  eclipse/MostPixelsEverTCP/video.jar
View
25 eclipse/MPEMessagingExamples/.classpath
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="lib" path="lib/core/core.jar">
+ <attributes>
+ <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="MPEMessagingExamples/lib/core"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="lib" path="lib/video/video.jar">
+ <attributes>
+ <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="MPEMessagingExamples/lib/video"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="lib" path="lib/simpleML.jar"/>
+ <classpathentry kind="lib" path="mpe.jar"/>
+ <classpathentry kind="lib" path="lib/minim/library/jl1.0.jar"/>
+ <classpathentry kind="lib" path="lib/minim/library/jsminim.jar"/>
+ <classpathentry kind="lib" path="lib/minim/library/minim-spi.jar"/>
+ <classpathentry kind="lib" path="lib/minim/library/minim.jar"/>
+ <classpathentry kind="lib" path="lib/minim/library/mp3spi1.9.4.jar"/>
+ <classpathentry kind="lib" path="lib/minim/library/tritonus_aos.jar"/>
+ <classpathentry kind="lib" path="lib/minim/library/tritonus_share.jar"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
View
17 eclipse/MPEMessagingExamples/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>MPEMessagingExamples</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
View
BIN  eclipse/MPEMessagingExamples/bin/feeds/Headline.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/feeds/Headlines.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/fourthclient/Ball.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/fourthclient/Messenger.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/fourthclient/Throwing.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/helloworld/HelloWorld.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/soundinput/Ball.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/soundinput/Threshold.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/soundinput/Volume.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/soundinput/WaveForm.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/twocameras/Jiggler.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/twocameras/OverallMotion.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/video/ColorTracking.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/video/Jiggler.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/bin/video/OverallMotion.class
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/lib/core/core.jar
Binary file not shown
View
41 eclipse/MPEMessagingExamples/lib/minim/changelog.txt
@@ -0,0 +1,41 @@
+Changelog!
+
+Version 2.0.2
+
+Fixed Bugs:
+
++ filenames were being parsed incorrectly by createRecorder.
+
++ fixed audio processing routines for AudioPlayer and AudioSnippet so that
+ they don't spend cycles doing nothing while not in the "play" state.
+
++ fixed the zombie thread bug, which kept audio processing Threads from
+ exiting when close() was called.
+
++ fixed out-of-memory problems that could occur when large files were
+ played. this does come at the cost of slower seek times.
+
++ fixed the isEnabled(AudioEffect) function, which, uh, wasn't working.
+
++ fixed the pan() function, which was returning the BALANCE control.
+
+New Features:
+
++ added functions to FFT for doing forward transforms with an offset:
+ forward(float[] samples, offset) and forward(AudioBuffer samples, offset)
+
++ added a freqToIndex(float freq) method to FFT for finding out the index
+ of the spectrum band that contains the passed in frequency.
+
++ added a stop() method to AudioSample, so that playing samples can be
+ immediately silenced.
+
++ added setPanNoGlide(float pan) to Controller, which will snap the panning
+ setting of a sound to the provided value.
+
++ added setInputMixer(Mixer) and setOutputMixer(Mixer), which allow you to
+ specify which Java Mixer object should be used when obtaining inputs (AudioInput)
+ and outputs (AudioOuput, AudioPlayer, AudioSnippet, AudioSample).
+
+
+
View
1  eclipse/MPEMessagingExamples/lib/minim/library/export.txt
@@ -0,0 +1 @@
+name = Minim Audio
View
BIN  eclipse/MPEMessagingExamples/lib/minim/library/jl1.0.jar
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/lib/minim/library/jsminim.jar
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/lib/minim/library/minim-spi.jar
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/lib/minim/library/minim.jar
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/lib/minim/library/mp3spi1.9.4.jar
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/lib/minim/library/tritonus_aos.jar
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/lib/minim/library/tritonus_share.jar
Binary file not shown
View
165 eclipse/MPEMessagingExamples/lib/minim/license.txt
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
View
1  eclipse/MPEMessagingExamples/lib/minim/version.txt
@@ -0,0 +1 @@
+2.0.2
View
BIN  eclipse/MPEMessagingExamples/lib/simpleML.jar
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/lib/video/video.jar
Binary file not shown
View
BIN  eclipse/MPEMessagingExamples/mpe.jar
Binary file not shown
View
7 eclipse/MPEMessagingExamples/mpefiles/mpe0.ini
@@ -0,0 +1,7 @@
+id=0;
+server=localhost;
+port=9002;
+localScreenSize=320,240;
+localLocation=0,0;
+masterDimensions=960,240;
+debug=0;
View
7 eclipse/MPEMessagingExamples/mpefiles/mpe1.ini
@@ -0,0 +1,7 @@
+id=1;
+server=localhost;
+port=9002;
+localScreenSize=320,240;
+localLocation=320,0;
+masterDimensions=960,240;
+debug=0;
View
7 eclipse/MPEMessagingExamples/mpefiles/mpe2.ini
@@ -0,0 +1,7 @@
+id=2;
+server=localhost;
+port=9002;
+localScreenSize=320,240;
+localLocation=640,0;
+masterDimensions=960,240;
+debug=0;
View
59 eclipse/MPEMessagingExamples/src/feeds/Headline.java
@@ -0,0 +1,59 @@
+/**
+ * Class to display a String headline
+ * @author Shiffman
+ */
+
+package feeds;
+
+import mpe.client.TCPClient;
+import processing.core.PApplet;
+import processing.core.PFont;
+
+public class Headline {
+
+ // So we know about the PApplet and the Client
+ PApplet parent;
+ TCPClient client;
+
+ // Location and speed
+ float x = 0;
+ float y = 0;
+ float vy;
+
+ // Font and String
+ PFont f;
+ String headline = "";
+
+ // Initialize all variables in the constructor
+ public Headline(PApplet _parent, TCPClient _c, String s, float _x, float _y){
+ parent = _parent;
+ client = _c;
+ x = _x;
+ y = _y;
+ f = parent.createFont("Georgia",16,true);
+ headline = s;
+ vy = -2f; // Headline starts moving up
+ }
+
+ public void move() {
+ // velocity increases exponentially
+ vy *= 1.02f;
+ y += vy;
+ }
+
+ // Display the headline
+ public void draw(){
+ parent.smooth();
+ parent.fill(0);
+ parent.textFont(f);
+ parent.text(headline,x,y);
+ }
+
+ // If the headline is way off screen, we don't need it
+ public boolean finished() {
+ if (y < -100) {
+ return true;
+ }
+ return false;
+ }
+}
View
122 eclipse/MPEMessagingExamples/src/feeds/Headlines.java
@@ -0,0 +1,122 @@
+/**
+ * MPE Messainge Demo with simpleML library grabbing XML feed
+ * @author Shiffman
+ */
+
+package feeds;
+
+import java.util.ArrayList;
+
+import mpe.client.TCPClient;
+
+import processing.core.PApplet;
+import simpleML.*;
+
+public class Headlines extends PApplet {
+
+ // MPE Client Stuff
+ final int ID = 1;
+ TCPClient client;
+
+ // simpleML request object
+ XMLRequest xmlRequest;
+ // ArrayList of Headline objects
+ ArrayList headlines;
+
+ // We will store the headlines we retrieve in a String
+ String[] yahoos;
+ // The counter will go through the headlines one at a time
+ // -1 means no headlines yet
+ int counter = -1;
+
+ boolean started = false;
+
+ //--------------------------------------
+ static public void main(String args[]) {
+ PApplet.main(new String[] { "feeds.Headlines"});
+ }
+
+ //--------------------------------------
+ public void setup() {
+ // make a new Client using an INI file
+ // sketchPath() is used so that the INI file is local to the sketch
+ client = new TCPClient(sketchPath("mpefiles/mpe"+ID+".ini"), this);
+
+ // the size is determined by the client's local width and height
+ size(client.getLWidth(), client.getLHeight());
+
+ // the random seed must be identical for all clients
+ randomSeed(1);
+
+ headlines = new ArrayList();
+
+ // Creating and starting the request
+ // Only if we are client 0!!! (one thing we could do is have different clients read from different feeds)
+ if (client.getID() == 0) {
+ xmlRequest = new XMLRequest(this,"http://rss.news.yahoo.com/rss/topstories");
+ xmlRequest.makeRequest();
+ }
+ client.start();
+ }
+
+ //--------------------------------------
+ // Keep the motor running... draw() needs to be added in auto mode, even if
+ // it is empty to keep things rolling.
+ public void draw() {
+ frame.setLocation(client.getID()*client.getLWidth(),0);
+ }
+
+ //--------------------------------------
+ // Triggered by the client whenever a new frame should be rendered.
+ // All synchronized drawing should be done here when in auto mode.
+ public void frameEvent(TCPClient c) {
+
+ if (c.messageAvailable()) {
+ String[] msg = c.getDataMessage();
+ // For every message a new object is made
+ for (int i = 0; i < msg.length; i++) {
+ Headline headline = new Headline(this,client,msg[i], random(client.getMWidth()),client.getMHeight());
+ headlines.add(headline);
+ }
+ }
+
+ background(255);
+
+ // Deal with all of the headline objects
+ // We iterate backwards b/c we are deleting
+ for (int i = headlines.size()-1; i >= 0; i--) {
+ Headline headline = (Headline) headlines.get(i);
+ headline.move();
+ headline.draw();
+ // Deleting ones that are off the screen
+ if (headline.finished()) {
+ headlines.remove(i);
+ }
+ }
+
+ // Here is the funny business
+ // If we are client #0, and there are headlines available
+ // We broadcast a new one every 30 frames
+ // (We don't have to do it this way, we could just send them all at once, just an arbitrary method!)
+ if (client.getID() == 0 && counter > -1 && client.getFrameCount() % 30 == 0) {
+ String headline = yahoos[counter];
+ headline = headline.replaceAll(":", " "); // Make sure there are no semi-colons!!
+ client.broadcast(headline); // send out the String
+ counter++; // Go to the next one
+ // If we're at the end, reset
+ if (counter == yahoos.length) {
+ counter = -1;
+ xmlRequest.makeRequest(); // and make the request again!
+ }
+ }
+ }
+
+
+ // When the request is complete
+ public void netEvent(XMLRequest ml) {
+ // Retrieving an array of all XML elements inside "<title*>" tags
+ yahoos = ml.getElementArray("title");
+ // Counter restarts at 0
+ counter = 0;
+ }
+}
View
51 eclipse/MPEMessagingExamples/src/fourthclient/Ball.java
@@ -0,0 +1,51 @@
+/**
+ * Ball class for Sound example
+ * <http://mostpixelsever.com>
+ * @author Shiffman
+ */
+
+package fourthclient;
+
+import mpe.client.TCPClient;
+import processing.core.PApplet;
+
+public class Ball {
+
+ PApplet parent;
+ TCPClient client;
+
+ float x = 0; //ellipse x location
+ float y = 0; //ellipse y location
+ float xvel = 1; //x velocity
+ float yvel = 1; //y velocity
+
+ float gravity = 0.5f;
+
+ public Ball(PApplet _parent, TCPClient _c, float _x, float _y){
+ parent = _parent;
+ client = _c;
+ xvel = parent.random(10,20);
+ yvel = parent.random(-2,2);
+ x = _x;
+ y = _y;
+ }
+
+ //a simple bounce across the screen
+ public void calc(){
+ if (y > client.getMHeight()) {
+ yvel *= -1;
+ y = client.getMHeight();
+ }
+ x += xvel;
+ y += yvel;
+
+ yvel += gravity;
+ }
+
+ public void draw(){
+ parent.smooth();
+ parent.fill(0);
+ parent.ellipse(x,y,16,16);
+ }
+
+}
View
64 eclipse/MPEMessagingExamples/src/fourthclient/Messenger.java
@@ -0,0 +1,64 @@
+/**
+ * Quotes Demo
+ * The QuoteFetcher is an asynchronous client which fetches the quotes from a
+ * server and broadcasts them for the QuoteDisplays to display.
+ * <http://code.google.com/p/mostpixelsever/>
+ *
+ * @author Elie Zananiri
+ */
+
+package fourthclient;
+
+import mpe.client.*;
+import processing.core.*;
+
+public class Messenger extends PApplet {
+
+ //--------------------------------------
+ AsyncClient client;
+ PFont font;
+
+ boolean message = false;
+
+ //--------------------------------------
+ public void setup() {
+ // set up the client
+ client = new AsyncClient("localhost",9003);
+ size(350, 200);
+
+ smooth();
+ frameRate(30);
+ font = createFont("Arial", 12);
+ }
+
+ //--------------------------------------
+ public void draw() {
+ if (message) {
+ background(0);
+ message = false;
+ } else {
+ background(255);
+ }
+ fill(0);
+ textFont(font, 18);
+ textAlign(CENTER, CENTER);
+ text("Click the mouse to launch a ball",width/2,height/2);
+ }
+
+ //--------------------------------------
+ public void mousePressed() {
+ message = true;
+ client.broadcast("C");
+ }
+
+
+
+
+
+
+
+ //--------------------------------------
+ static public void main(String args[]) {
+ PApplet.main(new String[] { "fourthclient.Messenger" });
+ }
+}
View
88 eclipse/MPEMessagingExamples/src/fourthclient/Throwing.java
@@ -0,0 +1,88 @@
+
+/**
+ * Big Screens Week 4
+ * Reads sound level from microphone and broadcasts sound events to all clients
+ * @author Shiffman
+ */
+
+package fourthclient;
+
+import java.util.ArrayList;
+
+import mpe.client.TCPClient;
+
+import processing.core.PApplet;
+
+public class Throwing extends PApplet {
+
+ final int ID = 1;
+
+ TCPClient client;
+
+ ArrayList balls;
+
+ //--------------------------------------
+ static public void main(String args[]) {
+ PApplet.main(new String[] { "fourthclient.Throwing"});
+ }
+
+
+ //--------------------------------------
+ public void setup() {
+ // make a new Client using an INI file
+ // sketchPath() is used so that the INI file is local to the sketch
+ client = new TCPClient(sketchPath("mpefiles/mpe"+ID+".ini"), this);
+
+ // the size is determined by the client's local width and height
+ size(client.getLWidth(), client.getLHeight());
+
+ balls = new ArrayList();
+ randomSeed(1);
+
+ smooth();
+ background(255);
+
+ // IMPORTANT, YOU MUST START THE CLIENT!
+ client.start();
+ }
+
+ //--------------------------------------
+ // Keep the motor running... draw() needs to be added in auto mode, even if
+ // it is empty to keep things rolling.
+ public void draw() {
+ frame.setLocation(client.getID()*client.getLWidth(),0);
+ }
+
+ //--------------------------------------
+ // Triggered by the client whenever a new frame should be rendered.
+ // All synchronized drawing should be done here when in auto mode.
+ public void frameEvent(TCPClient c) {
+ background(255);
+ if (c.messageAvailable()) {
+ String[] msg = c.getDataMessage();
+ // If the message C comes in, then make a new Ball object
+ // and add to ArrayList
+ if (msg[0].equals("C")) {
+ balls.add(new Ball(this,client,0,height/2));
+ }
+ }
+
+ // Deal with all balls
+ for (int i = 0; i < balls.size(); i++) {
+ Ball b = (Ball) balls.get(i);
+ b.calc();
+ b.draw();
+ }
+
+ }
+
+
+}
+
+
+
+
+
+
+
+
View
66 eclipse/MPEMessagingExamples/src/helloworld/HelloWorld.java
@@ -0,0 +1,66 @@
+/**
+ * Big Screens Week 3 exercise
+ * Convert to multi-screen with <http://www.mostpixelsever.com>
+ * @author Shiffman
+ */
+
+//This one should be really easy!
+//Just moves a rectangle across the screen. . .
+
+package helloworld;
+
+import mpe.client.TCPClient;
+import processing.core.PApplet;
+
+
+public class HelloWorld extends PApplet {
+
+ final int ID = 1;
+ float x;
+ TCPClient client;
+
+ //--------------------------------------
+ static public void main(String args[]) {
+ PApplet.main(new String[] { "helloworld.HelloWorld" });
+ }
+
+ //--------------------------------------
+ public void setup() {
+ // make a new Client using an INI file
+ // sketchPath() is used so that the INI file is local to the sketch
+ client = new TCPClient(sketchPath("mpefiles/mpe"+ID+".ini"), this);
+
+ // the size is determined by the client's local width and height
+ size(client.getLWidth(), client.getLHeight());
+
+ // the random seed must be identical for all clients
+ randomSeed(1);
+
+ smooth();
+ background(255);
+
+ // IMPORTANT, YOU MUST START THE CLIENT!
+ client.start();
+ }
+
+ //--------------------------------------
+ // Keep the motor running... draw() needs to be added in auto mode, even if
+ // it is empty to keep things rolling.
+ public void draw() {
+ frame.setLocation(client.getID()*client.getLWidth(),0);
+ }
+
+ //--------------------------------------
+ // Triggered by the client whenever a new frame should be rendered.
+ // All synchronized drawing should be done here when in auto mode.
+ public void frameEvent(TCPClient c) {
+ // clear the screen
+ background(255);
+ fill(0);
+ rect(x,0,40,height);
+ x = (x + 5) % client.getMWidth();
+ }
+
+}
+
+
View
51 eclipse/MPEMessagingExamples/src/soundinput/Ball.java
@@ -0,0 +1,51 @@
+/**
+ * Ball class for Sound example
+ * <http://mostpixelsever.com>
+ * @author Shiffman
+ */
+
+package soundinput;
+
+import mpe.client.TCPClient;
+import processing.core.PApplet;
+
+public class Ball {
+
+ PApplet parent;
+ TCPClient client;
+
+ float x = 0; //ellipse x location
+ float y = 0; //ellipse y location
+ float xvel = 1; //x velocity
+ float yvel = 1; //y velocity
+
+ float gravity = 0.5f;
+
+ public Ball(PApplet _parent, TCPClient _c, float _x, float _y){
+ parent = _parent;
+ client = _c;
+ xvel = parent.random(10,20);
+ yvel = parent.random(-2,2);
+ x = _x;
+ y = _y;
+ }
+
+ //a simple bounce across the screen
+ public void calc(){
+ if (y > client.getMHeight()) {
+ yvel *= -1;
+ y = client.getMHeight();
+ }
+ x += xvel;
+ y += yvel;
+
+ yvel += gravity;
+ }
+
+ public void draw(){
+ parent.smooth();
+ parent.fill(0);
+ parent.ellipse(x,y,16,16);
+ }
+
+}
View
128 eclipse/MPEMessagingExamples/src/soundinput/Threshold.java
@@ -0,0 +1,128 @@
+
+/**
+ * Big Screens Week 4
+ * Reads sound level from microphone and broadcasts sound events to all clients
+ * @author Shiffman
+ */
+
+package soundinput;
+
+import java.util.ArrayList;
+
+import ddf.minim.AudioInput;
+import ddf.minim.Minim;
+
+import mpe.client.TCPClient;
+
+import processing.core.PApplet;
+
+public class Threshold extends PApplet {
+
+ final int ID = 0;
+ TCPClient client;
+
+ float clapLevel = 0.05f; // How loud is a clap
+ float threshold = 0.005f; // How quiet is silence
+ boolean clapping = false;
+
+ ArrayList balls;
+
+ Minim minim;
+ AudioInput in;
+
+
+ //--------------------------------------
+ static public void main(String args[]) {
+ PApplet.main(new String[] { "soundinput.Threshold"});
+ }
+
+
+ //--------------------------------------
+ public void setup() {
+ // make a new Client using an INI file
+ // sketchPath() is used so that the INI file is local to the sketch
+ client = new TCPClient(sketchPath("mpefiles/mpe"+ID+".ini"), this);
+
+ // the size is determined by the client's local width and height
+ size(client.getLWidth(), client.getLHeight());
+
+ balls = new ArrayList();
+ randomSeed(1);
+
+ if (client.getID() == 0) {
+ minim = new Minim(this);
+ in = minim.getLineIn(Minim.MONO, 256);
+ }
+
+
+ smooth();
+ background(255);
+
+ // IMPORTANT, YOU MUST START THE CLIENT!
+ client.start();
+ }
+
+ //--------------------------------------
+ // Keep the motor running... draw() needs to be added in auto mode, even if
+ // it is empty to keep things rolling.
+ public void draw() {
+ frame.setLocation(client.getID()*client.getLWidth(),0);
+ }
+
+ //--------------------------------------
+ // Triggered by the client whenever a new frame should be rendered.
+ // All synchronized drawing should be done here when in auto mode.
+ public void frameEvent(TCPClient c) {
+ background(255);
+ if (c.messageAvailable()) {
+ String[] msg = c.getDataMessage();
+ // If the message C comes in, then make a new Ball object
+ // and add to ArrayList
+ if (msg[0].equals("C")) {
+ balls.add(new Ball(this,client,0,height/2));
+ }
+ }
+
+ // Deal with all balls
+ for (int i = 0; i < balls.size(); i++) {
+ Ball b = (Ball) balls.get(i);
+ b.calc();
+ b.draw();
+ }
+
+ if (client.getID() == 0) {
+ // Get the overall volume (between 0 and ??)
+ float vol = in.left.level();
+ noStroke();
+ // If the volume is greater than one and
+ // we are not clapping
+ if (vol > clapLevel && !clapping) {
+ // When we are clapping broadcast a "C" (this is an arbitrary choice)
+ client.broadcast("C");
+ clapping = true; // We are now clapping!
+ // If we are finished clapping
+ } else if (clapping && vol < 0.5) {
+ clapping = false;
+ }
+ }
+
+ }
+
+ //--------------------------------------
+ public void stop() {
+ if (client.getID() == 0) {
+ in.close();
+ minim.stop();
+ }
+ super.stop();
+ }
+
+}
+
+
+
+
+
+
+
+
View
100 eclipse/MPEMessagingExamples/src/soundinput/Volume.java
@@ -0,0 +1,100 @@
+/**
+ * Big Screens Week 4
+ * Reads sound level from microphone and broadcasts volume to all clients
+ * @author Shiffman
+ */
+
+package soundinput;
+
+import ddf.minim.AudioInput;
+import ddf.minim.Minim;
+import mpe.client.TCPClient;
+
+import processing.core.PApplet;
+
+public class Volume extends PApplet {
+
+ final int ID = 0;
+ TCPClient client;
+ float volume = 0;
+
+ Minim minim;
+ AudioInput in;
+
+ //--------------------------------------
+ static public void main(String args[]) {
+ PApplet.main(new String[] { "soundinput.Volume"});
+ }
+
+
+ //--------------------------------------
+ public void setup() {
+ // make a new Client using an INI file
+ // sketchPath() is used so that the INI file is local to the sketch
+ client = new TCPClient(sketchPath("mpefiles/mpe"+ID+".ini"), this);
+
+ // the size is determined by the client's local width and height
+ size(client.getLWidth(), client.getLHeight());
+
+ if (client.getID() == 0) {
+ minim = new Minim(this);
+ in = minim.getLineIn(Minim.STEREO, 512);
+ }
+
+ smooth();
+ background(255);
+
+ // IMPORTANT, YOU MUST START THE CLIENT!
+ client.start();
+ }
+
+ //--------------------------------------
+ // Keep the motor running... draw() needs to be added in auto mode, even if
+ // it is empty to keep things rolling.
+ public void draw() {
+ frame.setLocation(client.getID()*client.getLWidth(),0);
+ }
+
+ //--------------------------------------
+ // Triggered by the client whenever a new frame should be rendered.
+ // All synchronized drawing should be done here when in auto mode.
+ public void frameEvent(TCPClient c) {
+ if (c.messageAvailable()) {
+ String[] msg = c.getDataMessage();
+ // Convert the first element in the array to a float
+ volume = Float.parseFloat(msg[0]);
+ }
+ background(255);
+
+ rectMode(CENTER);
+ fill(0,150);
+ noStroke();
+
+ // Rectangles are drawn based on global variable "volume"
+ for (int x = 0; x < client.getMWidth(); x += 25) {
+ rect(x,client.getMHeight()/2,volume*client.getMHeight(),volume*client.getMHeight());
+ }
+
+ // If we are client 0, then broadcast the volume level
+ if (client.getID() == 0) {
+ float level = (in.left.level() + in.right.level())/2;
+ client.broadcast("" + level);
+ }
+ }
+
+ //--------------------------------------
+ public void stop() {
+ if (client.getID() == 0) {
+ in.close();
+ minim.stop();
+ }
+ super.stop();
+ }
+
+}
+
+
+
+
+
+
View
111 eclipse/MPEMessagingExamples/src/soundinput/WaveForm.java
@@ -0,0 +1,111 @@
+/**
+ * Big Screens Week 4
+ * Reads from microphone and broadcasts pitch as an array
+ * @author Shiffman
+ */
+
+package soundinput;
+
+import ddf.minim.AudioInput;
+import ddf.minim.Minim;
+import mpe.client.TCPClient;
+
+import processing.core.PApplet;
+
+public class WaveForm extends PApplet {
+
+ final int ID = 1;
+
+ // A client object
+ TCPClient client;
+
+ Minim minim;
+ AudioInput in;
+
+ // An array of pitch values
+ float[] wave;
+
+ //--------------------------------------
+ static public void main(String args[]) {
+ PApplet.main(new String[] { "soundinput.WaveForm"});
+ }
+
+ //--------------------------------------
+ public void setup() {
+ // make a new Client using an INI file
+ // sketchPath() is used so that the INI file is local to the sketch
+ client = new TCPClient(sketchPath("mpefiles/mpe"+ID+".ini"), this);
+
+ // the size is determined by the client's local width and height
+ size(client.getLWidth(), client.getLHeight());
+
+ if (client.getID() == 0) {
+ minim = new Minim(this);
+ in = minim.getLineIn(Minim.MONO, 256);
+ }
+
+ smooth();
+
+ // IMPORTANT, YOU MUST START THE CLIENT!
+ client.start();
+ }
+
+ //--------------------------------------
+ // Keep the motor running... draw() needs to be added in auto mode, even if
+ // it is empty to keep things rolling.
+ public void draw() {
+ frame.setLocation(client.getID()*client.getLWidth(),0);
+ }
+
+ //--------------------------------------
+ // Triggered by the client whenever a new frame should be rendered.
+ // All synchronized drawing should be done here when in auto mode.
+ public void frameEvent(TCPClient c) {
+ background(255);
+
+ // If we get bytes in, put them in our global variable
+ if (c.messageAvailable()) {
+ String[] msg = c.getDataMessage();
+ String[] vals = msg[0].split(",");
+ wave = new float[vals.length];
+ for (int i = 0; i < wave.length; i++) {
+ wave[i] = Float.parseFloat(vals[i]);
+ }
+ }
+ rectMode(CENTER);
+ stroke(0);
+
+ // As long as the array exists, draw lines based on values
+ if (wave != null) {
+ float w = (float) client.getMWidth() / wave.length;
+ beginShape();
+ for (int i = 0; i < wave.length; i++) {
+ float val = map(wave[i],-1,1,0,height);
+ float x = i*w;
+ vertex(x,height-val);
+ }
+ endShape();
+ }
+
+ // One client gets the pitch values and broadcasts them
+ if (client.getID() == 0) {
+ String message = "";
+ for(int i = 0; i < in.bufferSize(); i++) {
+ message += in.left.get(i);
+ message += ",";
+ }
+ client.broadcast(message);
+ }
+ }
+
+ //--------------------------------------
+ public void stop() {
+ if (client.getID() == 0) {
+ in.close();
+ minim.stop();
+ }
+ super.stop();
+ }
+}
+
+
View
74 eclipse/MPEMessagingExamples/src/twocameras/Jiggler.java
@@ -0,0 +1,74 @@
+/**
+ * Jiggler class for motion example
+ * <http://mostpixelsever.com>
+ * @author Shiffman
+ */
+
+package twocameras;
+
+import mpe.client.TCPClient;
+import processing.core.PApplet;
+import processing.core.PConstants;
+
+public class Jiggler {
+
+ // Know about both the PApplet and the Client
+ PApplet parent;
+ TCPClient client;
+
+ float x = 0; //ellipse x location
+ float y = 0; //ellipse y location
+
+ float vx = 0;
+ float vy = 0;
+
+ boolean flying;
+
+ float w;
+
+ // Initialize in the constructor
+ public Jiggler(PApplet _parent, TCPClient _c, float _x, float _y){
+ parent = _parent;
+ client = _c;
+ x = _x;
+ y = _y;
+ w = parent.random(4,16);
+ }
+
+ public void update() {
+ x += vx;
+ y += vy;
+
+ vx *= 0.9f;
+ vy *= 0.9f;
+ }
+
+ public void shoot(float otherX, float otherY) {
+ // A little algorithm to send the jigglers towards the camera point
+ float dx = otherX - x;
+ float dy = otherY - y;
+ float d = parent.dist(otherX,otherY,x,y);
+ dx /= d;
+ dy /= d;
+ vx += dx;
+ vy += dy;
+ }
+
+ // Display
+ public void draw(){
+ parent.fill(0,150);
+ parent.stroke(0);
+ parent.rectMode(PConstants.CENTER);
+ parent.rect(x,y,w,w);
+ }
+
+
+ public boolean flying() {
+ if (vx*vx + vy*vy > 1) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+}
View
151 eclipse/MPEMessagingExamples/src/twocameras/OverallMotion.java
@@ -0,0 +1,151 @@
+/**
+ * Big Screens Week 4
+ * Analyzes motion in video and broadcasts
+ * @author Shiffman
+ */
+
+package twocameras;
+
+import mpe.client.TCPClient;
+import processing.core.PApplet;
+import processing.core.PImage;
+import processing.video.*;
+
+public class OverallMotion extends PApplet {
+
+ final int ID = 0;
+
+ // Variable for capture device
+ Capture video;
+ // Previous Frame
+ PImage prevFrame;
+
+ // How different must a pixel be to be a "motion" pixel
+ float threshold = 50;
+
+ // An array of objects
+ Jiggler[] jigglers = new Jiggler[50];
+
+ // A client object
+ TCPClient client;
+
+ // Global variables for motion
+ float motion = 0;
+
+
+ //--------------------------------------
+ static public void main(String args[]) {
+ PApplet.main(new String[] { "twocameras.OverallMotion"});
+ }
+
+ //--------------------------------------
+ public void setup() {
+ // make a new Client using an INI file
+ // sketchPath() is used so that the INI file is local to the sketch
+ client = new TCPClient(sketchPath("mpefiles/mpe"+ID+".ini"), this);
+
+ // the size is determined by the client's local width and height
+ size(client.getLWidth(), client.getLHeight());
+
+ // the random seed must be identical for all clients
+ randomSeed(1);
+
+ // Only if I am client 0
+ if (client.getID() == 0 || client.getID() == 2) {
+ // Using the default capture device
+ video = new Capture(this, 160, 120, 30);
+ // Create an empty image the same size as the video
+ prevFrame = createImage(video.width,video.height,RGB);
+ }
+
+
+ for (int i = 0; i < jigglers.length; i++) {
+ jigglers[i] = new Jiggler(this,client,random(client.getMWidth()),random(client.getMHeight()));
+ }
+
+ smooth();
+
+ // IMPORTANT, YOU MUST START THE CLIENT!
+ client.start();
+ }
+
+ //--------------------------------------
+ // Keep the motor running... draw() needs to be added in auto mode, even if
+ // it is empty to keep things rolling.
+ public void draw() {
+ frame.setLocation(client.getID()*client.getLWidth(),0);
+ }
+
+ //--------------------------------------
+ // Triggered by the client whenever a new frame should be rendered.
+ // All synchronized drawing should be done here when in auto mode.
+ public void frameEvent(TCPClient c) {
+ background(255);
+
+ // Get the message and convert it to a float for motion variables
+ if (c.messageAvailable()) {
+ // Get the messages in an array
+ String[] msg = c.getDataMessage();
+ // We might have more than one message, loop through each one!
+ for (int i = 0; i < msg.length; i++) {
+ // Our protocol is ID COMMA VALUE
+ String[] stuff = msg[i].split(",");
+ // Get the ID (index 0)
+ int id = Integer.parseInt(stuff[0]);
+ // Get the value (index 1), we aren't really using it in this example, but we could
+ float motion = Float.parseFloat(stuff[1]);
+ for (int j = 0; j < jigglers.length; j++) {
+ if (!jigglers[j].flying()) {
+ jigglers[j].shoot(id*client.getLWidth()+client.getLWidth()/2, client.getMHeight()/2);
+ }
+ }
+ }
+ }
+
+ // Call video analysis function if I am client 0 or 2
+ if (client.getID() == 0 || client.getID() == 2) {
+ analyzeVideo();
+ }
+
+ for (int i = 0; i < jigglers.length; i++) {
+ jigglers[i].update();
+ jigglers[i].draw();
+ }
+ }
+
+
+ void analyzeVideo() {
+ if (video.available()) {
+ // Save previous frame for motion detection!!
+ prevFrame.copy(video,0,0,video.width,video.height,0,0,video.width,video.height);
+ prevFrame.updatePixels();
+ video.read();
+ }
+
+ video.loadPixels();
+ prevFrame.loadPixels();
+
+ // Begin loop to walk through every pixel
+ // Start with a total of 0
+ float totalMotion = 0;
+
+ // Sum the brightness of each pixel
+ for (int i = 0; i < video.pixels.length; i++) {
+ int current = video.pixels[i]; // Step 2, what is the current color
+ int previous = prevFrame.pixels[i]; // Step 3, what is the previous color
+ // Step 4, compare colors (previous vs. current)
+ float r1 = red(current); float g1 = green(current); float b1 = blue(current);
+ float r2 = red(previous); float g2 = green(previous); float b2 = blue(previous);
+ float diff = dist(r1,g1,b1,r2,g2,b2);
+ totalMotion += diff;
+ }
+
+ float avgMotion = totalMotion / video.pixels.length;
+
+ // We aren't broadcasting the video!
+ // We are just analyzing it and broadcasting a single value!
+ if (avgMotion > 20) {
+ client.broadcast(ID + "," + (int) avgMotion);
+ }
+ }
+}
View
146 eclipse/MPEMessagingExamples/src/video/ColorTracking.java
@@ -0,0 +1,146 @@
+/**
+ * Big Screens Week 4
+ * Track color XY and broadcast info
+ * @author Shiffman
+ */
+
+package video;
+
+import mpe.client.TCPClient;
+import processing.core.PApplet;
+import processing.core.PImage;
+import processing.video.*;
+
+public class ColorTracking extends PApplet {
+
+ final int ID = 1;
+
+ // Variable for capture device
+ Capture video;
+ // Previous Frame
+ PImage prevFrame;
+
+ int trackColor;
+
+ int x;
+ int y;
+
+ // A client object
+ TCPClient client;
+
+ // Global variables for motion
+ float motion = 0;
+
+
+ //--------------------------------------
+ static public void main(String args[]) {
+ PApplet.main(new String[] { "video.ColorTracking"});
+ }
+
+ //--------------------------------------
+ public void setup() {
+ // make a new Client using an INI file
+ // sketchPath() is used so that the INI file is local to the sketch
+ client = new TCPClient(sketchPath("mpefiles/mpe"+ID+".ini"), this);
+
+ // the size is determined by the client's local width and height
+ size(client.getLWidth(), client.getLHeight());
+
+ // the random seed must be identical for all clients
+ randomSeed(1);
+
+ trackColor = color(255,0,0); // Start off tracking for red
+
+ // Only if I am client 0
+ if (client.getID() == 0) {
+ // Using the default capture device
+ video = new Capture(this, width, height, 15);
+ }
+
+ smooth();
+
+ // IMPORTANT, YOU MUST START THE CLIENT!
+ client.start();
+ }
+
+ //--------------------------------------
+ // Keep the motor running... draw() needs to be added in auto mode, even if
+ // it is empty to keep things rolling.
+ public void draw() {
+ frame.setLocation(client.getID()*client.getLWidth(),0);
+ }
+
+ //--------------------------------------
+ // Triggered by the client whenever a new frame should be rendered.
+ // All synchronized drawing should be done here when in auto mode.
+ public void frameEvent(TCPClient c) {
+ background(255);
+
+ // Get the message and convert it to xy coordinate
+ if (c.messageAvailable()) {
+ String[] msg = c.getDataMessage();
+ String[] xy = msg[0].split(",");
+ x = Integer.parseInt(xy[0]);
+ y = Integer.parseInt(xy[1]);
+ }
+
+ // Call video analysis function if I am client 0
+ if (client.getID() == 0) {
+ trackColors();
+ image(video,0,0);
+ }
+
+ fill(trackColor);
+ strokeWeight(4.0f);
+ stroke(0);
+ ellipse(x + client.getXoffset(), y + client.getYoffset(),16,16);
+
+ }
+
+ void trackColors() {
+ // Capture and display the video
+ if (video.available()) {
+ video.read();
+ }
+ video.loadPixels();
+
+ // Closest record, we start with a high number
+ float closestRecord = 500.0f;
+ // XY coordinate of closest color
+ int closestX = 0;
+ int closestY = 0;
+ // Begin loop to walk through every pixel
+ for ( int x = 0; x < video.width; x++) {
+ for ( int y = 0; y < video.height; y++) {
+ int loc = x + y*video.width;
+ // What is current color
+ int currentColor = video.pixels[loc];
+ float r1 = red(currentColor);
+ float g1 = green(currentColor);
+ float b1 = blue(currentColor);
+ float r2 = red(trackColor);
+ float g2 = green(trackColor);
+ float b2 = blue(trackColor);
+ // Using euclidean distance to compare colors
+ float d = dist(r1,g1,b1,r2,g2,b2);
+ // If current color is more similar to tracked color than
+ // closest color, save current location and current difference
+ if (d < closestRecord) {
+ closestRecord = d;
+ closestX = x;
+ closestY = y;
+ }
+ }
+ }
+
+ client.broadcast(closestX + "," + closestY);
+ }
+
+ public void mousePressed() {
+ // Save color where the mouse is clicked in trackColor variable
+ if (client.getID() == 0) {
+ int loc = mouseX + mouseY*video.width;
+ trackColor = video.pixels[loc];
+ }
+ }
+}
View
47 eclipse/MPEMessagingExamples/src/video/Jiggler.java
@@ -0,0 +1,47 @@
+/**
+ * Jiggler class for motion example
+ * <http://mostpixelsever.com>
+ * @author Shiffman
+ */
+
+package video;
+
+import mpe.client.TCPClient;
+import processing.core.PApplet;
+
+public class Jiggler {
+
+ // Know about both the PApplet and the Client
+ PApplet parent;
+ TCPClient client;
+
+ float x = 0; //ellipse x location
+ float y = 0; //ellipse y location
+
+ // Initialize in the constructor
+ public Jiggler(PApplet _parent, TCPClient _c, float _x, float _y){
+ parent = _parent;
+ client = _c;
+ x = _x;
+ y = _y;
+ }
+
+ // Move randomly
+ public void jiggle(float amount) {
+ x += parent.random(0,amount/2);
+ y += parent.random(-amount,amount);
+
+ if (x > client.getMWidth() + 100) {
+ x = -100;
+ }
+ }
+
+ // Display
+ public void draw(){
+ parent.smooth();
+ parent.fill(0,150);
+ parent.stroke(0);
+ parent.ellipse(x,y,32,32);
+ }
+
+}
View
141 eclipse/MPEMessagingExamples/src/video/OverallMotion.java
@@ -0,0 +1,141 @@
+/**
+ * Big Screens Week 4
+ * Analyzes motion in video and broadcasts
+ * @author Shiffman
+ */
+
+package video;
+
+import mpe.client.TCPClient;
+import processing.core.PApplet;
+import processing.core.PImage;
+import processing.video.*;
+
+public class OverallMotion extends PApplet {
+
+ final int ID = 0;
+
+ // Variable for capture device
+ Capture video;
+ // Previous Frame
+ PImage prevFrame;
+
+ // How different must a pixel be to be a "motion" pixel
+ float threshold = 50;
+
+ // An array of objects
+ Jiggler[] jigglers = new Jiggler[100];
+
+ // A client object
+ TCPClient client;
+
+ // Global variables for motion
+ float motion = 0;
+
+
+ //--------------------------------------
+ static public void main(String args[]) {
+ PApplet.main(new String[] { "video.OverallMotion"});
+ }
+
+ //--------------------------------------
+ public void setup() {
+ // make a new Client using an INI file
+ // sketchPath() is used so that the INI file is local to the sketch
+ client = new TCPClient(sketchPath("mpefiles/mpe"+ID+".ini"), this);
+
+ // the size is determined by the client's local width and height
+ size(client.getLWidth(), client.getLHeight());
+
+ // the random seed must be identical for all clients
+ randomSeed(1);
+
+ // Only if I am client 0
+ if (client.getID() == 0) {
+ // Using the default capture device
+ video = new Capture(this, width, height, 15);
+ // Create an empty image the same size as the video
+ prevFrame = createImage(video.width,video.height,RGB);
+ }
+
+ for (int i = 0; i < jigglers.length; i++) {
+ jigglers[i] = new Jiggler(this,client,random(client.getMWidth()),random(client.getMHeight()));
+ }
+
+ smooth();
+
+ // IMPORTANT, YOU MUST START THE CLIENT!
+ client.start();
+ }
+
+ //--------------------------------------
+ // Keep the motor running... draw() needs to be added in auto mode, even if
+ // it is empty to keep things rolling.
+ public void draw() {
+ frame.setLocation(client.getID()*client.getLWidth(),0);
+ }
+
+ //--------------------------------------
+ // Triggered by the client whenever a new frame should be rendered.
+ // All synchronized drawing should be done here when in auto mode.
+ public void frameEvent(TCPClient c) {
+ background(255);
+
+ // Get the message and convert it to a float for motion variables
+ if (c.messageAvailable()) {
+ String[] msg = c.getDataMessage();
+ motion = Float.parseFloat(msg[0]);
+ }
+
+ // Call video analysis function if I am client 0
+ if (client.getID() == 0) {
+ analyzeVideo();
+ }
+
+ for (int i = 0; i < jigglers.length; i++) {
+ // Objects move around based on overall motion
+ jigglers[i].jiggle(motion / 32f);
+ jigglers[i].draw();
+ }
+ }
+
+
+ void analyzeVideo() {
+ if (video.available()) {
+ // Save previous frame for motion detection!!
+ prevFrame.copy(video,0,0,video.width,video.height,0,0,video.width,video.height);
+ prevFrame.updatePixels();
+ video.read();
+ }
+
+ video.loadPixels();
+ prevFrame.loadPixels();
+
+ // Begin loop to walk through every pixel
+ // Start with a total of 0
+ float totalMotion = 0;
+
+ // Sum the brightness of each pixel
+ for (int i = 0; i < video.pixels.length; i++) {
+ int current = video.pixels[i]; // Step 2, what is the current color
+ int previous = prevFrame.pixels[i]; // Step 3, what is the previous color
+ // Step 4, compare colors (previous vs. current)
+ float r1 = red(current); float g1 = green(current); float b1 = blue(current);
+ float r2 = red(previous); float g2 = green(previous); float b2 = blue(previous);
+ float diff = dist(r1,g1,b1,r2,g2,b2);
+ totalMotion += diff;
+ }
+
+ float avgMotion = totalMotion / video.pixels.length;
+
+ // We aren't broadcasting the video!
+ // We are just analyzing it and broadcasting a single value!
+ client.broadcast("" + (int) avgMotion);
+ }
+}
+
+
+
+
+
+
View
8 eclipse/MostPixelsEverTCP/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path=""/>
+ <classpathentry kind="lib" path="core.jar"/>
+ <classpathentry kind="lib" path="video.jar"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path=""/>
+</classpath>
View
17 eclipse/MostPixelsEverTCP/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>MostPixelsEverTCP</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
View
BIN  eclipse/MostPixelsEverTCP/core.jar
Binary file not shown
View
BIN  eclipse/MostPixelsEverTCP/data/Arial-BoldMT-18.vlw
Binary file not shown
View
BIN  eclipse/MostPixelsEverTCP/data/texture.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
7 eclipse/MostPixelsEverTCP/ini_quotes/mpeSc0.ini
@@ -0,0 +1,7 @@
+id=0;
+server=localhost;
+port=9002;
+localScreenSize=400,400;
+localLocation=0,0;
+masterDimensions=800,400;
+debug=0;
View
7 eclipse/MostPixelsEverTCP/ini_quotes/mpeSc1.ini
@@ -0,0 +1,7 @@
+id=1;
+server=localhost;
+port=9002;
+localScreenSize=400,400;
+localLocation=400,0;
+masterDimensions=800,400;
+debug=0;
View
7 eclipse/MostPixelsEverTCP/ini_threeD/mpe0.ini
@@ -0,0 +1,7 @@
+id=0;
+server=localhost;
+port=9002;
+localScreenSize=320,240;
+localLocation=0,0;
+masterDimensions=640,240;
+debug=0;
View
7 eclipse/MostPixelsEverTCP/ini_threeD/mpe1.ini
@@ -0,0 +1,7 @@
+id=1;
+server=localhost;
+port=9002;
+localScreenSize=320,240;
+localLocation=320,0;
+masterDimensions=640,240;
+debug=0;
View
176 eclipse/MostPixelsEverTCP/mpe/client/AsyncClient.java
@@ -0,0 +1,176 @@
+package mpe.client;
+
+import java.io.*;
+import java.net.*;
+
+import mpe.config.*;
+
+public class AsyncClient {
+
+
+ /** If DEBUG is true, the client will print lots of messages about what it is doing.
+ * Set with debug=1; in your INI file. */
+
+ public static boolean DEBUG = true;
+
+ protected FileParser fp;
+
+ protected boolean running;
+
+ // TCP stuff
+ String hostName;
+ int serverPort = 9003;
+ Socket socket;
+ InputStream is;
+ //DataInputStream dis;
+ BufferedReader brin;
+ DataOutputStream dos;
+ OutputStream os;
+
+ /**
+ * Builds a default AsyncClient. It connects to 'localhost' on port 9003.
+ */
+ public AsyncClient() {
+ this("localhost", 9003);
+ }
+
+ /**
+ * Builds an AsyncClient.
+ *
+ * @param _hostName the server host name
+ * @param _serverPort the server port
+ */
+ public AsyncClient(String _hostName, int _serverPort) {
+ connect(_hostName, _serverPort);
+ }
+
+ /**
+ * Builds an AsyncClient using an INI file.
+ *
+ * @param _fileString the path to the INI file
+
+ */
+ public AsyncClient(String _fileString) {
+ loadIniFile(_fileString);
+ connect(hostName, serverPort);
+ }
+
+ /**
+ * Loads the settings from the Client INI file.
+ *
+ * @param fileString the path to the INI file
+ */
+ protected void loadIniFile(String _fileString) {
+ fp = new FileParser(_fileString);
+
+ if (fp.fileExists()) {
+ // parse INI file
+ setServer(fp.getStringValue("server"));
+ setPort(fp.getIntValue("port"));
+ out("Settings: server = " + hostName + ":" + serverPort);
+ if (fp.getIntValue("debug") == 1) DEBUG = true;
+ }
+ }
+
+ /**
+ * Connects to the server.
+ *
+ * @param _hostName the server host name
+ * @param _serverPort the server port
+ */
+ protected void connect(String _hostName, int _serverPort) {
+ // create a socket
+ try {
+ socket = new Socket(_hostName, _serverPort);
+ os = socket.getOutputStream();
+ dos = new DataOutputStream(os);
+ } catch (UnknownHostException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ // set the server address and port
+ setServer(_hostName);
+ setPort(_serverPort);
+ }
+
+ /**
+ * Sets the server address.
+ *
+ * @param _hostName the server host name
+ */
+ protected void setServer(String _hostName) {
+ if (_hostName != null) {
+ hostName = _hostName;
+ }
+ }
+
+ /**
+ * Sets the server port.
+ *
+ * @param _serverPort the server port
+ */
+ protected void setPort(int _serverPort) {
+ if (_serverPort > -1)
+ serverPort = _serverPort;
+ }
+
+ public int getPort() { return serverPort; }
+
+ /**
+ * Format a broadcast message and send it.
+ *
+ * @param _msg the message to broadcast
+ */
+ public void broadcast(String _msg) {
+ // The AsyncClient doesn't need to prepend
+ // _msg = "T"+ _msg;
+ send(_msg);
+ }
+
+ /**
+ * Send a message to the server using TCP.
+ *
+ * @param _msg the message to send
+ */
+ private void send(String _msg) {
+ if (DEBUG) out("Sending: " + _msg);
+ _msg += "\n";
+ try {
+ dos.write(_msg.getBytes());
+ dos.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Outputs a message to the console.
+ *
+ * @param _str the message to output.
+ */
+ protected void out(String _str) {
+ print(_str);
+ }
+
+ /**
+ * Outputs a message to the console.
+ *
+ * @param _str the message to output.
+ */
+ protected void print(String _str) {
+ System.out.println("Client: " + _str);
+ }
+
+ /**
+ * Outputs an error message to the console.
+ *
+ * @param _str the message to output.
+ */
+ protected void err(String _str) {
+ System.err.println("Client: " + _str);
+ }
+}
View
11 eclipse/MostPixelsEverTCP/mpe/client/MpeDataListener.java
@@ -0,0 +1,11 @@
+/**
+ * Data Listener Interface
+ * <http://mostpixelsever.com>
+ * @author Shiffman and Kairalla
+ */
+
+package mpe.client;
+
+public interface MpeDataListener {
+ public void frameEvent(TCPClient c);
+}
View
849 eclipse/MostPixelsEverTCP/mpe/client/TCPClient.java
@@ -0,0 +1,849 @@
+/**
+ * The MPE Client
+ * The Client class registers itself with a server
+ * and receives messages related to frame rendering and data input
+ * <http://mostpixelsever.com>
+ * @author Shiffman and Kairalla
+ */
+
+package mpe.client;
+
+import java.io.BufferedReader;
+//import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.reflect.Method;
+import java.net.Socket;
+
+import mpe.config.FileParser;
+
+import processing.core.PApplet;
+import processing.core.PConstants;
+import processing.core.PGraphics3D;
+
+public class TCPClient extends Thread {
+ /** If DEBUG is true, the client will print lots of messages about what it is doing.
+ * Set with debug=1; in your INI file. */
+ public static boolean DEBUG = false;
+
+ // TCP stuff
+ FileParser fp;
+ String hostName;
+ int serverPort = 9002;
+ Socket socket;
+ InputStream is;
+ //DataInputStream dis;
+ BufferedReader brin;
+ DataOutputStream dos;
+ OutputStream os;
+
+ PApplet p5parent;
+ MpeDataListener parent;
+ Method frameEventMethod;
+
+ /** The id is used for communication with the server, to let it know which
+ * client is speaking and how to order the screens. */
+ int id = 0;
+ /** The total number of screens. */
+ int numScreens;
+
+ /** The master width. */
+ protected int mWidth = -1;
+ /** The master height. */
+ protected int mHeight = -1;
+
+ /** The local width. */
+ protected int lWidth = 640;
+ /** The local height. */
+ protected int lHeight = 480;
+
+ int xOffset = 0;
+ int yOffset = 0;
+
+ boolean running = false;
+ boolean useProcessing = false;
+ boolean rendering = false;
+ boolean autoMode = false;
+
+ int frameCount = 0;
+ float fps = 0.f;
+ long lastMs = 0;
+
+ // Are we broadcasting?
+ // boolean broadcastingData = false;
+ // Do we need to wait to broadcast b/c we have alreaddy done so this frame?
+ // boolean waitToSend = false;
+ // protected boolean sayDoneAgain = false; // Do we need to say we're done after a lot of data has been sent
+
+ /** True if all the other clients are connected. */
+ // FIXME Maybe this doesn't need to be public.
+ public boolean allConnected = false;
+
+ protected boolean messageAvailable; // Is a message available?
+ protected boolean intsAvailable; // Is an int array available?
+ protected boolean bytesAvailable; // Is a byte array avaialble?
+ protected String[] dataMessage; // data that has come in
+ protected int[] ints; // ints that have come in
+ protected byte[] bytes; // bytes that have come in
+
+ // 3D variables
+ protected boolean enable3D = false;
+ protected float fieldOfView = 30.0f;
+ protected float cameraZ;
+
+ /**
+ * Client is constructed with an init file location, and the parent PApplet.
+ * The parent PApplet must have a method called "frameEvent(Client c)".
+ *
+ * The frameEvent handles syncing up the frame rate on the
+ * multiple screens. A typical implementation may look like this:
+ *
+ * public void frameEvent(Client c){
+ * if (!started) started = true;
+ * redraw();
+ * }
+ *
+ */
+ public TCPClient(String _fileString, PApplet _p) {
+ this(_fileString, _p, true);
+ }
+
+ public TCPClient(String _fileString, PApplet _p, boolean _autoMode) {
+ useProcessing = true;
+ p5parent = _p;
+
+ // Autodetecting if we should use 3D or not
+ enable3D = p5parent.g instanceof PGraphics3D;
+
+ autoMode = _autoMode;
+ cameraZ = (p5parent.height/2.0f) / PApplet.tan(PConstants.PI * fieldOfView/360.0f);
+
+ loadIniFile(_fileString);
+ connect(hostName, serverPort, id);
+
+ // look for a method called "frameEvent" in the parent PApplet, with one
+ // argument of type Client
+ try {
+ frameEventMethod = p5parent.getClass().getMethod("frameEvent",
+ new Class[] { TCPClient.class });
+ } catch (Exception e) {
+ System.out.println("You are missing the frameEvent() method. " + e);
+ }
+
+ if (autoMode) {
+ p5parent.registerDraw(this);
+ }
+
+ }
+
+ /**
+ * Called automatically by PApplet.draw() when using auto mode.
+ */
+ public void draw() {
+ if (running && rendering) {
+ placeScreen();
+ if (frameEventMethod != null) {
+ try {
+ // call the method with this object as the argument!
+ frameEventMethod.invoke(p5parent, new Object[] { this });
+
+ } catch (Exception e) {
+ err("Could not invoke the \"frameEvent()\" method for some reason.");
+ e.printStackTrace();
+ frameEventMethod = null;
+ }
+ }
+ done();
+ }
+ }
+
+ /**
+ * Builds a Client using an INI file and a parent MpeDataListener.
+ *
+ * The parent MpeDataListener must have a method called
+ * "frameEvent(UDPClient c)", which handles syncing up the frame rate on the
+ * multiple screens. A typical implementation may look like this:
+ *
+ * public void frameEvent(Client c){
+ * if (!started) started = true;
+ * // Do your computation and paint to the screen here
+ * }
+ *
+ * @param _fileString the path to the INI file
+ * @param _p the parent MpeDataListener
+ */
+ public TCPClient(String _fileString, MpeDataListener _p) {
+ parent = _p;
+ loadIniFile(_fileString);
+ connect(hostName, serverPort, id);
+ }
+
+ /**
+ * Loads the settings from the Client INI file.
+ *
+ * @param _fileString the path to the INI file
+ */
+ private void loadIniFile(String fileString) {
+ fp = new FileParser(fileString);
+
+ if (fp.fileExists()) {
+ // parse INI file
+ setServer(fp.getStringValue("server"));
+ setPort(fp.getIntValue("port"));
+ setID(fp.getIntValue("id"));
+
+ int[] localDim = fp.getIntValues("localScreenSize");
+ setLocalDimensions(localDim[0], localDim[1]);
+
+ int[] offsets = fp.getIntValues("localLocation");
+ setOffsets(offsets[0], offsets[1]);
+
+ // XXXBUG This somehow got lost w/ the separate client and server INI files
+ int[] masterDims = fp.getIntValues("masterDimensions");
+ this.setMasterDimensions(masterDims[0], masterDims[1]);
+
+ out("Settings: server = " + hostName + ":" + serverPort + ", id = " + id
+ + ", local dimensions = " + lWidth + ", " + lHeight
+ + ", location = " + xOffset + ", " + yOffset);
+
+ if (fp.getIntValue("debug") == 1) DEBUG = true;
+ }
+ }
+
+ /**
+ * Connects to the server.
+ *
+ * @param _hostName the server host name
+ * @param _serverPort the server port
+ * @param _id the client id
+ */
+ private void connect(String _hostName, int _serverPort, int _id) {
+ // set the server address and port
+ setServer(_hostName);
+ setPort(_serverPort);
+ setID(_id);
+ }
+
+ /**
+ * Sets the server address.
+ *
+ * @param _hostName the server host name
+ */
+ protected void setServer(String _hostName) {
+ if (_hostName != null)
+ hostName = _hostName;
+ }
+
+ /**
+ * Sets the server port.
+ *
+ * @param _serverPort the server port
+ */
+ protected void setPort(int _serverPort) {
+ if (_serverPort > -1)
+ serverPort = _serverPort;
+ }
+
+ /** @return the server port */
+ public int getPort() { return serverPort; }
+
+ /**
+ * Sets the client ID.
+ *
+ * @param _id the client id
+ */
+ protected void setID(int _id) {
+ if (_id > -1)
+ id = _id;
+ }
+
+ /** @return the client ID */
+ public int getID() { return id; }
+
+ /**
+ * Sets the dimensions for the local display.
+ *
+ * @param _lWidth The local width
+ * @param _lHeight The local height
+ */
+ protected void setLocalDimensions(int _lWidth, int _lHeight) {
+ if (_lWidth > -1 && _lHeight > -1) {
+ lWidth = _lWidth;
+ lHeight = _lHeight;
+ }
+ }
+
+ /**
+ * Sets the offsets for the local display.
+ *
+ * @param _xOffset Offsets the display along x axis
+ * @param _yOffset Offsets the display along y axis
+ */
+ protected void setOffsets(int _xOffset, int _yOffset) {
+ if (_xOffset > -1 && _yOffset > -1) {
+ xOffset = _xOffset;
+ yOffset = _yOffset;
+ }
+ }
+
+ /**
+ * Sets the dimensions for the local display.
+ * The offsets are used to determine what part of the Master Dimensions to render.
+ * For example, if you have two screens, each 100x100, and the master dimensions are 200x100
+ * then you would set
+ * client 0: setLocalDimensions(0, 0, 100, 100);
+ * client 1: setLocalDimensions(100, 0, 100, 100);
+ * for a 10 pixel overlap you would do:
+ * client 0: setLocalDimensions(0, 0, 110, 100);
+ * client 1: setLocalDimensions(90, 0, 110, 100);
+ *
+ * @param _xOffset Offsets the display along x axis
+ * @param _yOffset Offsets the display along y axis
+ * @param _lWidth The local width
+ * @param _lHeight The local height
+ */
+ public void setLocalDimensions(int _xOffset, int _yOffset, int _lWidth, int _lHeight) {
+ setOffsets(_xOffset, _yOffset);
+ setLocalDimensions(_lWidth, _lHeight);
+ }
+
+ /**
+ * Sets the master dimensions for the Video Wall. This is used to calculate
+ * what is rendered.
+ *
+ * @param _mWidth The master width
+ * @param _mHeight he master height
+ */
+ public void setMasterDimensions(int _mWidth, int _mHeight) {
+ if (_mWidth > -1 && _mHeight > -1) {
+ mWidth = _mWidth;
+ mHeight = _mHeight;
+ }
+ }
+
+ /** @return the local width in pixels */
+ public int getLWidth() { return lWidth; }
+
+ /** @return the local height in pixels */
+ public int getLHeight() { return lHeight; }
+
+ /** @return the x-offset of frame in pixels */
+ public int getXoffset() { return xOffset; }
+
+ /** @return the y-offset of frame in pixels */
+ public int getYoffset() { return yOffset; }
+
+ /** @return the master width in pixels */
+ public int getMWidth() { return mWidth; }
+
+ /** @return the master height in pixels */
+ public int getMHeight() { return mHeight; }
+
+ /** @return the total number of frames rendered */
+ public int getFrameCount() { return frameCount; }
+
+ /** @return the client framerate */
+ public float getFPS() { return fps; }
+
+ /** @return whether or not the client is rendering */
+ public boolean isRendering() { return rendering; }
+
+ /**
+ * Sets the field of view of the camera when rendering in 3D.
+ * Note that this has no effect when rendering in 2D.
+ *
+ * @param val the value of the field of view
+ */
+ public void setFieldOfView(float val) {
+ fieldOfView = val;
+
+ if (p5parent != null) {
+ cameraZ = (p5parent.height/2.0f) / PApplet.tan(PConstants.PI * fieldOfView/360.0f);
+
+ if (!(p5parent.g instanceof PGraphics3D)) {
+ out("MPE Warning: Rendering in 2D! fieldOfView has no effect!");
+ }
+ } else {
+ out("MPE Warning: Not using Processing! fieldOfView has no effect!");
+ }
+ }
+
+ /** @return the value of the field of view */
+ public float getFieldOfView() { return fieldOfView; }
+
+ /**
+ * Places the viewing area for this screen. This must be called at the
+ * beginning of the render loop. If you are using Processing, you would
+ * typically place it at the beginning of your draw() function.
+ */
+ public void placeScreen() {
+ if (enable3D) {
+ placeScreen3D();
+ } else {
+ placeScreen2D();
+ }
+ }
+
+ /**
+ * If you want to enable or disable 3D manually in automode
+ */
+ public void enable3D(boolean b) {
+ enable3D = b;
+ }
+
+ /**
+ * Places the viewing area for this screen when rendering in 2D.
+ */
+ public void placeScreen2D() {
+ p5parent.translate(xOffset * -1, yOffset * -1);
+ }
+
+ /**
+ * Places the viewing area for this screen when rendering in 3D.
+ */
+ public void placeScreen3D() {
+ p5parent.camera(mWidth/2.0f, mHeight/2.0f, cameraZ,
+ mWidth/2.0f, mHeight/2.0f, 0,
+ 0, 1, 0);
+
+
+ // The frustum defines the 3D clipping plane for each Client window!
+ float mod = 1f/10f;
+ float left = (xOffset - mWidth/2)*mod;
+ float right = (xOffset + lWidth - mWidth/2)*mod;
+ float top = (yOffset - mHeight/2)*mod;
+ float bottom = (yOffset + lHeight-mHeight/2)*mod;
+ float near = cameraZ*mod;
+ float far = 10000;
+ p5parent.frustum(left,right,top,bottom,near,far);
+ }
+