#0 

10-08-2012 17:38:36

Kaze
Membre
Date d'inscription: 12-03-2011
Messages: 60

Bonjour à tous,

comme le titre vous l'explique, j'essaye de créer une gravité avec Newton et le moteur Irrlicht. J'ai créer, grâce au tutos que j'ai pu trouver sur internet, un code qui est censé modélisé un cube et le soumettre a la gravité. Mais mon code ne fonctionne pas, il m'affiche un cube mais il est immobile. Voici mon code :

main.hpp :

#ifndef MAIN_HPP
#define MAIN_HPP

#include <irr/Irrlicht.h>
#include <iostream>
#include "newton.h"

void drawScene();
void force(NewtonBody *body);
void initScene();

#endif

main.cpp :

#include "main.hpp"

static NewtonWorld* world;
static NewtonBody* body;

irr::IrrlichtDevice *device = 0;
irr::video::IVideoDriver *driver = 0;
irr::scene::ISceneManager *sceneManager = 0;

irr::scene::ISceneNode *cubeNode = 0;
irr::scene::ISceneNode *cam = 0;
unsigned int lasttick;

void initScene()
{
    device = irr::createDevice(irr::video::EDT_OPENGL, irr::core::dimension2d<irr::u32>(640,480), false);
    driver = device->getVideoDriver();
    sceneManager = device->getSceneManager();
    sceneManager->addSkyBoxSceneNode(driver->getTexture("data/irrlicht2_up.bmp"),driver->getTexture("data/irrlicht2_dn.bmp"),driver->getTexture("data/irrlicht2_rt.bmp"),driver->getTexture("data/irrlicht2_lf.bmp"),driver->getTexture("data/irrlicht2_ft.bmp"),driver->getTexture("data/irrlicht2_bk.bmp"));


    world = NewtonCreate (NULL, NULL);

    irr::scene::IMesh* cubeMesh = sceneManager->getMesh("data/smallcube.3ds");
    cubeNode = sceneManager->addMeshSceneNode(cubeMesh);
    cubeNode->setMaterialTexture(0, driver->getTexture("data/crate.jpg"));
    cubeNode->setMaterialFlag(irr::video::EMF_LIGHTING, false);

    NewtonCollision *collision;
    collision = NewtonCreateBox(world, 0, 0, 0, NULL);
    body = NewtonCreateBody (world, collision);
    NewtonReleaseCollision (world, collision);   

    NewtonBodySetUserData(body, cubeNode);
   
    float masse = 100.0;
    NewtonBodySetMassMatrix(body, masse, 1.0f, 1.0f, 1.0f);
   
    irr::core::matrix4 mat;
    mat.setTranslation(irr::core::vector3df(0.0,0.0,0.0));
    NewtonBodySetMatrix(body, mat.pointer());

    irr::scene::ICameraSceneNode* cam = sceneManager->addCameraSceneNode();
    cam->setPosition(irr::core::vector3df(200,100,0));
    cam->setTarget(irr::core::vector3df(0,0,0));
   
    irr::core::vector3df inertie;
    irr::core::vector3df taille = irr::core::vector3df(10,10,10);
        inertie.X = (masse/12)*(pow(taille.Y,2)+pow(taille.Z,2));
        inertie.Y = (masse/12)*(pow(taille.X,2)+pow(taille.Z,2));
        inertie.Z = (masse/12)*(pow(taille.X,2)+pow(taille.Y,2));
        NewtonBodySetMassMatrix (body, masse, inertie.X, inertie.Y, inertie.Z);
        force(body);
}

void force(NewtonBody *body){
   
    float masse;
    irr::core::vector3df inertie;
    float force[3];
   
    NewtonBodyGetMassMatrix (body, &masse, &inertie.X, &inertie.Y, &inertie.Z);
   
    force[0] = 0.0f;
    force[1] = -9.81 * masse;
    force[2] = 0.0f;

    NewtonBodyAddForce(body, force); 
}

void drawScene(){
   
    if (device->getTimer()->getTime() > lasttick + 10)
    {   
    lasttick = device->getTimer()->getTime();
    NewtonUpdate(world, 0.01f);
    }
   
    irr::core::matrix4 mat;
    NewtonBodyGetMatrix(body, mat.pointer());
    cubeNode->setPosition(mat.getTranslation());
    cubeNode->setRotation(mat.getRotationDegrees());
}

int main()
{
   initScene();

   while(device->run())
   {
      drawScene();
      driver->beginScene(true, true, irr::video::SColor(255,255,255,255));
      sceneManager->drawAll();
      driver->endScene();
   }
   
   NewtonDestroy(world);
   device->drop();
   return 0;
}

Mais je ne comprend pas où plante le code. Pourriez vous m'aider ?

Merci d'avance.

Hors ligne


#1 

10-08-2012 18:42:40

Copland
Modérateur
Lieu: ZarbiLand
Date d'inscription: 22-09-2006
Messages: 657
Site web

Salut Kaze,
Sur quelle version de newton tu bosses ?
Je pourrais regarder ça dans la soirée si personne t'a débloqué avant.
A plus tard donc smile


Config : I5 2400, ATI HD6870 1Go DDR5, 4Go DDR3.
Single Boot : Windows Seven.

Hors ligne


#2 

10-08-2012 19:13:07

Kaze
Membre
Date d'inscription: 12-03-2011
Messages: 60

