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
