TUIO Processing: Accessing x, y pos from the CursorList
Posted: 01 June 2008 03:27 AM   [ Ignore ]
New Member
Rank
Total Posts:  2
Joined  2008-06-01

So I am hoping to use a multi-touch table I built with a classmate in a show on Wednesday. I have the great examples from picturetunes as well as the Demo from the TUIO website. They both run perfectly.  My question is: How can I access the array of x and y positions of all the cursors from the main draw() function? If i have to create a whole program inside of the draw function of the TuioCursor class I guess I will...but Id rather not =P. Thanks a lot! Any suggestions would be helpful as I am a beginner at dealing with reading TUIO in Processing.

import processing.opengl.*;
import tuio.*;
TuioClient client;
TuiCursorList cursorList;
void setup()
{
size(1024,768, OPENGL);
client = new TuioClient(this); // the TuioClient receives the information from Touchlib
cursorList = new TuiCursorList(); //this is your little helper who handles all the cursors for you
frameRate(30);
}

void draw()
{
cursorList.draw(); //draw the cursors
smooth();
noStroke();
}

/*
based on:::::::::::::::::::::::::::::::::::::::::::::::
TUIO processing demo - part of the reacTIVision project
http://mtg.upf.es/reactable
by Martin Kaltenbrunner
(see bottom of page for details)
modified by::::::::::::::::::::::::::::::::::::::::::::
picturetunes (http://christoph.picturetunes.at)
*/

//***************************//
// PREDEFINED TUIO FUNCTIONS //
//***************************//

