Newton Callbacks don´t work

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Newton Callbacks don´t work

Postby RobbRob » Sun Jan 03, 2010 5:24 pm

Hello,

my name is Robert and I am trying to implement Newton Engine into my Irrlicht frame work.
There is one point which causes me a lot of headaches; the callback function will not be accepted by my CodeBlocks compiler, I always get the same error:
Code: Select all
[b]
GameCPP\newtonIrr.cpp(133) : error C2664: 'NewtonBodySetForceAndTorqueCallback' : cannot convert parameter 2 from 'void (const NewtonBody *)' to 'NewtonApplyForceAndTorque'

GameCPP\newtonIrr.cpp(134) : error C2664: 'NewtonBodySetTransformCallback' : cannot convert parameter 2 from 'void (const NewtonBody *,const float *)' to 'NewtonSetTransform'
[/b]


My cpp code is following
Code: Select all
#include <newtonIrr.h>

CMyNewton::CMyNewton() : IrrToNewton(1.0f / NewtonToIrr) , NewtonToIrr(32.0f)
{
    Init();
}

CMyNewton::~CMyNewton()
{
    Clean();
}

float CMyNewton::getIrrToNewton()
{
    return IrrToNewton;
}

float CMyNewton::getNewtonToIrr()
{
    return NewtonToIrr;
}

//---------------------------------------------------------------------------------


void _cdecl CMyNewton::setMeshTransformEvent_explobox(const NewtonBody* body, const float* matrix)

{
CMyNewton* controller=(CMyNewton*)NewtonBodyGetUserData(body);
controller->setMeshTransformEventExploboxHandler(body,matrix);
}


void CMyNewton::setMeshTransformEventExploboxHandler(const NewtonBody* body, const float* matrix)
{
    matrix4 mat;
    memcpy(mat.pointer(), matrix, sizeof(float)*16);
    IAnimatedMeshSceneNode *tmp = (IAnimatedMeshSceneNode*)NewtonBodyGetUserData(body);
   if (tmp)
   {
      tmp->setPosition(mat.getTranslation());
      tmp->setRotation(mat.getRotationDegrees());
   }

}
void _cdecl CMyNewton::applyForceAndTorqueEvent_explobox(const NewtonBody*body)
{
    CMyNewton* controller=(CMyNewton*)NewtonBodyGetUserData(body);
    controller->applyForceAndTorqueEventExploboxHandler(body);
}

void CMyNewton::applyForceAndTorqueEventExploboxHandler(const NewtonBody*body)
{
   float timestep, timestepInv;
    float mass;
    float Ixx;
    float Iyy;
    float Izz;

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

    timestepInv = 1.0f/timestep;
    vector3df force(0.0f, NEWTON_GRAVITY *mass, 0.0f);
    vector3df torque(0.0f, 0.0f, 0.0f);
    NewtonBodyAddForce(body, &force.X);
    NewtonBodyAddTorque(body, &torque.X);
}


//--------------------------------------------------------------------------------------------

void CMyNewton::createEarthBody(IAnimatedMeshSceneNode* node)
{

    aabbox3d<f32> box = node->getBoundingBox();
   vector3df size = box.getExtent() * IrrToNewton;
   NewtonCollision* collision = NewtonCreateBox(nWorld, size.X, size.Y, size.Z, NULL,NULL);
   static NewtonBody*  node_Body = NewtonCreateBody(nWorld, collision);
   NewtonReleaseCollision (nWorld, collision);

   NewtonBodySetMassMatrix (node_Body, 1.0f, 5.0f, 1.0f, 5.0f);

   //NewtonBodySetUserData(node_Body, node);
   //NewtonBodySetDestructorCallback (node_Body, DestroyPistonEvent);

   core::matrix4 matrix = node->getRelativeTransformation();
   core::vector3df origin = matrix.getTranslation() * IrrToNewton;
   matrix.setTranslation (origin);
   NewtonBodySetMatrix(node_Body, matrix.pointer());

   float omega[] = {0.0f, 10.0f, 0.0f};
   NewtonBodySetOmega (node_Body, &omega[0]);
   earthNode = node;
   earthBody = node_Body;
}


