mouse vs translation (event handling)

hi all

i am having a problem getting rollover states etc. for a cursor over an object that has been drawn after a translation (eventually this will be multitouch using ofxTuio)

i thought that a way to do this may be to add an event handler to the sprite object so that I could have it receive mouse events in it’s native coordinate system, but my app keeps crashing when trying to execute addListener()

does anyone have any advice on the best way to approach this?
any help greatly appreciated.

nay.

can you post some code? your idea seems right but surely there’s some uninitialized variable or something like that

thanks arturo
i had another crack at it:
http://renechristen.net/temp/events-test.zip
requires ofxTuio and ofxMSAInteractiveObject. you’ll need the Tuio Simulator to get it to display the problem, just drag a shape from the edge of the java applet to the simulated table top:
http://prdownloads.sourceforge.net/reac-…-p?download
the white squares are meant to act as buttons

this time i am using the ofxMSAInteractiveObject class. I have an instance of this inside a menu item class, and i am calling the update and draw methods for the class manually, rather than using the app event handling. but it doesn’t seem to be receiving the mouse events at all, even though this compiles and doesn’t crash

when i use this object class inside the testapp instance, instead of my class it works. but if i translate the view and then draw the object, it still uses the coordinates in relation to the top left corner when checking for mouse over states etc.

so i need a way to resolve these two problems.
best,
rene.

Hi

so i cannot test it right now as it’s using some 0.57something version i don’t have anymore. if you wait some days, you can try with 006

anyway the problem with the coordinates is normal, if you do some transformation using gl functions, the mouse coordinates won’t be affected by that so you need to apply the same transformations to the mouse, try using ofxVectorMath.

Also i can’t see where are you using the ofxMSAInteractiveObject. testapp has an instance of myTuio which is a tuioclient with a vector of fiducials, but no instance is using ofxMSAObject.

thanks arturo

each fiducial instance creates an instance of menu, which has an array of menuItems. each menu item has an ofxMSAInteractiveObject class.

regarding the translation. can you explain the approach here? i take it i create a vector to update an x,y offset from 0,0 with each translation that i then add to the cursor coordinates when checking for rollovers etc.

i understand that this is just adding and subtracting the offsets for translation. but can you explain the technique if using this method for a view that has been rotated as well as translated? i will try and look up the trig for this soon and post back if i figure it out.

i was hoping there’d be some nifty function to calculate this for me or to return the cursor relevant to the current matrix (would be a great thing to add to OF if possible). I will try with 006 from SVN. looking forward to the official 006 release.

ah ok didn’t notice about the menu in the fiducials

so for example in menuitem.h you are doing:

  
glRotatef(angle,0,0,1);   

before drawing.

you can rotate by the same amount the coordinates of the mouse with ofxVectorMath:

  
void onMouseMove(int x, int y){  
	ofxVec2f mouse(x,y);  
	mouse.rotate(angle);  
	printf("menu::onMouseMove(x: %i, y: %i)\n", mouse.x, mouse.y);  
}  

that should make the coordinates of the mouse be as rotated as the menuitem, so you can compare one with the other to know if the mouse is inside the menuitem.

to do it with ofxMSAInteractiveObject you should modify it to test on rotated objects, as there’s no coordinates there to rotate you can rotate the mouse coordinates by the negative angle and do the comparison with the original position and size.

There’s a function called hitTest, it should be a matter of adding a new rotate function and change hitTest like this:

  
ofxMSAInteractiveObject::rotate(float _angle){  
	angle=_angle;  
}  
  
ofxMSAInteractiveObject::hitTest(float tx, float ty){  
	ofxVec2f coords(tx,ty);  
	coords.rotate(-angle);  
	return ((coords.x > x) && (coords.x < x + width) && (coords.y > y) && (coords.y < y + height));  
}  

and then call rotate with the same angle as you are rotating when drawing.

alrighty, so i tried a simple app to test the translation but am having no luck…

i translate the view (and draw a rect for reference), then rotate, then draw a rect which needs to receive mouse events. I am content to measure distance between 2 points to get rollover states for now. one point being the cursor, the other being the center of the rect acting as a button.

in the code below, if i can get the ellipse to appear on top of the second rect, it should work (prints “over” to the console).

  
  
#ifndef _TEST_APP  
#define _TEST_APP  
  
#include "ofMain.h"  
#define OF_ADDON_USING_OFXVECTORMATH  
#include "ofAddons.h"  
  
class testApp : public ofSimpleApp{  
	  
	public:  
	  
	bool debug, fullscreen;  
	int mx, my, w, x, y;  
	ofxVec2f mouse, button;  
	float angle;  
	  
	void setup(){  
		ofBackground(0,0,0);  
		w = 20; //width of objects  
		ofSetRectMode(OF_RECTMODE_CENTER);  
		x = 200;//pos to translate to  
		y = 200;  
		angle = 45;//angle to rotate  
	}  
  
	void draw(){  
		glPushMatrix();  
		//translate to pos:  
		glTranslatef(x,y,0);  
		ofSetColor(0xFFFFFF);  
		ofRect(0,0,w,w);  
		//rotate:  
		glRotatef(angle,0,0,1);  
		ofSetColor(0xFFFFFF);  
		//draw square at new location from rotation point  
		ofRect(100,0,w,w);  
		glPopMatrix();  
		  
		//draw vector for button loc  
		ofSetColor(0xCCCCCC);  
		ofEllipse(button.x,button.y,w/2,w/2);  
		  
	}  
  
	int distance(int x1, int x2, int y1, int y2){  
		return sqrt(pow(x2-x1,2) + pow(y2-y1,2));  
	}  
  
	void mouseMoved(int _x, int _y ){  
		mouse.set(_x,_y);  
		  
		button.set(x,y);  
		button.rotate(-angle);  
		button.set(button.x+100, button.y);  
		  
		//printf("menu::onMouseMove(x: %f, y: %f)\n", mouse.x, mouse.y);   
		  
		int dist = distance(mouse.x,button.x,mouse.y,button.y);  
		if (dist <= 10) cout<<"over"<<endl;  
		//printf("dist %i\n",dist);  
	}  
		  
};  
#endif  
	  
  

so after some space from the prob i realised that i just needed to re-order my cursor translations/rotations

  
  
button.set(100, 0); //button pos inside rotated section  
button.rotate(angle); //rotation of section  
button.set(button.x+x,button.y+y); //add position of rotated section as offset  
  

thanks!

*edit* much better in the long run the perform the operations on the cursor rather than the button, think i misunderstood before. so better to be something like:

  
  
		button.set(100, 0);  
		cursor.set(mx-x,my-y);  
		cursor.rotate(-angle);  
  

still no luck getting mouse event handling to work on 00573 or 006 though.

**EDIT** event handling working fine in the official 06 pre-release. the suggested changes to the ofxMSAInteractiveObject class above worked a treat!