////the redraw functions are no longer needed because we use a constant framerate
// called after each message bundle
void refresh() {
//redraw();
}
// called when a cursor appears the scene
void addTuiCursor(Integer s_id) {
System.out.println("add cursor “+s_id);
cursorList.add(s_id);
//redraw();
}

// called when a cursor is removed from the scene
void removeTuiCursor(Integer s_id) {
System.out.println("remove cursor “+s_id);
cursorList.remove(s_id);
//redraw();
}

// called when a cursor is moved
void updateTuiCursor (Integer s_id, Float xpos, Float ypos) {
//System.out.println("update cursor “+s_id+” “+xpos+” “+ypos);
float xsize =width;
float ysize =height;
//the following lines of code could be probably improved
// the position values are read and casted to float
// the values should (but strangely do not precicesly) start at 0 and end at 1 so you have to multiply them by the screensize to map them to the screen
// the calculated values are subtracted from the screensize to mirror the coordinates
cursorList.update(s_id,(float)xsize-((xsize*xpos.floatValue())),ysize-((float)(ysize*ypos.floatValue())));
//redraw();
}
//****************//
// LITTLE HELPERS //
//****************//

//this class stores all the cursors…
class TuiCursorList {
java.util.Hashtable cursorList;

TuiCursorList() {
//...in this java hastable
cursorList = new Hashtable();
}
//call the draw method of the cursors (just for testing to see what is happening)
void draw() {
Enumeration e = cursorList.elements();
while (e.hasMoreElements()) {
TuioCursor cursorPoint = (TuioCursor)e.nextElement();
cursorPoint.draw();
}
}
//create new cursor instance
void add(Integer s_id) {
//Vector pointList = new Vector();
TuioCursor cursorPoint = new TuioCursor();
cursorList.put(s_id,cursorPoint);
}
//remove cursor
void remove(Integer s_id) {
cursorList.remove(s_id);
}
//update cursor position
void update(Integer s_id, float xpos, float ypos) {
// println("number of cursors in cursor list:"+cursorList.size());
// that is a nasty little detail: for some reason updateTuiCursor() is called before add addTuiCursor()
// which causes the programm to behave strangly. to avoid that you want to check if the object you want ot update is already there
if(cursorList.containsKey(s_id)){
TuioCursor cursorPoint = (TuioCursor)cursorList.get(s_id);
cursorPoint.update(xpos,ypos);
}
}
}
// this is the class for the cursors. it doesn`t do pretty much yet but of course you can extend it!
class TuioCursor{
public float x,y;

TuioCursor(){
//println("hello i am a tuio cursor");

}

void update(float px, float py){
// println("hurray somebody updates my position x:"+px+" y"+y);
this.x=px;
this.y=py;
}

void draw(){

//this comes handy for testing - you get visual response from your cursors
//println("hurray somebody draws me");
fill(0,50);
ellipse(x, y, 16, 16);
fill(250,50);
rect(0,0,width, height);
}

}

Profile
 
 
Posted: 02 June 2008 02:46 PM   [ Ignore ]   [ # 1 ]
Elite
Avatar
RankRankRankRank
Total Posts:  156
Joined  2007-09-13

Try the following (it worked for me):

Enumeration e cursorList.cursorList.elements();
while (
e.hasMoreElements()) {
  TuioCursor cursorPoint 
= (TuioCursor)e.nextElement();
  
println (cursorPoint.x);
  
println (cursorPoint.y);
}

Instead of ‘println’, you could store the values in arrays, for instance.

Hope it helps. It’s a little annoying that this TUIO class mixes Java in, because I’m not all that good at it.

Profile
 
 
Posted: 03 June 2008 03:41 PM   [ Ignore ]   [ # 2 ]
New Member
Rank
Total Posts:  2
Joined  2008-06-01

Thanks a lot for the reply! So I experimented a bunch without an array and got a nice little drawing program going, so now I am going to try to create it for more than one cursor. I took your advice and got the values out of the hashtable, MAN java is a bitch! wink So here is what I came up with:
void draw() {
Enumeration e = cursorList.elements();
int curElement=0;
while (e.hasMoreElements()) {
TuioCursor cursorPoint = (TuioCursor)e.nextElement();
//cursorPoint.draw();
xVals[curElement] = cursorPoint.x;
yVals[curElement] = cursorPoint.y;
curElement++;
}
}

void getVals() { /////new function to get the x and y values
Enumeration e = cursorList.elements();
int curElement=0;
while (e.hasMoreElements()) {
println("X: “+ xVals[curElement] + “, Y: “+ yVals[curElement]);
TuioCursor cursorPoint = (TuioCursor)e.nextElement();
xVals[curElement] = cursorPoint.x;
yVals[curElement] = cursorPoint.y;
curElement++;
}

}
//create new cursor instance
void add(Integer s_id) {
if(numCursors //Vector pointList = new Vector();
TuioCursor cursorPoint = new TuioCursor();
cursorList.put(s_id,cursorPoint);
numCursors++;
}
}
//remove cursor
void remove(Integer s_id) {
cursorList.remove(s_id);
if(numCursors>maxCursors){
numCursors = 8;
}
else{
numCursors--;
}
}

I am totally not limiting the boundaries of this array properly, but Ill get some help or something and figure it out. Anyways, the main draw function looks like:
void draw()
{
background(255);
cursorList.draw(); //draw the cursors
for(int i=0; i circles = new Circle(2);
circles.update(xVals, yVals);
circles.display();
}
smooth();
}

So Im just gonna mess with this other the next day or two and hopefullly have a nice multi-touch drawing program by Thurs ! Thanks again for the input, and more suggestions from anyone is sincerely welcome..I know its hard to make suggestions with this small of a start tho smile Ill post the results in a few days regardless!

Profile
 
 
Posted: 03 June 2008 05:24 PM   [ Ignore ]   [ # 3 ]
Elite
Avatar
RankRankRankRank
Total Posts:  156
Joined  2007-09-13

Good on you, mate. Glad to hear it helped out. Let me know how it turns out.

Profile
 
 
Posted: 24 July 2008 10:54 AM   [ Ignore ]   [ # 4 ]
Elite
Avatar
RankRankRankRank
Total Posts:  212
Joined  2007-09-18

@ Ben ,

I am also struggling with this TUIO/P5 !!

i have been trying your post with no success
( “cannot find a variable named Xvals ...” , and Y vals, and the Circle class?)

Can you post the sketch ?

 Signature 

http://sassexperience.org/projects.html

Profile
 
 
Posted: 24 July 2008 01:06 PM   [ Ignore ]   [ # 5 ]
Elite
Avatar
RankRankRankRank
Total Posts:  212
Joined  2007-09-18

here a very basic (cave) painting app !

unzip, launch osc.exe, launch cave_painting.exe

bad issues with opengl :

the drawing is much better but ... the screen is blinking

also with P3D :

no stroke Weight allowed !

So if you have any clue to solve those problems ....

File Attachments
application.windows.rar  (File Size: 1180KB - Downloads: 17)
application.macosx.rar  (File Size: 1295KB - Downloads: 14)
application.linux.rar  (File Size: 1276KB - Downloads: 14)
 Signature 

http://sassexperience.org/projects.html

Profile
 
 
Posted: 24 July 2008 01:53 PM   [ Ignore ]   [ # 6 ]
New Member
Avatar
Rank
Total Posts:  24
Joined  2008-06-16

Hello,
You should download the latest TUIO client that comes with the reacTIVision 1.4 prerelease.
I improved and simplified the Processing client a lot and it should be easier to get started with it.
best,
Martin.K

 Signature 

reacTIVision framework: http://reactivision.sf.net/
TUIO protocol specification: http://reactable.iua.upf.edu/?tuio
reacTIVision & TUIO CVS: http://sourceforge.net/projects/reacTIVision

Profile
 
 
Posted: 24 July 2008 03:49 PM   [ Ignore ]   [ # 7 ]
Elite
Avatar
RankRankRankRank
Total Posts:  212
Joined  2007-09-18

Alleluya, Mazeltof, Nasdrovia ! Salio el sol ! Thanks a lot , Martin !!!!!!!
Can’t have a more precise answer !

Can you tell us more about the getPath() vector ?

Any plan to lead reactivision workshop soon ?

Best interactive wishes !

You should post a new thread “TUIO Processing , how to “ with the text from the readme.txt and the download link.

 Signature 

http://sassexperience.org/projects.html

Profile
 
 
Posted: 25 July 2008 08:38 AM   [ Ignore ]   [ # 8 ]
Elite
Avatar
RankRankRankRank
Total Posts:  156
Joined  2007-09-13

Yeah, that’s great news Martin. Thanks! I’ve played around with the previous TUIO Processing client and it was indeed a bit of a nightmare.

I’ve already downloaded the new 1.4 version but haven’t had time to explore it yet.

@jimihertz: good idea. A quick “getting started” would be most welcome.

Profile
 
 
Posted: 25 July 2008 09:48 AM   [ Ignore ]   [ # 9 ]
New Member
Avatar
Rank
Total Posts:  24
Joined  2008-06-16
jimihertz - 24 July 2008 03:49 PM

Can you tell us more about the getPath() vector ?
Any plan to lead reactivision workshop soon ?
You should post a new thread “TUIO Processing , how to “ with the text from the readme.txt and the download link.

de nada ...

the getPath() method returns a vector of all the points accumulated by a TuioObject or TuioCursor.
since this is commonly needed I just added that to the TuioClient already.

I am usually doing workshops on tangible interaction in spain, austria and portugal within the university courses I am teaching there.
if you are interested in organizing a workshop and my time allows it I am happy to join in ...

and yes I know, I still need to update the documentation, but I still did not fully finish the design of the 1.4 client API.

best,
Martin.K

 Signature 

reacTIVision framework: http://reactivision.sf.net/
TUIO protocol specification: http://reactable.iua.upf.edu/?tuio
reacTIVision & TUIO CVS: http://sourceforge.net/projects/reacTIVision

Profile
 
 
Posted: 25 July 2008 11:06 AM   [ Ignore ]   [ # 10 ]
Elite
Avatar
RankRankRankRank
Total Posts:  212
Joined  2007-09-18

hi , Martin ,

i’ve been trying your successfully your TUIO ;

have one more question !

how do you implement a class in order to get the values ?

I have done a basic sketch with moving rectangles , to be stopped with the cursor .
(for now they are stopped by the mouse ).
Could you send the “corrigé “sketch , if so I will join it to the “quick “getting started” with TUIO/P5” thread

About the workshop , i will be honored to organize one in Paris in October or November .
send me requirements and details at :

File Attachments
application.windows.rar  (File Size: 1133KB - Downloads: 15)
application.macosx.rar  (File Size: 1248KB - Downloads: 15)
application.linux.rar  (File Size: 1228KB - Downloads: 13)
 Signature 

http://sassexperience.org/projects.html

Profile
 
 
Posted: 26 July 2008 03:37 AM   [ Ignore ]   [ # 11 ]
New Member
Avatar
Rank
Total Posts:  24
Joined  2008-06-16

Hey,
you have two options to get the TuioCursor information:
event based via the callback methods you are required to implement in your listener class
or polling the TuioClient in order to get lists of the current cursors and objects.

if you want to use the polling method you could pass the TuioClient to the reactangle.check() method and then retrieve all the TuioCursors from the TuioClient checking if they meet your condition.
using the callback alternative you could move the rectangle.check() method to the updateTuioCursor callback and there simply pass the x and y coordinates of the retrieved TuioCursor to your rectangle.check() method.

you will of course need to update your rectangle class accordingly by implementing either check(TuioClient client) or check(int x, int y).

best,
Martin.K

 Signature 

reacTIVision framework: http://reactivision.sf.net/
TUIO protocol specification: http://reactable.iua.upf.edu/?tuio
reacTIVision & TUIO CVS: http://sourceforge.net/projects/reacTIVision

Profile
 
 
Posted: 29 July 2008 08:17 AM   [ Ignore ]   [ # 12 ]
Elite
Avatar
RankRankRankRank
Total Posts:  212
Joined  2007-09-18

Thanks Martin,

your answer seems quite clear in the paper , but i can’t get it .
still struggling!

I ‘ve been looking for quite a long time some examples or sketches ,
in order to interact with content and objects/cursors,
i didn’t find anything else than the basics “ draw at the cursor/object position “.

so if you have any , i will dive into !

.

 Signature 

http://sassexperience.org/projects.html

Profile
 
 
Posted: 29 July 2008 04:07 PM   [ Ignore ]   [ # 13 ]
Elite
Avatar
RankRankRankRank
Total Posts:  212
Joined  2007-09-18

Wet and back to the surface , ( a min (s) for the open source Surface )
Solve at last , yes !

Thanx again Martin! ( for you patience, also)
It sometimes harsh to translate from one language to another then to a programming one .( newbie complain)

The gate is now open for more creative stuff .(more headaches? and more fun !)

( the next step is : resize and rotate )

File Attachments
Tuio_Solved_basic_rectangles1.rar  (File Size: 3KB - Downloads: 17)
 Signature 

http://sassexperience.org/projects.html

Profile
 
 
Posted: 29 July 2008 04:35 PM   [ Ignore ]   [ # 14 ]
New Member
Avatar
Rank
Total Posts:  24
Joined  2008-06-16

yes, I think it would be nice to have a more extensive demo application for all environments.
usually the first exercise that I do with workshop participants is the creation of a “multi-touch hello world” that does the typical translation, rotation and zoom of a world map picture.
I have that basic demo prepared for the java TUIO package, and some stuff done for C++ and Processing but my plan was to extend it to all TUIO client examples.
Probably I will add that in the last minute before one of my next reacTIVision workshops wink , but if anybody wants to volunteer I am happy to receive any submission.

best,
Martin.K

 Signature 

reacTIVision framework: http://reactivision.sf.net/
TUIO protocol specification: http://reactable.iua.upf.edu/?tuio
reacTIVision & TUIO CVS: http://sourceforge.net/projects/reacTIVision

Profile