Il me semble que c'est la version  2.3 mais je n'en suis vraiment pas sur. Et merci pour ton aide.

Dernière modification par Kaze (10-08-2012 19:13:25)

Hors ligne


#3 

11-08-2012 09:07:57

Gehogor
Abonné
Lieu: Paris
Date d'inscription: 02-06-2009
Messages: 130
Corrections: 7

Salut Kaze, alors j'ai vu deux trois tucs:

Déjà, pour ton code:

Code:

NewtonBodySetUserData(body, cubeNode);

Écris plutôt:

Code:

NewtonBodySetUserData(body,reinterpret_cast<void*>(cubeNode));

De cette manière, tu dis au compilo comment le pointeur de ton cubeNode doit être.

De plus, lorsque Newton désire changer la position du cube, il appelle le pointeur d'une méthode que tu peux capter, c'est la méthode:

Code:

void GrNewton::SetMeshTransformMesh(const NewtonBody* body,const float* matrix,int threadIndex)
{
    // On retransforme le pointeur dans la bonne forme.
    ISceneNode*cubeNode = reinterpret_cast<ISceneNode*>(NewtonBodyGetUserData(body));
    if(cubeNode == 0)
        return;

    // Conversion et création de la bonne matrice, ...
    cubeNode->setPosition(mat.getTranslation());
    cubeNode->setRotation(mat.getRotationDegrees());
}

Cette méthode se configure comme ça dans l'initialisation de ton code:

Code:

    ...ton code
    NewtonBodySetUserData(body, cubeNode);

    // Association d'une "Callback" (ici:SetMeshTransformMesh) à l'objet Newton,
    // elle sera appellée lorsque l'objet bougera selon le moteur Newton (il y a bcp d'exemple là dessus).
    NewtonBodySetTransformCallback(body,SetMeshTransformMesh);

Il est donc inutile d'écrire le code suivant dans la méthode  "drawScene()":

Code:

NewtonBodyGetMatrix(body, mat.pointer());

Voilà, j'espère qu'il n'y avait que ça, désolé de ne pas être plus précis, ma fille pleure, il faut que j'y aille ! smile

Dernière modification par Gehogor (11-08-2012 09:10:16)


Et hop... wink

Hors ligne


#4 

11-08-2012 13:05:11

Copland
Modérateur
Lieu: ZarbiLand
Date d'inscription: 22-09-2006
Messages: 657
Site web

Hello, merci Gehogor smile.Petit contre temps hier soir j'ai pas pût regarder mais si tu l'as aidé c'est cool ! amusez vous bien.
Je retourne dans mon code moi wink


Config : I5 2400, ATI HD6870 1Go DDR5, 4Go DDR3.
Single Boot : Windows Seven.

Hors ligne


#5 

11-08-2012 14:53:32

Kaze
Membre
Date d'inscription: 12-03-2011
Messages: 60

Waouh !!! Moi qui ne comprend rien à Newton je suis un peu perdu. J'ai compris la première modification (même si je n'ai pas compris à quoi servait cette fonction) mais pour la seconde ... j'ai laché. Faut dire que même les tutos que j'ai pu trouvé ne m'ont pas été d'une grande aide.