void CMyNewton::createExploBox(IAnimatedMeshSceneNode* exploBox_node,IAnimatedMesh* mesh)
{

    aabbox3d<f32>explobox;
    explobox=mesh->getMesh(0)->getBoundingBox();
    vector3df explobox_size;
    vector3df explobox_edges[8];
    NewtonCollision *explobox_collision;
    matrix4 explobox_matrix;
    explobox_matrix.setTranslation(exploBox_node->getPosition()*IrrToNewton);
    explobox_size = explobox.getExtent()*IrrToNewton;

    //----------------------------------------------------------------------

    explobox_collision = NewtonCreateBox(nWorld,explobox_size.X*20,explobox_size.Y*20, explobox_size.Z*20, NULL, NULL);
    NewtonBody* explobox_body=NewtonCreateBody(nWorld, explobox_collision);
    NewtonBodySetUserData(explobox_body, this);
    NewtonReleaseCollision(nWorld, explobox_collision);

    float explobox_mass = 1.0f;
    float Ixx=0.7*explobox_mass*(explobox_size.Y*explobox_size.Y + explobox_size.Z*explobox_size.Z)*12.0f;
    float Iyy=0.7*explobox_mass*(explobox_size.X*explobox_size.X + explobox_size.Z*explobox_size.Z)*12.0f;
    float Izz=0.7*explobox_mass*(explobox_size.Y*explobox_size.Y + explobox_size.X*explobox_size.X)*12.0f;

    NewtonBodySetMassMatrix(explobox_body, explobox_mass, Ixx, Iyy, Izz);
    NewtonBodySetMatrix(explobox_body, explobox_matrix.pointer());
    setMeshTransformEvent_explobox(explobox_body, explobox_matrix.pointer());

    NewtonReleaseCollision(nWorld, explobox_collision);

    //NewtonBodySetFreezeTreshold(explobox_body, 1.0, 1.0, 1);

        //callback function


    NewtonBodySetForceAndTorqueCallback(explobox_body, applyForceAndTorqueEvent_explobox);
    NewtonBodySetTransformCallback(explobox_body, setMeshTransformEvent_explobox);

    NewtonBodySetAutoSleep(explobox_body,0);




    exploboxNode = exploBox_node;
   boxBody = explobox_body;
   explobox_matrix = box_matrix;

}

/*CMyNewton::updateExplobox()
{
    applyForceAndTorqueEvent_explobox(boxBody);
    setMeshTransformEvent_explobox(boxBody, box_matrix);
}*/



//-----------------------------------------------------------------------------------------------------




void CMyNewton::MyNewtonUpdate(CGameManager* pManager)
{
    float fps = (float) pManager->getDriver()->getFPS();
      if (fps > 0.0f)

    NewtonUpdate(nWorld, 1.0f/ fps );

    //Body-Update
    updateEarthBody();
    //updateExplobox();
}



void CMyNewton::updateEarthBody()
{
      // rotate node
     core::matrix4 mat;
     NewtonBodyGetMatrix(earthBody, mat.pointer());
      //Set node position
     earthNode->setPosition(mat.getTranslation() * NewtonToIrr);
     // set node rotation
     core::vector3df euler;
     NewtonGetEulerAngle ( mat.pointer(), &euler.X);
     earthNode->setRotation(euler * (180.0f / 3.1416f));

}

void CMyNewton::Clean()
{
    NewtonDestroyAllBodies (nWorld);
   NewtonDestroy(nWorld);
}


void CMyNewton::Init()
{
    nWorld= NewtonCreate();

    int i = NewtonMaterialGetDefaultGroupID(nWorld);
    NewtonMaterialSetDefaultFriction(nWorld,i,i,0.8f,0.9f);
    NewtonMaterialSetDefaultElasticity(nWorld,i,i,0.9f);
    NewtonMaterialSetDefaultSoftness(nWorld,i,i,0.9f);
    NewtonMaterialSetCollisionCallback(nWorld,i,i,NULL,NULL,NULL);

}

void* _cdecl CMyNewton::PhysicsAlloc(int sizeInBytes)
{
    return new char[sizeInBytes];

}

void  _cdecl CMyNewton::PhysicsFree(void* ptr, int sizeInBytes)
{
    char* tmp;
    tmp=(char*)ptr;
    delete[] tmp;

}




And the header looks like this:

Code: Select all
#if !defined(CMYNEWTON_H_INCLUDED_)
#define CMYNEWTON_H_INCLUDED_

#include <header_include.h>
#include<Newton.h>

#define NEWTON_GRAVITY -400.0f

class CMyNewton;
class CGameManager;

class CMyNewton
{
    public:
        CMyNewton();
        virtual ~CMyNewton();

        float getIrrToNewton();
        float getNewtonToIrr();

