20-11-2010 00:40:14
- kiricou974
- Membres
- Date d'inscription:
- Messages: 34
- IP: 77.205.172.249
- Courriel
Bonjours, je cherche un moteur physique et son warpper pour irrlicht.
Se serait le mieux si il pouvait gérer les ragdols et de pouvoir utiliser le moteur pour faire des ragdols mais avec les meshs avec une armature.
bon je ne sait pas quoi dire de plus, si se n'est que je vous remercie d'avance de vous penchez sur mon sujet.
Hors ligne
20-11-2010 11:30:44
- Magun
- Administrateurs

- Date d'inscription:
- Messages: 910
- IP: 188.93.45.30
- Courriel Site web
un peut de recherche sa fait pas de mal .... non ?
bullet : http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=36861&highlight= | http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=22764
physix : http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=30804&highlight=physix
newton : http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=17698&highlight=newton
havok : http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=38541
les warper ses pas bien, sa ne s'adapte pas forcement a se que tu souhaite faire, de plus c'est vraiment pas se qu'i y a de complique'r a mettre en place ... enfin ...
et pour les ragdoll pareil, et il ne me semble pas qu'un de ses warper les mis en place
Hors ligne
20-11-2010 13:34:09
- nabouill
- Membres

- Date d'inscription:
- Messages: 242
- IP: 77.198.97.165
- Courriel
effectivement, il me semble qu'aucun de ces warpper met en place un système de ragdoll, de plus le problème avec les warpper (surtout ceux d'Irrlicht) les dernière mise a jour date de ..... bien trop longtemps... (style 2007 pour IrrPhysix ou 2006 pour Irrnewt il me semble) ce n'est donc vraiment pas optimisé !
Comme le dit Magun, il est donc préférable (à mon gout) de mettre en place toi même ton moteur favoris.
Hors ligne
21-11-2010 10:04:49
- Gehogor
- Membres