Est-ce qu'il serait possible d'être plus précis ? Ou si vous avez un code qui me permette de mieux comprendre Newton (même s'il ne fait pas ce que je veux) ? Ce serait génial. Sinon merci de vous pencher sur mon problème.

Hors ligne


#6 

11-08-2012 16:31:54

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Dans ta boucle de rendu tu dois faire un NewtonUpdate(...). Regarde dans la doc pour le paramètrage.

Je te passe un bout de code pour un framerate libre (pas de vsync):

Code:

void Systeme::rendu()
{
    /// variables pour le chronomètrage de l'execution des frames
    mTimeElapsed = 0;
    u32 startTime = 0;
    /// variable pour le rafraichissement de la physique
    u32 lastTime = 0;

    /// entrée dans la boucle
    while(mDevice->run())
    {
        /// on enregistre le temps de départ de la frame
        startTime = mDevice->getTimer()->getTime();
        /// update la physique
        if( startTime > (lastTime + TIME_STEP_MS) )
        {
            NewtonUpdate(mWorld, TIME_STEP_S );
            lastTime = startTime;
        }
        /// commence l'update de l'écran
        mDriver->beginScene(true, true, mBackgroundColor);
        /// dessine la scène
        mSmgr->drawAll();
        /// fin de l'update de l'écran
        mDriver->endScene();
        /// on calcule et enregistre le temps d'éxécution de la frame
        mTimeElapsed = mDevice->getTimer()->getTime() - startTime;

    #ifdef _DEBUG
    stringw str = L"My Game ["; str += mDriver->getName();str += "] ";
    str += "Temps de frame: "; str += mTimeElapsed; str += " ms";
    mDevice->setWindowCaption(str.c_str());
    #endif
    }
}

Dernière modification par johnplayer (11-08-2012 16:35:18)


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#7 

11-08-2012 18:06:01

Kaze
Membre
Date d'inscription: 12-03-2011
Messages: 60

Je n'ai pas compris. Ma fonction drawScene() utilise NewtonUpdate. Je ne vois pas ce que ton code change vu que lorsque j'integre ton code, mon cube est toujours immobile.

Hors ligne


#8 

11-08-2012 19:42:30

Gehogor
Abonné
Lieu: Paris
Date d'inscription: 02-06-2009
Messages: 130
Corrections: 7

En effet Johnplayer, j'ai failli lui faire la même remarque mais en fait il appelle correctement la méthode "NewtonUpadte()" qui se cache discrètement dans la méthode "drawScene()".

Un callback est un processus qui appelle une méthode via son pointeur. C'est très pratique, lorsque Newton fait ses calculs et qu'il veut donner ses résultats, à savoir, les nouvelles positions, forces, couples, vitesses et accélération d'un corps, il est possible de les récupérer via ses méthodes callback. Les plus importantes sont:

Code:

// Association d'une "Callback" (ici:SetMeshTransformMesh) à l'objet Newton,
    // elle sera appellée lorsque l'objet bougera selon le moteur Newton (il y a bcp d'exemple là dessus).
    NewtonBodySetTransformCallback(newBody,SetMeshTransformMesh);

    // Association d'une "Callback" (ici:ApplyForceAndTorqueEvent) à l'objet Newton,
    // elle sera appellée lorsque l'objet devra subir une force (il y a bcp d'exemple là dessus).
    NewtonBodySetForceAndTorqueCallback(newBody,ApplyForceAndTorqueEvent);

"ApplyForceAndTorqueEvent" est la méthode qui permet d'indiquer à Newton quels forces et couples on désire appliquer à nos corps, la plupart du temps, c'est la gravité. Elle est donc appelée avant le processus de calcul de Newton.

Ensuite, "SetMeshTransformMesh" est la méthode qui permet de récupérer le pointeur du corps qui vient de bouger après le calcul de Newton.

Lorsque tu appelles les méthodes "NewtonBodySetTransformCallback" et "NewtonBodySetForceAndTorqueCallback", tu indiques en fait à Newton quelles méthodes il doit appeler pour faire ses calculs.

  Je pense qu'il faut que tu jettes un oeil encore plus attentif sur les docs et exemples, ce serait un très bon investissement pour ton avenir d'utilisateur de puissantes lib...

         Courage. wink


Et hop... wink

Hors ligne


#9 

11-08-2012 19:53:05

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

En effet, j'ai pas été très attentif. Regarde aussi la taille de ton cube et celle du body. Il y a un rapport de 32 entre l'échelle d'irrlicht et celle de newton.


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#10 

11-08-2012 19:56:42

Kaze
Membre
Date d'inscription: 12-03-2011
Messages: 60

Merci Gehogor, je vais essayer de voir ces differentes fonctions et je reviendrai si j'ai d'autres problèmes.

Dernière modification par Kaze (11-08-2012 19:56:51)

Hors ligne


#11 

11-08-2012 21:42:23

Gehogor
Abonné
Lieu: Paris
Date d'inscription: 02-06-2009
Messages: 130
Corrections: 7

Juste comme ça johnplayer, pourquoi y a t-il un rapport 32 entre Irrlicht et Newton ?

De mon coté j'ai en effet une échelle de 39.370078... ce qui est en faite 100/2.54, car 2.54 cm représente 1 inch. Cette échelle est dû à mes fichiers 3ds qui avaient été mal converti, raisons historiques...  J'avais constaté ça avec mon module de mesure de distance.
Mais cette échelle s'annule entre Irrlicht et Newton, autrement dit, j'ai un rapport 1 entre les deux.

-> Donc je n'ai pas de rapport de 32.

Je n'ai jamais constaté de bug de rendu, peux-tu m'expliquer d'où vient ton 32 ?

Je pourrai peut-être améliorer des choses de mon coté.

Dernière modification par Gehogor (11-08-2012 22:00:06)


Et hop... wink

Hors ligne


#12 

11-08-2012 22:27:15

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Par exemple, pour avoir une collision correcte avec un cube:

Code:

// rapport d'échelle 
#define NEWTON_TO_IRR 32.0f
#define IRR_TO_NEWTON (1.0f/NEWTON_TO_IRR)

/// cube irrlicht
ISceneNode *Node001 = smgr->addCubeSceneNode(200);
/// 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; // ADAPTATION DE L'ECHELLE AVEC UN COEF
/// créé le cube qui servira pour le calcul de collision
NewtonCollision* NC_Node001 = NewtonCreateBox(World, size.X, size.Y, size.Z, -1, NULL);

En appliquant le coef les collisions sont bonnes. J'utilise ce coef aussi pour les mesh importés.

Code:

NewtonCollision* createTreeCollisionFromMesh(NewtonWorld* nWorld, IMesh* irr_mesh)
{
    //Create new (tree optimized) collision mesh
    NewtonCollision* collision_obj = NewtonCreateTreeCollision(nWorld,0);

    //Begin collision mesh construction
    NewtonTreeCollisionBeginBuild(collision_obj);

    u32 nMeshBuffer = 0; //Mesh Buffer count
    u16 v_index[3] = {0,0,0}; //vertex indices
    IMeshBuffer *mesh_buffer = 0;
    float array[9]; //Array to store 3 vertices

    //Get (irr_)mesh buffers and copy face by face to collision mesh
    for( nMeshBuffer=0 ; nMeshBuffer < irr_mesh->getMeshBufferCount() ; nMeshBuffer++ )
    {
        mesh_buffer = irr_mesh->getMeshBuffer(nMeshBuffer);

        //Get pointer to vertices and indices
        S3DVertex *vertices = (S3DVertex*)mesh_buffer->getVertices();
        u16 *indices = mesh_buffer->getIndices();

        //Fill collision mesh
        for(u32 i=0; i<mesh_buffer->getIndexCount(); i+=3)
        {
            v_index[0] = indices[ i ];
            v_index[1] = indices[i+1];
            v_index[2] = indices[i+2];

            // 1st position vertex
            array[0] = vertices[ v_index[0] ].Pos.X * IRR_TO_NEWTON;
            array[1] = vertices[ v_index[0] ].Pos.Y * IRR_TO_NEWTON;
            array[2] = vertices[ v_index[0] ].Pos.Z * IRR_TO_NEWTON;

            // 2nd position vertex
            array[3] = vertices[ v_index[1] ].Pos.X * IRR_TO_NEWTON;
            array[4] = vertices[ v_index[1] ].Pos.Y * IRR_TO_NEWTON;
            array[5] = vertices[ v_index[1] ].Pos.Z * IRR_TO_NEWTON;

            // 3rd position vertex
            array[6] = vertices[ v_index[2] ].Pos.X * IRR_TO_NEWTON;
            array[7] = vertices[ v_index[2] ].Pos.Y * IRR_TO_NEWTON;
            array[8] = vertices[ v_index[2] ].Pos.Z * IRR_TO_NEWTON;

            //Add new face to collision mesh
            NewtonTreeCollisionAddFace( collision_obj,  //collision mesh to add face to
                                        3,              //number of vertices in array
                                        (float*)array,  //pointer to vertex array
                                        3*sizeof(float),//size of each vertex
                                        1);             //ID of the face
        }
    }
    //End collision contruction , set 1 as 2dn param for optimization
    NewtonTreeCollisionEndBuild(collision_obj,0);

    return collision_obj;
}

J'ai testé newton 2.35 avec irrlicht 1.8 et ça marche nickel avec ces coefs. Si je ne les appliquent pas les meshs se traversent. Et puisque les coefs résolvent le problème pour les meshs régénérés directement avec Irrlicht (addCubeSceneNode, addSphereSceneNode...), j'en ai déduit que c'est un problème d'échelle entre irrlicht et newton.


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#13 

12-08-2012 00:34:50

Kaze
Membre
Date d'inscription: 12-03-2011
Messages: 60

Après avoir lu de nouveau les docs, je peux vous assurer ... n'avoir rien compris à cette idée de callback. Je ne comprend pas à quoi elle sert, où il faut placer cette méthode, et surtout ce qui la compose : "ApplyForceAndTorqueEvent".

Pourtant, dans mon code, je donne au cube un corps que Newton peux utiliser, ensuite je lui applique une force. Je ne vois pas quel est le but de cette méthode. Il faut l'appeler à chaque fois que l'objet se déplace, mais je ne comprend pas ce qu'elle fait de plus que "NewtonBodyAddForce(body, force); " Serait il possible que vous m'expliquiez au moins ce qu'est " ApplyForceAndTorqueEvent " ?

En fait j'ai créer, à partir d'un code trouver sur internet, les deux callbacks :

<code>
void SetMeshTransformEvent(NewtonBody* body, float* matrix)
{
    // Copie de la matrice
    matrix4 mat;
    memcpy(mat.pointer(), matrix, sizeof(float)*16);

    // Retreive the user data attached to the newton body
    ISceneNode *tmp = (ISceneNode *)NewtonBodyGetUserData(body);
    if (tmp)
    {
        tmp->setPosition(mat.getTranslation());
        tmp->setRotation(mat.getRotationDegrees());
    }
}

void ApplyForceAndTorqueEvent(NewtonBody* body)
{
   float masse;
   float inertieX;
   float inertieY;
   float inertieZ;
   float force[3];
   float torque[3];

   NewtonBodyGetMassMatrix (body, &masse, &inertieX, &inertieY, &inertieZ);

   force[0] = 0.0f;
   force[1] = -6.81 * masse;
   force[2] = 0.0f;

   torque[0] = 0.0f;
   torque[1] = 0.0f;
   torque[2] = 0.0f;

   NewtonBodyAddForce(body, force);
   NewtonBodyAddTorque(body, torque);
}
</code>

Et je les appelles avec :

<code>
NewtonBodySetTransformCallback(body, SetMeshTransformEvent);
NewtonBodySetForceAndTorqueCallback(body, ApplyForceAndTorqueEvent);
</code>

Mais je ne vois pas où est transmis la matrice nécessaire à la méthode SetMeshTransformEvent. S'il est question de la matrice de body, je pourrais la récupérer avec un NewtonBodyGetMatrix ?

Merci d'avance.

Dernière modification par Kaze (12-08-2012 00:58:07)

Hors ligne


#14 

12-08-2012 00:38:32

Gehogor
Abonné
Lieu: Paris
Date d'inscription: 02-06-2009
Messages: 130
Corrections: 7

Ok, j'applique l'échelle de la même manière. Mais je ne comprends toujours pas pourquoi tu utilises "32". Es-tu sûr que, lorsque un cube est en collision avec un autre, il n'y a aucune pénétration, en regardant bien de près ? Comment as-tu déterminé 32 ?

Sur l'image suivante, je fais un essai de collision avec un cube générer par irrlicht:


Le coefficient 32 n'est pas suffisant, je suis obligé de prendre 39.37, mais ça c'est normal, c'est l'échelle globale de mon appli.

J'ai également fait un essai avec aucune échelle, tout est à 1.0. Et là, ça fonctionne sans problème.


Sans doute que quelque chose m'échappe dans ce code, il est temps que je me couche. C'est bizarre quand même...

          Désolé d'insister, mais c'est comme ça qu'on fait les choses bien et qu'on évite des soucis futurs.

Dernière modification par Gehogor (12-08-2012 00:54:37)


Et hop... wink

Hors ligne


#15 

12-08-2012 01:16:19

Kaze
Membre
Date d'inscription: 12-03-2011
Messages: 60

Comme je l'ai dit dans mon précédant message, j'ai récupérer les callbacks d'un autre programme pour essayer. Voici mon nouveau code :

main.hpp :

Code c++ :


#ifndef MAIN_HPP
#define MAIN_HPP

#include <irr/Irrlicht.h>
#include <iostream>
#include "newton.h"

//callback Newton
void SetMeshTransformEvent(const NewtonBody* body, const float* matrix);
void ApplyForceAndTorqueEvent(const NewtonBody* body);

void drawScene();
void initScene();

#endif



main.cpp :

Code c++ :


#include "main.hpp"

static NewtonWorld* world;
static NewtonBody* body;

irr::IrrlichtDevice *device = 0;
irr::video::IVideoDriver *driver = 0;
irr::scene::ISceneManager *sceneManager = 0;

irr::scene::ISceneNode *cubeNode = 0;
irr::scene::ISceneNode *cam = 0;
unsigned int lasttick;

void initScene()
{
    device = irr::createDevice(irr::video::EDT_OPENGL, irr::core::dimension2d<irr::u32>(640,480), false);
    driver = device->getVideoDriver();
    sceneManager = device->getSceneManager();
    sceneManager->addSkyBoxSceneNode(driver->getTexture("data/irrlicht2_up.bmp"),driver->getTexture("data/irrlicht2_dn.bmp"),driver->getTexture("data/irrlicht2_rt.bmp"),driver->getTexture("data/irrlicht2_lf.bmp"),driver->getTexture("data/irrlicht2_ft.bmp"),driver->getTexture("data/irrlicht2_bk.bmp"));


    world = NewtonCreate (NULL, NULL);

    irr::scene::IMesh* cubeMesh = sceneManager->getMesh("data/smallcube.3ds");
    cubeNode = sceneManager->addMeshSceneNode(cubeMesh);
    cubeNode->setMaterialTexture(0, driver->getTexture("data/crate.jpg"));
    cubeNode->setMaterialFlag(irr::video::EMF_LIGHTING, false);

    NewtonCollision *collision;
    collision = NewtonCreateBox(world, 0, 0, 0, NULL);
    body = NewtonCreateBody (world, collision);
    NewtonReleaseCollision (world, collision);   

    NewtonBodySetUserData(body,reinterpret_cast<void*>(cubeNode));
   
    float masse = 100.0;
   
    irr::scene::ICameraSceneNode* cam = sceneManager->addCameraSceneNode();
    cam->setPosition(irr::core::vector3df(200,100,0));
    cam->setTarget(irr::core::vector3df(0,0,0));
   
    irr::core::vector3df inertie;
    irr::core::vector3df taille = irr::core::vector3df(10,10,10);
    inertie.X = (masse/12)*(pow(taille.Y,2)+pow(taille.Z,2));
    inertie.Y = (masse/12)*(pow(taille.X,2)+pow(taille.Z,2));
    inertie.Z = (masse/12)*(pow(taille.X,2)+pow(taille.Y,2));
    NewtonBodySetMassMatrix (body, masse, inertie.X, inertie.Y, inertie.Z);
   
   
    NewtonBodySetTransformCallback(body, SetMeshTransformEvent);
    NewtonBodySetForceAndTorqueCallback(body, ApplyForceAndTorqueEvent);
   
   
    irr::core::matrix4 mat;
    mat.setTranslation(irr::core::vector3df(0.0,0.0,0.0));
    NewtonBodySetMatrix(body, mat.pointer());
}

// -----------------------------------------------------------------------------
// --------------------------------- CALLBACK ----------------------------------
// -----------------------------------------------------------------------------

void SetMeshTransformEvent(const NewtonBody* body, const float* matrix)
{
    irr::core::matrix4 mat;
    memcpy(mat.pointer(), matrix, sizeof(float)*16);

    irr::scene::ISceneNode *tmp = (irr::scene::ISceneNode *)NewtonBodyGetUserData(body);
    if (tmp)
    {
        tmp->setPosition(mat.getTranslation());
        tmp->setRotation(mat.getRotationDegrees());
    }
}

void ApplyForceAndTorqueEvent(const NewtonBody* body)
{
   float masse;
   float inertieX;
   float inertieY;
   float inertieZ;
   float force[3];
   float torque[3];

   NewtonBodyGetMassMatrix (body, &masse, &inertieX, &inertieY, &inertieZ);

   force[0] = 0.0f;
   force[1] = -6.81 * masse;
   force[2] = 0.0f;

   torque[0] = 0.0f;
   torque[1] = 0.0f;
   torque[2] = 0.0f;

   NewtonBodyAddForce(body, force);
   NewtonBodyAddTorque(body, torque);
}

// ------------------------------- END OF CALLBACK -----------------------------

void drawScene(){
   
    if (device->getTimer()->getTime() > lasttick + 10)
    {   
    lasttick = device->getTimer()->getTime();
    NewtonUpdate(world, 0.01f);
    }
   
    irr::core::matrix4 mat;
    cubeNode->setPosition(mat.getTranslation());
    cubeNode->setRotation(mat.getRotationDegrees());
}

int main()
{
   initScene();
   
   while(device->run())
   {
      drawScene();
      driver->beginScene(true, true, irr::video::SColor(255,255,255,255));
      sceneManager->drawAll();
      driver->endScene();
   }
   
   NewtonDestroy(world);
   device->drop();
   return 0;
}


Mais mon cube reste encore et toujours immobile, et je n'ai pas bien compris le fonctionnement de ces callbacks (même si ça va mieux qu'avant).

