Page 1 of 1

Node not matching Newton collision object ( FIXED(kind of) )

Posted: Mon Aug 07, 2006 12:30 am
by Cartaa
Hi, I found this code here ]http://irrlicht.sourceforge.net/phpBB2/ ... whatsoever and I thought i'd try it out as I assumed it was "working" because i was having trouble with all other samples etc for Newton but the problem I have is that the mesh is way up in the air, but the debugging shape for Newton is on the ground. The translation, force and torque callbacks are never being called. So I was wondering if anyone had experienced problems with this and if so how they fixed it.

Thanks in advance.

Code: Select all

#include <Irrlicht.h> 
#include "newton.h" 
#include <memory.h> 


static NewtonWorld* nWorld; 

using namespace irr; 
using namespace core; 
using namespace scene; 
using namespace video; 
using namespace io; 
using namespace gui; 



#pragma comment(lib, "Irrlicht.lib") 
#pragma comment(lib, "Newton.lib") 



IrrlichtDevice *device = NULL; 
IVideoDriver* driver = NULL; 
ISceneManager* smgr = NULL; 
float NewtonToIrr = 32.0f; 
float IrrToNewton = 1/NewtonToIrr; 
IGUIStaticText* pText = NULL; 
bool debugOn = true; 


class MyEventReceiver : public  IEventReceiver 
{ 
public: 

/////////////////////////// 

   virtual bool OnEvent(SEvent event) 
   { 


      
       if (event.EventType == irr::EET_KEY_INPUT_EVENT&& 
         event.KeyInput.PressedDown) 
      { 
          
         switch(event.KeyInput.Key) 
         { 
            case KEY_ESCAPE: 
            device->closeDevice(); 
            break; 

            case KEY_KEY_D: 
            debugOn = !debugOn; 
            break; 

         } 



      }// pressdown 

      return 0; 

   } 



}; 


MyEventReceiver receiver; 



// allocation of memory from Newton 
void* _cdecl 
NewtonAlloc (int sizeInBytes) 
{ 
   return new char[sizeInBytes]; 
} 

// destruction of memory from Newton 
void _cdecl 
NewtonFree (void *ptr, int sizeInBytes) 
{ 
   char *tmp; 
   tmp = (char*) ptr; 
   delete[] tmp; 
} 



/* 
Function:   AddGlobalForce (vector3df Force, vector3df Point, matrix4 BodyMatrix,const NewtonBody* body) 

Returns:   Nothing 
Parameters:   vector3df Force -- the force you want to apply 
         vector3df Point -- global space location to apply the force 
         matrix4 BodyMatrix -- Newton Matrix describing object 
         NewtonBody* body   -- the body in question 

Purpose:   Add a force to an object displaced from the center of mass 

Note:      Because of the displacement, you will get a spin or torque, and 
         you have to tell Newton what that spin is. Thats what this function 
         does. 

*/ 


void AddGlobalForce (vector3df Force, vector3df Point, matrix4 BodyMatrix,const NewtonBody* body) 
{ 
   vector3df R = Point - BodyMatrix.getTranslation(); 
    vector3df Torque = R.crossProduct(Force); 
    NewtonBodyAddForce (body,&Force.X); 
    NewtonBodyAddTorque (body,&Torque.X); 
} 

/* 
Function:   AddLocalForce (vector3df Force, vector3df LocalPoint, matrix4 BodyMatrix,const NewtonBody* body) 

Returns:   Nothing 
Parameters:   vector3df Force -- the force you want to apply, in local space 
         vector3df Point -- local space location to apply the force 
         matrix4 BodyMatrix -- Newton Matrix describing object 
         NewtonBody* body   -- the body in question 

Purpose:   Takes a local force and displacement and translates it into a global 
         force request 

Note:      Because of the displacement, you will get a spin or torque, and 
         you have to tell Newton what that spin is. Thats what this function 
         does.Called only from within ApplyTorqueandForceHandler 

*/ 
void AddLocalForce (vector3df LocalForce, vector3df LocalPoint, matrix4 BodyMatrix,const NewtonBody* body) 
{ 
     vector3df GlobalForce,GlobalPoint; 
     BodyMatrix.transformVect(LocalForce,GlobalForce); 
    BodyMatrix.transformVect(LocalPoint,GlobalPoint); 
   if (LocalForce.X == 0.0f && LocalForce.Y == 0.0f && LocalForce.Z == 0.0f) 
   { 

   } 
   else 
   { 
      AddGlobalForce (GlobalForce, GlobalPoint,BodyMatrix,body); 
       
   } 
} 




