#0 

02-08-2013 16:29:02

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

Bonjour,

mon problème est le suivant : j'ai un mesh soumis à la gravité. Et pour le faire se déplacer je applique à ce mesh une force dirigée suivant x. Dans ce cas on a la gravité (suivant -y) et la force (suivant x). Je place mon modèle à une certaine distance du sol pour pouvoir observer l'influence des deux forces. Mais mon problème est là car quelque soit la manière dont j'applique la force, il ne considère que celle là. Au final j'ai un mesh qui flotte en l'air et se déplace dans la direction de la force. Voila je vais vous montrer mon code sinon ça ne sert à rien (si vous voulez voir plus de choses, il suffit de demander) :

Main.cpp :

Code c++ :

#include "main.hpp"

int main(void)
{
    irr::IrrlichtDevice *device = irr::createDevice(irr::video::EDT_OPENGL, irr::core::dimension2d<irr::u32>(1024,768), 32,false,true,false,0);
    irr::video::IVideoDriver* driver = device->getVideoDriver();
    irr::scene::ISceneManager *sceneManager = device->getSceneManager();
         
    device->getCursorControl()->setVisible(false);
    device->setWindowCaption(L"Personnage");
   
    Physics newton(device, driver, sceneManager);
    newton.Sol();
   
    Personnage Akku(device, driver, sceneManager, newton.getNewtonWorld());
    Akku.Shape(irr::core::vector3df(0,10,0), 0, false);
    Akku.Move();
   
    while (device->run ())
    {
        newton.Update();
        Akku.Loop();
       
        driver->beginScene (true, true, irr::video::SColor (255,100,100,255));
        sceneManager->drawAll ();
        driver->endScene ();
    }

    device->drop ();
    return 0;
}



personnage.cpp :

Code c++ :

#include "personnage.hpp"

// VARIABLE STATIQUE -----------------------------------------------------------

NewtonWorld* Personnage::persoWorld = NULL;
NewtonBody* Personnage::persoBody = NULL;

irr::core::vector3df Personnage::persoPosition = irr::core::vector3df(0,0,0);

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

Personnage::Personnage(irr::IrrlichtDevice *device, irr::video::IVideoDriver *driver, irr::scene::ISceneManager *sceneManager, NewtonWorld *newtonWorld){
    persoDevice = device;
    persoDriver = driver;
    persoSceneManager = sceneManager;
    persoCamera = persoSceneManager->addCameraSceneNode();
   
    persoWorld = newtonWorld;
}

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

Personnage::~Personnage(){
}

// FONCTIONS -------------------------------------------------------------------

void Personnage::Camera(irr::core::vector3df position){
    irr::core::vector3df cameraPosition = position;
    cameraPosition.X += 10;
    cameraPosition.Y += 5;
   
    persoCamera->setPosition(cameraPosition);
    persoCamera->setTarget(position);
}

void Personnage::Loop(){
    Camera(persoPosition);
   
    float force[3];
    NewtonBodyGetForce(persoBody, force);
    std::cout << "Personnage" << force[0] << "Force appliquee : X = " << force[1] << "; Y = " << force[2] << "; Z = " << std::endl;
}

void Personnage::Move(){
    NewtonBodySetForceAndTorqueCallback(persoBody, ApplyForceX);
    /*
    float force[3];
    force[0] = 0.0f;
    force[1] = 1000.0f;
    force[2] = 0.0f;
    NewtonBodyAddForce(persoBody, force);
    */

}

void Personnage::Shape(irr::core::vector3df position, int type, bool pnj = true){
   
    float masse = 80.0;
   
    irr::scene::IAnimatedMesh* mesh;
   
    switch(type){
        case 0: // Akku
             mesh = persoSceneManager->getMesh(";");
             persoNode = persoSceneManager->addAnimatedMeshSceneNode(mesh);
             persoNode->setMaterialTexture(0, persoDriver->getTexture("ressources/Akku.md2"));
             break;
             
        case 4: // Kyle
             mesh = persoSceneManager->getMesh("ressources/Akku.png");
             persoNode = persoSceneManager->addAnimatedMeshSceneNode(mesh);
             persoNode->setMaterialTexture(0, persoDriver->getTexture("ressources/Kyle.md2"));
             break;
             
    }
   
    persoNode->setMaterialFlag(irr::video::EMF_LIGHTING, false);
    persoNode->setAnimationSpeed(0);
    persoNode->setLoopMode(false);
   
    irr::core::aabbox3d<irr::f32> volume;
    volume = persoNode->getBoundingBox();
    irr::core::vector3df mini = volume.MinEdge;
    irr::core::vector3df maxi = volume.MaxEdge;
    irr::core::vector3df taille = maxi-mini;
   
    position.Y = position.Y + taille.Y/2;
   
    NewtonCollision* collision;
    irr::core::matrix4 mat;
    collision = NewtonCreateBox(persoWorld, taille.X, taille.Y, taille.Z, 0, NULL);
    persoBody = NewtonCreateBody(persoWorld, collision, mat.pointer());
    NewtonReleaseCollision(persoWorld, collision);
    NewtonBodySetUserData(persoBody,reinterpret_cast<void*>(persoNode));
   
    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 (persoBody, masse, inertie.X, inertie.Y, inertie.Z);
   
    NewtonBodySetTransformCallback(persoBody, SetMeshTransformEvent);
    NewtonBodySetForceAndTorqueCallback(persoBody, ApplyForceAndTorqueEvent);
   
    mat.setTranslation(position);
    NewtonBodySetMatrix(persoBody, mat.pointer());
   
    if(pnj == false){
        persoPosition = position;
        Camera(persoPosition);
    }
}

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

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

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

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

