bool CollisionTools::raycast(const Ogre::Ray &ray, Ogre::Vector3 &result,Ogre::MovableObject* &target,float &closest_distance, const Ogre::uint32 queryMask) { target = NULL; // check we are initialised if (mRaySceneQuery != NULL) { // create a query object mRaySceneQuery->setRay(ray); mRaySceneQuery->setSortByDistance(true); mRaySceneQuery->setQueryMask(queryMask); // execute the query, returns a vector of hits if (mRaySceneQuery->execute().size() <= 0) { // raycast did not hit an objects bounding box return (false); } } else { //LOG_ERROR << "Cannot raycast without RaySceneQuery instance" << ENDLOG; return (false); } // at this point we have raycast to a series of different objects bounding boxes. // we need to test these different objects to see which is the first polygon hit. // there are some minor optimizations (distance based) that mean we wont have to // check all of the objects most of the time, but the worst case scenario is that // we need to test every triangle of every object. //Ogre::Ogre::Real closest_distance = -1.0f; closest_distance = -1.0f; Ogre::Vector3 closest_result; Ogre::RaySceneQueryResult &query_result = mRaySceneQuery->getLastResults(); #if 0 for (size_t qr_idx = 0; qr_idx < query_result.size(); qr_idx++) { const Ogre::RaySceneQueryResultEntry& result = query_result[qr_idx]; Ogre::Real distance = result.distance; Ogre::MovableObject* movable = static_cast<Ogre::MovableObject*>(result.movable); Ogre::SceneQuery::WorldFragment* worldFragment = result.worldFragment; if (movable) { const Ogre::String& type = movable->getMovableType(); const Ogre::String& name = movable->getName(); const Ogre::String& parentName = movable->getParentNode()->getName(); Ogre::uint32 flag = movable->getQueryFlags(); if (type.compare("Entity") == 0) { Ogre::Entity* ent = (Ogre::Entity*)movable; } std::ostrstream oss; oss<<"name:"<<name<<" distance:"<< distance <<" type:"<<type<<" flag:"<<flag<<" parent:"<<parentName<<std::endl; OutputDebugString(oss.str() ); } } #endif for (size_t qr_idx = 0; qr_idx < query_result.size(); qr_idx++) { // stop checking if we have found a raycast hit that is closer // than all remaining entities if ((closest_distance >= 0.0f) && (closest_distance < query_result[qr_idx].distance)) { break; } // only check this result if its a hit against an entity if ((query_result[qr_idx].movable != NULL) && (query_result[qr_idx].movable->getMovableType().compare("Entity") == 0)) { // get the entity to check Ogre::MovableObject *pentity = static_cast<Ogre::MovableObject*>(query_result[qr_idx].movable); // mesh data to retrieve size_t vertex_count; size_t index_count; Ogre::Vector3 *vertices = NULL; Ogre::uint32 *indices = NULL; // get the mesh information GetMeshInformation(((Ogre::Entity*)pentity)->getMesh(), vertex_count, vertices, index_count, indices, pentity->getParentNode()->_getDerivedPosition(), pentity->getParentNode()->_getDerivedOrientation(), pentity->getParentNode()->_getDerivedScale()); // test for hitting individual triangles on the mesh bool new_closest_found = false; for (size_t i = 0; i < index_count; i += 3) { // check for a hit against this triangle std::pair<bool, Ogre::Real> hit = Ogre::Math::intersects(ray, vertices[indices[i]], vertices[indices[i+1]], vertices[indices[i+2]], true, false); // if it was a hit check if its the closest if (hit.first) { if ((closest_distance < 0.0f) || (hit.second < closest_distance)) { // this is the closest so far, save it off closest_distance = hit.second; new_closest_found = true; } } } // free the verticies and indicies memory delete vertices; delete indices; // if we found a new closest raycast for this object, update the // closest_result before moving on to the next object. if (new_closest_found) { target = pentity; closest_result = ray.getPoint(closest_distance); } } } // return the result if (closest_distance >= 0.0f) { // raycast success result = closest_result; return (true); } else { // raycast failed return (false); } }
bool MyFrameListener::frameStarted(const FrameEvent& evt) { bool mbleft; // Botones del raton pulsados _keyboard->capture(); _mouse->capture(); // Captura eventos int posx = _mouse->getMouseState().X.abs; // Posicion del puntero int posy = _mouse->getMouseState().Y.abs; // en pixeles. // Botones del raton pulsados? ------------------------------------- mbleft = _mouse->getMouseState().buttonDown(OIS::MB_Left); if(_keyboard->isKeyDown(OIS::KC_ESCAPE)) return false; switch(_estado){ case 1: if(_keyboard->isKeyDown(OIS::KC_1)){ _sceneManager->destroySceneNode("ninicio"); _juego->generarTablero(); _juego->generarPlayers(); _juego->colocarBarcos(); _estado = 5; } if(_keyboard->isKeyDown(OIS::KC_2)){ _sceneManager->destroySceneNode("ninicio"); _juego->crearCreditos(); _estado = 2; } break; case 2: if(_keyboard->isKeyDown(OIS::KC_B)){ _sceneManager->destroySceneNode("ncreditos"); _juego->crearMenu(); _estado = 1; } break; // Exit! case 5: if (mbleft) { uint32 mask; mask = CUBE1 | STAGE; // Podemos elegir todo setRayQuery(posx, posy, mask); Ogre::RaySceneQueryResult &result = _raySceneQuery->execute(); Ogre::RaySceneQueryResult::iterator it; if(result.begin()!=result.end()){ it = result.begin(); Ogre::SceneNode* nodo = it->movable->getParentSceneNode(); Ogre::MovableObject* clickado = nodo->getAttachedObject(0); if(clickado->getQueryFlags()==CUBE1){ if(_turno==1 && (int)it->movable->getParentSceneNode()->getName()[3]-48>=0 && (int)it->movable->getParentSceneNode()->getName()[3]-48<8 && (int)it->movable->getParentSceneNode()->getName()[5]-48>=0 && (int)it->movable->getParentSceneNode()->getName()[5]-48<8){ _turno = _juego->simular((int)it->movable->getParentSceneNode()->getName()[3]-48, (int)it->movable->getParentSceneNode()->getName()[5 ]-48);//tabla ascii } if(_turno == 2){ _estado = 6; } } } } break; case 6: if(_keyboard->isKeyDown(OIS::KC_RETURN)){ _juego->reiniciar(); _juego->generarPlayers(); _juego->colocarBarcos(); _estado = 5; _turno = 1; std::cout << _estado << std::endl; } break; } return true; }