Sign in to follow this  
SavyCat

[.net] Help with mesh.intersect function

Recommended Posts

Hello there This is my first post on these forums, and I hope I don't sound too noobish. I am a student in my first year, and I am writing a simple game engine in managed Direct X and c#. I have run into a glitch which I cant figure out and don't know who to turn to. The books out there for MDX are not all that informative (at leaste the ones I have read). Thanks in advance. Ok here is my problem: Im trying to select meshes with my mouse, but they are not getting selected. In my main game loop, I cycle through each object in the world and update its matrices, render it, and do a few other activities. For simplicity's sake i created a simple directX box, which Im rendering with the drawsubset function. Back in main: once the box is rendered and transformed I call a function in my Ray class which hopefully should have returned a bool value for if an intersection occured. Basically Im trying to select an object with the mouse. here is the call: *edited to pseudocode* foreach ( Entity en in world ) { drawEntity(); if (mouseButtonClicked) { //Check if there is a selection with entity Ray.pick( camera, device, en ); } } Here is the the Ray.Pick function:
public bool Pick( Camera myCamera, Device myDevice, DinoEntity entity )
        {
            Point mouseLoc = DinoInput.MouseInputCamera.screenPoints;
            bool pickFound = false;
            IntersectInformation intInf;

            Vector3 rayStart, rayDirection;
            Matrix proj = myCamera.Projection;

            Vector3 v;
            v.X = ( ( ( 2.0f * mouseLoc.X ) / myDevice.PresentationParameters.BackBufferWidth ) - 1 ) / proj.M11;
            v.Y = -( ( ( 2.0f * mouseLoc.Y ) / myDevice.PresentationParameters.BackBufferHeight ) - 1 ) / proj.M22;
            v.Z = 1.0f;

            // Get the inverse of the composite view and world matrix      
            Matrix matView = myCamera.View;
            Matrix matWorld = myCamera.World;
            Matrix m = matWorld * matView;
            m.Invert();

            // Transform the screen space pick ray into 3D space       
            rayDirection.X = v.X * m.M11 + v.Y * m.M21 + v.Z * m.M31;
            rayDirection.Y = v.X * m.M12 + v.Y * m.M22 + v.Z * m.M32;
            rayDirection.Z = v.X * m.M13 + v.Y * m.M23 + v.Z * m.M33;

            rayStart.X = m.M41;
            rayStart.Y = m.M42;
            rayStart.Z = m.M43;

            if ( entity.Pick( rayStart, rayDirection, out intInf ) && intInf.Dist < minDistance )
            {
                pickFound = true;
            }

            return pickFound;
        }
The Ray.Pick function created the Ray origin and direction, and then sends this information to the Entity class which finally determines whether there was a hit. My Entity class contains a mesh holder, and its position, scale, and rotation. As well as a few other things. Here is the Pick function in the entity class:
public bool Pick( Vector3 rayStart, Vector3 rayDirection, out IntersectInformation intInf )
        {
            // Convert ray to model space
            Matrix World =
                Matrix.Scaling( enScale ) *
                Matrix.RotationYawPitchRoll( enRotation.X, enRotation.Y, enRotation.Z ) *
                Matrix.Translation( enPosition );

            Matrix inverseWorld = Matrix.Invert( World );

            Vector3 localStart = Vector3.TransformCoordinate( rayStart, inverseWorld );
            Vector3 localDirection = Vector3.TransformNormal( rayDirection, inverseWorld );
            localDirection.Normalize();

            // Check for mesh intersection
            for ( int i = 0; i < entityMesh.NumberAttributes; ++i )
            {
                if ( entityMesh.IntersectSubset( i, localStart, localDirection, out intInf ) )
                {
                    return true;
                }
            }

            intInf = new IntersectInformation();
            return false;
        } 
I have tried looking in the forums but couldn't find anything for my problem. Thank you kindly for any help. SC [Edited by - SavyCat on March 26, 2006 2:09:33 PM]

Share this post


Link to post
Share on other sites
Ok, after a day of testing every possible problem I seem to have got at leaste some of the code working. For some odd reason, the pick function is only working with a few selected models; here are my tests:

tiger.x (SDK static model) - perfect detection
tiny.x (SDK animated model) - partial detection
DirectX Spheres and boxes - perfect detection
My own imported Spheres and boxes - perfect detection
my own imported models (static) - partial detection
my own imported models (animated) - partial detection

So what exactly does this mean? It can detect when a model is selected ( ala tiger.x model ), but for others it only detects parts of it. Does anyone know if the intersect function is exact EVERY time, or does it only get estimations? Any suggestion as to why some are exact and others are not?
Thanks once again.

Share this post


Link to post
Share on other sites
Quote:
                       if ( ray.Update( device, camera, prim ) )
{
test = "selected";
}
else
{
test = "Not selected";
}

This doesn't seem quite right to be doing every time around the loop. It seems to me it will only work if the ray intersects the last face; you should do something more like (pseudocode):

Primitive selectedFace = null;
foreach(Primitive prim in shape){
if(RayIntersects(prim)){
selectedFace = prim; break;
}
}

if(selectedFace != null) DisplaySomething();

Share this post


Link to post
Share on other sites
Sorry, I was getting the term primitive mixed up. I thought primitive was a simple 3d shape. I edited the above code to show my updated version.

Share this post


Link to post
Share on other sites
Okay, I think I found the problem. I was wrong about the my imported models working. The ones which I tested that were supposedly working, were infact not. The short end of this - my code must in theory be fine, as the tiger and simple direct x models work. Anything imported does not. I used the PandaX exporter for my meshes. They render just fine, even when animated. But it seems to me that DX cant use the intersect function with them. I must be wrong. Has anyone ever had a similar problem? Thanks

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this