Irrlicht and Newton

BlitzMax Forums/BlitzMax Programming/Irrlicht and Newton

this one should be compatible with any mesh type:
Function AnimatedMeshToNewtonCollisionTree:Byte Ptr(nWorld:Byte Ptr,g_map:IAnimatedMesh,g_newtonMap:Byte Ptr)
	NewtonTreeCollisionBeginBuild(g_newtonmap)
	Local cMeshBuffer:Int,j:Int
	Local v1i:Int,v2i:Int,v3i:Int
	Local mb:IMeshBuffer
	
	Local vArray:Float[9]	'vertex array (3*3 floats)
	
	Local tmpCount:Int = 0
	
	For cMeshBuffer=0 To g_map.getMesh(0).getMeshBufferCount() - 1
		
		mb = g_map.getMesh(0).getMeshBuffer(cMeshBuffer)

		Local vertType:Int=mb.getVertexType()
		
		Local arr_standardVerts:Array_S3DVertex=Null
		Local arr_2TCoordVerts:Array_S3DVertex2TCoords=Null
		Local arr_TangentVerts:Array_S3DVertexTangents=Null

		If vertType=EVT_STANDARD
			arr_standardVerts=mb.getVertices()
		Else If vertType=EVT_2TCOORDS
			arr_2TCoordVerts=mb.getVertices2TCoords()
		Else If vertType=EVT_TANGENTS
			arr_TangentVerts=mb.getVerticesTangents()
		EndIf
		
		Local mb_indices:Array_u16=mb.getIndices()
		
		'add each triangle from the mesh
		For j=0 To mb.getIndexCount() - 1 Step 3
			v1i=mb_indices.elementAt(j)[0]
			v2i=mb_indices.elementAt(j+1)[0]
			v3i=mb_indices.elementAt(j+2)[0]

			Local v1:Vertex=Null
			Local v2:Vertex=Null
			Local v3:Vertex=Null
			
			If vertType=EVT_STANDARD
				v1=Vertex(arr_standardVerts.elementAt(v1i))
				v2=Vertex(arr_standardVerts.elementAt(v2i))
				v3=Vertex(arr_standardVerts.elementAt(v3i))
			Else If vertType=EVT_2TCOORDS
				v1=Vertex(arr_2TCoordVerts.elementAt(v1i))
				v2=Vertex(arr_2TCoordVerts.elementAt(v2i))
				v3=Vertex(arr_2TCoordVerts.elementAt(v3i))
			Else If vertType=EVT_TANGENTS
				v1=Vertex(arr_tangentVerts.elementAt(v1i))
				v2=Vertex(arr_tangentVerts.elementAt(v2i))
				v3=Vertex(arr_tangentVerts.elementAt(v3i))
			EndIf
			
			vArray[0]=v1.getPos().getX()
			vArray[1]=v1.getPos().getY()
			vArray[2]=v1.getPos().getZ()
			vArray[3]=v2.getPos().getX()
			vArray[4]=v2.getPos().getY()
			vArray[5]=v2.getPos().getZ()
			vArray[6]=v3.getPos().getX()
			vArray[7]=v3.getPos().getY()
			vArray[8]=v3.getPos().getZ()
			
			NewtonTreeCollisionAddFace(g_newtonmap, 3,Varptr vArray[0], 12, j)
		Next
		
	Next
	NewtonTreeCollisionEndBuild(g_newtonmap,0)
	Local g_newtonmapbody:Byte Ptr=NewtonCreateBody(nWorld,g_newtonmap)
	
Rem
After loading the bsp mesh in irrlicht we must create a newton collision tree consisting of all the triangles
in the bsp mesh. To do this we loop through the indices list And add vertices 3 at a time into newton. I should
mention here that I was lazy when writing this And just used a straight cast To video::S3DVertex2TCoords - this is because
bsp meshes have lightmap textures on them. If you are using a mesh with only 1 set of texture co-ordinates (like
a landscape Or .x level) Then use (video::S3DVertex).
Newton requires 2 pointers For every Object - a NewtonBody* For the rigid body, And a NewtonCollision* that
describes the objects geometry. After creating the tree collision geometry, we create a body For the map And
assign it To the collision. Bodys which have a tree collision For their geometry are static And their mass
will be ignored by newton - so you can only use meshes For your scenery!
End Rem
	Rem
	'set the newton world size based on the bsp size
	Local boxP0:Float[3] 
	Local boxP1:Float[3] 
	Local matrix:Float[16] 
	NewtonBodyGetMatrix g_newtonmapbody,Varptr matrix[0]
	NewtonCollisionCalculateAABB g_newtonmap,Varptr matrix[0],Varptr boxP0[0],Varptr boxP1[0]
	'pad the box
	boxP0[0]:-10
	boxP1[0]:+10
	boxP0[1]:-10
	boxP1[1]:+10
	boxP0[2]:-10
	boxP1[2]:+10
	NewtonSetWorldSize nWorld,Varptr boxP0[0],Varptr boxP1[0]
	EndRem
Rem
After loading the map, we can calculate the bounding box surrounding it And set the newton world size To
match. Newton should automatically disable anything which falls out of the map this way.
End Rem
	Return g_newtonmapbody	
End Function