Historique des modifications - Message

Message #10655

Sujet: Test de gravité - Irrlicht + Newton


Type Date Auteur Contenu
Création du message 12-08-2012 08:20:46 johnplayer
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;
}

Retour

Options Liens officiels Caractéristiques Statistiques Communauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1440 sujets
11337 messages
Dernier membre inscrit: Saidov17
230 invités en ligne
membre en ligne: -
RSS Feed