[JV-ODE] Problem creating a tri-mesh

BlitzMax Forums/BlitzMax Programming/[JV-ODE] Problem creating a tri-mesh

monotonic(Posted 2008) [#1]
Hi,

I have implemented my own variation of the CreateTriMesh function which is found in the examples folder of JV-ODE. Now, it all seems to work until a dynamic body hits the static geometry created as a tri-mesh.

When a body is colliding with the tri-mesh geometry, and I call this function
dSpaceCollide(ODE_Space, ODE_World, ODE_ContactGroup)

I get an 'Unhandled Memory Exception' error.

This is my tri-mesh function:
' this function builds a static tri mesh from an entity
' PARAMS:
'		entity - the entity to build the tri mesh from
'		ode_space - the ODE space to add this tri mesh to
Function BuildTriMesh:Int(entity:Int, ode_space:Int) 
	
	' locals
	Local vert_list:TList = New TList			' this is a temp list to store vertices
	Local tri_list:TList = New TList			' this is a temp list to store triangle vertex indices
	Local vert_bank:TBank						' the actual vertex bank
	Local tri_bank:TBank						' the actual index bank
	Local vertex_index:Int						' this is used to hold vertex indices
	Local surface:Int							' this holds a pointer to a surface
	Local Offset:Int = 0						' the vertex offset
	Local TriOffset:Int = 0 					' the triangle offset
	
	' cycle through all of the surfaces
	For Local surf:Int = 1 To bbCountSurfaces(entity) 
		
		' get the surface pointer		
		surface = bbGetSurface(entity, surf) 
	
		' cycle through each triangle in this surface
		For Local tri:Int = 1 To bbCountTriangles(surface) - 1
			
			' add all three vertices and indices to the list
			For Local vert:Int = 0 To 2			
				vertex_index = bbTriangleVertex(surface, tri, vert) 
				vert_list.AddLast(String(bbVertexX(surface, vertex_index))) 
				vert_list.AddLast(String(bbVertexY(surface, vertex_index))) 
				vert_list.AddLast(String(bbVertexZ(surface, vertex_index))) 
				vert_list.AddLast("0.0") 

				' add the vertex index to the list
				tri_list.AddLast(String(vert_list.count() - 1)) 
			Next
		
		Next
	
	Next
	
	
	' now create the banks
	vert_bank = CreateBank(vert_list.count() * 4 * 4) 
	tri_bank = CreateBank(tri_list.count() * 3 * 4) 
	
	' the vertex bank
	For Local v:String = EachIn vert_list
		PokeFloat(vert_bank, Offset, v.ToFloat()) 
		Offset:+4
	Next

	' the triangle bank
	For Local t:String = EachIn tri_list
		PokeInt(tri_bank, TriOffset, t.ToInt()) 
		TriOffset:+4
	Next
	
	
	' now create the tri mesh in ODE
	Local TriMeshData:Int = dGeomTriMeshDataCreate() 
	dGeomTriMeshDataBuildSimple(TriMeshData, BankBuf(vert_bank), vert_list.count(), BankBuf(tri_bank), tri_list.count()) 
	
	' return the tri mesh
	Return dCreateTriMesh(ode_space, TriMeshData) 

End Function


This is the code I use to setup ODE
ODE_World = dWorldCreate( )			' create the world
ODE_Space = dHashSpaceCreate( 0 )		' create the hash space
ODE_ContactGroup = dJointGroupCreate( 0 )	' create the default joint group
dWorldSetAutoDisableFlag( ODE_World, True )		' enable auto bpdy disable
dWorldSetGravity(ODE_World, 0.0, - 10.0, 0.0) 		' set the default gravity
dContactSetMode( dContactBounce )						' set the contact mode to bouncy
dContactSetBounce( 0.2 )								' set the bouncy-ness of the world
dContactSetMu( 48 )										' set the global friction


And, this is the code used to update ODE:
dSpaceCollide(ODE_Space, ODE_World, ODE_ContactGroup) 
dWorldQuickStep(ODE_World, 0.1) 
dJointGroupEmpty(ODE_ContactGroup) 



Any ideas.


VIP3R(Posted 2008) [#2]
Hmm, why are you using strings for the verts and tris?

The error sounds like the mesh isn't being contructed correctly into a TriMesh, which points to your vert and tri data.

[Edit] No the offset is not it.

I can't test the code as you're using another library, B3DSDK? But I suspect the vert and tri data is being stored into the bank in the wrong order somewhere.

I can send you a copy of the Blitz3D version of the TriMesh function, it contains surface counts etc and will be simple enough to convert. Let me know if you want it.


monotonic(Posted 2008) [#3]
Hi VIP3R,

I'm using strings to store the floating point variables in the TLists because they don't allow you to store standard data types only objects. So, I store them as strings then convert them back to strings.

It's strange isn't it, the error only occurs when the dynamic objects collide with the tri-mesh.


Damien Sturdy(Posted 2008) [#4]
I havent used ODE for a while- In newton we have a debug option that draws the collision meshes in wireframe- Do you have this in JVOde? I'm not sure it's possible.

In a while i'll have the ability to use ODE in flow again, then i'll be in heaven- Newton and ODE hehe.

Maybe you are sending the triangles in an odd way, and the meshes criss-cross, that'll crash it easily.


Damien Sturdy(Posted 2008) [#5]
Oops


VIP3R(Posted 2008) [#6]
You may have missed the previous post monotonic, I was editing as you replied ^

I've sent you a copy of the Blitz3D version to compare or convert. Check your email inbox.

The TriMesh will still build ok with incorrect data (without giving an error), but as soon as another object contacts it an error will occur if the vert and tri data are not formatted correctly.


monotonic(Posted 2008) [#7]
Ok, I'm still having a problem with this.

I have narrowed it down, when I load a mesh using bbLoadMesh the physics work perfectly however, if I load the mesh using bbLoadAnimMesh it crashes with the said error.

I need to use the bbLoadAnimMesh function because, I want to pull apart the mesh and parse the individual parts seperately.

This is the *new* code I am using to create the tri-mesh:
' this method creates a static tri mesh from this entity
	Method CreateTriMesh(trispace:Int, xscale:Float = 1.0, yscale:Float = 1.0, zscale:Float = 1.0) 

		' locals
		Local tricount:Int = 0
		Local vertcount:Int = 0
		Local TriBank:TBank
		Local VertBank:TBank
		Local offset:Int
		Local trioffset:Int
		Local vertoffset:Int
		Local surface:Int
	
		For Local i:Int = 1 To bbCountSurfaces(Entity) 
			tricount = tricount + bbCountTriangles(bbGetSurface(Entity, i)) 
			vertcount = vertcount + bbCountVertices(bbGetSurface(Entity, i)) 
		Next
		
		tribank=CreateBank(tricount*3*4)
		vertbank=CreateBank(vertcount*4*4)
		
		offset=0
		trioffset=0
		vertoffset=0
		
		For Local j:Int = 1 To bbCountSurfaces(Entity) 
			surface = bbGetSurface(Entity, j) 
			For Local vert:Int = 0 To bbCountVertices(surface) - 1
				PokeFloat(VertBank, offset, xscale * bbVertexX(surface, vert)) 
				offset=offset+4
				PokeFloat(VertBank, offset, yscale * bbVertexY(surface, vert)) 
				offset=offset+4
				PokeFloat(VertBank, offset, zscale * bbVertexZ(surface, vert)) 
				offset=offset+8
			Next
			For Local tri:Int = 0 To bbCountTriangles(surface) - 1
				For Local corner:Int = 0 To 2
					PokeInt(TriBank, trioffset, bbTriangleVertex(surface, tri, corner) + vertoffset) 
					trioffset=trioffset+4
				Next
			Next
			vertoffset = vertoffset + bbCountVertices(surface) 
		Next
		
		Local trimeshdata:Int = dGeomTriMeshDataCreate() 
		
		dGeomTriMeshDataBuildSimple(trimeshdata, BankBuf(VertBank) , vertcount, BankBuf(TriBank), tricount * 3) 
		
		ODE_Geom = dCreateTriMesh(trispace, trimeshdata) 
	
	End Method


Any ideas why this doesn't work?


VIP3R(Posted 2008) [#8]
You've nearly got it but you're not taking into account the children of the animated mesh, which is most likely resulting in incorrect formatting of the vert and tri data.

I've emailed you the Blitz3D version of the CreateAnimTriMesh() function to compare or convert.

Let me know if you need any more info.