Bonjour à tous,
Voici un moment que je ne suis plus venu sur le forum, car je continuais à programmer un peu, jusqu'à être confonté à un nouveau problème.
Voilà, je fais un jeu avec Irrlicht, et j'aurais besoin de savoir si Irrlicht permettais de savoir lorsque 2 mesh entre en collision, pour que je puisse faire par exemple un :
if(mesh1->isCollideWith(mesh2))
etc...
Ma question est simple mais j'ai beau avoir chercher dans la doc et beaucoup sur les forums je n'ai pas trouver de réponse.
Pouvez-vous m'aider ?
Merci d'avance
Capry
Hors ligne
J'ai pas mal travaillé sur ce problème moi aussi pour mon jeu, et je pense avoir pour toi une piste intéressante.
Dans le ISceneCollisionManager, il existe une fonction qui est
getCollisionPoint(const core::line3d< f32 > &ray, ITriangleSelector *selector, core::vector3df &outCollisionPoint, core::triangle3df &outTriangle).
L'idée est que tu fais partir un rayon de ton mesh1 (const core::line3d< f32 > &ray), et tu testes si il entre en collision avec le ITriangleSelector de ton mesh 2. Si oui, la fonction renvoie true, ainsi que le point de collision, et le triangle d'intersection (les deux derniers arguments).
Après, la version 1.6 d'irrlicht a fait des progrès dans ce domaine, en particulier, cette fonction renvoie désormais un pointeur vers le mesh qui est touché par le ray. Dans ce cas, tu peux regrouper tous tes mesh dans un seul gros TriangleSelector, et utiliser la fonction pour savoir avec quel mesh tu collisionne. Du coup, tu pourrais faire un truc du genre.
mesh2 = mesh1->getCollision()
Je te conseille d'attendre encore un petit peu, je pense que la doc (et surtout l'API) de la 1.6 va bientôt remplacer celle de la 1.5.1 sur le site officiel pour avoir plus d'aide sur ce sujet.
PS : Quand je dis mesh, je veux bien sûr parler de MeshSceneNode...
Dernière modification par Hawk (07-10-2009 16:42:09)
Hors ligne
Merci pour ta réponse. l'idée est bonne j'y avais déjà pensé, mais faire une ligne à partir de mon mesh1 n'est pas assez précis car il faudrais que mon mesh2 touche la ligne. Or il peut quand même toucher le mesh1 sans toucher la ligne !
Sinon j'avais aussi eu l'idée d'utiliser la classe : irr::core::aabbox3d< T > avec la fonction :
bool intersectsWithBox (const aabbox3d< T > &other) const
Sauf que celle-ci me renvoi true (même si les deux mesh sont très éloigné et qu'il y à normalement 0% de chance que leur boite englobante se touchent). Si vous avez aussi une idée sur ce point ce serais pas mal, car ça me semblais une bonne solution...
Hors ligne
J'ai découvert autre chose sur la 1.6 qui pourrait être utile.
Le "ISceneNodeAnimatorCollisionResponse" dispose maintenant d'une fonction "getCollisionNode" pour savoir avec qui le node qui a cet animator collisionne.
Une idée serait, je pense, de mettre tous les meshs dans un grand triangle selector, que tu pourrais utiliser pour le AnimatorCollisionResponse.
Je sais pas si je suis très clair, et je suis pas sûr que ça marche, mais c'est une piste à creuser. Tu peux trouver de la doc la dessus avec la 1.6 (en fait, la doc n'est pas sur le site, mais elle est dans le package Irrlicht 1.6 !)
Pour tes Box, c'est étrange que ça collisionne. Je n'ai jamais essayé cette solution, donc je ne sais pas pourquoi ça fait ça.
Dernière modification par Hawk (09-10-2009 00:07:34)
Hors ligne
ah merci, je vais tester ta solution, à défaut d'en avoir d'autre.
Je vais voir ce que je peux faire avec ça...
EDIT :
Euh... là j'ai un joli problème. Pour utiliser la nouvelle fonction j'ai dû passer à Irrlicht 1.6. Au moment de tout recompiler il me dis que j'ai une erreur (dans un autre fichier) :
[...] no matching function for call to `irr::scene::ISceneCollisionManager::getCollisionPoint(irr::core::line3d<irr::f32>&, irr::scene::ITriangleSelector*, irr::core::vector3df&, irr::core::triangle3df&, irr::scene::ISceneNode*&)'
[...]
candidates are: virtual bool irr::scene::ISceneCollisionManager::getCollisionPoint(const irr::core::line3d<irr::f32>&, irr::scene::ITriangleSelector*, irr::core::vector3df&, irr::core::triangle3df&, const irr::scene::ISceneNode*&)
Alors là je ne comprends plus rien *_*. Les deux fonctions sont strictement identiques sauf le "const" devant le premier et dernier paramètre. De plus j'ai beau remettre la version 1.5 d'Irrlicht maintenant il me fait la même erreur alors qu'avant non... I need help please =S
Dernière modification par capry (09-10-2009 15:19:33)
Hors ligne
J'ai eu ce problème aussi, en fait, il faut envoyer un pointeur vers ISceneNode constant pour que ça marche.
Donc juste avant, tu fais un const irr::sceneISceneNode* node= 0, et tu envoie le node comme paramètre.
Moi je l'ai fais et ça marche.
Hors ligne
bah nan toujours le même résultat =S
Hors ligne
Etrange.
Moi j'ai ça dans mon code :
Et ça marche très bien avec la 1.6 !
Hors ligne
c'est bon j'ai résolu le problème, j'ai mis tout recompiler et ça à marcher ><. Je suis sur dev et des fois ça arrive qu'un recompilage du programme résolve les problèmes. Bien maintenant que je suis bien à la 1.6, il me reste maintenant à bien détecter les collisions. Seulement voilà, j'ai utilisé la méthode avec "getCollisionNode()" du "ISceneNodeAnimatorCollisionResponse" mais là lorsque je fais
La condition n'est jamais vraie =S. Même si les nodes entre en collision la condition ne va jamais se faire. C'est l'opposé de l'autre problème cette fois, lol.
Peut-être ais-je mal définis la variable "collisionResponse" :
Merci de m'aider encore pour ce problème...
Hors ligne
Salut perso quand j'ai ce genre de soucis je fais un
std::cout << collisionResponse->getCollisionNode() << ":" << node1 << std::endl;
à chaque frame.
Ca me permet de mieux comprendre si la collision fonctionne ou si mon pointeur "node1" est mal référencé.
Hors ligne
Si je fais ça je vois que les deux me renvoie une chaine bizarre avec 0x[...] mais le [...] est différent pour les deux. Le collisionResponse->getCollisionNode() renvoi toujours "0x3fa71e4c" ou "0x3dc2d82d" (1 fois sur 2 en fait) alors que "node1" me renvoi "0xa6e8518". C'est grave docteur ? Comment corriger ça ?
Hors ligne
Le code ne dis rien (c'est l'adresse mémoire de l'objet en héxa) ca veux juste dire que la collision fonctionnne puisque collision->getnode change. Donc commence par vérifier si node1 est bien référencé. Essaye de modifier un de ses paramêtres pour être sur que le pointeur est à jour.
Hors ligne
désolé de remonter ce topic mais moi, la méthode getCollisionNode() me renvoie un pointeur vers le mesh lié au collisionResponseAnimator (sauf quand celui ci est dans le vide, la ca me renvoie rien) ...
[EDIT]désolé, en fait les adresses était quasi identiques alors je me suis trompé, c'est bien vers un node différent que pointe le node que me renvoie getCollisionNode() mais je n'arrive pas a l'identifier, ce n'est ni celui de la salle, ni celui de mon zombie ni celui de la chaise au fond de la scene.
quand j'éssais de déplacer le node renvoyé par getCollisionNode(), le compilo me dit ça :
impossible de convertir un pointeur 'this' de 'const irr::scene::ISceneNode' en 'irr::scene::ISceneNode &'.
Dernière modification par Ilovechocolat (02-01-2010 15:51:21)
Hors ligne
Ca serait plus simple avec la ligne concernée ainsi que le code précédent ...
désolé
je ne vois pas ce qui est 'this' à ce moment ...
Dernière modification par TUpac (02-01-2010 16:54:28)
Hors ligne
j'avais oublié une partie de l'erreur :
error C2662: 'irr::scene::ISceneNode::setPosition' : impossible de convertir un pointeur 'this' de 'const irr::scene::ISceneNode' en 'irr::scene::ISceneNode &'
apparemment l'erreur est dans la fonction setPosition, voici la ligne de code :
[EDIT]je viens de me rendre compte que le fonction getCollisionNode ne marche que quand on a utilisé la fonction createOctTreeTriangleSelector et pas avec createTriangleSelectorFromBoundingBox.
Si quelqu'un connait un moyen d'y remédier.
Dernière modification par Ilovechocolat (04-01-2010 18:04:29)
Hors ligne