Tiens voila un main complet qui fonction avec newton 2.35 et irrlicht 1.8 :
Note : Dans le callback applyforceandtorque seul la force est appliquée donc petite modifs à faire.
Note 2 : si tu ne vois pas le cube tombé et qu'il est déjà posé sur l'autre cube, augmente la position Y de cube002.
/// IRRLICHT
#include "irrlicht.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
/// NEWTON
#include "newton.h"
#include "dMatrix.h"
/// Constantes
#define GRAVITY -9.8f
#define NEWTON_TO_IRR 32.0f
#define IRR_TO_NEWTON (1.0f/NEWTON_TO_IRR)
void PhysicsApplyForceAndTorque (const NewtonBody* body, float, int)
{
dFloat Ixx;
dFloat Iyy;
dFloat Izz;
dFloat mass;
NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);
dVector force (0.0f, mass * GRAVITY, 0.0f);
NewtonBodySetForce (body, &force.m_x);
}
// set the transformation of a rigid body
//You have to do this so that the Newton body and irrLicht scene node are in sync,
//and you actually see the changes created by the physics simulation
void PhysicsSetTransform (const NewtonBody* body, const dFloat* matrix, int)
{
scene::ISceneNode* primitive;
// get the graphic object form the rigid body
//Newton can store a pointer to the scene node in the body object.
primitive = (scene::ISceneNode*) NewtonBodyGetUserData (body);
// set the transformation matrix for this rigid body
dMatrix& mat = *((dMatrix*)matrix);
//Create a matrix to store the irrLicht transformation that will correspond
//to the Newton transformation
matrix4 irrMatrix;
//There's no easy way to get the information from one to the other, so a memory copy is required.
//The matrix is a 4x4 float
memcpy (irrMatrix.pointer(), &mat, 16*sizeof(float));
//In order to get the transform right, you have to apply the translation and the rotation
//from the Newton body to the irrLicht scene node.
vector3df position (irrMatrix.getTranslation());
position *= NEWTON_TO_IRR;
vector3df rotation;
NewtonGetEulerAngle(irrMatrix.pointer(), &rotation.X);
rotation = rotation * RADTODEG;
primitive->setPosition (position);
primitive->setRotation(rotation);
}
/// classe pour la gestion des événements
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(IrrlichtDevice*dev) { device = dev; }
IrrlichtDevice* device;
virtual bool OnEvent(const SEvent& event)
{
if (event.EventType == EET_KEY_INPUT_EVENT)
{
if(event.KeyInput.PressedDown)
{
switch(event.KeyInput.Key)
{
case KEY_ESCAPE:
device->closeDevice(); // QUITTE L'APPLICATION
return true;
default:
break;
}
}
}
/// aucun événement n'a été traité
return false;
}
};
int main(int argc, char** argv)
{
/// Initialisation de NEWTON
static NewtonWorld* World = NewtonCreate();
NewtonSetPlatformArchitecture(World, 0);
float minSize[3] = {-5000.0f, -5000.0f, -5000.0f};
float maxSize[3] = {5000.0f, 5000.0f, 5000.0f};
NewtonSetWorldSize(World, &minSize[0], &maxSize[0]);
NewtonSetSolverModel(World, 1);
NewtonSetFrictionModel(World, 1);
/// materiau par défaut
NewtonMaterialSetDefaultFriction( World, 0, 0, 0.5f, 0.5f);
NewtonMaterialSetDefaultElasticity( World, 0, 0, 0.0f);
NewtonMaterialSetDefaultSoftness( World, 0, 0, 1.0f);
//NewtonMaterialSetDefaultCollidable( World, 0, 2, 1); // autorise les collisions entre le groupID 2 et 3, le 1 veut dire true
/// Intitialisation d'IRRLICHT
IrrlichtDevice *device = createDevice(EDT_OPENGL, dimension2du(1280, 720), 32, false, false, false, 0);
device->setWindowCaption(L"Irrlicht Engine Essais");
/// Créé et applique le gestionnaire d'événements
MyEventReceiver receiver(device);
device->setEventReceiver(&receiver);
/// Créé les environnements
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
/// Créé la camera
ICameraSceneNode *NodeCamera = smgr->addCameraSceneNodeFPS();
NodeCamera->setFarValue(1000000.0f);
//NodeCamera->setPosition(vector3df(-2300,20,2300));
//NodeCamera->setTarget( vector3df(0,0,0) );
device->getCursorControl()->setVisible(false);
/// Créations
/// CUBE symbolisant le sol
ISceneNode *Node001 = smgr->addCubeSceneNode(500);
if( Node001 )
{
Node001->setMaterialFlag(EMF_LIGHTING, false);
Node001->setMaterialTexture(0, driver->getTexture("../MEDIAS/water.jpg"));
Node001->setPosition( vector3df(0,-500,0) );
/// ajout de la physique à Node002
NewtonCollision* NC_Node001 = NULL;
NewtonBody* NB_Node001 = NULL;
/// récupère la taille de la boundingbox du node pour la creation d'une collision de type "BOX"
vector3df size = Node001->getBoundingBox().getExtent() * IRR_TO_NEWTON;
#ifdef _DEBUG
printf("Node001 - size Newton : X=%f; Y=%f; Z=%f;\
", size.X, size.Y, size.Z);
#endif
/// créé le cube qui servira pour le calcul de collision
NC_Node001 = NewtonCreateBox(World, size.X, size.Y, size.Z, -1, NULL);
if(NC_Node001)
{
#ifdef _DEBUG
printf("Newton Collision - Node001 : OK\
");
#endif
/// transforme la matrice du node pour NEWTON
matrix4 matrix = Node001->getRelativeTransformation();
vector3df origin = Node001->getRelativeTransformation().getTranslation() * IRR_TO_NEWTON;
matrix.setTranslation(origin);
/// créé le corps pour l'application d'effets sur le node irrlicht
NB_Node001 = NewtonCreateBody(World, NC_Node001, matrix.pointer());
if(NB_Node001)
{
#ifdef _DEBUG
printf("Newton Body - Node001 : OK\
");
#endif
///
NewtonReleaseCollision(World, NC_Node001);
///
NewtonBodySetUserData(NB_Node001, Node001);
///
NewtonBodySetTransformCallback(NB_Node001, PhysicsSetTransform);
NewtonBodySetForceAndTorqueCallback(NB_Node001, PhysicsApplyForceAndTorque);
/// définit la masse et l'inertie de l'objet
NewtonBodySetMassMatrix (NB_Node001, 0.0f, 0.0f, 0.0f, 0.0f);
}
#ifdef _DEBUG
else printf("Newton Body - Node001 : PROBLEME\
");
#endif
}
#ifdef _DEBUG
else printf("Newton Collision - Node001 : PROBLEME\
");
#endif
#ifdef _DEBUG
printf("Node001 : OK\
");
}
else
{
printf("Node001 : PROBLEME\
");
#endif
}
/// CUBE tombant sur le sol
ISceneNode *Node002 = smgr->addCubeSceneNode(20);
if( Node002 )
{
Node002->setMaterialFlag(EMF_LIGHTING, false);
Node002->setMaterialTexture(0, driver->getTexture("../MEDIAS/water.jpg"));
Node002->setPosition( vector3df(0,1000,0) );
/// ajout de la physique à Node002
NewtonCollision* NC_Node002 = NULL;
NewtonBody* NB_Node002 = NULL;
/// récupère la taille de la boundingbox du node pour la creation d'une collision de type "BOX"
vector3df size = Node002->getBoundingBox().getExtent() * IRR_TO_NEWTON;
#ifdef _DEBUG
printf("Node002 - size Newton : X=%f; Y=%f; Z=%f;\
", size.X, size.Y, size.Z);
#endif
/// créé le cube qui servira pour le calcul de collision
NC_Node002 = NewtonCreateBox(World, size.X, size.Y, size.Z, -1, NULL);
if(NC_Node002)
{
#ifdef _DEBUG
printf("Newton Collision - Node002 : OK\
");
#endif
/// transforme la matrice du node pour NEWTON
matrix4 matrix = Node002->getRelativeTransformation();
vector3df origin = Node002->getRelativeTransformation().getTranslation() * IRR_TO_NEWTON;
matrix.setTranslation(origin);
/// créé le corps pour l'application d'effets sur le node irrlicht
NB_Node002 = NewtonCreateBody(World, NC_Node002, matrix.pointer());
if(NB_Node002)
{
#ifdef _DEBUG
printf("Newton Body - Node002 : OK\
");
#endif
///
NewtonReleaseCollision(World, NC_Node002);
///
NewtonBodySetUserData(NB_Node002, Node002);
///
NewtonBodySetTransformCallback(NB_Node002, PhysicsSetTransform);
NewtonBodySetForceAndTorqueCallback(NB_Node002, PhysicsApplyForceAndTorque);
/// définit la masse et l'inertie de l'objet
NewtonBodySetMassMatrix (NB_Node002, 1.0f, 0.0f, 0.0f, 0.0f);
}
#ifdef _DEBUG
else printf("Newton Body - Node002 : PROBLEME\
");
#endif
}
#ifdef _DEBUG
else printf("Newton Collision - Node002 : PROBLEME\
");
#endif
#ifdef _DEBUG
printf("Node002 : OK\
");
}
else
{
printf("Node002 : PROBLEME\
");
#endif
}
/// Boucle de rendu
int lastFPS = -1;
u32 lastTime = 0;
f32 timestepS = 0.017f; u32 timestepMS = timestepS * 500;
#ifdef _DEBUG
printf("On entre dans la boucle de rendu.\
");
#endif
while(device->run())
{
/// update la physique
u32 courantTime = device->getTimer()->getTime();
if( courantTime > (lastTime + timestepMS) )
{
NewtonUpdate(World, timestepS );
lastTime = courantTime;
}
/// dessine la frame
driver->beginScene(true, true, SColor(0,200,200,200));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
/// affiche le nombre de fps dans la barre de titre
int fps_int = driver->getFPS();
if (lastFPS != fps_int)
{
stringw str = L"Irrlicht Engine Essais [";
str += driver->getName();
str += "] FPS:"; str += fps_int;
str += " | Triangles :"; str += driver->getPrimitiveCountDrawn();
device->setWindowCaption(str.c_str());
lastFPS = fps_int;
}
}
/// libération de Newton
NewtonDestroyAllBodies(World);
NewtonDestroy (World);
/// libération d'Irrlicht
device->drop();
/// sortie du programme
return 0;
}