#50 

23-08-2012 19:26:55

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

Fais plutot sauter un node tongue.
Sinon, sérieusement lors de l'appui sur le bouton saut fait un addForce, le callback sert pour ce qui est fixe. Par contre, à toi d'utiliser un booléen pour que la fonction soit appelée lors du passage à l'état pressé de la touche. Sinon ton addForce sera éxécuté à chaque frame tant que ton "bouton sauter" restera appuyé.
Ah! Et pour ton cube, Ne JAMAIS déplacer un node géré par newton manuellement! Parce que sinon ton node et donc ton mesh seront décalés pour Irrlicht mais Newton n'en saura rien. Si tu regardes ton programme, Newton applique la physique à son body, en déduit une rotation et une translation, puis l'applique au node d'irrlicht. Donc faire un setPosition ou un setRotation crééra un décalage entre le body et le node.

Dernière modification par johnplayer (23-08-2012 19:31:56)


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


#51 

23-08-2012 19:48:58

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

donc pour la deuxième question, il faut que je traduise la translation avec les matrice de newton. Ok, je sais faire. Merci

Hors ligne


#52 

23-08-2012 20:02:50

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

Moi je ferais un truc du genre :

1/ récupération de la matrice du body
NewtonBodyGetMatrix( const NewtonBody* bodyPtr, dFloat* matrixPtr)
2/ on effectue la translation et la rotation
calcule de la nouvelle matrice. ATTENTION : l'échelle de Newton est différente de celle d'Irrlicht donc applique le facteur d'échelle aux translations.
3/ On applique les changements
NewtonBodySetMatrix( const NewtonBody* bodyPtr, const dFloat* matrixPtr)


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


#53 

24-08-2012 02:01:04

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

J'ai un autre problème (mais ya plus rien à voir avec le titre du sujet). J'ai créer une méthode pour récupérer un clic gauche de la souris et créer un cube avec. Mais le code se lance parfaitement mais lorsque je clic, rien ne se passe.

Voici ma méthode :

Code c++ :


bool Physics::OnEvent(const irr::SEvent& event){
     
    if(event.EventType == irr::EET_MOUSE_INPUT_EVENT && event.MouseInput.Event == irr::EMIE_LMOUSE_PRESSED_DOWN)
    {
        irr::core::vector3df position = irr::core::vector3df(0,60,0);
        irr::core::vector3df taille = irr::core::vector3df(40,40,40);
        float masse = 1000.0;
        //Physics::Cube(position, taille, masse);
        Cube(position, taille, masse);
       
        return true;
    }
    return false;
}


J'ai essayé soit avec Cube(); soit avec Physics::Cube(); sans résultat dans les deux cas.

Saurais-tu où se cache le problème ?

EDIT :

J'ai rajouté

#ifdef _DEBUG
printf("Cliq OK\n");
#endif

dans le if mais rien n'est apparu. Comment puis-je voir le printf ?

Dernière modification par Kaze (24-08-2012 02:03:41)

Hors ligne


#54 

24-08-2012 08:04:50

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

Normal! Quand est-ce que tu appelles Physics::OnEvent?
1/ Physics ne dérive pas de IEventReceiver!
2/ Physics n'est pas le IEventReceiver attaché au device!

Créé un eventReceiver dans la partie de ton code qui contient ce qui appartient à Irrlicht.

Je ferais comme ça :

class Engine : public IEventReceiver
{
     // classe principale contenant ce qui concerne Irrlicht
     // contient aussi les pointeurs vers tes autres classes comme Physics

Engine();
virtual~Engine();

//! contient le code pour les événements
virtual bool OnEvent();

//! créé la fenetre et la classe Physique (instance de Physics)
bool init();

//! boucle de rendu
void run();

//! Quitte le jeu (quitte proprement irrlicht, et détruit l'instance Physique)
u32 Quit();

}

class Physics
{
     // contient ce qui concerne Newton
}

Physics ne reçoit des infos appartenant a engine QUE par arguments (dans ces fonctions ou constructeurs)
Engine a un pointeur sur Physics pour faire appel à ses fonctions, ainsi que le créé et le détruire.

Le code sera déjà mieux structuré. Parce que tu créé une classe afin de séparer Irrlicht et Newton et ensuite tu mets du code Irrlicht (OnEvent) dans le code Newton. Garde à l'esprit que la base de ton code est Irrlicht donc c'est lui qui gère l'intégration des autres parties (newton, irrklang...). Et que les autres parties sont autonomes! Newton fait des "trucs Newtonien" et Irrlicht appelle ces "trucs Newtonien". Si tu gardes cette optique, tu devrais pouvoir faire un code cohérent, sinon tu te seras compliqué la vie pour rien puisque ton code équivaudra à avoir tout codé dans le "main".

