While I'm at it I'll just show you the module I'm working on; it gives what I showed you guys some context.
Rem bbdoc: Irrlicht and Newton Integration Helper End Rem Module Pub.NewtonAndIrrlicht ModuleInfo "Author: Bill Whitacre (ninjarat)" ModuleInfo "History: Added functions used in Newton Examples and converted to Irrlicht graphics." Import BRL.LinkedList Import Pub.Newton Import Irrlicht.Extended Global nMemSize,nNodeDestroyList:TList=New TList Global mat#[16] Global omega#[3] 'Excellent Euler Matrix converter functions. Not by me, and I would give credit where 'it was called for, except I honestly don't know who did this. Function GetEulerMatrix(NSceneNode:ISceneNode,NewtonMat#[]) Local Euler#[3] Euler[0]=NSceneNode.getRotation().getX()*(Pi/180#) Euler[1]=NSceneNode.getRotation().getY()*(Pi/180#) Euler[2]=NSceneNode.getRotation().getZ()*(Pi/180#) NewtonSetEulerAngle(Varptr Euler[0],Varptr NewtonMat[0]) NewtonMat[12]=NSceneNode.getPosition().getX() NewtonMat[13]=NSceneNode.getPosition().getY() NewtonMat[14]=NSceneNode.getPosition().getZ() End Function Function SetEulerMatrix(NSceneNode:ISceneNode,NewtonMat#[]) Local Euler#[3] NewtonGetEulerAngle(Varptr NewtonMat[0],Varptr Euler[0]) NSceneNode.setPosition _VECTOR3DF(NewtonMat[12],NewtonMat[13],NewtonMat[14]) NSceneNode.setRotation _VECTOR3DF(Euler[0]*(180/Pi),Euler[1]*(180/Pi),Euler[2]*(180/Pi)) End Function 'pointer edition euler matrix functions Function GetEulerMatrix2(NSceneNode:ISceneNode,NewtonMat:Float Ptr) Local Euler#[3] Euler[0]=NSceneNode.getRotation().getX()*(Pi/180) Euler[1]=NSceneNode.getRotation().getY()*(Pi/180) Euler[2]=NSceneNode.getRotation().getZ()*(Pi/180) NewtonSetEulerAngle Varptr Euler[0],Varptr newtonMat[0] Newtonmat[12]=NSceneNode.getPosition().getX() newtonMat[13]=NSceneNode.getPosition().getY() NewtonMat[14]=NSceneNode.getPosition().getZ() End Function Function SetEulerMatrix2(NSceneNode:ISceneNode,NewtonMat:Float Ptr) Local Euler#[3] NewtonGetEulerAngle Varptr NewtonMat[0],Varptr Euler[0] NSceneNode.setPosition Vector3df.createFromVals(NewtonMat[12],NewtonMat[13],NewtonMat[14]) NSceneNode.setRotation Vector3df.createfromVals(Euler[0]*(180/Pi),Euler[1]*(180/Pi),Euler[2]*(180/Pi)) End Function 'These override Newton's local memory functions with native function wrappers. Function MemAllocate:Byte Ptr(size:Int) nMemSize:+size Return MemAlloc(size) End Function Function MemRelease(memptr:Byte Ptr,size:Int) nMemSize:-size MemClear memptr,size MemFree memptr GCCollect End Function 'body event callbacks Function ApplyForceAndTorque(Body:Byte Ptr) 'gravity callback Local mass#,Ixx#,Iyy#,Izz# NewtonBodyGetMassMatrix(body,Varptr mass, Varptr Ixx, Varptr Iyy, Varptr Izz) Local force#[]=[0#,Iyy*mass*-550#,0#] NewtonBodySetForce body,Varptr force[0] End Function Function NSetTransform(body:Byte Ptr,NewtonMat# Ptr) 'the N prefix is because the 'set transform function is already used 'by this language for something else. Local node:ISceneNode node=ISceneNode.CreateFromHandle(Int(newtonBodyGetUserData(body)),False) newtonBodyGetMatrix body,Varptr NewtonMat[0] SetEulerMatrix2 node,Varptr NewtonMat[0] End Function Function BodyLeftWorld(body:Byte Ptr) 'What do we do if we've gone off the edge of the 'world? Answer: We get dropped back in. Local node:ISceneNode=ISceneNode.CreateFromHandle(Int(newtonBodyGetUserData(body)),False) node.setPosition _VECTOR3DF(0,0,0) GetEulerMatrix node,mat NewtonBodySetMatrix body,Varptr mat[0] End Function Function BodyDestructor(body:Byte Ptr) 'if a physical body is destroyed, we add it's 'graphics node to the destructor list. Local NodeHandle:Int NodeHandle=Int(newtonBodyGetUserData(body)) nNodeDestroyList.AddLast NodeHandle End Function 'Destructor for the released scene nodes. Call every time any node(s) is destroyed. Function NodeDestructor() If nNodeDestroyList.Count()>0 Then Local tempNode:ISceneNode Local objarr:Object[]=ListToArray(nNodeDestroyList) Local intarr[objarr.length] For j=0 To objarr.length-1 intarr[j]=objarr[j] Next For del=EachIn intarr tempNode=ISceneNode.CreateFromHandle(del,False) tempNode.remove Next nNodeDestroyList=New TList;tempNode=Null;objarr=Null;intarr=Null GCCollect End If End Function 'this is where the trouble is. 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 mb_vertices:Array_S3DVertex=mb.getVertices() 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] vArray[0]=mb_vertices.elementAt(v1i).getPos().getX() vArray[1]=mb_vertices.elementAt(v1i).getPos().getY() vArray[2]=mb_vertices.elementAt(v1i).getPos().getZ() vArray[3]=mb_vertices.elementAt(v2i).getPos().getX() vArray[4]=mb_vertices.elementAt(v2i).getPos().getY() vArray[5]=mb_vertices.elementAt(v2i).getPos().getZ() vArray[6]=mb_vertices.elementAt(v3i).getPos().getX() vArray[7]=mb_vertices.elementAt(v3i).getPos().getY() vArray[8]=mb_vertices.elementAt(v3i).getPos().getZ() NewtonTreeCollisionAddFace(g_newtonmap,3,Varptr vArray[0],12,1) 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 'set the newton world size based on the bsp size Local boxP0#[3] Local boxP1#[3] NewtonBodyGetMatrix g_newtonmapbody,Varptr mat[0] NewtonCollisionCalculateAABB g_newtonmap,Varptr mat[0],Varptr boxP0[0],Varptr boxP1[0] 'pad the box boxP0[0]:-100 boxP1[0]:+100 boxP0[1]:-100 boxP1[1]:+100 boxP0[2]:-100 boxP1[2]:+100 NewtonSetWorldSize nWorld,Varptr boxP0[0],Varptr boxP1[0] 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