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.
Dernière modification par motohime (09-03-2011 19:47:52)
Hors ligne