#0 

04-04-2015 00:20:22

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Salut !

Une question me préoccupe, j'aimerais comprendre comment on peut associer un système de ragdoll avec l'animation d'un personnage ? A mon avis il faut animer autrement que par des setFrame ? Enfin bref, si quelqu'un détient la réponse...

Merci smile

Dernière modification par jonath313 (04-04-2015 00:32:04)

Hors ligne


#1 

05-04-2015 09:21:50

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

salut
le plus simple c'est de désactiver le ragdoll lorsque ton personnage est "vivant"
animer un ragdoll pour "binder" les positions sur l'animation c'est beaucoup trop coûteux
et tu devra géré les différence de poids et de force si tu veux que ce soit bien fait et que ton perso ne parte pas n'importe comment
si tu veut partir dans cette direction tu devras passer par une lib genre http://smartbody.ict.usc.edu/

après lorsque ton perso est mort la oui
tu auras besoin d'un modèle physic avec les contraintes le plus chiant
et la effectivement sa vaut le coup

tu set ton IAnimatedMeshSceneNode::setJointMode( EJUOR_CONTROL );
et ta plus cas copier les positions et les rotations (faire la différence avec la position du joueurs puisque ces transformation sont local)

voila je sais pas si tu veut plus d'info

Hors ligne


#2 

05-04-2015 22:57:57

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Merci pour tas réponse Magun,

Enfait tu me conseil de copier les positions et rotations des bones de mon mesh animé et de les appliquer au ragdoll. Mais si je fais cela le ragdoll devient inutile. Par exemple, imaginons que le personnage est entreint de marcher, si je lui lance un cube lourd sur la tronche, il risque d'y avoir aucun effet sur sa chute car le controle des éléments constituants le ragdoll sera dépendant des positions des bones. Moi je pensais que les personnages étaient animés par la partie physique et nonplus par une animation en frame... Le fait d'activer ou de désactiver le ragdoll est contraignant et j'ai déja réalisé l'animation d'un personnage qui marche manuellement et effectivement çà demande énormément de ressources. Mais à mon avis tas solution est la plus logique... Je peux peut être  jouer sur les collisions, si le personnage est percuté par un objet, j'active le ragdoll.

... je médite encore

Hors ligne


#3 

06-04-2015 00:19:09

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

si tu veut effectivement aller au font des choses le faites d'activée le ragdoll au hit d'un objet est une solution pas trop mal
mais encore une fois ce n'est pas simple, tout dépend à quel degrée tu veut que cela soit réaliste

veut tu que ton perso puisse rester debout en fonctions de la force du choc ?
où activer le ragdoll un certain temps puis "binder" une animation pour le relever te conviendrait ? (inverse kinematics)

le gros soucis ça reste d'animer le modèle par la physique ou non
tout dépend du domaine d'application que tu vise jeux/scientifique/... ?

smartbody c'est justement de faire calculer les animations par la physique,
de calculer les forces nécéssaires pour les mouvements,
récupéré après un choc, évité des obstacles, ... etc
c'est plutot performant, avec du multi-threading mes ça reste lourd par rapport a une animation classic

faut voir, ce que tu as beusoin sans forcement te lancer dans un projet secondaire uniquement pour l'animation

Hors ligne


#4 

06-04-2015 17:12:56

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Je ne pense pas avoir besoin de quelque chose d'aussi performant, juste besoin d'un minimum de réalisme. Je pense que "binder" une animation devrait le faire. Je veux pas faire un jeux physique, ni beau graphiquement, juste un jeux avec des possibilités fun et addictive et je pense que du coté physique il y a moyen de faire un truc simpas en alliant l'anim et la physique.

Hors ligne


#5 

07-04-2015 16:46:54

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

donne plus d'info sur ce que tu souhaite réalisé
j'essaierai de t'orienter wink

Hors ligne


#6 

09-04-2015 20:40:56

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

hé bien tout d'abord il y a certaines animation que je n'arrive pas à faire de maniére réaliste par exemple le saut. Pour moi c'est simplement dut au fait que j'essai de donner des trajectoires au personnage, alors je me suis dis pourquoi pas traiter çà de maniére physique avec de l'inertie et de la gravité ... enfin bref beaucoups de choses complexe à programmer. C'est pareil, je suis sur un ptit jeux 2 player sur un écran et j'aimerai faire des choses plutôt simpas au niveau déplacement, du genre subir des choc, se cacher dérriére des mur, ... çà fais un moment que je suis sur le projet mais là je suis devant des questions blocantes, comment réalise t'on ce que je veux faire ?

Merci pour ton aide wink

Hors ligne


#7 

10-04-2015 00:15:03

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

uhm bon, ça manque d'info !

