TEST_F(SceneQueryTest, Ray) { RaySceneQuery* rayQuery = mSceneMgr->createRayQuery(mCamera->getCameraToViewportRay(0.5, 0.5)); rayQuery->setSortByDistance(true, 2); RaySceneQueryResult& results = rayQuery->execute(); ASSERT_EQ("501", results[0].movable->getName()); ASSERT_EQ("397", results[1].movable->getName()); }
Item* OrbitState::pickItem(int x, int y) { Vector2 pickPos = rGUIManager()->getRelativeCursorPosition(x, y); Ray pickRay = orbitScreen->trackBallCamera->getCamera()->getCameraToViewportRay(pickPos[0], pickPos[1]); RaySceneQuery* query = orbitScreen->sceneManager->createRayQuery(pickRay, 0xFFFFFFFF); query->setSortByDistance(true); RaySceneQueryResult& intersections = query->execute(); Item* pickedItem = NULL; float pickedDistance = FLT_MAX; for(RaySceneQueryResult::const_iterator objectI = intersections.begin(); objectI != intersections.end(); ++objectI) { RaySceneQueryResultEntry entry = *objectI; if(entry.distance > pickedDistance) return pickedItem; if(entry.movable != NULL) { if(entry.movable->isVisible() == false) continue; UserDefinedObject* userObject = entry.movable->getUserObject(); // MovableObjects and Entities aren't dynamic so we can't know if we hit one. But we know UserObjects are only attached // to Entities. if(userObject != NULL) { Entity* entity = static_cast<Entity*>(entry.movable); Item* target = dynamic_cast<Item*>(userObject); if(target != NULL) { Real distance; if(CollisionManager::getSingleton().isIntersecting(pickRay, entity, distance) && distance < pickedDistance) { pickedItem = target; pickedDistance = distance; } } } } } return pickedItem; }
void ControllerInput::PerformMouseOver(int MouseX, int MouseY, bool IsClick) { // normalise mouse coordinates to [0,1] float scrx = (float)MouseX / (float)OgreClient::Singleton->Viewport->getActualWidth(); float scry = (float)MouseY / (float)OgreClient::Singleton->Viewport->getActualHeight(); // create ray & query Ray ray = OgreClient::Singleton->Camera->getCameraToViewportRay(scrx, scry); RaySceneQuery* query = OgreClient::Singleton->SceneManager->createRayQuery(ray, 0xFFFFFFFF); // make it also find billboards and sort by distance query->setQueryTypeMask(0xFFFFFFFF); query->setSortByDistance(true); // execute query RaySceneQueryResult result = query->execute(); if (result.size() > 0) { List<unsigned int>^ objectIDs = gcnew List<unsigned int>(result.size()); // iterate hits for(unsigned int i=0; i<result.size();i++) { // get next hit and its type RaySceneQueryResultEntry entry = result.at(i); ::Ogre::String type = entry.movable->getMovableType(); // we only care for types Entity (3d model) // and billboards (2d model) if (type.compare("Entity") == 0 || type.compare("BillboardSet") == 0) { // get name as CLR string ::Ogre::String ostr = entry.movable->getName(); System::String^ s = StringConvert::OgreToCLR(ostr); // try parse an id out of name string unsigned int objectid; System::UInt32::TryParse(s->Substring(s->LastIndexOf('/') + 1), objectid); if (objectid > 0) { RoomObject^ obj = OgreClient::Singleton->Data->RoomObjects->GetItemByID(objectid); // don't select own avatar by clicks if (obj != nullptr && !obj->IsAvatar) { objectIDs->Add(objectid); // for mouseover we just need the first hit if (!IsClick) break; } } } } // reset mouseover object if (!IsClick) OgreClient::Singleton->Data->RoomObjects->ResetHighlighted(); // execute target clicker or mouseover if (objectIDs->Count > 0) { ControllerUI::MouseCursor->setImage(UI_MOUSECURSOR_TARGET); if (IsClick) OgreClient::Singleton->Data->ClickTarget(objectIDs, !IsSelfTargetDown); else OgreClient::Singleton->Data->RoomObjects->HighlightObject(objectIDs[0]); } else { ControllerUI::MouseCursor->setImage(UI_DEFAULTARROW); } } // cleanup query OgreClient::Singleton->SceneManager->destroyQuery(query); };
void WeaponTower::update( Crawler *closestEnemy, float dist , float dt, TowerGameApp *game ) { if (m_type == Type_NODULE) { // nodules dont do anything return; } // don't update if out of range or no bug ParticleEmitter *emitter = m_psys->getEmitter( 0 ); if ((dist > m_sensorRange) || (!closestEnemy)) { emitter->setEnabled( false ); return; } // turn on the juice emitter->setEnabled( true ); // aim at the bug Vector3 myPos = m_platform->getPosition(); Vector3 crawlerPos = closestEnemy->getNode()->getPosition(); Vector3 dir = crawlerPos - myPos; dir.y = 0.0; dir.normalise(); //Radian targetHeading = Ogre::Math::ATan2( dir.x, dir.z ); //m_bracket->yaw( targetHeading ); m_bracket->setDirection( dir, Ogre::Node::TS_WORLD ); dir = crawlerPos - (myPos + Vector3( 0.0, 7.0, 0.0)); //float adj = sqrt((dir.x * dir.x) + ( dir.z * dir.z)); //Radian angle = Ogre::Math::ATan2( dir.y, adj ); //m_gun->pitch( angle, Ogre::Node::TS_LOCAL); m_gun->setDirection( dir, Ogre::Node::TS_WORLD ); //game->mFrameListener->mDebugText = " blarg blarg"; // Ok.. now actually apply damage if (m_timeout < 0.001) { #if 0 Ray shooty( m_gun->getWorldPosition(), m_gun->getWorldOrientation().zAxis() ); RaySceneQuery *rayQuery = m_sceneMgr ->createRayQuery( shooty ); rayQuery->setQueryMask( MASK_CRAWLER ); RaySceneQueryResult &result = rayQuery->execute(); RaySceneQueryResult::iterator itr = result.begin(); /// did we hit a crawler game->mFrameListener->mDebugText = String("Hit Test: "); if (itr != result.end() && ( itr->movable)) { game->mFrameListener->mDebugText += String(" movable: ") + itr->movable->getName(); SceneNode *node = itr->movable->getParentSceneNode(); if (node) { game->mFrameListener->mDebugText += node->getName(); // did we hit a crawler?? for (std::vector<Crawler*>::iterator ci = game->m_crawlers.begin(); ci != game->m_crawlers.end(); ++ci ) { if ( (*ci)->getNode() == node ) { // hit! (*ci)->m_health -= m_damage; } } } } m_sceneMgr->destroyQuery(rayQuery); #endif // forget all of that nonsense... just hit the // closest crawler if (m_type == Type_FLAMETHROWER) { // TODO: should be all enemies within range closestEnemy->m_health -= m_damage * dt; } else { closestEnemy->m_health -= m_damage; } // reset timeout m_timeout = m_reloadTime; } else { // wait to 'recharge' m_timeout -= dt; } }