Hors ligne


#16 

12-08-2012 09:04:44

Gehogor
Abonné
Lieu: Paris
Date d'inscription: 02-06-2009
Messages: 130
Corrections: 7

Ça me semble mieux, par contre:
D'un coté tu mets à jour en position ton node dans "SetMeshTransformEvent" et de l'autre tu ré-écrases cette même position dans la méthode "drawScene()" avec une matrice identité, soit pas de translation, pas de rotation, ...

Il faut donc enlever la partie dans "drawScene()" qui ne sert à rien à part de dire à ton node: "Non, tu ne bougeras pas !".


Et hop... wink

Hors ligne


#17 

12-08-2012 10:20:46

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

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.

Code:

/// 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;\n", 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\n");
    #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\n");
    #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\n");
    #endif
        }
    #ifdef _DEBUG
        else printf("Newton Collision - Node001 : PROBLEME\n");
    #endif

#ifdef _DEBUG
        printf("Node001 : OK\n");
    }
    else
    {
        printf("Node001 : PROBLEME\n");
#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;\n", 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\n");
    #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\n");
    #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\n");
    #endif
        }
    #ifdef _DEBUG
        else printf("Newton Collision - Node002 : PROBLEME\n");
    #endif

#ifdef _DEBUG
        printf("Node002 : OK\n");
    }
    else
    {
        printf("Node002 : PROBLEME\n");
#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.\n");
#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;
}