déjà perso j'oublirais directement l'animation du personnage par la physique,
c'est un troue sans fin tu va réinventer la roue ça va être une merde pas possible
très peut d'api sont disponible pour faire ceci c'est par pour rien
smartbody est le seul disponible en opensource
il te suffi de regarder les vidéos ou sont concurrent (oublier le nom basé sur physx)

maniére réaliste par exemple le saut.


bon normalement ta du commencer a faire les base de ton applications je ne rentre pas dedans (ou demande)
actuelement je suppose que ton personnage est géré par btPairCachingGhostObject / btKinematicCharacterController
pour l'animation donc il ne te suffi que de custommisé btKinematicCharacterController

tu regarderas particulierement du coter de btKinematicCharacterController::PostStep
normalement a ce moment un raycast est opéré.
donc quand tu jump, tu déclenche ton animation de saut
quand la distance avec le sol commence a dimminuer tu fait ton animation de chute
et tu te trouve une distance minimal pour déclencher ta 3ème animation d'atérissage ou mort

et puis quand ton perso tombe étant donner que c'est ton raycast qui détermine l'animation ça te feras l'effect escompter en même temps

subir des chocs


je pensse que j'opterais pour un skellette basé sur des btGhostObjects pour la détection "d'intrusion physique"
un peut comme des teste d'intersection aabbox en mieux smile

le plus dure va être de faire du binding d'animation, une classe permetant de jouer l'animation de ton personnage
tout en permettant d'animer "manuelement" partielement ou non le skellette en fonction du choc et de ça direction
et je te renvoie encore une fois sur l'inverse kinematics

ou d'activer partielement le ragdoll pour le membre avec les contraintes sur le reste
(utiliser btOverlapFilterCallback pour forcer la collision avec les btCollisionShape des btGhostObject du ragdoll)
en admetant que le choc tue le personnage a ce moment, la oui tu auras bien ton ragdoll

se cacher dérriére des murs


en "général", ont va plutot dire dans les dernier jeux commerciaux à grand titre
comme le budget est souvent négliger et qu'il sont contraint a des délais cette fonction,
c'est plus ou moin une finte comme souvent en prog ...

tu remarquera d'ailleur que le gameplay t'oblige a intéragir pour te cacher
donc ce sont des zones prédeterminées, donc au final ce n'est qu'un jeux d'animation différent
en ajoutant un test d'intersection avec la surface en question pour le point n°2 (btOverlapFilterCallback)

voila voila, bon si malgré tout ça ne te convien pas et que tu souhaite faire de l'animation par la physique
dans ce cas tu peut te diriger vers l'exemple <<Dynamic Control>> de bullet tu regarde et nous en reparleron
j'ai beusoin de faire plus d'approfondissement, mais y a moyen que ce soit pas mal wink

enfin bon, je ne suis peut-être pas le mieux placer pour ce sujet

ps: utilise bullet 3.x grande différence de performance avec la 2.x et meilleur gestion du thread-safe

Hors ligne


#8 

11-04-2015 02:07:05

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Il faut que je trouve des tutoriaux pour débutant car là perso tu m'a complétement largué, je me rend compte que c'est hyper complexe. Je pensais pouvoirs déplacer mon personnage avec les positions irrlicht en utilisant les collisions bullet, mais plus rien ne fonctionne. En tout cas merci pour tes conseils.

Hors ligne


#9 

11-04-2015 12:01:15

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Sais-tu comment on fait pour déplacer un objet avec bullet ?
J'ai fais une box et je voudrais la déplacer en fonction des évents :

Code c++ :

    ISceneNode *Node = smgr->addCubeSceneNode(1.0f);
    Node->setScale(TScale);
    ///Node->setMaterialFlag(EMF_LIGHTING, 1);
    ///Node->setMaterialFlag(EMF_NORMALIZE_NORMALS, true);
    Node->setMaterialTexture(0, driver->getTexture("media/rose.png"));
    Node ->setMaterialFlag(irr::video::EMF_LIGHTING, true);
    Node->setMaterialFlag(EMF_NORMALIZE_NORMALS, true);
    // Set the initial position of the object
    btTransform Transform;
    Transform.setIdentity();
    Transform.setOrigin(TPosition);

    btDefaultMotionState *MotionState = new btDefaultMotionState(Transform);

    // Create the shape
    btVector3 HalfExtents(TScale.X * 0.5f, TScale.Y * 0.5f, TScale.Z * 0.5f);
    btCollisionShape *Shape = new btBoxShape(HalfExtents);

    // Add mass
    btVector3 LocalInertia;
    Shape->calculateLocalInertia(TMass, LocalInertia);

    // Create the rigid body object
    btRigidBody *RigidBody = new btRigidBody(TMass, MotionState, Shape, LocalInertia);

    // Store a pointer to the irrlicht node so we can UPDATE it later
    RigidBody->setUserPointer((void *)(Node));

    // Add it to the world
    World->addRigidBody(RigidBody);
    Objects.push_back(RigidBody);


Cette box sera le cube de collision de mon personnage par exemple.

Merci smile

Hors ligne


#10 

11-04-2015 13:48:19

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

si c'est pour un personnage btKinematicCharacterController

Code c++ :


            shape = new btCapsuleShape(width, height);

            ghost = new btPairCachingGhostObject();
            ghost->setActivationState(DISABLE_DEACTIVATION);
            ghost->setCollisionShape(shape);
            ghost->setUserPointer((void*)(this));

            character = new btKinematicCharacterController(
                ghost, (btConvexShape*)shape,
                btScalar(box.getExtent().Y/5)
            );


update:

Code c++ :


                irr::u32 time = phy->getEnityManager()->getDevice()->getTimer()->getTime();
                irr::f32 DeltaTime = (time-TimeStamp) / 500.0f;

                btTransform &xform = m_ghost->getWorldTransform();
                btMatrix3x3 &orn = xform.getBasis();

                orn *= btMatrix3x3(
                    btQuaternion(
                        {0,1,0},
                        DeltaTime*(m_rotateLeft-m_rotateRight)
                    )
                );

                btVector3 forwardDir = orn[2].normalize();
                btVector3 strafeDir = orn[0].normalize();

                btVector3 walkDirection;

                walkDirection = strafeDir*(m_strafeRight - m_strafeLeft)*0.5f;
                walkDirection += forwardDir*(m_forkward - m_backward);
                character->setWalkDirection(walkDirection*speed);

                TimeStamp = time;



note btCapsuleShape pour un personage, c'est mieux pour les escaliers ...
sinon tu peut jouer avec setInterpolationLinearVelocity mais c'est moin bien

Hors ligne


#11 

11-04-2015 18:35:15

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

ha merci, j'y vois plus clair smile
Juste une question de base, pourquoi quand j'écris :

Code c++ :

btCollisionShape* shape = new btCapsuleShape(width, height);      --> Là çà compile
ou
shape = new btCapsuleShape(width, height);                                --> Là çà compile pas


Car je n'arrive pas à trouver les types pour les lignes :

Code c++ :

XXXX* ghost = new btPairCachingGhostObject();
XXXX* character = new btKinematicCharacterController(...);


Je remarque que dans la plupart des codes ils ne sont pas mentionnés , peut être que je ne link pas les bonnes lib ?

Code c++ :

#include <bullet/btBulletCollisionCommon.h>
#include <bullet/btBulletDynamicsCommon.h>

Dernière modification par jonath313 (11-04-2015 18:36:10)

Hors ligne


#12 

11-04-2015 19:50:32

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

#1: pas de soucis de mon coté, il faudrait l'erreur généré
#2: si tu ne connais pas le type en c++11 tu peut passer par auto
      ou simplement regarder l'api
      http://bulletphysics.org/Bullet/BulletF … oller.html
      http://bulletphysics.org/Bullet/BulletF … bject.html
      ps: pour bullet 3 tu devras généré la doc depuis les sources avec doxygen par exemple
            globalement l'api ne change pas beaucoup avec la 2.x
      ou juste regarder les sources depuis ton ide ... clic droit sur le nom -> find declaration of '...'
#3: perso, je ne passe pas par ces headers, je n'inclue que le minimum pour chaque classes,
ça permet au compilateur d'optimiser un peut et diminuer la taille des executables
et puis il te suffis de regarder le contenue de ces headers, tu verras qu'il n'inclue pas tout pour la même raison

Code c++ :


#include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <BulletDynamics/Character/btKinematicCharacterController.h>



wink

Hors ligne


#13 

11-04-2015 22:25:05

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

C'est bon merci du coups j'ai trouvé. çà compile mais je ne vois rien. Peux tu me détailler à coi servent les lignes de ton code stp ?

Hors ligne


#14 

11-04-2015 22:29:38

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

le quelle ?

Hors ligne


#15 

11-04-2015 22:33:40

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Celui-ci déjà :

Code c++ :

            shape = new btCapsuleShape(width, height);

            ghost = new btPairCachingGhostObject();
            ghost->setActivationState(DISABLE_DEACTIVATION);
            ghost->setCollisionShape(shape);
            ghost->setUserPointer((void*)(this));

            character = new btKinematicCharacterController(
                ghost, (btConvexShape*)shape,
                btScalar(box.getExtent().Y/5)
            );


Je devrais voir un objet ? Car je ne vois rien.
Merci

Dernière modification par jonath313 (11-04-2015 22:34:29)

Hors ligne


#16 

12-04-2015 10:42:59

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

forcement tu doit l'ajouter a la simulation ^^

