looking for ray pick samples in c# code

Started by
7 comments, last by remigius 18 years, 6 months ago
hi guys, any pick sample in c#? i don't know how to convert the mouse position according to the window form to the position in the directx scene?
Advertisement
Ray picking is pretty platform independent, so a standard DX one should work, you just need to find the equivilent functions in Managed DX.

There are some great tutorials on the subject out there, but I don't have any of the links on my work comp sorry.

Matt Hughson
__________________________________[ Website ] [ Résumé ] [ [email=contact[at]matthughson[dot]com]Contact[/email] ][ Have I been Helpful? Hook me up! ]
Hi billconan,
How are you doing buddy?

The Problem
Getting mouse coordinates in screen space and then converting them to other spaces.

The Solution
You are totally in luck as I have written a sample that will check mouse coordinates for a given form

Getting mouse coordinates in screen space and validating them
private void ValidateMouseCoordinates(Form window){	//Computes the screen space coordinates to client coordinates	cursor = window.PointToClient(Cursor.Position);	if(cursor.X < 0) //if the x position is less than 0. set it to the window width		cursor.X = window.Width;	if(cursor.Y < 0) //if the y position is less than 0. set it to the window height		cursor.Y = window.Height;}


And then once you have the screen coordinates you can do a number of things with these coordinates.
You can project them to object space using Vector3.Unproject() method.
Or you can check if the mouse intersects with an object. Here is some source code that will help you with that.

Check if mouse ray intersects with object.
//The entity here is just an entity class that I created that stores an entities//world matrix and mesh objects etc...public bool Intersect(Microsoft.DirectX.Direct3D.Device device, Entity entity){	//intersection information	IntersectInformation closest;	//the near vector	Vector3 near;	//the far vector	Vector3 far;	near = new Vector3(cursor.X, cursor.Y, 0); //the mouse coordinates	far = new Vector3(cursor.X, cursor.Y, 1); //the mouse coordinates	near.Unproject(device.Viewport, device.Transform.Projection, device.Transform.View, entity.MatWorld);	far.Unproject(device.Viewport, device.Transform.Projection, device.Transform.View, entity.MatWorld);	far.Subtract(near);	if(entity.Mesh.Intersect(near, far, out closest))		return true;	return false;}


I hope this helps a bit buddy.
Take care and if you have any other questions don't hesitate to ask ok?
hi there, thanks a lot.

i've found some code too, in a german site. i cannot read german, but i guess the code works

private static Microsoft.DirectX.Direct3D.Device device;private static Microsoft.DirectX.Vector3 mouseVector;private static Microsoft.DirectX.Matrix projMatrix;private static Microsoft.DirectX.Matrix viewMatrix;private static Microsoft.DirectX.Vector3 rayDir;private static Microsoft.DirectX.Vector3 rayOrigin;private static int width;private static int height;private static int posX;private static int posY;Funktion:public static void getRay(Device device, int xPos, int yPos){CMousePicking.device = device;projMatrix = device.GetTransform(TransformType.Projection);viewMatrix = device.GetTransform(TransformType.View);height = device.Viewport.Height;width = device.Viewport.Width;posX = xPos;posY = yPos;mouseVector.X = ( ( ( 2.0f * posX ) / width ) - 1 ) / projMatrix.M11;mouseVector.Y = -( ( ( 2.0f * posY ) / height ) - 1 ) / projMatrix.M22;mouseVector.Z = 1.0f;Microsoft.DirectX.Matrix invertedViewMatrix = Microsoft.DirectX.Matrix.Invert(viewMatrix);// Transform the screen space pick ray into 3D spacerayDir.X = mouseVector.X*invertedViewMatrix.M11 + mouseVector.Y*invertedViewMatrix.M21 + mouseVector.Z*invertedViewMatrix.M31;rayDir.Y = mouseVector.X*invertedViewMatrix.M12 + mouseVector.Y*invertedViewMatrix.M22 + mouseVector.Z*invertedViewMatrix.M32;rayDir.Z = mouseVector.X*invertedViewMatrix.M13 + mouseVector.Y*invertedViewMatrix.M23 + mouseVector.Z*invertedViewMatrix.M33;rayOrigin.X = invertedViewMatrix.M41;rayOrigin.Y = invertedViewMatrix.M42;rayOrigin.Z = invertedViewMatrix.M43;}private static Microsoft.DirectX.Direct3D.Device device;private static Microsoft.DirectX.Vector3 mouseVector;private static Microsoft.DirectX.Matrix projMatrix;private static Microsoft.DirectX.Matrix viewMatrix;private static Microsoft.DirectX.Vector3 rayDir;private static Microsoft.DirectX.Vector3 rayOrigin;private static int width;private static int height;private static int posX;private static int posY;Funktion:public static void getRay(Device device, int xPos, int yPos){CMousePicking.device = device;projMatrix = device.GetTransform(TransformType.Projection);viewMatrix = device.GetTransform(TransformType.View);height = device.Viewport.Height;width = device.Viewport.Width;posX = xPos;posY = yPos;mouseVector.X = ( ( ( 2.0f * posX ) / width ) - 1 ) / projMatrix.M11;mouseVector.Y = -( ( ( 2.0f * posY ) / height ) - 1 ) / projMatrix.M22;mouseVector.Z = 1.0f;Microsoft.DirectX.Matrix invertedViewMatrix = Microsoft.DirectX.Matrix.Invert(viewMatrix);// Transform the screen space pick ray into 3D spacerayDir.X = mouseVector.X*invertedViewMatrix.M11 + mouseVector.Y*invertedViewMatrix.M21 + mouseVector.Z*invertedViewMatrix.M31;rayDir.Y = mouseVector.X*invertedViewMatrix.M12 + mouseVector.Y*invertedViewMatrix.M22 + mouseVector.Z*invertedViewMatrix.M32;rayDir.Z = mouseVector.X*invertedViewMatrix.M13 + mouseVector.Y*invertedViewMatrix.M23 + mouseVector.Z*invertedViewMatrix.M33;rayOrigin.X = invertedViewMatrix.M41;rayOrigin.Y = invertedViewMatrix.M42;rayOrigin.Z = invertedViewMatrix.M43;}


thank u guys again, i will have a try
hello Armadon, i know it may be a stupid question, but what is "entity" you used to test collision. i use my own datastructure, and i convert it to index buffer before rendering, so what should i do.
The entity Armadon is using is probably a class storing a scene object's Mesh and WorldMatrix for rendering and other tasks, like picking. In your case you should probably use the world transform matrix you set before rendering your custom object. For the intersection test, it probably pays off to put your custom data structure in a Mesh object. Check out the How do I create a Mesh paragraph on the Mesh class documentation page if you are unsure how to do this.

Just a quick question here. Armadon's example seems to be translated from a MVP sample, while the german code seems to be translated from Toymaker's article (good short read) on picking. Are they really equivalent, because Armadon's code looks so clean I can't believe that's all there is to it after my wrestling to translate the toymaker codesample :)
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
i agree and can say it does work, i first used toymaker's picking code but now use the directX project/unproject functions. Cant really say which is better but im lazy so i go for the directX ones. :P and i like clean code :D
hey, thanks. but is that mean if i wanna adopt the directx's project/unproject function, i need to use the mesh? i think this could be annoying, 'cause my project is kinda like a 3d modeller, so i need to pick up everything in the 3d scene, i mean like, lines, vertices and faces. i just can't convert all this things into directx mesh. any suggestion? thanks!
Well, you only need the Mesh if you want to use the Mesh.Intersect function to do the test, obviously :)

DirectX has some other utility classes to perform intersection tests, like the Plane and most importantly the Geometry class. The latter supports intersection test on triangles, which is the way to go to accurately intersect arbitrary meshes.

That said, as long as you're not working with 'subobjects' (triangles, planes etc), you might do some quick and cheap intersection tests using bounding spheres. The Geometry class allows you to comute such a bounding sphere, but as far as I can tell it only works on non-indexed vertexbuffers... which is quite logical now that I think of it and shouldn't be a problem ;)
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!

This topic is closed to new replies.

Advertisement