core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#18 

12-08-2012 12:43:00

Kaze
Membre
Date d'inscription: 12-03-2011
Messages: 60

Merci à vous deux, je vais essayer de corriger mon code et j'étudierai celui qu'à envoyé Johnplayer. Je reviendrai peut-être si j'ai de nouveau problèmes.

J'ai supprimé la partie de ma méthode drawScene et ... ça marche impec !!!!

Encore merci.

Dernière modification par Kaze (12-08-2012 18:26:49)

Hors ligne


#19 

12-08-2012 20:21:27

Kaze
Membre
Date d'inscription: 12-03-2011
Messages: 60

J'ai un autre petit problème qui doit être tout bête. J'avais en fait installé la version 1.53 de newton et tout fonctionne. J'ai voulu installer la version 2.35 pour tester le code de johnplayer mais le compilo me dit qu'à travers dMatrix.h, le fichier dVector.h est introuvable alors qu'il se trouve dans le même dossier :

/Dev-Cpp/include/newt/dMath/dMatrix.h D:\Projet\\Irrlicht\tuto\18-eighteenth- Physique 3\test collision\C dVector.h: No such file or directory.

J'ai bien tout linké comme il faut et mis les bons .dll mais je ne comprend pas pourquoi il ne trouve pas le fichier. En plus dans mon dossier test collision, je n'ai rien qui a pour nom "C" ?