Ceci dit, je dis ça pour t'aider. Après libre à toi de le suivre ou non. Mais saches qu'il est plus facile de debugger un code bien structuré et que moi ainsi que les autres sur le forum t'aideront plus facilement aussi.


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


#55 

24-08-2012 09:30:23

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

Je t'explique pourquoi j'avais fais comme ça :

Comme, dans ma méthode qui gère l'event, je vais utiliser que des fonctions de newton (vu que je vais deplacer mon objet comme tu l'as dit sur les messages precedants ou le faire "sauter") je voulais mettre cette méthode dans ma classe Physics.

Après, je suis en train de faire des exemples de code. Mon but final, serait d'avoir des fichiers qu'il me suffirais d'inclure dans un projet pour que je rajoute un système. Pour être clair, si je veux qu'un projet puisse gérer a physique, je n'ai qu'à inclure physics.cpp et physics.hpp (et à modifier un peu le main).  C'est pourquoi ça m'embêterais de créer une classe avec tout les truc d'Irrlicht vu qu'au final, ces éléments serait créer dans un main.

Cependant, j'aimerais tout de même voir comment faire un Engine comme toi pour comprendre (parce qu'à vrai dire, c'est un peu abstrait cette classe Engine), c'est pourquoi je me demande :

1 : dans mon void run(); je n'aurais que la grande boucle : while (m_device->run()) ?

2 : tout les trucks d'irrlicht comme les devices, drivers, ..., seront appelé dans le constructeur de Engine ou dans le bool init() ?

3 : dans la méthode OnEvent, je vais devoir faire appel à des méthodes de newton cela signifie qu'il faut que je crée une méthode pour chaque déplacements ?

Je crois que c'est tout pour l'instant. Mais je vais essayer de mon coté.

Hors ligne


#56 

24-08-2012 10:30:33

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

Pour ton onEvent, je vois ce que tu veux dire. Mais pour ce qui est de séparer Irrlicht dans une classe en héritant de IEventReceiver, c'est quasi-impératif. Crois-en mon expérience, j'ai pensé comme toi au début jusqu'à ce que je m'aperçoive d'un gros problème : si tu créé une classe eventReceiver (obligatoire pour gérer les events) et que tu veux accéder à des variables de ton main, tu es obligé de déclarer ces variables en globales. Par contre, si tu créé la classe Irrlicht (qui sera réutilisable comme physics) tu n'auras plus ce problème. DONC fais-moi confiance et créé une classe pour la partie Irrlicht. De plus, tu as un avantage de faire une classe : tu peux dispatcher tes implémentations de fonctions sur plusieurs fichiers cpp. Ca évite d'avoir un fichier de 5000 lignes.

Pour ton histoire de OnEvent avec physics, tu peux faire ainsi :

Code c++ :


//! initialisation d'irrlicht et création de l'instance de Physics
Engine::init()
{
     // initialisation device, smgr...

     // mets en place la partie event pour que Engine::OnEvent soit appelée par Irrlicht
     device->setEventReceiver(this);

     // création de l'instance Physics
...
}

//! OnEvent de la class engine
bool Engine::OnEvent()
{
     // gestion des events irrlicht
...

     // gestion des events Physics (avec Physics* Physique membre de la classe Engine)
     return Physique->OnEvent();
}

//! OnEvent de la classe Physics
bool Physics::OnEvent()
{
     // gestion des events physics
...

     // aucun event traité
     return false;
}



ATTENTION : Lorsque tu as traité un événement dans une fonction OnEvent fait un return true. Tu le fais déjà mais c'est juste pour être sûr que tu y fasses bien attention.

Ensuite,

1 : oui c'est ça juste la boucle et peut-être aussi des variables locales à déclarer avant l'entrée de boucle.

2 : oui, on évite les initialisations comme device, smgr et driver dans les constructeurs. la fonction init permet de renvoyer false si un problème est survenu. Tu peux donc quitter le programme sans planter grâce à la valeur de retour de init().

3 : Si tu fais le OnEvent comme je t'ai montré au-dessus, tu peux faire comme tu le voulais au départ^^.

Normalement ton main sera ultra-minimaliste genre :

Code c++ :