void _cdecl NewtonDebugCollision(const NewtonBody* body, int vertexCount, const float* FaceArray, int faceId) 
{ 
   core::vector3df p0 (FaceArray[0], FaceArray[1], FaceArray[2] ); 
    
   const video::SColor c0(255,55,255,0); 

   for (int i = 2; i < vertexCount; i ++) 
   { 
      core::vector3df p1( FaceArray[(i-1) * 3 + 0], FaceArray[(i-1) * 3 + 1], FaceArray[(i-1) * 3 + 2] ); 
      core::vector3df p2( FaceArray[i * 3 + 0], FaceArray[i * 3 + 1], FaceArray[i * 3 + 2] ); 
    
      core::triangle3df t; 
      t.set(p1*NewtonToIrr, 
           p2*NewtonToIrr, 
           p0*NewtonToIrr); 
       
       driver->draw3DTriangle(t, c0); 
   } 
} 



void _cdecl NewtonDebugBody (const NewtonBody* body) 
{ 
  

   matrix4 mat; 
   SMaterial material; 

   material.Texture1 = 0; 
   material.Lighting = false; 
    driver->setTransform(video::ETS_WORLD, mat); 
    driver->setMaterial(material); 
   NewtonBodyForEachPolygonDo(body,NewtonDebugCollision); 



} 




static void setTransform(const NewtonBody* body, const float* matrix) 
{ 
    //get graphic object 
    ISceneNode* node = (ISceneNode*) NewtonBodyGetUserData(body); 

    //copy matrix to an irrlicht matrix 
    matrix4 mat; 
    memcpy(mat.M, matrix, sizeof(float)*16); 

    //set transformation 
    node->setPosition(mat.getTranslation() * NewtonToIrr); 
   node->setRotation(mat.getRotationDegrees()); 
} 

static void setForceAndTorque(const NewtonBody* body) 
{ 
    float mass; 
    float Ixx; 
    float Iyy; 
    float Izz; 
   matrix4 mat; 
   mat.makeIdentity(); 
   NewtonBodyGetMatrix(body,mat.M); 

    NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz); 

    vector3df force(0, -mass* 9.8f, 0.0); 
    vector3df torque(0, 00.0f, 0); 
   vector3df mforce(0,0,5); 
   vector3df displace(2,0,0); 
    NewtonBodyAddForce(body, &force.X); 
    AddLocalForce(mforce,displace,mat,body); 
} 


