Bonjour,
J'utilise Irrlicht depuis quelques mois et je suis (encore XD) confronté à un problème.
Voilà mon problème :
J'ai 3 cubes, et je veux faire en sorte que lorsque l'on clique sur un des cubes, celui-ci s'illumine.
Mais voilà, comment faire pour que le programme détecte si la position de la souris est placée sur le cube 3D ??
Je pensais à un truc comme la ligne 3D pour faire comme dans les tutos officiels, mais je ne vois rien qui puisse relier la souris à la 2D :S . Quel serais alors la méthode ?
Merci d'avance,
Cordialement
Capry
Hors ligne
"getSceneNodeFromScreenCoordinatesBB" devrait t'aider, sinon va voir les sources de "getSceneNodeFromCameraBB"
les fonctions, sont accessible via "smgr->getSceneCollisionManager()->"
franchement regard la doc ... sa ma prit 20 sec si ses bon ... cherche un peut quand même car ton poste laisse croire le contraire
et l'exemple sur les collisions l'utilise.
Dernière modification par Magun (25-04-2009 06:20:03)
Hors ligne
line3df ray = pScene->getSceneCollisionManager()->getRayFromScreenCoordinates(core::vector2di(MouseX,MouseY),pCamera);
pScene->getSceneCollisionManager()->getSceneNodeAndCollisionPointFromRay(ray,blabla....)
Hors ligne
Merci pour vos réponses !
Mais j'ai besoin encore de quelques précisions :
line3df ray = pScene->getSceneCollisionManager()->getRayFromScreenCoordinates(core::vector2di(MouseX,MouseY),pCamera);
Que retourne cette ligne ? Un vector 3df qui contient quelles positions ?
pScene->getSceneCollisionManager()->getSceneNodeAndCollisionPointFromRay(ray,blabla....)
Et celle-ci à quoi sert-elle ? On y place comme argument la variable "ray" définie plutôt, donc ça dois détecter une collision mais quoi ?
EDIT: après recherche dans la doc, la seconde ligne retournerais apparemment le node(mesh) le plus proche de la collision avec la ligne 3D, et la première crée cette ligne 3D en partant de la position du curseur et de la caméra ? Merci beaucoup à tous (surtout pour la rapidité ),
Dernière modification par capry (22-04-2009 12:16:52)
Hors ligne
line3df ray = pScene->getSceneCollisionManager()->getRayFromScreenCoordinates(core::vector2di(MouseX,MouseY),pCamera);
Cette ligne se contante de transposer des coordonnées 2D sur l'écran (fournis par exemple par une position
d'un pointeur de souris) en une ligne 3D situé dans ton univers 3D.
Cette routine permet par exemple de préparer un test de picking.
Hors ligne
J'ai oublié de demander quelque chose. Comment savoir où la collisions à été faite ? Par exemple si elle à heurtée le node1 à l'emplacement (23,92,68) , comment le savoir, et comment donné à un node cette direction ? Merci d'avance.
Hors ligne
je sais pas trop comment ses foutue, donc pas forcement juste ...
"line3df ray = pScene->getSceneCollisionManager()->getRayFromScreenCoordinates(core::vector2di(MouseX,MouseY),pCamera);" donc je suppose que le début de la ligne est la position de la camera et la fin c'est la ou a lieu la collision ... enfin je suppose
pour la direction j'avais un truc pour ça, mais je les plus, tu doit tant douté il faut utiliser cos, sin ou/et tan ... bien que certain arrive sans
Hors ligne
Dans ce cas comment obtenir la fin de cette ligne ?
Pour la direction j'ai fais un truc comme ça (je veux juste avoir celle autour de l'axe y) :
//"position" est la position du node et "point" est la position du point où s'est faite la collision
rotation.Y=(point.Z-position.Z, point.Y-Position-Y)*180/math_PI
Mais cette formule n'a pas l'air de marcher ...
Hors ligne
Il y a une méthode quelque peu bourrine. A chaque fois que tu inseres un mesh dans irrlicht tu créé un triangle selector que tu stockes dans un array et tu stockes dans un autre array le node associé. Ensuite dans ta boucle de rendu tu fais une boucle de test de collision pour tout les triangle selectors et lorsque qu'il y a collision tu recupère le node dans le array.
Enfin, c'est loin d'être top mais c'est une idée de départ.
Hors ligne
ça pourrais marcher mais c'est beaucoup trop long étant que si je fais ça rien qu'avec la map par exemple, ça fais des centaines (peut-être milliers ??) de triangle à vérifiés :S .
J'aimerais si possible avoir une autre solution plus pratique, et se faisant plus rapidemment.
Hors ligne
Hors ligne
Ah pardon, merci beaucoup ! J'avais pas cherché ça par contre, désolé :S.
Et pour la direction que dois prendre le node (le personnage en fait) ?
Dernière modification par capry (27-04-2009 08:54:27)
Hors ligne
Voici un de mes multiples petit code bien utiles.
Ce code oriente un node vers une position donnée ( on fournis juste les coordonnée dans l'espace de la position choisie).
C'est volontairement détaillé ligne à ligne.
Cela devrait t'aider dans ce que tu cherche à faire, à toi d'adapter pour ton usage perso
PointTargetNode(scene::ISceneNode *node1, float px, float py, float pz, float roll) { core::vector3df target = node1->getPosition(); float x=target.X; float y=target.Y; float z=target.Z; float xdiff=px-x; float ydiff=py-y; float zdiff=pz-z; float dist22=sqrt( (xdiff*xdiff) + (zdiff*zdiff) ); float pitch=atan2(ydiff,dist22); float yaw=atan2(xdiff,zdiff); node1->setRotation( core::vector3df(RAD2DEG(-pitch), RAD2DEG(yaw) , RAD2DEG(roll)) ); }
Hors ligne
Merci beaucoup !! C'est pile ce que je voulais ^^. Juste une dernière précision : qu'est-ce que le "roll" que l'on doit fournir en argument à la fonction ?
EDIT : C'est bon en fait je n'en avais pas besoin de toute façon puisque je voulais juste la direction autour de Y ^^.
Merci beaucoup à tous !
Dernière modification par capry (27-04-2009 10:12:46)
Hors ligne
capry :
Merci beaucoup !! C'est pile ce que je voulais ^^. Juste une dernière précision : qu'est-ce que le "roll" que l'on doit fournir en argument à la fonction ?
petite réponse quand même, en fait c'est si tu souhaite appliquer un roulis à ton node lors de son orientation (mettre 0 par défaut)
Hors ligne
Ah d'accord merci je saurais à l'avenir .
Par contre pour en revenir à la ligne 3D, maligne3d.start, va bien me donné le point de départ de la ligne, mais maligne3d.end va me donner LA FIN de la ligne (ce qui ne correspond pas forcement à l'impacte de la collision). Ce que je voulais c'est l'impact, car la ligne continue même après la collision avec un objets :S ...
Hors ligne
Copland :
line3df ray = pScene->getSceneCollisionManager()->getRayFromScreenCoordinates(core::vector2di(MouseX,MouseY),pCamera);
pScene->getSceneCollisionManager()->getCollisionPoint(ray,blabla....)
Copland t'a donnée la réponse. La fonction getCollisionPoint te donne le position exacte de la collision sur ton objet.
Donc pas de soucis, zieute la doc sur cette fonction et tu trouveras ton bonheur.
Hors ligne
Ah ouin effectivement j'avais pas pensé à aller dans les trucs de scène. Je n'avais cherché que dans la classe "line3d" . Mais en ce qui concerne le getCollisionPoint(), il retourne un booléen (qui veut sans doute dire si la collision est détecté ou pas). Mais moi je sais qu'une collision est détectée, et après je veux savoir où. Ce n'est donc pas la bonne fonction, non ?
Hors ligne
Oui pour le booléen. Mais si tu regarde de plus près la fonction te permet de récupérer dans 'outCollisionPoint' et 'outTriangle' le point de contact ainsi que le triangle percuté.
Hors ligne
Le programme crash quand j'utilise la fonction :S.
de plus OutCollisionPoint et OutTriangle passés en arguments ne sont pas des pointeurs, comment je fais pour les récupérer alors ?
Hors ligne
capry :
OutCollisionPoint et OutTriangle passés en arguments ne sont pas des pointeurs, comment je fais pour les récupérer alors ?
faut faire simple
c'est tout.
Hors ligne
Oui mais si je veux récupérer la valeur de outCollisionPoint. La fonction ne va pas donner une nouvelle valeur à la variable. On fournit donc une valeur à la fonction qu'elle ne peut modifier car n'étant pas un pointeur...
Hors ligne
capry :
Oui mais si je veux récupérer la valeur de outCollisionPoint. La fonction ne va pas donner une nouvelle valeur à la variable. On fournit donc une valeur à la fonction qu'elle ne peut modifier car n'étant pas un pointeur...
Si justement, essais tu verras bien. Tu ne fournis aucune valeurs, mais deux données par le biais d'un 'const core::vector3df &out...'
Je sais, en C++ la transmission des info n'est pas toujours super intuitives, mais cela fonctionne bien.
Hors ligne
Ah ? ok d'accord, mais ça ne résous pas le porblème du crash. D'où peut-il provenir ???
Hors ligne
Faudrait donner ton bout de code
Souvent, les crash sont liées à des pointeurs invalides. Mais sans plus d'info, pas facile à dire.
Hors ligne