void Personnage::ApplyForceX(const NewtonBody* persoBody, float, int)
{
    float masse;
    float inertieX;
    float inertieY;
    float inertieZ;
    float force[3];
   
    NewtonBodyGetMassMatrix (persoBody, &masse, &inertieX, &inertieY, &inertieZ);
   
    force[0] = -100.0f;
    force[1] = 0.0f;
    force[2] = 0.0f;
   
    NewtonBodyAddForce(persoBody, force);
}



Cela fait quelques semaines que je tourne en rond, soit c'est la gravité qui est appliquée seule, soit la force dirigée vers x et je n'arrive pas à les assembler. Si vous pouviez m'expliquer pourquoi j'ai ce problème, merci d'avance.

PS : Dans le code qui apparait, les "case" du "switch" sont faux alors que dans le code ils sont justes donc je les recopie juste pour que le code soit plus clair (il y a bien sur des "" autour des adresses des fichiers mais ils sont mal pris en compte dans la balise code=cpp) :

Code c++ :

case 0: // Akku
mesh = persoSceneManager->getMesh(ressources/Akku.md2);
persoNode = persoSceneManager->addAnimatedMeshSceneNode(mesh);
persoNode->setMaterialTexture(0, persoDriver->getTexture(ressources/Akku.png));
break;

case 4: // Kyle
mesh = persoSceneManager->getMesh(ressources/Kyle.md2);
persoNode = persoSceneManager->addAnimatedMeshSceneNode(mesh);
persoNode->setMaterialTexture(0, persoDriver->getTexture(ressources/Kyle.png));
break;

Dernière modification par Kaze (02-08-2013 20:01:36)

Hors ligne


#1 

03-08-2013 03:07:26

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

puisque personne n'est présent, j'ai chercher un peut
l'idée semble correct

    irr::core::vector3df force(10.f, 0.f, 0.f);
    NewtonBodyAddForce(persoBody, &force);

me semble tout fois plus approprié que

    NewtonBodySetForceAndTorqueCallback(persoBody, ApplyForceX);

mise a par ça je ne voie pas, n'étant pas utilisateur de Newton tu m'excusera
http://irrlicht-fr.org/viewtopic.php?id=1697&p=1 tu trouvera peut-être quelque chose ...

sur ce bonne chance, je serai dans les parages si beusoin, bien que je ne soit le plus approprier à te venir en aide wink

Hors ligne


#2 

03-08-2013 13:32:24

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

Alors je pense avoir trouver le problème, je suis retourné voir la doc et j'ai remarqué que lorsque les callbacks étaient appelés avec NewtonBodySetForceAndTorqueCallback, Newton s'occupait d'effacer toutes les forces appliquées aux body en question. Donc je suis en train de chercher un moyen de contourner le problème.

Hors ligne


#3 

03-08-2013 15:35:20

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

save la force au moment du SetMeshTransformEvent je pensse qu'il est appeler a la fin de la simulation,
force que tu restitue dans ApplyForceAndTorqueEvent

tu crée un structure genre

Code c++ :

struct link
{
       link() : force(irr::core::vetor3df(0.f,-9.81.f, 0.f)) {}
       irr::scene::ISceneNode *node;
       irr::core::vector3df force;
       irr::core::vector3df torque;
};



que tu passe à NewtonBodySetUserData

Code c++ :

void Personnage::ApplyForceAndTorqueEvent(const NewtonBody* body, float, int)
{
    link *entity = (link*)NewtonBodyGetUserData(body);
    NewtonBodyAddForce(persoBody, &entity->force);
    NewtonBodyAddTorque(persoBody, &entity->torque);
}



je me demandais, ça me semble logique qu'il clear la force a chaque step, puisque ta force seras rapporter sur la velociter ... non ?
en plus tu risque d'avoir des problèmes de gravité

dans ce cas tu devrait plutot passer par NewtonBodySetVelocity

et faire un truc dans le genre

Code c++ :

irr::core::vector3df velocity;
NewtonBodyGetVelocity(body, &velocity);
velocity.X += 10.f;
NewtonBodySetVelocity(body, &velocity);



ps: je t'invite ici https://dl.dropbox.com/u/103286/temp/MN … 0120721.7z peut-être trouvera-tu quelque chose

Hors ligne


#4 

05-08-2013 00:44:58

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

Alors j'avais pensé à faire ça mais à moindre frais vu qu'au final je n'avais que deux forces qui allait être conserver (la gravité + une pour avoir un mouvement constant dans une direction). Je voulais rajouter ces deux forces à chaque callback comme ça elles sont toujours présentes.

Mais ton idée m'intéresse énormément donc je vais essayer de faire quelque chose de bien.

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
883 membres
1429 sujets
11121 messages
Dernier membre inscrit: Saidov17
102 invités en ligne
Aucun membre connecté
RSS Feed