Message #9864
Sujet: raycasting avec irrlicht
| Type | Date | Auteur | Contenu |
|---|---|---|---|
| Dernière modification | 09-03-2011 18:47:52 | motohime |
Bonjour.
Je tente actuellement de faire du raycasting avec irrlicht ( comme le nom du sujet l'indique ^^ ). Je rencontre cependant un problème. Voici tout d'abord la démarche avant mon raycasting : J'ai un terrain charger depuis un .obj je crée donc une node pour mon terrain, puis je lui set une ID. Ensuite je crée plusieurs unités, et chaque unité possède donc bien entendu sa propre node, et donc idem sa propre ID. Afin de n'avoir qu'un réseau de node à parcourir pour tester les collisions entre mon rayon et l'une de mes nodes, je crée une node bidon de stockage à laquelle je parente chacune de mes autres nodes ( mon terrain / mes unités ...etc). Le but de mon ray casting est de détecter la visibilité entre mes unités. lorsque je tente d'effectuer mon raycasting, j'initialise une line3d<irr::f32> avec comme point de départ ma node A (mon unité) puis comme point d'arrivé la node B ( une autre unité quelconque ), puis j'utilise la méthode de l'API : getSceneNodeAndCollisionPointFromRay(). Cependant le retour de cette méthode me donne selon moi des résultats farfelu ( ma propre node ( node A ) est retourné par la fonction ). J'ai donc essayer de faire partir le rayon depuis : position node A + vecteur unitaire ( A->B ) afin de ne jamais intersecter ma propre node mais le résultat est identique. Voici un extrait de mon code: //Creation d'un iterateur sur la map des unités std::map<std::string,BasicEntity*>::iterator IT = m_entityList.begin(); int iRayDetection = m_unit->Get_RayDetection(); irr::core::vector3df myposition = m_unit->Get_Position(); //parcour toutes les unités while ( IT != m_entityList.end() ) { //L'unité est différente de moi même if(m_unit != IT->second) { //test de distance entre chaques unité et moi meme if ( myposition.getDistanceFrom(IT->second->Get_Position()) <= iRayDetection ) { //vecteur entre moi et l'unité irr::core::vector3df VDirection = IT->second->Get_Position() - myposition; VDirection.normalize(); float Value = VDirection.dotProduct(m_unit->Get_Direction()); //Le joueur adverse est'il devant moi compris dans un angle de 45° de part et d'autre de mon veteur direction float Angle = (float)acos(Value); if (radToDeg(Angle) <= 45) { //Effectue un lancé de rayon pour savoir si je peu voir l'unités. //Scene Manager irr::scene::ISceneManager* TempSceneManager = CRenderWindow::GetRenderWindow()->GetSceneManager(); //Collision manager irr::scene::ISceneCollisionManager* collMan = TempSceneManager->getSceneCollisionManager(); //ray casting irr::core::line3d<irr::f32> ray; irr::core::vector3df temppos = m_unit->Get_Position(); temppos.Y += 80.0f; ray.start = temppos; ray.end = IT->second->Get_Position(); // Tracks the current intersection point with the level or a mesh irr::core::vector3df intersection; // Used to show with triangle has been hit irr::core::triangle3df hitTriangle; EntityManager* myEntityManager = EntityManager::Get_Singleton_EntityManager(); irr::scene::ISceneNode* globalscenenode = myEntityManager->Get_GlobalSceneNode(); ISceneNode * selectedSceneNode = collMan->getSceneNodeAndCollisionPointFromRay(ray, intersection, hitTriangle, 0, globalscenenode); if ( selectedSceneNode ) { if ( selectedSceneNode->getID() == -10 ) { std::cout << "MUR" << std::endl; } if ( (selectedSceneNode->getID() >= 0) && (selectedSceneNode->getID() < myEntityManager->Get_AllEntity().size()) ) { std::cout << "Moi " << m_unit->Get_ID() << " cible " << selectedSceneNode->getID() << std::endl; } } } } } //incrémentation de l'iterateur IT++; } Merci d'avance de votre aide. Je suis ouvert a toutes suggestions si ma méthode n'est pas l'idéale. |
| Création du message | 09-03-2011 18:47:16 | motohime |
Bonjour.
Je tente actuellement de faire du raycasting avec irrlicht ( comme le nom du sujet l'indique ^^ ). Je rencontre cependant un problème. Voici tout d'abord la démarche avant mon raycasting : J'ai un terrain charger depuis un .obj je crée donc une node pour mon terrain, puis je lui set une ID. Ensuite je crée plusieurs unités, et chaque unité possède donc bien entendu sa propre node, et donc idem sa propre ID. Afin de n'avoir qu'un réseau de node à parcourir pour tester les collisions entre mon rayon et l'une de mes nodes, je crée une node bidon de stockage à laquelle je parente chacune de mes autres nodes ( mon terrain / mes unités ...etc). Le but de mon ray casting est de détecter la visibilité entre mes unités. lorsque je tente d'effectuer mon raycasting, j'initialise une line3d<irr::f32> avec comme point de départ ma node A (mon unité) puis comme point d'arrivé la node B ( une autre unité quelconque ), puis j'utilise la méthode de l'API : getSceneNodeAndCollisionPointFromRay(). Cependant le retour de cette méthode me donne selon moi des résultats farfelu ( ma propre node ( node A ) est retourné par la fonction ). J'ai donc essayer de faire partir le rayon depuis : position node A + vecteur unitaire ( A->B ) afin de ne jamais intersecter ma propre node mais le résultat est identique. Voici un extrait de mon code: //Creation d'un iterateur sur la map des unités std::map<std::string,BasicEntity*>::iterator IT = m_entityList.begin(); int iRayDetection = m_unit->Get_RayDetection(); irr::core::vector3df myposition = m_unit->Get_Position(); //parcour toutes les unités while ( IT != m_entityList.end() ) { //L'unité est différente de moi même if(m_unit != IT->second) { //test de distance entre chaques unité et moi meme if ( myposition.getDistanceFrom(IT->second->Get_Position()) <= iRayDetection ) { //vecteur entre moi et l'unité irr::core::vector3df VDirection = IT->second->Get_Position() - myposition; VDirection.normalize(); float Value = VDirection.dotProduct(m_unit->Get_Direction()); //Le joueur adverse est'il devant moi compris dans un angle de 45° de part et d'autre de mon veteur direction float Angle = (float)acos(Value); if (radToDeg(Angle) <= 45) { //Effectue un lancé de rayon pour savoir si je peu voir l'unités. //Scene Manager irr::scene::ISceneManager* TempSceneManager = CRenderWindow::GetRenderWindow()->GetSceneManager(); //Collision manager irr::scene::ISceneCollisionManager* collMan = TempSceneManager->getSceneCollisionManager(); //ray casting irr::core::line3d<irr::f32> ray; irr::core::vector3df temppos = m_unit->Get_Position(); temppos.Y += 80.0f; ray.start = temppos; ray.end = IT->second->Get_Position(); // Tracks the current intersection point with the level or a mesh irr::core::vector3df intersection; // Used to show with triangle has been hit irr::core::triangle3df hitTriangle; EntityManager* myEntityManager = EntityManager::Get_Singleton_EntityManager(); irr::scene::ISceneNode* globalscenenode = myEntityManager->Get_GlobalSceneNode(); ISceneNode * selectedSceneNode = collMan->getSceneNodeAndCollisionPointFromRay(ray, intersection, hitTriangle, 0, globalscenenode); if ( selectedSceneNode ) { if ( selectedSceneNode->getID() == -10 ) { std::cout << "MUR" << std::endl; } if ( (selectedSceneNode->getID() >= 0) && (selectedSceneNode->getID() < myEntityManager->Get_AllEntity().size()) ) { std::cout << "Moi " << m_unit->Get_ID() << " cible " << selectedSceneNode->getID() << std::endl; } } } } } //incrémentation de l'iterateur IT++; } Merci d'avance de votre aide. Je suis ouvert a toutes suggestions si ma méthode n'est pas l'idéale. |
| Options | Liens officiels | Caractéristiques | Statistiques | Communauté |
|---|---|---|---|---|
|
Préférences cookies Corrections |
![]() ![]() ![]() ![]() |
Propulsé par Django xhtml 1.0 css 2.1 |
884 membres 1440 sujets 11337 messages |
Dernier membre inscrit: Saidov17 144 invités en ligne membre en ligne: - RSS Feed |