Is there a library for detecting mouse over 3d objects?

Hi

I’m looking to be able to select and transform individual 3D objects and aim to implement some simple transform GUI tools as 3D geometry (a 3-axes move/drag tool, a 3-axes rotate tool and a 3-axes scale tool).

In order to do that I need to be able to first select the geometry I want to transform and then select the individual axes of the transform tool I want to use.

So basically I need to be able to achieve mouse rollover/rollout and mouse click/release of these 3D elements.

I don’t know much about 3D hit-testing but after a little research it seems like drawing individual elements using different draw colours to an FBO and then using the mouse position on that FBO to return the colour at that pixel, along with a lookup table to associate the 3D elements with the colour, seems to be a fairly solid and reliable way of doing this. I have come across it in a few searches now but the principle’s described here (in the answer to the post) http://gamedev.stackexchange.com/

I think I will be able to do this myself, but it would save me a lot of time if this has already been implemented for OF? Could anyone tell me if they know of an addon that does this (or indeed anything that will achieve the same) so I don’t have to reinvent the wheel?

Thanks

I could see how the color method would work, but if you need more precision ray casting is the way to go. I’ve used Elliot Wood’s OfxRay before to detect when the mouse hovers over complex 3D forms.

Thanks Caroline
I did scan over that earlier but wasn’t sure it would do what I wanted.
If that’s a more precise way of picking/hit-testing then I’ll figure it and use that instead.
Cheers!

Hi Caroline.

Would you mind pointing me towards how to intersect complex geometry with ofxRay please?

The example is for the intersection of a plane primitive using the ofxRay::Plane / ofPlane but I’m stuck as to how to extend that on i.e. a sphere. Am I missing something or do I have to do it using a plane for each face in the mesh I want to intersect with?

Thanks

Sorry! I looked back at my code and remembered I just created a plane over each piece of geometry and that was accurate enough for me.

It is seems possible in other languages / frameworks. Here it is in unity and three.js. So I would think there is a way of using rays to detect objects other than a plane in OF as well, but I don’t have time to dig into it just now. I think the projector example in ofxRay might have some starting points.

The point picker example (examples/3d/pointPickerExample) uses a much simpler distance based method for selection. It is isn’t exactly what you want, but it still might be helpful to check out.

No worries, thanks for the pointers!
I’ll check out the examples tomorrow and see what fits best.
Thanks

Hi
You can subdivide your 3d shape in triangles , use the ofxRay method to get a line between the cameraPos and the point you clicked on your screen .
Use the ofxRay coordinates points to check if the Ray intersects your triangles representing the 3D Shape Collider.
Here is a piece of code in C# I edited, checking if a Line intersects a Plane in a 3D space

void checkIntersectionPlaneAndLine(Vector3[] pointsDroite, Vector3[] pointsPlan){
		
		Vector3 P1, P2;
		P1 = pointsDroite [0];
		P2 = pointsDroite [1];
			
		Vector3 p1, p2, p3;
		p1 = pointsPlan [0];
		p2 = pointsPlan [1];
		p3 = pointsPlan [2];
		
		Vector3 v1 = p1 - p2;
		Vector3 v2 = p3 - p2;
		
		float a, b, c, d;
		
		a = v1.y * v2.z - v1.z * v2.y;	
		b = -(v1.x * v2.z - v1.z * v2.x);
		c = v1.x * v2.y - v1.y * v2.x;
		d = -(a * p1.x + b * p1.y + c * p1.z);
		
		Vector3 O = P1;
		Vector3 V = P2 - P1;
		
		float t;
		
		t = -(a * O.x + b * O.y + c * O.z + d) / (a * V.x + b * V.y + c * V.z);
		
		Vector3 p = O + V * t;
		
		float xmin = Mathf.Min (P1.x,P2.x);
		float ymin = Mathf.Min (P1.y,P2.y);
		float zmin = Mathf.Min (P1.z,P2.z);
		
		float xmax = Mathf.Max (P1.x,P2.x);
		float ymax = Mathf.Max (P1.y,P2.y);
		float zmax = Mathf.Max (P1.z,P2.z);
		

		if(!inside (p , xmin, xmax, ymin, ymax, zmin, zmax)){
			
			            print ("outside!!");
					
		}else{
                               print ("intersect at "+ p);
			}

}
    			`

And the inside function is a very basic way to check if the point is outside the Triangle BoundingBox

bool inside(Vector3 p,float xmin,float xmax,float ymin,float ymax,float zmin, float zmax){

		if (p.x >= xmin && p.x <= xmax && p.y >= ymin && p.y <= ymax && p.z >= zmin && p.z <= zmax)
			return true;

		return false;

	}

Thanks sachaamm, I’ve already got what I want working using a separate FBO and drawing each object using a unique color then a standard mouse hit test to return pixel colour. That works for my needs right now but I appreciate the above code, hopefully it’ll come in useful later

Would you happen to have the code framework for this handy for me to see? :slight_smile: