[irrlicht/newton] Un boulier Difficulté : 60/100
Publié le 09/02/2008 à 20h 01min par Marco565



Faire un boulier avec un moteur physique



Vous allez réaliser un boulier avec le moteur physique newton et comme appui graphique irrlicht.

Prés requis
Savoir utiliser newton, les joints et les materials, et bon la partie graphique est très simple.

Aide
Vous utiliserais les NewtonConstraintCreateBall comme type de joints.
Vous pouvez n'en mettre que un cela sufit.

Correction
Bon maintenant passons au code, quand on ne sait pas utiliser newton c'est vrais que cet exercice peu être très dur mais pour les habitué sa devrais être de la routine.


Code : cpp
  1. #include <iostream>
  2. #include <irr/irrlicht.h>
  3. #include <newton/newton.h>
  4.  
  5. using namespace std;
  6. using namespace irr;
  7.  
  8.  
  9. //Les fonctions
  10. void addForce(const NewtonBody *nBody);
  11. void setTransform(const NewtonBody* body, const float* matrix);
  12.  
  13.  
  14. //Les variables generales
  15. NewtonWorld *world = NewtonCreate(NULL,NULL);
  16. scene::ISceneManager *scenegraph = NULL;
  17. int fer = NewtonMaterialCreateGroupID(world);
  18.  
  19.  
  20. class Boule
  21. {
  22. public:
  23. void init(core::vector3df pos, core::vector3df posJoint)
  24. {
  25. //On crée un coprs qui gere la physique
  26. body = NewtonCreateBody(world,NewtonCreateSphere(world,2,2,2,NULL));
  27.  
  28. //On ajoute une boule
  29. node = scenegraph->addSphereSceneNode(2);
  30.  
  31. //On ajoute un fil a cette boule
  32. scene::ISceneNode *tube = scenegraph->addAnimatedMeshSceneNode(
  33. scenegraph->getMesh("data/tube.3ds"), node);
  34. //On regle les parametre des fils
  35. tube->setPosition(core::vector3df(0,8,0));
  36. tube->setScale(core::vector3df(5,10,5));
  37.  
  38. //On definis les proprietes du corps
  39. NewtonBodySetMassMatrix(body, 100,0,0,0);
  40. NewtonBodySetUserData(body, node);
  41.  
  42. //On diminue les frotements de l'air
  43. NewtonBodySetLinearDamping(body, 0.001);
  44.  
  45. //On lui attibue un material qui est simlaire a celui du fer
  46. NewtonBodySetMaterialGroupID(body, fer);
  47.  
  48. //On desactive le blocage automatique
  49. NewtonBodySetAutoFreeze(body, 0);
  50.  
  51. //On cree une matrice qui recupere la position envoiyé au body.
  52. //puis on la met dans les proprietes du body
  53. core::matrix4 mat;
  54. mat.setTranslation(pos);
  55. NewtonBodySetMatrix(body, &mat[0]);
  56.  
  57.  
  58. //Ici on s'occupe du Joint
  59. pJoint[0] = posJoint.X;
  60. pJoint[1] = posJoint.Y;
  61. pJoint[2] = posJoint.Z;
  62.  
  63. //On cree une jointure ici un fil
  64. joint = NewtonConstraintCreateBall(world, pJoint, body, NULL);
  65.  
  66.  
  67.  
  68. //On attribu les callback au body
  69. NewtonBodySetForceAndTorqueCallback(body, addForce);
  70. NewtonBodySetTransformCallback(body, setTransform);
  71. }
  72.  
  73. void setMove()
  74. {
  75. float v[3] = {8,0,0};
  76. //On ajoute une vitesse
  77. NewtonBodySetVelocity(body, v);
  78. }
  79.  
  80.  
  81.  
  82.  
  83. private:
  84. NewtonBody *body;
  85. NewtonJoint *joint;
  86. scene::ISceneNode *node;
  87.  
  88. float pJoint[3];
  89.  
  90. };
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99. int main()
  100. {
  101. //Materail fer sur fer
  102. NewtonMaterialSetDefaultElasticity (world, fer, fer, .97);
  103. NewtonMaterialSetDefaultFriction (world, fer, fer, 0, 0.1);
  104.  
  105.  
  106. IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D9,
  107. core::dimension2d<s32>(800,600), 32, false, true, false);
  108.  
  109. scenegraph = device->getSceneManager();
  110. video::IVideoDriver *driver = device->getVideoDriver();
  111. device->setWindowCaption(L"Boulier irr/newt");
  112.  
  113.  
  114. //La camera
  115. scene::ICameraSceneNode *camera = scenegraph->addCameraSceneNode();
  116. camera->setPosition(core::vector3df(0,0,-40));
  117.  
  118. //La lumiere
  119. scene::ILightSceneNode *lumiere = scenegraph->addLightSceneNode();
  120.  
  121. //Un petit skybox pour le style
  122. scenegraph->addSkyBoxSceneNode(
  123. driver->getTexture("data/irrlicht2_up.jpg"),
  124. driver->getTexture("data/irrlicht2_dn.jpg"),
  125. driver->getTexture("data/irrlicht2_lf.jpg"),
  126. driver->getTexture("data/irrlicht2_rt.jpg"),
  127. driver->getTexture("data/irrlicht2_ft.jpg"),
  128. driver->getTexture("data/irrlicht2_bk.jpg"));
  129.  
  130.  
  131. Boule boule;
  132. boule.init(core::vector3df(0,-8,0), core::vector3df(0,10,0));
  133.  
  134. Boule boule1;
  135. boule1.init(core::vector3df(-4,-8,0), core::vector3df(-4,10,0));
  136.  
  137. Boule boule2;
  138. boule2.init(core::vector3df(-8,-8,0), core::vector3df(-8,10,0));
  139.  
  140. Boule boule3;
  141. boule3.init(core::vector3df(4,-8,0), core::vector3df(4,10,0));
  142.  
  143. Boule boule4;
  144. boule4.init(core::vector3df(8,-8,0), core::vector3df(8,10,0));
  145. boule4.setMove();
  146.  
  147.  
  148. //un Boulier (eu enfin le cadre)
  149. scene::ISceneNode *node1 = scenegraph->addAnimatedMeshSceneNode(
  150. scenegraph->getMesh("data/boulier2.3ds"));
  151.  
  152.  
  153. //On l'ajute (a l'oeul )
  154. node1->setScale(core::vector3df(8,8,8));
  155. node1->setRotation(core::vector3df(0,90,0));
  156. node1->setPosition(core::vector3df(0,0,0));
  157.  
  158.  
  159.  
  160. while(device->run())
  161. {
  162.  
  163. driver->beginScene(true, true, video::SColor(128,128,128,128));
  164.  
  165. scenegraph->drawAll();
  166. NewtonUpdate(world, 0.01);
  167.  
  168.  
  169.  
  170. driver->endScene();
  171. }
  172.  
  173.  
  174. device->drop();
  175.  
  176.  
  177. return 0;
  178. }
  179.  
  180.  
  181.  
  182. void addForce(const NewtonBody *nBody)
  183. {
  184. float mass, ix, iy, iz;
  185.  
  186. //On recupere la masse et l'inertie du corp
  187. NewtonBodyGetMassMatrix(nBody, &mass, &ix, &iy, &iz);
  188.  
  189.  
  190. //on cree une force tridimentionelle
  191. float force[3] = {0, mass * -9.81,0};
  192.  
  193.  
  194. //On les envoi au corps
  195. NewtonBodyAddForce(nBody, force);
  196. }
  197.  
  198. void setTransform(const NewtonBody* body, const float* matrix)
  199. {
  200. core::matrix4 mat;
  201. mat.setM(matrix);
  202.  
  203. scene::ISceneNode *tmp = (scene::ISceneNode*)NewtonBodyGetUserData(body);
  204.  
  205. tmp->setPosition(mat.getTranslation()); // set position
  206. tmp->setRotation(mat.getRotationDegrees()); // and rotation
  207.  
  208.  
  209. }
  210.  
  211.  
  212.  
  213.