invalid mesh reference?

hey.. im trying to finish a directx 3d game assignment for my uni course and came to a problem i apparently cannot solve by myself.

i have an arraylist containing players (objects of type Player). each of the players contains his own arraylist of characters (objects of type Character). upon a creation of the character object, specific mesh from .x file is loaded, processed and stored into charMesh variable.
the meshloading method goes like this:

public static void LoadMesh( D3D.Device device, string filename, string texture, ref Mesh mesh, ref Material[] meshmaterials, ref Texture[] meshtextures, ref float meshradius )
{
ExtendedMaterial[] materialarray;
if( MainForm.RELEASE == 1 )
mesh = Mesh.FromFile( filename, MeshFlags.Managed, device, out materialarray );
else
mesh = Mesh.FromFile( "../../" + filename, MeshFlags.Managed, device, out materialarray );

if( ( materialarray != null ) && ( materialarray.Length > 0 ) )
{
meshmaterials = new Material[materialarray.Length];
meshtextures = new Texture[materialarray.Length];

for( int i = 0; i < materialarray.Length; i++ )
{
meshmaterialsIdea = materialarrayIdea.Material3D;
meshmaterialsIdea.Ambient = meshmaterialsIdea.Diffuse;

if( ( materialarrayIdea.TextureFilename != null ) && ( materialarrayIdea.TextureFilename != string.Empty ) )
{
if( MainForm.RELEASE == 1 )
{
meshtexturesIdea = TextureLoader.FromFile( device, MainForm.TXDIR + materialarrayIdea.TextureFilename );
}
else
{
meshtexturesIdea = TextureLoader.FromFile( device, "../../" + materialarrayIdea.TextureFilename );
}
}
else if(texture != null && texture != String.Empty)
{
if( MainForm.RELEASE == 1 )
{
meshtexturesIdea = TextureLoader.FromFile( device, MainForm.TXDIR + texture );
}
else
{
meshtexturesIdea = TextureLoader.FromFile( device, "../../" + texture );
}
}
}
}

mesh = mesh.Clone( mesh.Options.Value, CustomVertex.PositionNormalTextured.Format, device );
mesh.ComputeNormals();

VertexBuffer vertices = mesh.VertexBuffer;
GraphicsStream stream = vertices.Lock( 0, 0, LockFlags.None );
Vector3 meshcenter;
meshradius = Geometry.ComputeBoundingSphere( stream, mesh.NumberVertices, mesh.VertexFormat, out meshcenter ) * scaling;
vertices.Unlock();
}

this method is a part of a MeshHelper class that contains only static methods that help with mesh processing. the actual method of the character class that calls this static method looks like this:

MeshHelper.LoadMesh( device, filename, textures[color] as String, ref panacikMesh, ref panacikMaterials, ref panacikTextures, ref panacikRadius );

this is being called from the Character constructor.

now the application world contains 4 players (green, brown, yellow and orange; in the order how they are put in the players arraylist) with 4 characters each that are placed on a field.
now in a special occation, id like to test for a character mesh intersection with already computed vectors. i am sure those vectors are not the source of the following problem cause ive been using them in other circumstances and everything worked correctly with them.
so the green player is active in the current round and id like to pick one of the characters with a mouse-click. so i have a simple for cycle that goes thru the characters arraylist of the green player and checks for the character mesh intersection with the vectors. the actual intersection part should be correct as ive tested it before with one character present on the field.
if the intersection succeeds, there are information about the intersection and the character i clicked on to be dumped on the screen so that i know it works. but no matter what and how i click around the green player characters, no dump information happens. then i just try clicking around the other players characters and voila! as i click on the very last character added to the arraylists (the 4th orange character), the intersection succeeds and im given the required dump information.
the interesting part is that the information about the clicked character contain stuff about green players first character, which is obviously the first one to be processed by the for cycle.
the actual intersection check looks like this:

for( int i = 0; i < ActivePlayer.characters.Count; i++ )
{
Character panak = ActivePlayer.charactersIdea as Character;
closestHit = new IntersectInformation();
isPicked = false;
if( panak.charMesh.Intersect( rayOrigin, rayDir,out closestHit ) )
{
if( closestHit.FaceIndex <= panak.charMesh.NumberFaces )
{
isPicked = true;
pickedPanakIndex = i;
isWaitingToPick = false;
intPanacik = panak;
break;
}
}
}

so it looks like the last orange players character has a mesh object that should belong to the first green players character..

any ideas :/


Answer this question

invalid mesh reference?

  • popit

    *bump*

    anyone :(

  • tronn

    Well it looks like you are not transforming your pick vectors into the world space of each of your game pieces. Since you have multiple things onthe screen each of them has a world matrix you are probably setting to move it to that position. Mesh.Intersect has no idea about this - it just does the intersection as if the piece is at the origin. So it thinks all your pieces are at the same spot and I am guessing that your orange piece is closest to the origin which is the only reason your picking is working at all.

    So inside your pick loop you need to unproject your pick vectors by the world matrix for each character.



  • Dan Mikkelsen

    Unprojecting is for going from screen space back into object space. But remember each object has its own object space becuase the world transform is different for each one. Well thats usually how you draw things at different places on the screen. Therefore you need to unrpoject the vectors for each object using the world transform for that particular object. SO instead of calling calcRay once on the nPaint you need to call it each time inside your picking loop and instead of using device.Transform.World use the world matrix for that particular object.



  • .net sukbir

    well that makes some sense! :)
    but im not sure i get what you meant by unprojecting those vectors. unprojecting is for transforming them into object space from the screen space afaik and i already did that with them. actually this is the method that creates those vectors (its being called in the OnPaint method):

    private void calcRay( int x, int y, ref Vector3 near, ref Vector3 far )
    {
    Vector3 vIn = new Vector3( x, y, 0 );
    Vector3 vFar = new Vector3( x, y, 1 );
    near = Vector3.Unproject( vIn, device.Viewport, device.Transform.Projection, device.Transform.View, device.Transform.World );
    vFar = Vector3.Unproject( vFar, device.Viewport, device.Transform.Projection, device.Transform.View, device.Transform.World );
    far = Vector3.Subtract( vFar, near );
    }

    i tried putting
    device.Transform.World = Matrix.Translation( panak.x, panak.y, 0 );
    just before the intersection check but it doesnt work. but i guess it just seems im doing THIS wrong :) so could you please write here what you meant with that unprojection
    as i said, those two vectors work for the intersection if there is only one object present on the scene.


    edit: i tried something, as described in
    http://www.gamedev.net/community/forums/viewreply.asp ID=2891057
    not working yet :I

  • invalid mesh reference?