Jump to content
  • Advertisement
Sign in to follow this  
sumit381

Mesh.Intersect issue

This topic is 4321 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I am writing a DX app using C#, VS05, and DX 9.0c SDK. My app takes an xml files filed with x,y,z coords and makes an array of Vector3 called dataList. This data is then used to create a bunch of spheres as data points on a grid. The problem I am having is being able to select the data point when I click on them. The data points are rendered as sphere meshes stored in a mesh called dataSphereMesh. When I render the data points, I loop through my dataList array and create a subset of the dataSphereMesh for each item in the array. This is the picking code that I am currently using:
private void DrawDataPoints()
{
   d3dDevice.SetTexture(0, null);
   for (int i = 0; i <= dataList.Length - 1; i++)
   {
      d3dDevice.Transform.World = Matrix.Translation((float)dataList.X, (float)dataList.Y, (float)dataList.Z);

      dataSphereMesh.DrawSubset(0);
   }
}

protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
   mousing = true;
   string test = "";
   for (int i = 0; i <= dataList.Length - 1; i++)
   {
      dataPosition = new Vector3(dataList.X, dataList.Y, dataList.Z);
      if (testHit(e.X, e.Y, dataPosition))
         test = "it's a hit!";
      else
         test = "false";
   }
   this.Text = test;
}


private bool testHit(Single x, Single y, Vector3 position)
{
   Vector3 near = new Vector3(x, y, 0);
   Vector3 far = new Vector3(x, y, 1);
   near.Unproject(d3dDevice.Viewport, d3dDevice.Transform.Projection, d3dDevice.Transform.View, Matrix.Translation(position));

   far.Unproject(d3dDevice.Viewport, d3dDevice.Transform.Projection, d3dDevice.Transform.View, Matrix.Translation(position));

   far.Subtract(near);
   IntersectInformation closest = new IntersectInformation();
   if (dataSphereMesh.Intersect(near, far, out closest))
     return true;
   else
     return false;
}

When I run the code, I am only able to click on the very last item in the array. Please help in this matter if possible, thanks. [Edited by - Washu on February 13, 2007 12:06:20 PM]

Share this post


Link to post
Share on other sites
Advertisement
hey.. i got the same/similar problem. i just wrote about it here couple of hours ago:
http://www.gamedev.net/community/forums/topic.asp?topic_id=435413

hopefully there is some solution for this.

Share this post


Link to post
Share on other sites
It seems the problem isn't with the picking, but with your looping. A hit on any other item than the last one does get recorded, but is subsequently overwritten as you continue to loop over the other elements in the data array. You should break or return from the loop when you have a hit, that ought to work.

@sumit381: your interest in this thread probably ends here, sorry for the Hijack [smile]

[Edited by - remigius on February 14, 2007 3:12:21 AM]

Share this post


Link to post
Share on other sites
well that makes sense but its not the problem in my case. im only cycling thru the first four objects and if there is a success, it breaks from the loop with a flag 'isPicked=true' and another variable set to the picked object (which is then used to output the information). those two get null'd everytime i click the mouse button. i get output only when i click on the 16th object, which is not even close to the first four im cycling thru and the fact that its the very last one just makes me wonder.. if it wasnt the last object, i guess it would be some kind of a bug but in this case i just thing there is something i missed.

i also tried to output some information about each of the meshes that get loaded upon the object creation and each of them has the same HashId. so now im even more confused. we're just goin to visit one of the proffessors from our uni and i hope he brings some light into our lives.

Share this post


Link to post
Share on other sites
@EwanK:

Was ZMan's reply in your MSDN thread of any use? Without more code, I'd make the same guess he offers. You need to unproject the ray for each object with the appropriate world matrix, otherwise it won't work. This is necessary since the Mesh.Intersect method works in local object space, as explained in more detail over here.

If you're using other world-space rays (for collision detection for example), you'll need to transform them by the inverse of the world matrix for each object, so the rays are in local object space to satisfy the requirements for using Mesh.Intersect.

Share this post


Link to post
Share on other sites
yeah, i just checked it out and already replied.
but as i wrote in my reply, im not sure how to do that unprojection he meant and included the code of my method that calculates those two vectors (which i havent made up myself, just modified a VB.NET sample i found somewhere before).

edit: just tell me what more code you need 8-)

Share this post


Link to post
Share on other sites
so ive changed the picking cycle to this:

for( int i = 0; i < ActivePlayer.characters.Count; i++ )
{
Character panak = ActivePlayer.characters as Character;
//IntersectInformation[] closestHit;
closestHit = new IntersectInformation();
isPicked = false;
intPanacik = null;
device.Transform.World = Matrix.Identity;
device.Transform.World = Matrix.Translation( panak.x, panak.y, 0 );
rayOrigin = new Vector3();
rayDir = new Vector3();
calcRay( mouseX, mouseY, ref rayOrigin, ref rayDir );
if( panak.charMesh.Intersect( rayOrigin, rayDir,out closestHit ) )
{
if( closestHit.FaceIndex <= panak.charMesh.NumberFaces )
{
isPicked = true;
pickedPanakIndex = i;
isWaitingToPick = false;
intPanacik = panak;
break;
}
}
}


so im actually recalculating the picking vectors just before the intersection check happens. the thing is that now i dont succeed with the last orange piece, but with each of the green ones, with output saying i clicked on the very first one. but we're coming closer! :)

edit: and i know for sure that the x and y of those four pieces are different as they were already used to draw them to their appropriate spots.

Share this post


Link to post
Share on other sites
The 'unprojection' basically is what happens in your calcRay method, the mouse coordinaate gets translated from camera space to your local object space. You need to unproject your ray seperately for each object, since each object has a different world matrix. So in pseudo code:


foreach( panak in yourPanakArray )
{
panakWorldMatrix = Matrix.Translation( panak.x, panak.y, 0 );

Vector3 vIn = new Vector3( mouseX, mouseY, 0 );
Vector3 vFar = new Vector3( mouseX, mouseY, 1 );

// use object's world matrix for EACH unprojection
near = Vector3.Unproject( vIn, device.Viewport, device.Transform.Projection,
device.Transform.View, panakWorldMatrix );

vFar = Vector3.Unproject( vFar, device.Viewport, device.Transform.Projection,
device.Transform.View, panakWorldMatrix );

far = Vector3.Subtract( vFar, near );

IntersectInformation closestHit;
if( panak.charMesh.Intersect( near, far, out closestHit ) )
{
// intersection!
}
}


As for why this is needed, it's a bit hard to explain without going into vector spaces. Basically the vertices in the mesh are defined in local object space. By transforming these with a world matrix, you typically display them at some location in the world space, but the vertices themselves are not changed and remain in local object space (as if a Matrix.Translation(0, 0, 0) was used for the world matrix).

Hence operations like Mesh.Intersect require the rays to be in local object space too, since the mesh doesn't know about any world space transformations. By unprojecting the rays for each object with its appropriate world matrix, you obtains the rays in local object space. Maybe a picture will clear things up:



Hope this helps (and upstages ZMan [wink])

Share this post


Link to post
Share on other sites
thanks for clearing it up :) but that does the same thing it does with my previous modifications - it succeeds with all four green pieces BUT says i clicked on the first one of them even tho i clicked on one of the other three. i think im still missing something :I

Share this post


Link to post
Share on other sites
aight, i got it working finally :) i just needed to multiply the objects world matrix with the scaling matrix. THANKS A LOT!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!