int main() 
{ 
device = createDevice(EDT_DIRECT3D9, 
                            dimension2d<s32>(640,480), 32,false,false,false,&receiver); 

driver = device->getVideoDriver(); 
smgr = device->getSceneManager(); 
IGUIEnvironment* env = device->getGUIEnvironment(); 
    
    pText = env->addStaticText(L"fred",core::rect<int>(20,20,440,200), false); 
   pText->setOverrideColor(video::SColor(255,240,240,235)); 
   pText->setOverrideFont( 
   env->getFont("midfont.bmp")); 

    
   //1. Create Newtonworld 
   nWorld =     NewtonCreate(NewtonAlloc, NewtonFree); 

   // Set up default material properties for newton 
   int i = NewtonMaterialGetDefaultGroupID(nWorld); 
   NewtonMaterialSetDefaultFriction   (nWorld, i, i, 0.8f, 0.4f); 
   NewtonMaterialSetDefaultElasticity (nWorld, i, i, 0.3f); 
   NewtonMaterialSetDefaultSoftness   (nWorld, i, i, 0.05f); 
   NewtonMaterialSetCollisionCallback (nWorld, i, i, NULL, NULL, NULL, NULL); 
    

    
   //MESH 
   //ISceneNode* node = smgr->addTestSceneNode(); 
    core::aabbox3d<f32> sbox; 
   vector3df ssize; 
   float sss = 2.0f; 
   IAnimatedMesh* mesh = smgr->getMesh("sydney.md2"); 
   IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh ); 
   if (node) 
   { 
      node->setMaterialFlag(EMF_LIGHTING, false); 
      node->setFrameLoop(320, 368); 
      node->setScale(vector3df(sss,sss,sss)); 
      node->setMaterialTexture( 0, driver->getTexture("sydney.bmp") ); 
      node->setPosition(core::vector3df(0,530,30)); 
      node->setAnimationSpeed(50); 

   //size the box in Newton units 
    sbox = mesh->getMesh(0)->getBoundingBox(); 
   ssize = sbox.getExtent()*IrrToNewton*sss; 
    
    
   } 
    
   //2.a Define Newtoncollision 
   NewtonCollision* myShape = NewtonCreateSphere(nWorld, ssize.X/2, ssize.Y/2, ssize.Z/2, NULL); 
    
   //b. Create NewtonBody 
   NewtonBody* myBody = NewtonCreateBody(nWorld, myShape); 
    
   //c. Set Body Properties 
   NewtonBodySetMassMatrix(myBody, 1.0f, 1.0f, 1.0f, 1.0f); 
   NewtonBodySetForceAndTorqueCallback(myBody, setForceAndTorque); 
   NewtonBodySetUserData(myBody, (void*) node); //with this you are sending your graphic pointer to Newton. 
   NewtonBodySetTransformCallback(myBody, setTransform); 
   NewtonBodySetLinearDamping(myBody,1); 
   vector3df rd(1,1,1); 
   NewtonBodySetAngularDamping(myBody,&rd.X); 

   NewtonJoint* upVector; 
   vector3df upDirection (0.0f, 1.0f, 0.0f); 
   upVector = NewtonConstraintCreateUpVector (nWorld, &upDirection.X, myBody); 
    


   ICameraSceneNode*  camera = smgr->addCameraSceneNodeFPS(0, 200.0f, 250.0f); 
   camera->setPosition(vector3df(0,10,-120)); 
   camera->setTarget(vector3df(0,0,0)); 
                
   //Level 
   device->getFileSystem()->addZipFileArchive 
      ("map-20kdm2.pk3"); 
   scene::IAnimatedMesh* q3levelmesh = smgr->getMesh("20kdm2.bsp"); 
   scene::ISceneNode* q3node = 0; 
    
     if (q3levelmesh) 
      q3node = smgr->addOctTreeSceneNode(q3levelmesh->getMesh(0)); 
   q3node->setPosition(core::vector3df(-1370,-130,-1400)); 
    
     //LevelNewtonCollision 
     NewtonCollision* nmapcollision = NewtonCreateTreeCollision(nWorld, NULL); 
     NewtonTreeCollisionBeginBuild(nmapcollision); 
     int cMeshBuffer, j; 
     int v1i, v2i, v3i; 
     IMeshBuffer *mb; 
     float vArray[9]; // vertex array (3*3 floats) 
     int tmpCount = 0; 
    






   core::aabbox3d<f32> box; 
   //size the box in Newton units 
    box = q3levelmesh->getMesh(0)->getBoundingBox(); 
   vector3df size = box.getExtent()*IrrToNewton; 




     for (cMeshBuffer=0; cMeshBuffer<q3levelmesh->getMesh(0)->getMeshBufferCount(); cMeshBuffer++) 
   {      
      mb = q3levelmesh->getMesh(0)->getMeshBuffer(cMeshBuffer); 
      S3DVertex2TCoords* mb_vertices = (S3DVertex2TCoords*)mb->getVertices(); 
      u16* mb_indices  = mb->getIndices(); 
      // add each triangle from the mesh 
      for (j=0; j<mb->getIndexCount(); j+=3) 
      { 
          
   //   printf("buff %d count %d\n",cMeshBuffer,j); 
        
       v1i = mb_indices[j]; 
         v2i = mb_indices[j+1]; 
         v3i = mb_indices[j+2]; 
       vArray[0] = mb_vertices[v1i].Pos.X* IrrToNewton; 
         vArray[1] = mb_vertices[v1i].Pos.Y* IrrToNewton; 
         vArray[2] = mb_vertices[v1i].Pos.Z* IrrToNewton; 
         vArray[3] = mb_vertices[v2i].Pos.X* IrrToNewton; 
         vArray[4] = mb_vertices[v2i].Pos.Y* IrrToNewton; 
         vArray[5] = mb_vertices[v2i].Pos.Z* IrrToNewton; 
         vArray[6] = mb_vertices[v3i].Pos.X* IrrToNewton; 
         vArray[7] = mb_vertices[v3i].Pos.Y* IrrToNewton; 
         vArray[8] = mb_vertices[v3i].Pos.Z* IrrToNewton; 
  
          NewtonTreeCollisionAddFace(nmapcollision, 3, &vArray[0], 12, 1); 
     } 
   } 
    
      NewtonTreeCollisionEndBuild(nmapcollision, 0); 
      NewtonBody* nmapbody = NewtonCreateBody(nWorld, nmapcollision); 
      
      // set the newton world size based on the bsp size 
      float boxP0[3]; 
      float boxP1[3]; 
      float matrix[4][4]; 
     matrix4 mmm; 
     mmm.setTranslation(vector3df(-1370,-130,-1400)*IrrToNewton); 

     NewtonBodySetMatrix(nmapbody,&mmm.M[0]); 
      NewtonCollisionCalculateAABB (nmapcollision, &matrix[0][0],  &boxP0[0], &boxP1[0]); 
      NewtonSetWorldSize (nWorld, (float*)boxP0, (float*)boxP1); 
     int rate; 
     wchar_t tmp[1024]; 
   while(device->run()) 
   { 
      NewtonUpdate(nWorld, 0.01f); 
      //camera->setTarget(node->getPosition()); 
      
      driver->beginScene(true, true, video::SColor(0,0,0,0)); 

      if (debugOn) 
      { 
           NewtonWorldForEachBodyDo (nWorld, NewtonDebugBody); 

      } 
         rate = driver->getFPS(); 

         vector3df cPos = camera->getAbsolutePosition(); 
         swprintf(tmp, 1024, L"camera[%2.1f,%2.1f,%2.1f] fps %d\nD toggle Debug",cPos.X,cPos.Y,cPos.Z,rate); 
         pText->setText(tmp); 
      smgr->drawAll(); 
     env->drawAll(); 
      driver->endScene(); 
   } 
   device->drop(); 
   // 4. Destroy World 
   NewtonDestroy(nWorld); 
   return 0; 
} 
[/url]

Oh and its the latest version of Irrlicht and Newton that i'm using (1.0 and 1.53 respectively)

Posted: Mon Aug 07, 2006 4:16 pm
by Cartaa
Hey, me again, just incase anyone did a search for this and came across this topic I think i've traced the problem to

Code: Select all

      float boxP0[3];
      float boxP1[3];
      float matrix[4][4];
     matrix4 mmm;
     mmm.setTranslation(vector3df(-1370,-130,-1400)*IrrToNewton);

     NewtonBodySetMatrix(nmapbody,&mmm.M[0]);
      NewtonCollisionCalculateAABB (nmapcollision, &matrix[0][0],  &boxP0[0], &boxP1[0]);
      NewtonSetWorldSize (nWorld, (float*)boxP0, (float*)boxP1); 
it seems when Newton calculates the AABB collision it does it wrong or something as when i checked the values it was something like -3.4e9 to -3.5e10 which seems very wrong, so what i did was just changed the NewtonSetWorldSize to set it at a size of like -1000 to 1000 and it all seems to be working fine.