here is the example using the sydney model with the AnimatedMeshToCollisionTree function. you should be able to change the node at the top right before the initScene() function to test out other meshes. i did comment out the set the world size part of the AnimatedMeshToCollisionTree function. please note that different vertex types will cause problems with the function. i will see if i can whip up a more compatible function sometime tomorrow.
SuperStrict Framework PUB.Newton Import Irrlicht.Core Import BRL.PNGLoader StartNewton() Local device:IrrlichtDevice = IrrlichtDevice.create(EDT_OPENGL , Dimension2di.create(640 , 480) , 16 , False , False , False , Null) Global driver:IVideoDriver = device.getVideoDriver() Global smgr:ISceneManager = device.getSceneManager() 'Local Tex:ITexture = driver.getTexture("brlLogo.png") Local camera:ICameraSceneNode = smgr.addCameraSceneNodeFPS() camera.setPosition(Vector3df.createFromVals(-19,-49,-30)) camera.setRotation(Vector3df.createFromVals(0 , 0 , 0)) Local light:ILightSceneNode = smgr.addLightSceneNode( Null , Vector3df.createfromVals(-20 , -40 , -30)) Global nWorld:Byte Ptr = NewtonCreate(PhysicsAlloc , PhysicsFree) ' ------------------------------------ ' new stuff ' ------------------------------------ ' ------------------------------------ ' TODO: edit this section for different meshes/nodes ' ------------------------------------ Global mesh:IAnimatedMesh=smgr.getMesh("sydney.md2") Global node:IAnimatedMeshSceneNode=smgr.addAnimatedMeshSceneNode(mesh) node.setAnimationSpeed(0) node.setPosition(_VECTOR3DF(-25,-40,0)) ' ------------------------------------ ' setup node in newton ' ------------------------------------ Local meshcollision:Byte Ptr = NewtonCreateTreeCollision(nWorld, Null) Local meshBody:Byte Ptr = AnimatedMeshToNewtonCollisionTree(nWorld, mesh, meshcollision) Local MeshMat:Float[16] NewtonBodySetUserData(meshBody,Byte Ptr(node.handle)) '// set a destrutor For this rigid body NewtonBodySetDestructorCallback(meshBody, PhysicsBodyDestructor) '// set the transformation For this rigid body GetMatrix(node ,Varptr MeshMat[0]) NewtonBodySetMatrix(meshBody,Varptr MeshMat[0]) newtonReleaseCollision(nWorld , meshcollision) ' ------------------------------------ initScene() ' ------------------------------------ Local Timer:Int = MilliSecs() While (device.run()) Timer:+MilliSecs() NewtonUpdate(nWorld , 0.001) Timer = MilliSecs() 'NewtonBodyGetMatrix(box , Varptr Mat[0]) 'SetMatrix(node , Mat) driver.beginScene(True , True , SColor.createFromVals(0,200 , 200 , 200)) smgr.drawAll() driver.endScene() Wend StopNewton() Rem '''''''''''''''''''''''''''''''''''///////////////////////////////////// The Convertion Matrix Functions GetMatrix is the function to get the matrix from the Irrlecht SceneNode And pass it to an array to be used by Newton. SetMatrix is the function to pass the Matrix from Newton to the Irrlicht SceneNode EndRem Function GetMatrix(NSceneNode:ISceneNode , NewtonMat:Float Ptr) Local Euler:Float[3] Euler[0] = NSceneNode.getRotation().getX() * (Pi / 180.0) Euler[1] = NSceneNode.getRotation().getY() * (Pi / 180.0) Euler[2] = NSceneNode.getRotation().getZ() * (Pi / 180.0) 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 SetMatrix(NSceneNode:ISceneNode , NewtonMat:Float Ptr) Local Euler:Float[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 Rem THE FUNCTIONS FROM TUTORIAL 2 End Rem Function PhysicsAlloc:Byte Ptr(sizeInBytes:Int) Return MemAlloc(sizeInBytes) End Function Function PhysicsFree( memptr:Byte Ptr, sizeInBytes:Int) MemFree (memptr) End Function ' set the tranformation of a rigid body Function PhysicsApplyForceAndTorque (Body:Byte Ptr) Local mass:Float Local Ixx:Float Local Iyy:Float Local Izz:Float NewtonBodyGetMassMatrix (body,Varptr mass, Varptr Ixx, Varptr Iyy, Varptr Izz); 'Local force:Float[] = [0.0, -mass * 9.8 , 0.0] ' GG: messed with the mass multiplier to make it look like the tutorial. have no idea why this is different. Local force:Float[] = [0.0, -mass * 410 , 0.0] NewtonBodySetForce (body, Varptr force[0]) End Function Function PhysicsSetTransform (body:Byte Ptr, NewtonMat:Float Ptr) Local primitive:ISceneNode '// get the graphic Object form the rigid body ' GG: changed to recreate the scenenode based on the C++ object handle primitive = ISceneNode.CreateFromHandle(Int(newtonBodyGetUserData(body)),False) '// set the transformation matrix For this rigid body newtonBodyGetMatrix(body , Varptr NewtonMat[0]) SetMatrix(Primitive , Varptr NewtonMat[0]) End Function Function PhysicsBodyDestructor(body:Byte Ptr) Local primitive:ISceneNode '// get the graphic Object form the rigid body ' GG: changed to recreate the scenenode based on the C++ object handle primitive = ISceneNode.CreateFromHandle(Int(newtonBodyGetUserData(body)),False) '// destroy the graphic Object primitive.remove() End Function Function CleanUp () '// destroy the Newton world NewtonDestroy (nWorld); End Function Function InitScene() Global Texture:ITexture = Driver.getTexture("doc/brllogo.png") Global box:ISceneNode Global IFloor:ISceneNode Global boxBody:Byte Ptr Global floorBody:Byte Ptr Global collision:Byte Ptr Global Mat:Float[16] '// create the newton world '// set the linear solver model For faster speed NewtonSetSolverModel(nWorld, 8) '// set the adpative friction model For faster speed NewtonSetFrictionModel(nWorld, 1) '// Set the termination Function 'atexit(CleanUp); '//// I Haven't Found The Apropriaty Function for Irrlicht ' ------------------------------------ ' floor ' ------------------------------------ '// create the the Floor graphic objects IFloor = smgr.addCubeSceneNode(100 ) 'IFloor.setMaterialFlag(EMF_LIGHTING,True) IFloor.setMaterialTexture(0 , texture) IFloor.setPosition(Vector3df.createFromVals(0,-100 , 0)) collision = newtonCreateBox(nWorld , 100.0 , 100.0 , 100.0 , Null) FloorBody = newtonCreateBody(nWorld , collision) '// set the transformation For this rigid body GetMatrix(IFloor ,Varptr Mat[0]) NewtonBodySetMatrix(floorBody,Varptr Mat[0]) '// save the pointer To the graphic Object with the body. ' GG: changed to store the scenenode C++ object handle instead of a reference to the BMAX object with falls out of scope NewtonBodySetUserData(floorBody,Byte Ptr(IFloor.handle)) '// set a destrutor For this rigid body NewtonBodySetDestructorCallback(floorBody, PhysicsBodyDestructor); ' ------------------------------------ ' ------------------------------------ ' boxes ' ------------------------------------ '// set the initial size 'size = dVector(0.5f, 0.5f, 0.5f); Not really nesesery(I think so) '// create the collision newtonReleaseCollision(nWorld , collision) collision = NewtonCreateBox(nWorld, 0.5 , 0.5, 0.5 , Null) Local location:Float[] = [0.0 , 0.0 , 0.0] location[0] = -10.0 'FOR X For Local k:Int = 0 To 9 location[2] = 0.0 'For Z For Local J:Int = 0 To 9 location[1] = 2.0 'For Y For Local i:Int = 0 To 9 box = smgr.addCubeSceneNode(0.5) box.setMaterialFlag(EMF_LIGHTING,True) box.SetMaterialTexture(0 , Texture) box.setPosition(Vector3df.createFromVals(location[0] ,location[1] , location[2])) boxBody = newtonCreateBody(nWorld , collision) ' GG: changed to store the scenenode C++ object handle instead of a reference to the BMAX object with falls out of scope newtonBodySetUserData(boxBody ,Byte Ptr(box.handle)) '// set a destrutor For this rigid body NewtonBodySetDestructorCallback(boxBody, PhysicsBodyDestructor) '// set the tranform call back Function NewtonBodySetTransformCallback(boxBody, PhysicsSetTransform) '// set the force And torque call back funtion NewtonBodySetForceAndTorqueCallback(boxBody, PhysicsApplyForceAndTorque) '// set the mass matrix '//NewtonBodySetMassMatrix (boxBody, 1.0f, 1.0f / 6.0f, 1.0f / 6.0f, 1.0f / 6.0f); NewtonBodySetMassMatrix(boxBody, 1.0, 1.0, 1.0, 1.0) '// set the matrix For tboth the rigid nody And the graphic body GetMatrix(box , Varptr Mat[0]) NewtonBodySetMatrix(boxBody,Varptr Mat[0]) PhysicsSetTransform(boxBody, Varptr Mat[0]) Location[1] :+ 0.5 * 2.0 Next Location[2] :- 0.5 * 4.0 Next location[0] :- 0.5 * 4.0 Next '// Release the collsion geometry when Not need it NewtonReleaseCollision(nWorld, collision) ' ------------------------------------ EndFunction 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, 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