Bonjour,
Je débute avec Newton et je voudrais gérer une collision de deux cubes.
Je mets donc ce code là trouvé avec un tuto:
#include <cstdlib> #include <iostream> #include <irr/irrlicht.h> #include <Newton/Newton.h> using namespace std; using namespace irr; using namespace core; using namespace gui; using namespace io; using namespace scene; using namespace video; void ApplyForce(const NewtonBody *nbody) { float mass, ixx, iyy, izz; NewtonBodyGetMassMatrix(nbody, &mass, &ixx, &iyy, &izz); float force[3] = {0, mass * -90.82, 0}; NewtonBodyAddForce(nbody, force); } int main(int argc, char **argv) { // Initialisation Newtoniénne // --------------------------------------------------------- NewtonWorld*world = NewtonCreate(0,0); // Initialisation Irrlichiénne // --------------------------------------------------------- IrrlichtDevice *irrDev = createDevice (EDT_OPENGL, dimension2d<s32>(800,600), 32, false, true, false, 0); IVideoDriver* driver = irrDev->getVideoDriver (); ISceneManager *scene = irrDev->getSceneManager (); scene->addCameraSceneNode (0, core::vector3df (0,0,0), core::vector3df (5,0,0)); // Creation d'une lumiere ambiente // ---------------------------------------- driver->setAmbientLight(video::SColorf(1.0, 1.0, 1.0,0.0)); // Creation d'une camera FPS // ---------------------------------------------- ICameraSceneNode *camera = scene->addCameraSceneNodeFPS (0,100,10); camera->setPosition(vector3df(0,1,-5)); // Créer le corp1 // ------------------ NewtonBody*body1 ; // On Initialise le corp1 // ---------- body1 = NewtonCreateBody(world,NewtonCreateBox(world,1,1,1,0)) ; // On lui assigne une matrice // ----- matrix4 mat1 ; mat1.setTranslation(vector3df(0.52,3,0)); NewtonBodySetMatrix(body1,&mat1.M[0]); // Configurer la mass et l'inertie //- NewtonBodySetMassMatrix(body1,10,2,2,2); // Force de gravité // ----------------- NewtonBodySetForceAndTorqueCallback(body1, ApplyForce); // Initialisation irr pour le cube1 // -------- ISceneNode*cube1 = scene->addCubeSceneNode(1); cube1->setMaterialTexture(0, driver->getTexture("t351sml.jpg")); // Créer le corp2 // ------------------ NewtonBody*body2 ; // On Initialise le corp2 // ---------- body2 = NewtonCreateBody(world,NewtonCreateBox(world,1,1,1,0)) ; // On lui assigne une matrice // ----- matrix4 mat2 ; NewtonBodySetMatrix(body2,&mat2.M[0]); // Configurer la mass et l'inertie //- NewtonBodySetMassMatrix(body2,0,0,0,0); // Initialisation irr pour le cube2 // -------- ISceneNode*cube2 = scene->addCubeSceneNode(1); cube2->setMaterialTexture(0, driver->getTexture("t351sml.jpg")); // La boucle principale du rendu // ----------------------------------------- while (irrDev->run ()) { NewtonBodyGetMatrix(body1,&mat1.M[0]); cube1->setRotation(mat1.getRotationDegrees()); cube1->setPosition(mat1.getTranslation()); NewtonBodyGetMatrix(body2,&mat2.M[0]); cube2->setRotation(mat2.getRotationDegrees()); cube2->setPosition(mat2.getTranslation()); NewtonUpdate ( world, 1 / 60 ) ; //On indique qu'on démarre la scène driver->beginScene (true, true, video::SColor (255,255,255,255)); scene->drawAll (); driver->endScene (); } return 0 ; }
Mais le débugeur trouve des bugs:
error C2248: 'irr::core::CMatrix4<T>::M' : impossible d'accéder à private membre déclaré(e) dans la classe 'irr::core::CMatrix4<T>'
1> with
1> [
1> T=irr::f32
1> ]
voir la déclaration de 'irr::core::CMatrix4<T>::M'
1> with
1> [
1> T=irr::f32
1> ]
error C2664: 'NewtonBodySetForceAndTorqueCallback' : impossible de convertir le paramètre 2 de 'void (__cdecl *)(const NewtonBody *)' en 'NewtonApplyForceAndTorque'
1> Aucune fonction ayant ce nom dans la portée ne correspond au type de la cible
error C2660: 'NewtonCreateBox' : la fonction ne prend pas 5 arguments
error C2248: 'irr::core::CMatrix4<T>::M' : impossible d'accéder à private membre déclaré(e) dans la classe 'irr::core::CMatrix4<T>'
1> with
1> [
1> T=irr::f32
1> ]
voir la déclaration de 'irr::core::CMatrix4<T>::M'
1> with
1> [
1> T=irr::f32
1> ]
error C2882: 'scene' : utilisation non conforme d'un identificateur d'espace de noms dans l'expression
error C2227: la partie gauche de '->addCubeSceneNode' doit pointer vers un type class/struct/union/générique
error C2248: 'irr::core::CMatrix4<T>::M' : impossible d'accéder à private membre déclaré(e) dans la classe 'irr::core::CMatrix4<T>'
1> with
1> [
1> T=irr::f32
1> ]
voir la déclaration de 'irr::core::CMatrix4<T>::M'
1> with
1> [
1> T=irr::f32
1> ]
error C2248: 'irr::core::CMatrix4<T>::M' : impossible d'accéder à private membre déclaré(e) dans la classe 'irr::core::CMatrix4<T>'
1> with
1> [
1> T=irr::f32
1> ]
voir la déclaration de 'irr::core::CMatrix4<T>::M'
1> with
1> [
1> T=irr::f32
1> ]
Hors ligne
salut, newton 2.xx à subi quelques modifications par rapport aux version 1.xx, ce qui fait que certains eléments ne s'utilise pas de la même façon,
faute de tuto à jour, je t'invite à voir ce topic: http://irrlicht-fr.org/viewtopic.php?id=1018 , c'est loin d'être un bon exemple, mais ça te permettra de voir les changements.
Hors ligne
Merci, maintenant, il n'y a aucun bug, cube1 "tombe", mais passe a travers cube2. Pourquoi?
Voici mon code actuel:
#include <cstdlib> #include <iostream> #include <irr/irrlicht.h> #include <Newton/Newton.h> using namespace std; using namespace irr; using namespace core; using namespace gui; using namespace io; using namespace scene; using namespace video; void _cdecl ApplyForceAndTorqueEvent (const NewtonBody* body,float timestep, int threadindex) { float mass; float Ixx; float Iyy; float Izz; float force[3]; float torque[3]; NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz); force[0] = 0.0f; force[1] = -9.81 * mass; force[2] = 0.0f; torque[0] = 0.0f; torque[1] = 0.0f; torque[2] = 0.0f; NewtonBodyAddForce (body, force); NewtonBodyAddTorque (body, torque); } int main(int argc, char **argv) { // Initialisation Newtoniénne // --------------------------------------------------------- NewtonWorld*world = NewtonCreate(0,0); // Initialisation Irrlichiénne // --------------------------------------------------------- IrrlichtDevice *irrDev = createDevice (EDT_OPENGL, dimension2d<s32>(800,600), 32, false, true, false, 0); IVideoDriver* driver = irrDev->getVideoDriver (); ISceneManager *scene = irrDev->getSceneManager (); scene->addCameraSceneNode (0, core::vector3df (0,0,0), core::vector3df (5,0,0)); // Creation d'une lumiere ambiente // ---------------------------------------- driver->setAmbientLight(video::SColorf(1.0, 1.0, 1.0,0.0)); // Creation d'une camera FPS // ---------------------------------------------- ICameraSceneNode *camera = scene->addCameraSceneNodeFPS (0,100,10); camera->setPosition(vector3df(0,1,-5)); // Créer le corp1 // ------------------ NewtonBody*body1 ; // On Initialise le corp1 // ---------- NewtonCollision* colision= NewtonCreateBox(world,1000,1000,1000,0,0); body1 = NewtonCreateBody(world,colision) ; NewtonBodySetCollision(body1, colision); NewtonReleaseCollision (world, colision); // On lui assigne une matrice // ----- core::matrix4 mat1 ; mat1.setTranslation(core::vector3df(0.52,3,0)); NewtonBodySetMatrix(body1,mat1.pointer()); // Configurer la mass et l'inertie //- NewtonBodySetMassMatrix(body1,20,2,2,2); // Force de gravité // ----------------- NewtonBodySetForceAndTorqueCallback(body1, ApplyForceAndTorqueEvent); // Initialisation irr pour le cube1 // -------- scene::ISceneNode*cube1 = smgr->addCubeSceneNode(10); cube1->setMaterialTexture(0, driver->getTexture("metal.jpg")); // Créer le corp2 // ------------------ NewtonBody*body2 ; // On Initialise le corp2 // ---------- NewtonCollision* colision2= NewtonCreateBox(world,1000,1000,1000,0,0); body2 = NewtonCreateBody(world,colision2); NewtonBodySetCollision(body2, colision2); NewtonReleaseCollision (world, colision2); // On lui assigne une matrice // ----- core::matrix4 mat2 ; NewtonBodySetMatrix(body2,mat2.pointer()); // Configurer la mass et l'inertie //- NewtonBodySetMassMatrix(body2,0,0,0,0); // Initialisation irr pour le cube2 // -------- scene::ISceneNode *cube2 = smgr->addCubeSceneNode(10); cube2->setMaterialTexture(0, driver->getTexture("carrelage.jpg")); // La boucle principale du rendu // ----------------------------------------- while (irrDev->run ()) { NewtonBodyGetMatrix(body1,&mat1.M[0]); cube1->setRotation(mat1.getRotationDegrees()); cube1->setPosition(mat1.getTranslation()); NewtonBodyGetMatrix(body2,&mat2.M[0]); cube2->setRotation(mat2.getRotationDegrees()); cube2->setPosition(mat2.getTranslation()); NewtonUpdate ( world, 1 / 60 ) ; //On indique qu'on démarre la scène driver->beginScene (true, true, video::SColor (255,255,255,255)); scene->drawAll (); driver->endScene (); } return 0 ; }
Hors ligne
il faut que tu rajoute un sol avec une mass à 0.
Hors ligne
Mais je voudrais que le sol soit cube2 qui lui à déjà une masse. Je voudrais que mon résultat soit un peu près comme celui-ci: http://www.jeux-libres.com/membres/mes_ … utoss2.jpg
Hors ligne
J'ai un peu galérer aussi a chercher des tutos pour faire fonctionner Irrlicht avec Newton (d'ailleurs je galère encore) en attendant si ça peut t'aider et même en aider d'autre, voici un petit bout de code que j'ai pus réaliser en grattant des petite ligne a droite a gauche. Tu peut le télécharger ici :
exemple Newton
c'est juste un sol avec un cube qui tombe dessus quand tu tape sur la touche espace, tu peut créer des cube a volonté, ça donne une idée du truc quoi..
Bon courage pour la suite.
Dernière modification par nabouill (27-03-2010 22:06:12)
Hors ligne
C'est vrai que pour trouver des bons tutos qui sont a jour c'est un peu la galère.
Sinon pour ton code, il est grand comparé au mien. Il faut vraiment tout cela juste pour faire "une collision réaliste avec de la physique", car mon code (d'apres un tuto) devait suffire?
Hors ligne
c'est que mon code intègre n'importe qu'elle type de model pour faire le sol, aussi bien un simple plan qu'une map toute entiere avec pleins de triangle dans tous les sens, c'est ce qui le rend aussi lourd.
Par contre on remarque que dans ton code, tu manipule tes 2 cubes a chaque frame, ce qui va vite devenir contraignant si tu compte y ajouter une cinquantaine de cube.
Sinon, comme la dit Nico, tu n'a pas defini de sol et (il me semble) il est important de définir la taille de ton monde.
Mais je ne suis pas assez caler sur newton pour t'aider plus que ça.
Bonne continuation
Hors ligne
C'est bon ça marche! Merci à vous deux!
Mais est-il possible de gérer la physique avec une sollison cube/camera, pour qu quand on "fonce sur un cube celui ci ce pousse en arrière?
Hors ligne
oui c'est possible, il faut pour ça appliquer une force sur l'axe Z par exemple pour pousser l'objet devant toi, mais plus l'objet a pousser est lourd plus la force a appliquer doit être élevé pour pouvoir pousser l'objet.
Hors ligne
EDIT : problème résolut.
Merci de m'avoir aidé.
Dernière modification par Kit-fisto24 (28-03-2010 20:32:57)
Hors ligne
J'ai encore un problème, c'est quand je fais NewtonBodySetForceAndTorqueCallback(body1, ApplyForceAndTorqueEvent); dans une fonction (et donc pas dans main), cela m'affiche une erreur: error C2664: 'NewtonBodySetForceAndTorqueCallback' : impossible de convertir le paramètre 2 de 'void' en 'NewtonApplyForceAndTorque'. Alors que si j'appellerai cette fonction dans main ça marcherai.
Voici mon code:
void Physique::CreationBodyMobile(core::vector3df position, scene::ISceneManager* smgr, video::IVideoDriver* driver) { // Créer le corp1 // ------------------ NewtonBody*body1 ; scene::ISceneNode*cube1 = smgr->addCubeSceneNode(64); cube1->setPosition(core::vector3df(2124,600,1152)); cube1->setMaterialTexture(0, driver->getTexture("metal.jpg")); cube1->setMaterialFlag(video::EMF_LIGHTING, false); // On Initialise le corp1 // ---------- NewtonCollision* colision= NewtonCreateBox(m_world,64,64,64,0,0); body1 = NewtonCreateBody(m_world,colision) ; // On lui assigne une matrice // ----- core::matrix4 mat1 ; mat1.setTranslation(core::vector3df(position.X,position.Y,position.Z)); NewtonBodySetMatrix(body1,mat1.pointer()); // Configurer la mass et l'inertie //- float inertieX = 0.7f * 50 * (64 * 64 + 64 * 64) / 12; float inertieY = 0.7f * 50 * (64 * 64 + 64 * 64) / 12; float inertieZ = 0.7f * 50 * (64 * 64 + 64 * 64) / 12; NewtonBodySetMassMatrix(body1,50,inertieX,inertieY,inertieZ); // Force de gravité // ----------------- NewtonBodySetTransformCallback(body1, SetMeshTransformEvent); NewtonBodySetForceAndTorqueCallback(body1, ApplyForceAndTorqueEvent); } void _cdecl SetMeshTransformEvent(const NewtonBody* body, const float* matrix,int) { // copy the matrix into an irrlicht matrix4 core::matrix4 mat; memcpy(mat.pointer(), matrix, sizeof(float)*16); // Retreive the user data attached to the newton body scene::ISceneNode *tmp = (scene::ISceneNode *)NewtonBodyGetUserData(body); if (tmp) { // Position the node tmp->setPosition(mat.getTranslation()); // set position tmp->setRotation(mat.getRotationDegrees()); // and rotation } } void _cdecl ApplyForceAndTorqueEvent (const NewtonBody* body,float timestep, int threadindex) { float mass; float Ixx; float Iyy; float Izz; float force[3]; float torque[3]; NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz); force[0] = 0.0f; force[1] = -mass * 90000; force[2] = -mass * 90000; torque[0] = 0.0f; torque[1] = 0.0f; torque[2] = 0.0f; NewtonBodyAddForce (body, force); NewtonBodyAddTorque (body, torque); }
Vous savez pourquoi ça ne marche pas quand c'est dans une autre fonction?
Hors ligne
j'ai eu exactement le même problème, je ne sais plus très bien le pourquoi du comment, mais je te met les source d'un test qui avait resolue ce probleme téléchargeable a cet adresse : http://www.mediafire.com/?tyytmoozhdz
il me semble que cela vient du fichier "dMatrix.cpp" a l'endroit ou on l'inclus.
Dernière modification par nabouill (30-03-2010 00:41:59)
Hors ligne