Jump to content
  • Advertisement
Sign in to follow this  
AntonyCoder

[.net] Can you spot anything wrong in this code that wraps ODE TriMeshes in C#?

This topic is 4499 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

We're wrapping a dll which it's self is a wrap of the ODE physics library. So far we've wrapped it in bmax(The language it's self was wrote for) and C# (Using a wrapper I wrote) And although it works perfectly with boxes and plane primitive geoms, when I use tri mesh in C# it doesn't work, the boxes fall through bits of geo they shouldn't and it eventually crashes. But I can be sure it's not a problem with the ode dll as it works perfectly in bmax. Here's the tri mesh class I wrote in C# that constructs the buffers and sends them to the dll. Am I doing something wrong with the pointers? Are pointers produced using fixed only valid as long as they're in context/scope?
public class TriMesh
    {
        public static ArrayList tmeshes = new ArrayList();
        public int meshdata, mesh;
        public float[] vertb;
        public int[] trib;
        public TriMesh(Space space, String MeshFile, AuroraC.Pivot parent)
        {
            
            AuroraC.Pivot pivot = AuroraC.SceneManager.CreatePivot();

            if(!(parent==null))
            {
                pivot.Position(parent.X(), parent.Y(), parent.Z());
                pivot.Rotate(parent.GetPitch(), parent.GetYaw(), parent.GetRoll());

            }
            AuroraC.MeshData md = pivot.CreateMeshData(MeshFile);
            float[] Verts = new float[md.Triangles() * 3*4+1];
            Console.WriteLine("");
            Console.WriteLine(md.Triangles() * 3 *3 +1);
            Console.WriteLine(md.Triangles());
            int offset = 0;
            int cnt=0;
            vertb = Verts;
            for (int t = 0; t < md.Triangles(); t++)
            {
                
                for (int v = 0; v < 3; v++)
                {
                    int vert = md.GetTriIndex(t, v);
                    md.GetVertex(vert);
                    Verts[offset] = md.VertexX();
                    Verts[offset + 1] = md.VertexY();
                    Verts[offset + 2] = md.VertexZ();
                    offset += 4;
                    cnt++;
                }
            }
            int[] Tris = new int[ md.Triangles()*3 ];
            offset=0;
            trib = Tris;
            int vrt=0;
            int ntris = ((cnt) / 3);
            int nverts = md.Triangles() * 3;
            nverts = cnt - 1;
            for(int i=0;i<ntris;i++)
            {
                Tris[offset] = vrt; 
                Tris[offset+1] = vrt+1;
                Tris[offset + 2] = vrt + 2;
                offset += 3;
                vrt += 3;
            }
            meshdata = ODE.odeGeomTriMeshDataCreate();

            unsafe
            {
                fixed (float * pVerts = Verts)
                {
                    fixed (int* pTris = Tris)
                    {
                        byte* ppVerts = (byte*)pVerts;
                        byte* ppTris = (byte*)pTris;
                        ODE.odeGeomTriMeshDataBuildSimple(meshdata, ppVerts, nverts, ppTris, ntris);
                    }
                }
            }
            mesh = ODE.odeCreateTriMesh(space.id, meshdata);
            TriMesh.tmeshes.Add(this);
        }
    }
    /*

Using this it eventually crashes at the OdeSpaceCollide fnuction ode. (Which takes space, world and a contact group if you're familar with ode) Here's the dll import section. Notice I use the unsafe keyword due to it having a byte pointer (byte *) type parameter. This compiles ok but I'm not sure if it's valid.
 [DllImport("jv.dll", EntryPoint = "_odeGeomTriMeshDataBuildSimple@20", ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static unsafe extern void odeGeomTriMeshDataBuildSimple(int trimesh,byte * vbank,int numverts,byte *tbank,int elements);
        [DllImport("jv.dll", EntryPoint = "_odeCreateTriMesh@8", ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern int odeCreateTriMesh(int trispace,int meshdata);
        [DllImport("jv.dll", EntryPoint = "_odeGeomTriMeshDataCreate@0", ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern int odeGeomTriMeshDataCreate();

For reference, here is our trimesh class wrote in bmax, which works perfectly. Can you spot where i've gone wrong in converting this code to C#?
 Type oTrimesh
	Field mesh
	Field Vertbank:TBank
	Field tribank:TBank
	Field trimeshdata:Int
	
	'Function CreateTriMesh:Int(trispace:Int,xscale:Float=1.0,yscale:Float=1.0,zscale:Float=1.0)
	Function CreateTriMesh:oTrimesh(trispace:Int,Meshfile$,parent:tentity=Null,x=0,y=0,z=0,doit=1)
	
		Local xscale:Float = 1.0 , yscale:Float = 1.0 , zscale:Float = 1.0
		Local Pivot:tpivot = TPivot.Create()

		If parent<>Null Then
			pivot.position(parent.x() , parent.y() , parent.z() )
			pivot.rotate(parent.getpitch(),parent.getyaw(),parent.getroll())
		EndIf

		If FileType("media\"+meshfile$)<>1 Then RuntimeError "Oh no! "+meshfile$
		Local md:tmeshdata = pivot.CreateMeshData(meshfile$)
		If MD.TRIANGLES()>0 Then
			
			Local vertexlistx#[(md.triangles() * 3)+1]
			Local vertexlisty#[(md.triangles() * 3)+1]
			Local vertexlistz#[(md.triangles() * 3)+1]
			Local cnt=0,vrt
			Local ntris = md.triangles()
			Local nverts=ntris*3
						
			For Local j=0 To md.triangles()-1
				For Local v=0 To 2 
					Local vert = md.getTriIndex( j,v ) 
					md.GetVertex( vert ) 
					vertexlistx[cnt] = md.x() 
					vertexlisty[cnt] = md.y() 
					vertexlistz[cnt] = md.z() 
					cnt = cnt + 1
				Next 
			Next



			Local tribank:TBank=CreateBank(NTris*3*4)
			Local Vertbank:TBank=CreateBank(NVerts*4*4)
			Local Offset:Int=0
			Local TriOffset:Int=0
			
			Local tm:oTrimesh = New oTrimesh
			tm.tribank=tribank
			tm.Vertbank=Vertbank
			ListAddFirst(Trimeshlist,tm:oTrimesh)
			
			For Local v=0 To cnt-1
 				PokeFloat(Vertbank,Offset,vertexlistx[v])
 				Offset:+4
 				PokeFloat(Vertbank,Offset,vertexlisty[v])
 				Offset:+4
 				PokeFloat(Vertbank,Offset,vertexlistz[v])
 				Offset:+ 8
 			Next
			ntris = ((cnt) / 3)-1
			nverts=cnt-1
			For Local v = 0 To NTRIS'(cnt - 1) / 3
				DebugLog trioffset+"   "+BankSize(tribank)
 				PokeInt(tribank,TriOffset,vrt)
				TriOffset:+4
 				PokeInt(tribank,TriOffset,vrt+1)
 				TriOffset:+4
 				PokeInt(tribank,TriOffset,vrt+2)
 				TriOffset:+ 4
				vrt=vrt+3
			Next
			
				Local trimeshdata:Int=dGeomTriMeshDataCreate()
				dGeomTriMeshDataBuildSimple(trimeshdata , BankBuf(Vertbank) , NVerts , BankBuf(tribank) , NTris * 3)
				tm.mesh = dCreateTriMesh(trispace , trimeshdata)
				tm.trimeshdata=trimeshdata
			
			Return tm
		EndIf
	End Function

Share this post


Link to post
Share on other sites
Advertisement
Not sure if this is your problem or not. But the casting of a float to a byte could be a huge problem...essentially you are taking a very large number, possibly 3.4 * 10^38 and truncating it to a range of 0-255. Essentially collapsing 8 bytes into 1 byte.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!