Pourriez vous m'aider de nouveau ?

Hors ligne


#20 

12-08-2012 23:04:04

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Si tu as C::B, dans les options de projets>>Sherach directory>>Compiler, tu dois mettre un path du genre "Newton 2.35\packages" et "Newton 2.35\packages\dMath". dVector.h se trouve dans dMath je crois.


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#21 

13-08-2012 01:14:21

Kaze
Membre
Date d'inscription: 12-03-2011
Messages: 60

OK. J'en profite pour poser une autre chose : J'ai un peu modifié mon code pour avoir trois cubes, un avec une masse nulle, un avec une masse = 100.0 et un autre avec une masse = 200.0. Comme on peux si attendre, le cube à masse nul reste immobile, pourtant les deux autres cubes tombent à la même vitesse alors que j'ai paramétrer la gravité pour qu'elle dépende du poids. Je vous donne donc mon code :

main.hpp

Code c++ :


#ifndef MAIN_HPP
#define MAIN_HPP

#include <irr/Irrlicht.h>
#include <iostream>
#include "newton.h"

void SetMeshTransformEvent(const NewtonBody* body, const float* matrix);
void ApplyForceAndTorqueEvent(const NewtonBody* body);

void drawScene();
void initScene();

#endif



main.cpp

Code c++ :


#include "main.hpp"

irr::IrrlichtDevice *device = 0;
irr::video::IVideoDriver *driver = 0;
irr::scene::ISceneManager *sceneManager = 0;

static NewtonWorld* world;

static NewtonBody* body;
static NewtonBody* bodyB;
static NewtonBody* bodyC;
irr::scene::ISceneNode *cubeNode = 0;

irr::scene::ISceneNode *cam = 0;
unsigned int lasttick;