- Date d'inscription:
- Messages: 130
- IP: 79.93.131.37
- Courriel
"Re"-effectivement, je partage complètement l'avis de nabouill et Magnum. Cependant je me mets à ta place et je me dis que ce n'est pas évident de faire son wrapper tout seul.
Et bien je te rassure, en fait, ça se fait très bien. J'en ai fait un entre Irrlicht et Newton 2.0 pour toute collision avec tous les paramètres physiques que le moteur physique met à disposition (par contre pas de ragdoll mais l'esprit est très clairement le même, désolé...) et c'est pas mal.
Bon, tout n'est pas fonctionnel dans Newton 2.0, il faut laisser du temps mais ça le fait quand même. Ce n'est pas très bien documenté mais il y a des exemples.
Pour finir, avoir un code qui distingue bien la partie physique de la partie graphique et bien plus propre à mon sens. En cas de gros bug "mystique venant de l'espace" c'est plus facile d'arrêter un des deux moteurs pour le corriger, enfin bon ...
Je ne sais pas si ça peut t'aider, mais ci-dessous je te transmets trois méthodes qui utilisent Newton. Elles transforment un objet "GrPhysics3D" en objet "Newton" ou plutôt "NewtonBody". L'objet "GrPhysics3D" est un objet perso, tu peux utiliser le tien évidemment. Normalement il y a des commentaires pour suivre le déroulement, j'espère que ça pourra t'aider un peu, on ne sais jamais. Les méthodes a priori peuvent faire peur mais en fait non, si tu suis le déroulement, ça devrait le faire, ...
Fonction d'initialisation:
Code c++ :
GrNewton::initialisation()
{
m_nWorld = NewtonCreate(); // Création du monde de Newton
float min[3];
float max[3];
min[0] = -50.0; // -x dans le vrai monde
min[1] = -2.0; // -z dans le vrai monde
min[2] = -50.0; // -y dans le vrai monde
max[0] = 50.0; // x dans le vrai monde
max[1] = 50.0; // z dans le vrai monde
max[2] = 50.0; // y dans le vrai monde
NewtonSetWorldSize(m_nWorld, min, max );
int materialID = NewtonMaterialGetDefaultGroupID(m_nWorld); // Récupération de la matière par défaut du monde "Newton"
NewtonMaterialSetDefaultFriction(m_nWorld, materialID, materialID, 0.8f, 0.4f); // Configuration de la friction de la matière par défaut
NewtonMaterialSetDefaultElasticity(m_nWorld, materialID, materialID, 0.8f); // Configuration de l'élasticité de la matière par défaut
NewtonMaterialSetDefaultSoftness(m_nWorld, materialID, materialID, 0.05f); // Configuration de la douceur de la matière par défaut
NewtonMaterialSetSurfaceThickness(m_nWorld, materialID, materialID,0.0f); // Ici, je ne sais pas trop... A voir !
// Association d'une méthode type "Callback" (ici: "ContactsProcess") à la matière par défaut, cette méthode est appellée par le moteur Newton
// lorsqu'il y a une collision entre de objet possédant cette même matière.
NewtonMaterialSetCollisionCallback(m_nWorld, materialID, materialID, NULL, OnAABBOverlap, ContactsProcess);
m_physicsActive = true; // Permission du thread de tourné
start(); // Lancement du thread
}Transformation d'un objet "physics3D" en objet "Newton":
Code c++ :
QString GrNewton::p_loadPhysics3D(GrPhysics3D* physics3D)
{
if(physics3D->collisionType() == GrPhysics3D::NO_COLLISION) // Si l'objet "physics3D" autorise les collisions
return QObject::trUtf8("Objet [%1] -- partie physique [%2]: Mode de collision désactivé.\
").arg(physics3D->root()->name()).arg(physics3D->name());
QString tmpInfo = QObject::trUtf8("Objet [%1] -- partie physique [%2]: Mise à jour de la partie physique.\
").arg(physics3D->root()->name()).arg(physics3D->name());
NewtonCollision* listCollision[NB_MAX_PRIMITIVE]; // Déclaration d'un tableau de pointeur d'objet collision Newton
int materialID = NewtonMaterialGetDefaultGroupID(m_nWorld); // Récupération de l'identifiant de la matière par défaut du monde de Newton
QString material = physics3D->parameter("Material").toString(); // Récupération de l'identifiant de la matière de l'objet "physics3d" concerné
if(!material.isEmpty())
materialID = m_physicsMaterial->materialID(material); // On note le bon identifiant
int nbForm = 0;
for(int i=0;i<physics3D->childSize();i++) // Parcours de tous les enfants de l'objet "physics3D" pour les transformer en "forme primitive"
{
GrPrimitive3D* primitive3D = dynamic_cast<GrPrimitive3D*>(physics3D->child(i));
if(primitive3D != NULL)
tmpInfo += p_loadPrimitive3DRecursif(primitive3D,listCollision,materialID,nbForm); // Méthode de tranformtion ou "mini wrapper"
}
if(nbForm == 0)
return tmpInfo + QObject::trUtf8("Aucune forme primitive de créée.\
");
else
tmpInfo += QObject::trUtf8("Nombre total de primitives: %1.\
").arg(nbForm);
NewtonCollision* newColGroup = NewtonCreateCompoundCollision(m_nWorld,nbForm,listCollision,materialID); // Fusion des primitives de collision en une seule, maillage purement convex
NewtonBody* newBody = NewtonCreateBody(m_nWorld,newColGroup); // Création d'un "NewtonBody" // Création du corps Newton associé à son maillage de collision
//---------------------------------- Récupération du maillage --------------------------------// Partie en developpement, peut être non fonctionnel dans Newton 2.0 ?? Car buger ??
NewtonMesh* nMesh = NewtonMeshCreateFromCollision(newColGroup);
int faceCount = NewtonMeshGetTotalFaceCount(nMesh);
int indexCount = NewtonMeshGetTotalIndexCount(nMesh);
tmpInfo += QObject::trUtf8("Nombre total de face: %1 et d'index %2.\
").arg(faceCount).arg(indexCount);
/*int vertexStrideInByte,normalStrideInByte,uvStrideInByte0,uvStrideInByte1; // TODO_G: PAS FONCTIONNEL DANS NEWTON OU AUTRE CHOSE, A VOIR!
dFloat *vertex,*normal,*uv0,*uv1;
NewtonMeshGetVertexStreams(nMesh,vertexStrideInByte,vertex,normalStrideInByte,normal,uvStrideInByte0,uv0,uvStrideInByte1,uv1);
for(int i=0;i<vertexStrideInByte;i=i+3)
{
vertex[i];
vertex[i+1];
vertex[i+2];
}*/
NewtonMeshDestroy(nMesh);
//--------------------------------------------------------------------------------------------//
float mPos[16];
MMatrixToNewtonMatrix(mPos,physics3D->absolutePosition()); // Récupération du la position absolue de notre objet "physics3D"
NewtonBodySetMatrix(newBody,mPos); // On transmet cette position au corps rigide pour newton
NewtonBodySetMaterialGroupID(newBody,materialID); // On indique à Newton de quelle matière il est fait
NewtonBodySetUserData(newBody,physics3D); // Stockage de "GrPhysics3D*" pour son utilisation dans les méthode "CallBack"
physics3D->setUserData(0,reinterpret_cast<void*>(newBody)); // Stockage de "NewtonBody*" afin de pouvoir le réutiliser dans le "run()"
float inertia[3],origin[3];
if(physics3D->parameter("AutoInertialAndMass").toBool()) // Calcul automatique de l'inertie de Newton en fonction des formes de collisions
{
NewtonConvexCollisionCalculateInertialMatrix(newColGroup,inertia,origin);
physics3D->setParameter("Ix",inertia[0]); // On indique à l'objet "physics3D" son inertie
physics3D->setParameter("Iy",inertia[2]);
physics3D->setParameter("Iz",inertia[1]);
physics3D->setParameter("CenterMass_X",origin[0]); // On indique à l'objet "physics3D" son centre de masse
physics3D->setParameter("CenterMass_Y",origin[2]);
physics3D->setParameter("CenterMass_Z",origin[1]);
}
float mass = physics3D->parameter("Mass").toFloat();
NewtonBodySetMassMatrix(newBody,mass, // Configuration de la masse et inertie de notre objet Newton
physics3D->parameter("Ix").toFloat()*mass,
physics3D->parameter("Iy").toFloat()*mass,
physics3D->parameter("Iz").toFloat()*mass);
origin[0] = physics3D->parameter("CenterMass_X").toFloat();
origin[2] = physics3D->parameter("CenterMass_Y").toFloat();
origin[1] = physics3D->parameter("CenterMass_Z").toFloat();
NewtonBodySetCentreOfMass(newBody,origin); // Configuration du centre de masse et inertie de notre objet Newton
NewtonBodySetLinearDamping(newBody,physics3D->parameter("LinearDamping").toFloat()); // Configuration de l'amortissement linéaire de notre objet Newton
float angularDamping[3];
angularDamping[0] = physics3D->parameter("AngularDamping_Rx").toFloat();
angularDamping[1] = physics3D->parameter("AngularDamping_Ry").toFloat();
angularDamping[2] = physics3D->parameter("AngularDamping_Rz").toFloat();
NewtonBodySetAngularDamping(newBody,angularDamping); // Configuration de l'amortissement rotoïde de notre objet Newton
NewtonBodySetFreezeState(newBody,0);
NewtonBodySetAutoSleep(newBody,0);
// Association d'une "Callback" (ici:SetMeshTransformMesh) à l'objet Newton,
// elle sera appellée lorsque l'objet bougera selon le moteur Newton (il y a bcp d'exemple là dessus)
NewtonBodySetTransformCallback(newBody,SetMeshTransformMesh);
// Association d'une "Callback" (ici:ApplyForceAndTorqueEvent) à l'objet Newton,
// elle sera appellée lorsque l'objet devra subir une force (il y a bcp d'exemple là dessus)
NewtonBodySetForceAndTorqueCallback(newBody,ApplyForceAndTorqueEvent);
float pt0[3],pt1[3];
NewtonBodyGetAABB(newBody,pt0,pt1); // Calcul de l'enveloppe totale de l'objet Newton pour information
tmpInfo += QObject::trUtf8("Dimensions externes: %1 %2 %3.\
").arg(pt1[0]-pt0[0]).arg(pt1[1]-pt0[1]).arg(pt1[2]-pt0[2]);
for(int i=0;i<nbForm;i++) // Désallocation de la mémoire des primitives de collision
NewtonReleaseCollision(m_nWorld,listCollision[i]);
NewtonReleaseCollision(m_nWorld,newColGroup); // Désallocation de la mémoire de la primitive groupe de collision
return tmpInfo; // On retourne les informations de la méthodes
}Fonction intermédiaire appellée dans "p_loadPhysics3D":
Code c++ :
QString GrNewton::p_loadPrimitive3DRecursif(GrPrimitive3D* primitive3D,NewtonCollision* listCollision[],int materialID,int& internalCounter)
{
QString tmpInfo;
float mPos[16];
float paramA = primitive3D->parameter("ScaleX").toFloat();
float paramB = primitive3D->parameter("ScaleY").toFloat();
float paramC = primitive3D->parameter("ScaleZ").toFloat();
// On récupère la position de la forme primitive du volume de collision par rapport à l'objet lui-même
MMatrixToNewtonMatrix(mPos,primitive3D->relativePosition());
NewtonCollision* newCol = NULL;
switch(primitive3D->primitiveForm())
{
case GrPrimitive3D::SPHERE:
newCol = NewtonCreateSphere(m_nWorld,paramA/2.0,paramC/2.0,paramB/2.0,materialID,mPos);
tmpInfo = QObject::trUtf8("La primitive est de forme SPHERE.");
break;
case GrPrimitive3D::BOX:
newCol = NewtonCreateBox(m_nWorld,paramA,paramC,paramB,materialID,mPos);
tmpInfo = QObject::trUtf8("La primitive est de forme BOX.");
break;
case GrPrimitive3D::CAPSULE:
newCol = NewtonCreateCapsule(m_nWorld,paramA/2.0,paramB*2.0,materialID,mPos);
tmpInfo = QObject::trUtf8("La primitive est de forme CAPSULE.");
break;
case GrPrimitive3D::CYLINDER:
newCol = NewtonCreateCylinder(m_nWorld,paramA/2.0,paramB,materialID,mPos);
tmpInfo = QObject::trUtf8("La primitive est de forme CYLINDER.");
break;
case GrPrimitive3D::CONE:
newCol = NewtonCreateCone(m_nWorld,paramA/2.0,paramB,materialID,mPos);
tmpInfo = QObject::trUtf8("La primitive est de forme CONE.");
break;
case GrPrimitive3D::CHAMFER_CYLINDER:
newCol = NewtonCreateChamferCylinder(m_nWorld,paramA/2.0,paramB,materialID,mPos);
tmpInfo = QObject::trUtf8("La primitive est de forme CHAMFER_CYLINDER.");
break;
case GrPrimitive3D::USER_PRIMITIVE:
irr::scene::IMesh* mesh = reinterpret_cast<irr::scene::IMesh*>(primitive3D->userData(3));
if(mesh != NULL)
{
float tolerance = primitive3D->parameter("MeshTolerance").toFloat();
if(mesh != NULL)
newCol = p_createCollisionFromMesh(m_nWorld,mesh,tolerance,paramA,paramB,paramC,materialID,mPos);
}
tmpInfo = QObject::trUtf8("La primitive est de forme USER_PRIMITIVE.");
break;
}
for(int i=0;i<primitive3D->childSize();i++) // Fonction récursive qui rappelle tous les enfant pour récupérer toutes les primitives
{
GrPrimitive3D* child = dynamic_cast<GrPrimitive3D*>(primitive3D->child(i));
if(child != NULL)
tmpInfo += p_loadPrimitive3DRecursif(child,listCollision,materialID,internalCounter);
}
if(newCol != NULL){
if(internalCounter<NB_MAX_PRIMITIVE){ // On limite le nombre de collision primitive total pour "UN" objet Newton
listCollision[internalCounter] = newCol;
internalCounter++;}
tmpInfo += QObject::trUtf8(" Création de la primitive réussie.\
");
}
return tmpInfo;
}Et hop...
Hors ligne
21-11-2010 11:20:55
- kiricou974
- Membres
- Date d'inscription:
- Messages: 34
- IP: 77.205.172.249
- Courriel
Merci pour vos reponse. mais je voudrai savoir le quelle est le plus performant. Pour l'instant je suis en train de tester le moteur ode et physix.
Je vous tiendrai au courant sur mon futur choix.
Hors ligne
22-11-2010 12:40:52
- wabb
- Membres