        void createEarthBody(IAnimatedMeshSceneNode* node);
        void MyNewtonUpdate(CGameManager* pManager);

        void createExploBox(IAnimatedMeshSceneNode*exploBox_node,IAnimatedMesh* mesh);
        static void _cdecl setMeshTransformEvent_explobox(const NewtonBody *body,const float*matrix);

        static void _cdecl applyForceAndTorqueEvent_explobox(const NewtonBody* body);
        void createNewton_Level(ISceneNode* newtonLevel_node, IAnimatedMesh* mesh);






  protected:

        void Clean();
        void Init();
        NewtonWorld* nWorld;

        const float NewtonToIrr;
        const float IrrToNewton ;

       static void* _cdecl PhysicsAlloc(int sizeInBytes);
       static void _cdecl PhysicsFree(void* ptr, int sizeInBytes);
       void setMeshTransformEventExploboxHandler(const NewtonBody* body, const float* matrix);
       void applyForceAndTorqueEventExploboxHandler(const NewtonBody*body);

        const NewtonBody*  earthBody;
        const NewtonBody*  boxBody;

        matrix4 box_matrix;

        IAnimatedMeshSceneNode* earthNode;
        IAnimatedMeshSceneNode* exploboxNode;


        void updateEarthBody();

};

#endif



This code is not yet finished, but it is in progress, by the way I am using now Newton 2.0;
in older games I used similar code, but without any class structure and it worked perfectly; but for bigger projects it makes no sense working without classes, maybe anybody could give me information to understand, why conversion from 'void (const NewtonBody *)' to 'NewtonApplyForceAndTorque' is not possible,
thank you for any support,


Robert :roll:
RobbRob
 
Posts: 7
Joined: Sun Jan 03, 2010 4:55 pm

Re: Newton Callbacks don´t work

Postby lesPaul456 » Sun Jan 03, 2010 5:33 pm

Make sure that the method signatures are correct. They should be something like this:

NewtonApplyForceAndTorque:
Code: Select all
static void ApplyForceAndTorque(const NewtonBody* body, const float timeStep, int threadIndex);


NewtonSetTransform:
Code: Select all
static void SetTransformCallback(const NewtonBody* body, const float* matrix, int threadIndex);


Hope this helps!
User avatar
lesPaul456
 
Posts: 17
Joined: Thu Dec 31, 2009 9:24 pm

Re: Newton Callbacks don´t work

Postby Stucuk » Mon Jan 04, 2010 1:27 am

You need to send them as Pointers. IIRC you just need to add & to the begining of there names when your sending them(C++ isn't my language).

I.E:

Code: Select all
NewtonBodySetForceAndTorqueCallback(explobox_body, &applyForceAndTorqueEvent_explobox);
NewtonBodySetTransformCallback(explobox_body, &setMeshTransformEvent_explobox);


Note: Since C++ isn't my main language i could be wrong. But in any case you need to send callbacks as pointers, not as methods. Basicaly to the compiler its just trying to "execute" the procedure its self rather than send it as a parameter. So because the ForceAndTorque + Transform callbacks never return the values the NewtonBodySetXCallback's expect it would never work. You can only send "Methods"(Procedures/Functions) as parameters when they are converted into a pointer.
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: Newton Callbacks don´t work

Postby lesPaul456 » Mon Jan 04, 2010 11:11 am

@Stucuk
The methods don't need to be passed as pointers, they just need to match the signatures of NewtonApplyForceAndTorque and NewtonSetTransform respectively.

@RobbRob
You simply have the method signatures declared incorrectly. If you look at the examples that come with Newton, you will see that the callbacks are declared the same as I had posted them earlier. That's what the errors are telling you: the method signatures do not match those of NewtonApplyForceAndTorque and NewtonSetTransform.
User avatar
lesPaul456
 
Posts: 17
Joined: Thu Dec 31, 2009 9:24 pm

Re: Newton Callbacks don´t work

Postby RobbRob » Mon Jan 04, 2010 5:36 pm

Dear Les Paul (quite excellent guitar, by the way),

thank you for your help, I did it exactly with this method signatures ( is that a prototyp of a function ?) and it work, except of "timestep" in NewtonApplyForceAndTorque , which didn´t accept const (no idea why), but now the compiler is satisfied,
also many thanks to Stucuk, for your explanations,
I guess I need further help for my next steps , lets see, :D


Robert
RobbRob
 
Posts: 7
Joined: Sun Jan 03, 2010 4:55 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 383 guests

cron