void initScene()
{
    device = irr::createDevice(irr::video::EDT_OPENGL, irr::core::dimension2d<irr::u32>(640,480), false);
    driver = device->getVideoDriver();
    sceneManager = device->getSceneManager();
    sceneManager->addSkyBoxSceneNode(driver->getTexture("data/irrlicht2_up.bmp"),driver->getTexture("data/irrlicht2_dn.bmp"),driver->getTexture("data/irrlicht2_rt.bmp"),driver->getTexture("data/irrlicht2_lf.bmp"),driver->getTexture("data/irrlicht2_ft.bmp"),driver->getTexture("data/irrlicht2_bk.bmp"));

    world = NewtonCreate (NULL, NULL);
   
    // Création d'un cube soumis à la gravité.
   
    irr::scene::IMesh* cubeMesh = sceneManager->getMesh("data/smallcube.3ds");
    cubeNode = sceneManager->addMeshSceneNode(cubeMesh);
    cubeNode->setMaterialTexture(0, driver->getTexture("data/crate.jpg"));
    cubeNode->setMaterialFlag(irr::video::EMF_LIGHTING, false);

    NewtonCollision *collision;
    collision = NewtonCreateBox(world, 0, 0, 0, NULL);
    body = NewtonCreateBody (world, collision);
    NewtonReleaseCollision (world, collision);   
   
    NewtonBodySetUserData(body,reinterpret_cast<void*>(cubeNode));
   
    // Calcul de l'inertie de l'objet.
    float masse = 100.0;
    irr::core::vector3df inertie;
    irr::core::vector3df taille = irr::core::vector3df(10,10,10);
    inertie.X = (masse/12)*(pow(taille.Y,2)+pow(taille.Z,2));
    inertie.Y = (masse/12)*(pow(taille.X,2)+pow(taille.Z,2));
    inertie.Z = (masse/12)*(pow(taille.X,2)+pow(taille.Y,2));
    NewtonBodySetMassMatrix (body, masse, inertie.X, inertie.Y, inertie.Z);
   
    // Méthode permettant la modification de l'objet en fonction des forces.
    NewtonBodySetTransformCallback(body, SetMeshTransformEvent);
    NewtonBodySetForceAndTorqueCallback(body, ApplyForceAndTorqueEvent);
   
    irr::core::matrix4 mat;
    mat.setTranslation(irr::core::vector3df(0.0,0.0,50.0));
    NewtonBodySetMatrix(body, mat.pointer());
   
    // Fin de création.
   
    // Création d'un cube soumis à la gravité.
   
    irr::scene::IMesh* cubeMeshB = sceneManager->getMesh("data/irrlicht2_up.bmp");
    cubeNode = sceneManager->addMeshSceneNode(cubeMeshB);
    cubeNode->setMaterialTexture(0, driver->getTexture("data/irrlicht2_dn.bmp"));
    cubeNode->setMaterialFlag(irr::video::EMF_LIGHTING, false);

    NewtonCollision *collisionB;
    collisionB = NewtonCreateBox(world, 0, 0, 0, NULL);
    bodyB = NewtonCreateBody (world, collisionB);
    NewtonReleaseCollision (world, collisionB);   
   
    NewtonBodySetUserData(bodyB,reinterpret_cast<void*>(cubeNode));
   
    // Calcul de l'inertie de l'objet.
    float masseB = 200.0;
    irr::core::vector3df inertieB;
    irr::core::vector3df tailleB = irr::core::vector3df(10,10,10);
    inertieB.X = (masseB/12)*(pow(tailleB.Y,2)+pow(tailleB.Z,2));
    inertieB.Y = (masseB/12)*(pow(tailleB.X,2)+pow(tailleB.Z,2));
    inertieB.Z = (masseB/12)*(pow(tailleB.X,2)+pow(tailleB.Y,2));
    NewtonBodySetMassMatrix (bodyB, masseB, inertieB.X, inertieB.Y, inertieB.Z);
   
    // Méthode permettant la modification de l'objet en fonction des forces.
    NewtonBodySetTransformCallback(bodyB, SetMeshTransformEvent);
    NewtonBodySetForceAndTorqueCallback(bodyB, ApplyForceAndTorqueEvent);
   
    irr::core::matrix4 matB;
    matB.setTranslation(irr::core::vector3df(0.0,0.0,-50.0));
    NewtonBodySetMatrix(bodyB, matB.pointer());
   
    // Fin de création.
   
    // Création d'un cube non soumis à la gravité.
   
    irr::scene::IMesh* cubeMeshC = sceneManager->getMesh("data/irrlicht2_rt.bmp");
    cubeNode = sceneManager->addMeshSceneNode(cubeMeshC);
    cubeNode->setMaterialTexture(0, driver->getTexture("data/irrlicht2_lf.bmp"));
    cubeNode->setMaterialFlag(irr::video::EMF_LIGHTING, false);

    NewtonCollision *collisionC;
    collisionC = NewtonCreateBox(world, 0, 0, 0, NULL);
    bodyC = NewtonCreateBody (world, collisionC);
    NewtonReleaseCollision (world, collisionC);   
   
    NewtonBodySetUserData(bodyC,reinterpret_cast<void*>(cubeNode));
   
    // Calcul de l'inertie de l'objet.
    float masseC = 0.0;
    irr::core::vector3df inertieC;
    irr::core::vector3df tailleC = irr::core::vector3df(10,10,10);
    inertieC.X = (masseC/12)*(pow(tailleC.Y,2)+pow(tailleC.Z,2));
    inertieC.Y = (masseC/12)*(pow(tailleC.X,2)+pow(tailleC.Z,2));
    inertieC.Z = (masseC/12)*(pow(tailleC.X,2)+pow(tailleC.Y,2));
    NewtonBodySetMassMatrix (bodyC, masseC, inertieC.X, inertieC.Y, inertieC.Z);
   
    // Méthode permettant la modification de l'objet en fonction des forces.
    NewtonBodySetTransformCallback(bodyC, SetMeshTransformEvent);
    NewtonBodySetForceAndTorqueCallback(bodyC, ApplyForceAndTorqueEvent);
   
    irr::core::matrix4 matC;
    matC.setTranslation(irr::core::vector3df(0.0,0.0,0.0));
    NewtonBodySetMatrix(bodyC, matC.pointer());
   
    // Fin de création.
   
   
    // Caméra
    irr::scene::ICameraSceneNode* cam = sceneManager->addCameraSceneNode();
    cam->setPosition(irr::core::vector3df(200,100,0));
    cam->setTarget(irr::core::vector3df(0,0,0));
}

