#0 

20-11-2010 01:40:14

kiricou974
Membre
Date d'inscription: 18-10-2010
Messages: 34

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


#1 

20-11-2010 12:30:44

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

un peut de recherche sa fait pas de mal .... non ?
bullet : http://irrlicht.sourceforge.net/phpBB2/ … highlight= | http://irrlicht.sourceforge.net/phpBB2/ … hp?t=22764
physix : http://irrlicht.sourceforge.net/phpBB2/ … ght=physix
newton : http://irrlicht.sourceforge.net/phpBB2/ … ght=newton
havok : http://irrlicht.sourceforge.net/phpBB2/ … hp?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


#2 

20-11-2010 14:34:09

nabouill
Abonné
Date d'inscription: 17-09-2009
Messages: 242
Corrections: 1

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.


mes sites: www.manga-vf.fr et www.series-vf.fr

Hors ligne


#3 

21-11-2010 11:04:49

Gehogor
Abonné
Lieu: Paris
Date d'inscription: 02-06-2009
Messages: 130
Corrections: 7

"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é.\n").arg(physics3D->root()->name()).arg(physics3D->name());

    QString tmpInfo = QObject::trUtf8("Objet [%1] -- partie physique [%2]: Mise à jour de la partie physique.\n").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.\n");
    else
        tmpInfo += QObject::trUtf8("Nombre total de primitives: %1.\n").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.\n").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.\n").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("Objet [%1] -- partie physique [%2]: Mode de collision désactivé.\n").toFloat();
    float paramB = primitive3D->parameter("Objet [%1] -- partie physique [%2]: Mise à jour de la partie physique.\n").toFloat();
    float paramC = primitive3D->parameter("Material").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("Aucune forme primitive de créée.\n");
        break;

        case GrPrimitive3D::BOX:
            newCol = NewtonCreateBox(m_nWorld,paramA,paramC,paramB,materialID,mPos);
            tmpInfo = QObject::trUtf8("Nombre total de primitives: %1.\n");
        break;

        case GrPrimitive3D::CAPSULE:
            newCol = NewtonCreateCapsule(m_nWorld,paramA/2.0,paramB*2.0,materialID,mPos);
            tmpInfo = QObject::trUtf8("Nombre total de face: %1 et d'index %2.\n");
        break;

        case GrPrimitive3D::CYLINDER:
            newCol = NewtonCreateCylinder(m_nWorld,paramA/2.0,paramB,materialID,mPos);
            tmpInfo = QObject::trUtf8("AutoInertialAndMass");
        break;

        case GrPrimitive3D::CONE:
            newCol = NewtonCreateCone(m_nWorld,paramA/2.0,paramB,materialID,mPos);
            tmpInfo = QObject::trUtf8("Ix");
        break;

        case GrPrimitive3D::CHAMFER_CYLINDER:
            newCol = NewtonCreateChamferCylinder(m_nWorld,paramA/2.0,paramB,materialID,mPos);
            tmpInfo = QObject::trUtf8("Iy");
        break;

        case GrPrimitive3D::USER_PRIMITIVE:   
            irr::scene::IMesh* mesh = reinterpret_cast<irr::scene::IMesh*>(primitive3D->userData(3));
            if(mesh != NULL)
            {
                float tolerance = primitive3D->parameter("Iz").toFloat();
                if(mesh != NULL)
                    newCol = p_createCollisionFromMesh(m_nWorld,mesh,tolerance,paramA,paramB,paramC,materialID,mPos);
            }
            tmpInfo = QObject::trUtf8("CenterMass_X");
        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("CenterMass_Y");
    }

    return tmpInfo;
}

Et hop... wink

Hors ligne


#4 

21-11-2010 12:20:55

kiricou974
Membre
Date d'inscription: 18-10-2010
Messages: 34

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


#5 

22-11-2010 13:40:52

wabb
Membre
Date d'inscription: 30-04-2010
Messages: 68
Corrections: 1
Site web

Hum...


Projet: EVO_Conflict's Factor (http://titanworks-system.over-blog.fr/#)

Hors ligne


#6 

22-11-2010 15:39:58

nabouill
Abonné
Date d'inscription: 17-09-2009
Messages: 242
Corrections: 1

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


mes sites: www.manga-vf.fr et www.series-vf.fr

Hors ligne


#7 

22-11-2010 18:50:38

kiricou974
Membre
Date d'inscription: 18-10-2010
Messages: 34

Merci nabouill je vais voir sa de suite.

Hors ligne


#8 

22-11-2010 21:47:06

nabouill
Abonné
Date d'inscription: 17-09-2009
Messages: 242
Corrections: 1

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

Dernière modification par nabouill (22-11-2010 21:55:00)


mes sites: www.manga-vf.fr et www.series-vf.fr

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
881 membres
1427 sujets
11117 messages
Dernier membre inscrit: Bidule
39 invités en ligne
Aucun membre connecté
RSS Feed