- Date d'inscription:
- Messages: 68
- IP: 82.145.208.77
- Courriel Site web
Hum...
Projet: EVO_Conflict's Factor (http://titanworks-system.over-blog.fr/#)
Hors ligne
22-11-2010 14:39:58
- nabouill
- Membres

- Date d'inscription:
- Messages: 242
- IP: 82.127.58.127
- Courriel
Auteur: nabouill
quote du topic id 1482:
le projet "PAL" a réaliser des benchmarks avec Irrlicht incluant 13 moteurs physiques differents.
Ceci peut être très bon a essayer avant de choisir son moteur physique.
plus d'info:
http://www.adrianboeing.com/pal/benchmark.html#irrdemo
Hors ligne
22-11-2010 17:50:38
- kiricou974
- Membres
- Date d'inscription:
- Messages: 34
- IP: 77.205.172.249
- Courriel
Merci nabouill je vais voir sa de suite.
Hors ligne
22-11-2010 20:47:06
- nabouill
- Membres

- Date d'inscription:
- Messages: 242
- IP: 77.198.97.165
- Courriel
Sinon, pour ce qui est des warpper (car c'est vrai que l'intégration d'un moteur physique n'est pas toujours super simple), il y a IrrOde qui lui est parfaitement à jour. Je ne l'ai pas encore bien testé, mais le si peut que j'ai vue a pas l'air trop mal et assez simple d'utilisation et les tuto on l'air assez clair, je pense que c'est à voir
Hors ligne



