Pages: 1
- Accueil forums
- » Physique
- » Action de la gravité + action d'un autre force = BUG
02-08-2013 14:29:02
- Kaze
- Membres
- Date d'inscription:
- Messages: 60
- IP: 109.212.199.31
- Courriel
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 << "Force appliquee : X = " << force[0] << "; Y = " << force[1] << "; Z = " << force[2] << ";" << 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("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;
}
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;Hors ligne
03-08-2013 01:07:26
- Magun
- Administrateurs

- Date d'inscription:
- Messages: 910
- IP: 37.220.53.89
- Courriel 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 ![]()
Hors ligne
03-08-2013 11:32:24
- Kaze
- Membres
- Date d'inscription:
- Messages: 60
- IP: 109.212.199.31
- Courriel
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
03-08-2013 13:35:20
- Magun
- Administrateurs

- Date d'inscription:
- Messages: 910
- IP: 37.220.53.89
- Courriel 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/MNewtonCharacterController20120721.7z peut-être trouvera-tu quelque chose
Hors ligne
04-08-2013 22:44:58
- Kaze
- Membres
- Date d'inscription:
- Messages: 60
- IP: 109.212.199.31
- Courriel
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