// en reprenant l'exemple que je t'ai donné quelques posts plus tôt
int main()
{
     Engine game();
     //! création de la fenetre, de la classe physics
     if( game.init() )
     {
          //! L'initialisation a réussie, lancement de jeu
          game.run();
     {
     //! libère Irrlicht, Newton, et quitte le programme
     return game.quit();
}



C'est une structure de programme que j'ai composé au fur et à mesure que j'ai créé mes petits programmes. J'essaie juste de te faire gagner du temps et de t'éviter des prises de tête (et donc tu pourras garder tes cheveux plus longtemps^^).
Avant d'arriver à structurer mon programme correctement, j'ai réécris certains de mes programmes plusieurs fois en changeant la structure pour corriger des problèmes.


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


#57 

24-08-2012 18:24:20

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

J'au une autre erreur :

evenement.hpp

Code c++ :


#ifndef EVENEMENT_HPP
#define EVENEMENT_HPP

#include "main.hpp"
#include "physics.hpp"

class Evenement : public irr::IEventReceiver
{
    public :
   
    Evenement();
    void Init();
    int Run();
   
    protected :
             
    virtual bool OnEvent(const irr::SEvent& event);
   
    private :
   
    irr::IrrlichtDevice* eventDevice;
    irr::video::IVideoDriver* eventDriver;
    irr::scene::ISceneManager* eventSceneManager;
   
    Physics newton;
   
};

#endif



evenement.cpp :

Code c++ :


#include "evenement.hpp"

Evenement::Evenement(){}

void Evenement::Init(){
   
    eventDevice = irr::createDevice(irr::video::EDT_OPENGL, irr::core::dimension2d<irr::u32>(640,480), false);
    eventDriver = eventDevice->getVideoDriver();
    eventSceneManager = eventDevice->getSceneManager();
    eventSceneManager->addSkyBoxSceneNode(eventDriver->getTexture("data/irrlicht2_up.bmp"),eventDriver->getTexture("data/irrlicht2_dn.bmp"),eventDriver->getTexture("data/irrlicht2_rt.bmp"),eventDriver->getTexture("data/irrlicht2_lf.bmp"),eventDriver->getTexture("data/irrlicht2_ft.bmp"),eventDriver->getTexture("data/irrlicht2_bk.bmp"));
   
    eventDevice->setWindowCaption(L"Test sur les evenements lies a la physique.");
   
    // Caméra
    irr::scene::ICameraSceneNode* camera = eventSceneManager->addCameraSceneNode();
    camera->setPosition(irr::core::vector3df(200,100,0));
    camera->setTarget(irr::core::vector3df(0,0,0));
   
    // Installation de la physique.
    Physics newton(eventDevice, eventDriver, eventSceneManager);
    newton.Sol();
   
    // Création d'un cube soumis à la gravité.
    irr::core::vector3df positionA = irr::core::vector3df(0,50,0);
    irr::core::vector3df tailleA = irr::core::vector3df(40,40,40);
    float masseA = 100.0;
    newton.Cube(positionA, tailleA, masseA);
   
    // Création d'un cube soumis à la gravité.
    irr::core::vector3df positionB = irr::core::vector3df(0,0,25);
    irr::core::vector3df tailleB = irr::core::vector3df(40,40,40);
    float masseB = 100.0;
    newton.Cube(positionB, tailleB, masseB);
   
    // Création d'un cube controler.
    irr::core::vector3df positionC = irr::core::vector3df(-50,-79,0);
    float masseC = 100.0;
    newton.Player(positionC, masseC);
   
    eventDevice->setEventReceiver(this);
}

int Evenement::Run(){
    while (eventDevice->run())
    {
        newton.Update();
       
        eventDriver->beginScene(true, true, irr::video::SColor(255,255,255,255));
        eventSceneManager->drawAll();
        eventDriver->endScene();
    }
    eventDevice->drop();
    return 0;
}

bool Evenement::OnEvent(const irr::SEvent& event){
     
    if(event.EventType == irr::EET_MOUSE_INPUT_EVENT)
    {
        if(event.MouseInput.Event == irr::EMIE_LMOUSE_PRESSED_DOWN)
        {
            newton.Cube(irr::core::vector3df(0,50,0), irr::core::vector3df(40,40,40), 100.0);
            return true;
        }
    }
    return false;
}



Je n'arrive pas à transmettre mon monde physique aux différentes méthodes de ma classe Evenement.  Je voudrais pouvoir utiliser "newton" comme j'utilise "eventDevice", c'est pourquoi j'ai utilisé Physics newton dans mon .hpp mais il ne veux pas.

Il ne me dit que : evenement.hpp `Physics' does not name a type

Dernière modification par Kaze (24-08-2012 18:24:55)

Hors ligne


#58 

24-08-2012 19:52:52

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

Essai ce code :

evenement.hpp

Code c++ :


#ifndef EVENEMENT_HPP
#define EVENEMENT_HPP

#include "main.hpp"

class Physics;

class Evenement : public irr::IEventReceiver
{
    public :
   
    Evenement();
    void Init();
    int Run();
   
    protected :
             
    virtual bool OnEvent(const irr::SEvent& event);
   
    private :
   
    irr::IrrlichtDevice* eventDevice;
    irr::video::IVideoDriver* eventDriver;
    irr::scene::ISceneManager* eventSceneManager;
   
    Physics *newton;
   
};

#endif



Ensuite tu ajoutes #include "main.hpp" dans  le fichier "physics.hpp".
Puis tu ajoutes #include "physics.hpp" dans "evenement.cpp"

Vu que newton est devenu un pointeur tes "newton." vont devenir "newton->".

Et dis-moi si tu as toujours une erreur.


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


#59 

25-08-2012 02:30:44

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

J'ai fais tous ce que tu as dit et ça plante toujours. Déjà, le compilo voulais pas que je mette newton->Sol(); dans le void Init(); J'ai tout de même remplacé :

newton.Update(); par newton->Update();
newton.Cube(); par newton->Cube();

J'ai placé aussi class Physics; dans evenement.hpp.

Mais le code s'ouvre avec une fenetre blanche et plante directement après et le code s'execute sans planter quand je met newton->Update(); et newton->Cube(); en commentaires.

Voilà donc je plante encore.

Hors ligne


#60 

25-08-2012 08:34:23

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

Montre tout ton code, pour que je puisse voir :
main.cpp
class evenement (.hpp + .cpp)
class physics (.hpp + .cpp)

Parce que sans ton code je peux rien faire.


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


#61 

25-08-2012 13:12:15

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

Désolé pour le retard donc voila :

main.cpp :

Code c++ :


#include "main.hpp"

int main(){
   
    Evenement engine;
    engine.Init();
    return engine.Run();
   
}



main.hpp :

Code c++ :


#ifndef MAIN_HPP
#define MAIN_HPP

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

#include "evenement.hpp"

#endif



physics.cpp :

Code c++ :


#include "physics.hpp"

NewtonWorld* Physics::newtonWorld = NULL;
NewtonBody* Physics::newtonBody = NULL;

// CONSTRUCTEUR ----------------------------------------------------------------

Physics::Physics(irr::IrrlichtDevice *device, irr::video::IVideoDriver *driver, irr::scene::ISceneManager *sceneManager){                   
    newtonDevice = device;
    newtonDriver = driver;
    newtonSceneManager = sceneManager;
   
    Physics::newtonWorld = NewtonCreate();
   
    // Initialisation du point initial du monde physique.
    pointS[0] = -500.0;
    pointS[1] = -500.0;
    pointS[2] = -500.0;
   
    // Initialisation du point final du monde physique.
    pointE[0] = 500.0;
    pointE[1] = 500.0;
    pointE[2] = 500.0;
   
    NewtonSetWorldSize(Physics::newtonWorld, pointS, pointE);
   
    newtonNode = NULL;
}

// DESTRUCTEUR -----------------------------------------------------------------

Physics::~Physics(){
    NewtonDestroy(newtonWorld);
}

// BUILDS ----------------------------------------------------------------------

void Physics::Cube(irr::core::vector3df position, irr::core::vector3df taille, float masse){
   
    irr::scene::IMesh* cubeMesh = newtonSceneManager->getMesh("data/irrlicht2_up.bmp");
    newtonNode = newtonSceneManager->addMeshSceneNode(cubeMesh);
    newtonNode->setMaterialTexture(0, newtonDriver->getTexture("data/irrlicht2_dn.bmp"));
    newtonNode->setMaterialFlag(irr::video::EMF_LIGHTING, false);
   
    NewtonCollision* collision;
    irr::core::matrix4 mat;
   
    collision = NewtonCreateBox(Physics::newtonWorld, taille.X, taille.Y, taille.Z, 0, NULL);
    Physics::newtonBody = NewtonCreateBody(Physics::newtonWorld, collision, mat.pointer());
    NewtonReleaseCollision(newtonWorld, collision);
   
    NewtonBodySetUserData(newtonBody,reinterpret_cast<void*>(newtonNode));
   
    if(masse == 0.0){newtonNode->setPosition(position);}
   
    if(masse != 0.0){
        irr::core::vector3df inertie;
        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 (newtonBody, masse, inertie.X, inertie.Y, inertie.Z);
       
        NewtonBodySetTransformCallback(newtonBody, SetMeshTransformEvent);
        NewtonBodySetForceAndTorqueCallback(newtonBody, ApplyForceAndTorqueEvent);
    }
   
    mat.setTranslation(position);
    NewtonBodySetMatrix(newtonBody, mat.pointer());
}

void Physics::Player(irr::core::vector3df position, float masse){
   
    irr::scene::IMesh* cubeMesh = newtonSceneManager->getMesh("data/irrlicht2_rt.bmp");
    newtonNode = newtonSceneManager->addMeshSceneNode(cubeMesh);
    newtonNode->setMaterialTexture(0, newtonDriver->getTexture("data/irrlicht2_lf.bmp"));
    newtonNode->setMaterialFlag(irr::video::EMF_LIGHTING, false);
   
    NewtonCollision* collision;
    irr::core::matrix4 mat;
   
    collision = NewtonCreateBox(Physics::newtonWorld, 40, 40, 40, 0, NULL);
    Physics::newtonBody = NewtonCreateBody(Physics::newtonWorld, collision, mat.pointer());
    NewtonReleaseCollision(newtonWorld, collision);
   
    NewtonBodySetUserData(newtonBody,reinterpret_cast<void*>(newtonNode));
   
    irr::core::vector3df inertie;
    inertie.X = (masse/12)*3200;
    inertie.Y = (masse/12)*3200;
    inertie.Z = (masse/12)*3200;
    NewtonBodySetMassMatrix (newtonBody, masse, inertie.X, inertie.Y, inertie.Z);
       
    NewtonBodySetTransformCallback(newtonBody, SetMeshTransformEvent);
    NewtonBodySetForceAndTorqueCallback(newtonBody, ApplyForceAndTorqueEvent);
   
    mat.setTranslation(position);
    NewtonBodySetMatrix(newtonBody, mat.pointer());
}

void Physics::Sol(){
   
    float largeur = pointE[0] - pointS[0];
    float longueur = pointE[2] - pointS[2];
    irr::core::vector3df position = irr::core::vector3df(0,-100,0);
   
    irr::scene::IAnimatedMesh* solMesh = newtonSceneManager->addHillPlaneMesh("data/irrlicht2_ft.bmp", irr::core::dimension2d<irr::f32>(200,170), irr::core::dimension2d<irr::u32>(5,5));
   
    newtonNode = newtonSceneManager->addMeshSceneNode(solMesh);
    newtonSceneManager->getMeshManipulator()->makePlanarTextureMapping(solMesh->getMesh(0), 0.01f);
    newtonNode->setMaterialTexture(0, newtonDriver->getTexture("data/irrlicht2_bk.bmp"));
    newtonNode->setMaterialFlag(irr::video::EMF_LIGHTING, false);
   
    NewtonCollision* collision;
    irr::core::matrix4 mat;
   
    collision = NewtonCreateBox(Physics::newtonWorld, largeur, 1, longueur, 0, NULL);
    Physics::newtonBody = NewtonCreateBody(Physics::newtonWorld, collision, mat.pointer());
    NewtonReleaseCollision(newtonWorld, collision);
   
    NewtonBodySetUserData(newtonBody,reinterpret_cast<void*>(newtonNode));
   
    newtonNode->setPosition(position);
    mat.setTranslation(position);
    NewtonBodySetMatrix(newtonBody, mat.pointer());
}

// EVENTS ----------------------------------------------------------------------




// METHODES --------------------------------------------------------------------

void Physics::Update(){
     
    if(newtonDevice->getTimer()->getTime() > lasttick + 10)
    {   
        lasttick = newtonDevice->getTimer()->getTime();
        NewtonUpdate(newtonWorld, 0.01f);
    }
}

// CALLBACKS -------------------------------------------------------------------

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

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

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

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



physics.hpp :

Code c++ :


#ifndef PHYSICS_HPP
#define PHYSICS_HPP

#include "newt/Newton.h"

#include "main.hpp"

class Physics
{
    public :
   
    // Constructeur - Destructeur ----------------------------------------------
    Physics(irr::IrrlichtDevice *device, irr::video::IVideoDriver *driver, irr::scene::ISceneManager *sceneManager);
    ~Physics();
   
    // Builds ------------------------------------------------------------------
    void Cube(irr::core::vector3df position, irr::core::vector3df taille, float masse);
    void Player(irr::core::vector3df position, float masse);
    void Sol();
   
    // Events ------------------------------------------------------------------
   
   
   
    // Methodes ----------------------------------------------------------------
    void Update();
   
    // Callbacks ---------------------------------------------------------------
   
    static void SetMeshTransformEvent(const NewtonBody* body, const float* matrix, int);
    static void ApplyForceAndTorqueEvent(const NewtonBody* body, float, int);
   
    // -------------------------------------------------------------------------
   
    private :
   
    irr::IrrlichtDevice* newtonDevice;
    irr::video::IVideoDriver* newtonDriver;
    irr::scene::ISceneManager* newtonSceneManager;
   
    static NewtonWorld* newtonWorld;
    static NewtonBody* newtonBody;
    irr::scene::ISceneNode* newtonNode;
   
    unsigned int lasttick;
    float pointS[3];
    float pointE[3];
};

#endif



evenement.cpp :

Code c++ :


#include "evenement.hpp"

Evenement::Evenement(){}

void Evenement::Init(){
   
    eventDevice = irr::createDevice(irr::video::EDT_OPENGL, irr::core::dimension2d<irr::u32>(640,480), false);
    eventDriver = eventDevice->getVideoDriver();
    eventSceneManager = eventDevice->getSceneManager();
    eventSceneManager->addSkyBoxSceneNode(eventDriver->getTexture("data/irrlicht2_up.bmp"),eventDriver->getTexture("data/irrlicht2_dn.bmp"),eventDriver->getTexture("data/irrlicht2_rt.bmp"),eventDriver->getTexture("data/irrlicht2_lf.bmp"),eventDriver->getTexture("data/irrlicht2_ft.bmp"),eventDriver->getTexture("data/irrlicht2_bk.bmp"));
   
    eventDevice->setWindowCaption(L"Test sur les evenements lies a la physique.");
   
    // Caméra
    irr::scene::ICameraSceneNode* camera = eventSceneManager->addCameraSceneNode();
    camera->setPosition(irr::core::vector3df(200,100,0));
    camera->setTarget(irr::core::vector3df(0,0,0));
   
    // Installation de la physique.
    Physics newton(eventDevice, eventDriver, eventSceneManager);
    newton.Sol();
   
    // Création d'un cube soumis à la gravité.
    irr::core::vector3df positionA = irr::core::vector3df(0,50,0);
    irr::core::vector3df tailleA = irr::core::vector3df(40,40,40);
    float masseA = 100.0;
    newton.Cube(positionA, tailleA, masseA);
   
    // Création d'un cube soumis à la gravité.
    irr::core::vector3df positionB = irr::core::vector3df(0,0,25);
    irr::core::vector3df tailleB = irr::core::vector3df(40,40,40);
    float masseB = 100.0;
    newton.Cube(positionB, tailleB, masseB);
   
    // Création d'un cube controler.
    irr::core::vector3df positionC = irr::core::vector3df(-50,-79,0);
    float masseC = 100.0;
    newton.Player(positionC, masseC);
   
    eventDevice->setEventReceiver(this);
}

int Evenement::Run(){
    while (eventDevice->run())
    {
        newton->Update();
       
        eventDriver->beginScene(true, true, irr::video::SColor(255,255,255,255));
        eventSceneManager->drawAll();
        eventDriver->endScene();
    }
    eventDevice->drop();
    return 0;
}

bool Evenement::OnEvent(const irr::SEvent& event){
     
    if(event.EventType == irr::EET_MOUSE_INPUT_EVENT)
    {
        if(event.MouseInput.Event == irr::EMIE_LMOUSE_PRESSED_DOWN)
        {
            //newton->Cube(irr::core::vector3df(0,50,0), irr::core::vector3df(40,40,40), 100.0);
            return true;
        }
    }
    return false;
}



evenement.hpp :

Code c++ :


#ifndef EVENEMENT_HPP
#define EVENEMENT_HPP

#include "main.hpp"
#include "physics.hpp"

class Physics;

class Evenement : public irr::IEventReceiver
{
    public :
   
    Evenement();
    void Init();
    int Run();
   
    protected :
             
    virtual bool OnEvent(const irr::SEvent& event);
   
    private :
   
    irr::IrrlichtDevice* eventDevice;
    irr::video::IVideoDriver* eventDriver;
    irr::scene::ISceneManager* eventSceneManager;
   
    Physics* newton;
   
};

#endif

Hors ligne


#62 

25-08-2012 18:12:01

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

Dans run() tu mets "eventDevice->drop();", c'est bien mais faut quand même mettre "delete newton;". Tu as une classe non détruite.

C'est quoi ça!
// Installation de la physique.
Physics newton(eventDevice, eventDriver, eventSceneManager);
newton.Sol();

"newton" est un pointeur sur une classe!
Là tu créé une classe locale à Init()! Donc Evenement::newton=NULL, du coup dès que tu essais d'utilisé Evenement::newton comme avec newton->cube(...) forcément ça ne peut que planter.

// Création de l'instance de la physique
newton = new Physics(eventDevice, eventDriver, eventSceneManager);
newton->sol();

Et changes tous les "newton." en "newton->". Si tu avais fait attention, tu te serais aperçu qu'il y avait un truc qui cloche! Un pointeur ne peut pas utilisé l'accesseur "." Donc c'est qu'il y avait une instance de type Physics.


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


#63 

25-08-2012 18:30:01

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

Ah d'accord, je veins de me rendre compte que j'avais rien compris avant.

Merci beaucoup je vais essayer de modifier pour voir.

EDIT : Tout marche correctement, je vais enfin pouvoir essayer de m'amuser en codant. Encore merci.

Hors ligne


#64 

25-08-2012 21:48:28

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

De rien, amuse-toi bien!


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


#65 

26-08-2012 16:05:39

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

Alors j'ai beaucoup de nouveaux problèmes ou questions désormais. Je vais d'abord montrer mon code avant de poser les questions.

physics.cpp (juste la partie des events)

Code c++ :


bool Physics::Down(){
   
    irr::core::matrix4 matPlayer;
    NewtonBodySetMatrix(newtonPlayer, matPlayer.pointer());
    Physics::positionPlayer.X += 8;
    matPlayer.setTranslation(Physics::positionPlayer);
    NewtonBodySetMatrix(newtonPlayer, matPlayer.pointer());
    return true;
}

bool Physics::Left(){
   
    irr::core::matrix4 matPlayer;
    NewtonBodySetMatrix(newtonPlayer, matPlayer.pointer());
    Physics::positionPlayer.Z -= 8;
    matPlayer.setTranslation(Physics::positionPlayer);
    NewtonBodySetMatrix(newtonPlayer, matPlayer.pointer());
    return true;
}

bool Physics::Right(){
   
    irr::core::matrix4 matPlayer;
    NewtonBodySetMatrix(newtonPlayer, matPlayer.pointer());
    Physics::positionPlayer.Z += 8;
    matPlayer.setTranslation(Physics::positionPlayer);
    NewtonBodySetMatrix(newtonPlayer, matPlayer.pointer());
    return true;
}

bool Physics::Up(){
   
    irr::core::matrix4 matPlayer;
    NewtonBodySetMatrix(newtonPlayer, matPlayer.pointer());
    Physics::positionPlayer.X -= 8;
    matPlayer.setTranslation(Physics::positionPlayer);
    NewtonBodySetMatrix(newtonPlayer, matPlayer.pointer());
    return true;
}

bool Physics::Jump(){
   
    float masse;
    float inertieX;
    float inertieY;
    float inertieZ;
    float force[3];
    NewtonBodyGetMassMatrix (newtonPlayer, &masse, &inertieX, &inertieY, &inertieZ);
   
    force[0] = 0.0f;
    force[1] = 60000.0;
    force[2] = 0.0f;
   
    NewtonBodySetForce(newtonPlayer, force);
    return true;
}



evenement.cpp (juste la partie des events)

Code c++ :


bool Evenement::OnEvent(const irr::SEvent& event){
   
    if(event.EventType == irr::EET_MOUSE_INPUT_EVENT)
    {
        if(event.MouseInput.Event == irr::EMIE_LMOUSE_PRESSED_DOWN)
        {
            newton->Cube(irr::core::vector3df(0,50,25), irr::core::vector3df(40,40,40), 100.0);
            return true;
        }
    }
   
    if(event.EventType == irr::EET_KEY_INPUT_EVENT)
    {
        switch(event.KeyInput.Key){
           
            case irr::KEY_DOWN :
                 return newton->Down();
                 break;
           
            case irr::KEY_LEFT :
                 return newton->Left();
                 break;
                 
            case irr::KEY_RIGHT :
                 return newton->Right();
                 break;
                 
            case irr::KEY_UP :
                 return newton->Up();
                 break;
                 
            case irr::KEY_KEY_J :
                 return newton->Jump();
                 break;
        }
    }
    return false;
}



Alors quand j'éxécute mon code il fonctionne mais avec des défauts :

1 : lorsque j'appuie sur une des flèches, mon cube effectue un mouvement de 8 pixels (comme demandé) puis il a un petit temps immobile, et enfin il comprend que j'appui toujours sur la flèche donc il fait un mouvement continue. Y aurait-il un moyen de couper se temps de latence ?

2 : lorsque après un mouvement latéral, je rencontre un cube déjà présent, le cube que je contrôle passe au travers alors qu'il y est censé avoir collision. Comment faire pour appliquer la collision sur les coté du cube ?

3 : pour faire sauter le cube, j'applique une force verticale de 60000. Mais rien à faire le cube ne se déplace absolument pas en hauteur. J'ai essayé toutes les combinaisons entre NewtonBodySetForce et NewtonBodyAddForce sans qu'aucune ne fonctionne. Comment faire sauter mon petit cube ?

4 : lorsque j'appuie sur deux flèches en même temps (haut ou bas + gauche ou droite), mon cube se déplace diagonalement. Mais lorsque j'appuie sur un flèche directionnelle puis sur une autre quelques instants après (tout en gardant appuyé la première), mon cube se déplace d'abord dans la première direction puis dans la deuxième. Y a-t-il un moyen de faire qu'en appuyant sur une flèche puis sur une autre (tout en gardant appuyé la première), mon cube fasse d'abord un mouvement dans la première direction puis dans la diagonale qui correspond à la somme des deux mouvements des deux flèches ?

J'espère avoir été clair pour les questions. Merci d'avance pour votre aide.

Dernière modification par Kaze (26-08-2012 16:07:28)

Hors ligne


#66 

26-08-2012 16:21:57

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

Alors :

1 : un booléen que tu mets à true lorsque l'event est "bouton est appuyé" et que tu mets à false lorsque "bouton est relâché". Du coup, tu éxécutes l'action tant que ce booléen est true.

2 : ça vient certainement de ton implémentation, tu déplaces la matrice manuellement, peut-être faut-il faire qqch mais là je ne sais pas.

3 : je ne sais pas trop, je n'ai pas utilisé newton comme ça pour l'instant.

4 : implémentes un système pour avoir plusieurs touches simultanées. Genre, un tableau de 4 booléens représentant tes 4 flèches et tu prends l'astuces que j'ai donné au-dessus. Ensuite dans OnEvent, tu implémentes ton système de direction à l'aide de ce tableau (si Haut && Gauche alors déplacement diagonal...).


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


#67 

26-08-2012 16:57:19

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

Pour le 1, j'avais essayé ce code avant mais j'avais le même problème :

Code c++ :


case irr::KEY_DOWN :
                 if(event.KeyInput.PressedDown == true){return newton->Down();}
                 else{return newton->Stop();}
                 break;
           
case irr::KEY_LEFT :
                 if(event.KeyInput.PressedDown == true){return newton->Left();}
                 else{return newton->Stop();}
                 break;
                 
case irr::KEY_RIGHT :
                 if(event.KeyInput.PressedDown == true){return newton->Right();}
                 else{return newton->Stop();}
                 break;
                 
case irr::KEY_UP :
                 if(event.KeyInput.PressedDown == true){return newton->Up();}
                 else{return newton->Stop();}
                 break;
                 
case irr::KEY_SPACE :
                 return newton->Jump();
                 break;



Code c++ :


bool Physics::Stop(){
   
    irr::core::matrix4 matPlayer;
    NewtonBodySetMatrix(newtonPlayer, matPlayer.pointer());
    matPlayer.setTranslation(Physics::positionPlayer);
    NewtonBodySetMatrix(newtonPlayer, matPlayer.pointer());
    return true;
}

Dernière modification par Kaze (26-08-2012 16:58:11)

Hors ligne


#68 

26-08-2012 17:42:19

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

Pourquoi n'appliquerais-tu pas une force à ton cube plutôt que de bouger la matrice?

Pour la fonction jump, pourquoi tu redéfinis tout, tu as fait un vulgaire copier-coller du callback?

Code c++ :


bool Physics::Jump()
{
    NewtonBodyAddForce(newtonPlayer, force);
    return true;
}

Dernière modification par johnplayer (26-08-2012 17:46:16)


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


#69 

26-08-2012 19:59:39

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

1 : Si on utilise des forces pour déplacer le cube, le problème ne se pose plus.
2 : idem
3 : la fonction NewtonBodyAddForce ou NewtonBodySetForce ne s'utilise que dans un callback donc j'ai créer un callbakc pour chaque mouvement.
4 : idem que 2 et 1

Mais maintenant j'ai un autre soucis qui est du au fait ....... que la physique est trop bien fait.

Lorsque je fais sauter mon cube, il monte puis redescend, touche le sol ...... et rebondi !!!!! La question est claire, si je veux transformer ce cube en un personnage de jeu, il serait préférable qu'il ne rebondisse pas comme un ballon.

Quelqu'un à une idée pour contrer le rebond ?

Hors ligne


#70 

26-08-2012 20:06:11

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

Ton body possède un materiau, il utilise le materiau par defaut qui lui possède des propriétés elasticity, softness...

Pour t'éclairer un peu mais va voir la doc pour plus d'explication

Code c++ :


/// materiau par défaut
NewtonMaterialSetDefaultFriction( World, 0, 0, 0.5f, 0.5f);
NewtonMaterialSetDefaultElasticity( World, 0, 0, 0.0f); // paramètre qui fait ou non rebondir le body (si = 0.0f, l'objet ne rebondit pas)
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

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


#71 

26-08-2012 22:37:36

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

J'avais vu cette fonction mais je n'ai pas trouvé comment dire que tel matérial a pour id 1 et qu'un autre a pour id 2. Je cherche encore.

EDIT : Trouver - c'est NewtonBodySetMaterialGroupID(Physics::newtonPlayer, id);

Dernière modification par Kaze (26-08-2012 22:47:41)

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
41 invités en ligne
Aucun membre connecté
RSS Feed