// -----------------------------------------------------------------------------
// --------------------------------- CALLBACK ----------------------------------
// -----------------------------------------------------------------------------

void SetMeshTransformEvent(const NewtonBody* body, const float* matrix)
{
    irr::core::matrix4 mat;
    memcpy(mat.pointer(), matrix, sizeof(float)*16);

    irr::scene::ISceneNode *cubeNode = (irr::scene::ISceneNode *)NewtonBodyGetUserData(body);
    if (cubeNode)
    {
        cubeNode->setPosition(mat.getTranslation());
        cubeNode->setRotation(mat.getRotationDegrees());
    }
}

void ApplyForceAndTorqueEvent(const NewtonBody* body)
{
    float masse;
    float inertieX;
    float inertieY;
    float inertieZ;
    float force[3];
    float torque[3];
   
    NewtonBodyGetMassMatrix (body, &masse, &inertieX, &inertieY, &inertieZ);
   
    force[0] = 0.0f;
    force[1] = -9.81 * masse;
    force[2] = 0.0f;
   
    torque[0] = 0.0f;
    torque[1] = 0.0f;
    torque[2] = 0.0f;
   
    NewtonBodyAddForce(body, force);
    NewtonBodyAddTorque(body, torque);
}

// -----------------------------------------------------------------------------
// ------------------------------- END OF CALLBACK -----------------------------
// -----------------------------------------------------------------------------

void drawScene(){
   
    if (device->getTimer()->getTime() > lasttick + 10)
    {   
    lasttick = device->getTimer()->getTime();
    NewtonUpdate(world, 0.01f);
    }
}

int main()
{
   initScene();
   
   while(device->run())
   {
      drawScene();
      driver->beginScene(true, true, irr::video::SColor(255,255,255,255));
      sceneManager->drawAll();
      driver->endScene();
   }
   
   NewtonDestroy(world);
   device->drop();
   return 0;
}



Je ne comprend pas pourquoi ça ne fonctionne pas. Pourriez vous m'aider pendant que je cherche de mon coté.

Dernière modification par Kaze (13-08-2012 01:15:12)

Hors ligne


#22 

13-08-2012 13:20:08

Gehogor
Abonné
Lieu: Paris
Date d'inscription: 02-06-2009
Messages: 130
Corrections: 7

Très cher Kaze, cette constatation fait partie des lois physiques que notre monde subi, en effet, la chute d'un corps ou plutôt son accélération de chute ne dépend pas de la masse mais que de l'accélération de pesanteur (enfin, à preuve du contraire, on ne sait jamais on pourrait faire de nouvelles découvertes).

Une plume chutera aussi vite qu'une voiture dans le vide, en respectant le fait qu'il n'y ait aucun frottement (l'air par exemple).


Et hop... wink

Hors ligne


#23 

13-08-2012 13:29:27

Kaze
Membre
Date d'inscription: 12-03-2011
Messages: 60

Je suis au courant mais pourtant, lorsque l'on crée un monde on lui applique un certain coefficient de friction qui est égal à 0.9 par défaut. Donc on crée un monde où il y a des frottements et par définition, les objets devraient tomber à deux vitesses différentes. C'est pour ça que je ne comprend pas.

Hors ligne


#24 

13-08-2012 19:23:26

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Dans la fonction"ApplyForceAndTorqueEvent"

Code:

remplace :

NewtonBodyAddForce(body, force);
NewtonBodyAddTorque(body, torque); 

par :

NewtonBodySetForce(body, force);
NewtonBodySetTorque(body, torque);

Parce que c'est vrai que 2 objets de masses différentes soumis à la même force de gravité tombe à la même vitesse. Mais là, en occurrence, les objets ont une gravité différente puisque dans "ApplyForceAndTorqueEvent", il multiplie la gravité par la masse. Par contre, le fait que tu ajoutes la force peut poser problème. Donc un "set" au lieu de "add" résoudrai peut-être le problème...


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
881 membres
1427 sujets
11117 messages
Dernier membre inscrit: Bidule
28 invités en ligne
Aucun membre connecté
RSS Feed