Code c++ :


dynamicsWorld->addRigidBody(
    btRigidBody::upcast(ghost),
    btBroadphaseProxy::CharacterFilter,
    btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter
);
dynamicsWorld->addAction(character);

mais bon la je ne te rend pas service tu fait du copier coller
tu devraient regarder les implementations de irrBulet/openmw/tutorial ?
http://codefreax.org/tutorials/view/id/3 30sec sur google ! :]

Hors ligne


#17 

23-04-2015 13:02:44

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

ok merci bien smile

J'ai une question:
Existe t-il un debug permettant de voir la shape bullet dans irrlicht?
La capsule n'est pas apparente en fait...

Hors ligne


#18 

24-04-2015 22:13:41

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

biensur tu doit dériver btIDebugDraw wink
et faire une implementation pour irrlicht et la repasser a bullet btDynamicsWorld::setDebugDraw(@interface)
pour afficher le debug (au sein du rendue) btDynamicsWorld::debugDrawWorld()

Hors ligne


#19 

25-04-2015 23:27:48

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

ok merci c'est cool çà marche smile

Par contre j'ai une question (encore hmm) mais d'ordre plus général ... Quand tu utilise bullet tu l'initialise comme ceci :

Code:

       btDiscreteDynamicsWorld *World = 0;
    btDefaultCollisionConfiguration *CollisionConfiguration = new btDefaultCollisionConfiguration();
    btBroadphaseInterface *BroadPhase = new btAxisSweep3(btVector3(-1000, -1000, -1000), btVector3(1000, 1000, 1000));
    btCollisionDispatcher *Dispatcher = new btCollisionDispatcher(CollisionConfiguration);
    btSequentialImpulseConstraintSolver *Solver = new btSequentialImpulseConstraintSolver();
    World = new btDiscreteDynamicsWorld(Dispatcher, BroadPhase, Solver, CollisionConfiguration);
    World->setGravity(btVector3(0,-9.8,0));

Tu me parle d'ajouter à la simulation çà signifie quoi ? Car je suis vraiment novice sur bullet ... je sais qu'il y a des fonctions à ajouter telles que :

Code:

static void UpdatePhysics(u32 TDeltaTime);
static void UpdateRender(btRigidBody *TObject);
static void ClearObjects();
static int GetRandInt(int TMax) { return rand() % TMax; }

Question :
Est-ce qu'il faut toujours avoir ces fonctions ? Et quel est le rôle de UpdateRender ?

Code:

void UpdateRender(btRigidBody *TObject) {
    ISceneNode *Node = static_cast<ISceneNode *>(TObject->getUserPointer());

    // Set position
    btVector3 Point = TObject->getCenterOfMassPosition();
    Node->setPosition(vector3df((f32)Point[0], (f32)Point[1], (f32)Point[2]));

    // Set rotation
    vector3df Euler;
    const btQuaternion& TQuat = TObject->getOrientation();
    quaternion q(TQuat.getX(), TQuat.getY(), TQuat.getZ(), TQuat.getW());
    q.toEuler(Euler);
    Euler *= RADTODEG;
    Node->setRotation(Euler);
}

C'est nécessaire de les avoir pour utiliser ce que tu m'expliquais avant sur l'utilisation de la capsuleshape et du ghost ?

Merci pour tes réponses

Hors ligne


#20 

27-04-2015 23:28:16

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

l'initialisation oui dans le cas général c'est ça il me semble

ajouter a la simulation ? mais enfin je t'est mis le code juste en dessous yikes
http://bulletphysics.org/Bullet/BulletF … a24dc21b9d
http://bulletphysics.org/Bullet/BulletF … 0055451456
http://bulletphysics.org/Bullet/BulletF … 8ebd33498c

pour t'est autre fonctions, navré mais elle n'appartienne pas a bullet donc je ne sais pas
par contre UpdateRender quelle morceaux ne comprend tu pas ?
ça ne fait que copier les positions/rotations du node bullet vers ton node irrlicht

ah mon avis tu ne sais pas chercher smile

Hors ligne


#21 

27-04-2015 23:36:59

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Ha mon avis c'était plus simple que çà, mais j'ai compris smile => Il y a le pas de calcul du simulateur physique qui doit être définit. Les codes c'est bien mais comprendre c'est mieux. Sinon merci pour tes liens vers la doc de l'API je vais y jeter un œil. Et m'en veux pas d'être nul sur bullet, il y a deux semaine je programmais de l'électronique embarqué pour faire un périphérique USB pour irrlicht alors bon j'étais pas du tout dans le même esprit.

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
882 membres
1429 sujets
11119 messages
Dernier membre inscrit: LiseBuisson96
254 invités en ligne
Aucun membre connecté
RSS Feed