void SelectionBox::performSelection(std::list<AgentId> &selection, Ogre::Camera *mCamera) { if((mRight - mLeft) * (mBottom - mTop) < 0.0001) return; float left = (mLeft + 1.f) / 2.f; float right = (mRight + 1.f) / 2.f; float top = (1.f - mBottom) / 2.f; float bottom = (1.f - mTop) / 2.f; Ogre::Ray topLeft = mCamera->getCameraToViewportRay(left, top); Ogre::Ray topRight = mCamera->getCameraToViewportRay(right, top); Ogre::Ray bottomLeft = mCamera->getCameraToViewportRay(left, bottom); Ogre::Ray bottomRight = mCamera->getCameraToViewportRay(right, bottom); // These planes have now defined an "open box" which extends to infinity in front of the camera. You can think of // the rectangle we drew with the mouse as being the termination point of the box just in front of the camera. Ogre::PlaneBoundedVolume vol; const Ogre::Real min = .1, max = 500; vol.planes.push_back(Ogre::Plane(topLeft.getPoint(min), topRight.getPoint(min), bottomRight.getPoint(min))); // front plane vol.planes.push_back(Ogre::Plane(topLeft.getOrigin(), topLeft.getPoint(max), topRight.getPoint(max))); // top plane vol.planes.push_back(Ogre::Plane(topLeft.getOrigin(), bottomLeft.getPoint(max), topLeft.getPoint(max))); // left plane vol.planes.push_back(Ogre::Plane(bottomLeft.getOrigin(), bottomRight.getPoint(max), bottomLeft.getPoint(max))); // bottom plane vol.planes.push_back(Ogre::Plane(topRight.getOrigin(), topRight.getPoint(max), bottomRight.getPoint(max))); // right plane Ogre::PlaneBoundedVolumeList volList; volList.push_back(vol); mVolQuery->setVolumes(volList); Ogre::SceneQueryResult result = mVolQuery->execute(); // Finally we need to handle the results of the query. First we will deselect all previously selected objects, // then we will select all objects which were found by the query. std::list<Ogre::SceneNode *> nodes; Ogre::SceneQueryResultMovableList::iterator iter; for(iter = result.movables.begin(); iter != result.movables.end(); ++iter) { Ogre::MovableObject *movable = *iter; if(movable->getMovableType().compare("Entity") == 0) { Ogre::Entity *pentity = static_cast<Ogre::Entity *>(movable); nodes.push_back(pentity->getParentSceneNode()); } } mEngine->level()->getAgentsIdsFromSceneNodes(nodes, selection); }
std::vector<Unite *> RTSState::getUnitesInRectangleUnderCamera(const Rectangle<float> &rectangle) const { Ogre::PlaneBoundedVolume vol; Ogre::Camera *camera = m_gameEngine->cameraManager()->camera(); Ogre::Ray topLeft = camera->getCameraToViewportRay(rectangle.left, rectangle.top); Ogre::Ray topRight = camera->getCameraToViewportRay(rectangle.left + rectangle.width, rectangle.top); Ogre::Ray bottomLeft = camera->getCameraToViewportRay(rectangle.left, rectangle.top + rectangle.height); Ogre::Ray bottomRight = camera->getCameraToViewportRay(rectangle.left + rectangle.width, rectangle.top + rectangle.height); vol.planes.push_back(Ogre::Plane(topLeft.getPoint(1), topRight.getPoint(1), bottomRight.getPoint(1))); // front plane vol.planes.push_back(Ogre::Plane(topLeft.getOrigin(), topLeft.getPoint(100), topRight.getPoint(100))); // top plane vol.planes.push_back(Ogre::Plane(topLeft.getOrigin(), bottomLeft.getPoint(100), topLeft.getPoint(100))); // left plane vol.planes.push_back(Ogre::Plane(bottomLeft.getOrigin(), bottomRight.getPoint(100), bottomLeft.getPoint(100))); // bottom plane vol.planes.push_back(Ogre::Plane(topRight.getOrigin(), topRight.getPoint(100), bottomRight.getPoint(100))); // right plane Ogre::PlaneBoundedVolumeList volList; volList.push_back(vol); EngineManager *mng = m_gameEngine->getManager(); Ogre::PlaneBoundedVolumeListSceneQuery *query = mng->getGraphic()->getSceneManager()->createPlaneBoundedVolumeQuery(volList); Ogre::SceneQueryResult result = query->execute(); std::vector<Unite *> foundUnits; std::for_each(result.movables.begin(), result.movables.end(), [&foundUnits](Ogre::MovableObject * obj) { try { WorldObject *worldObj = Ogre::any_cast<WorldObject *>(obj->getUserObjectBindings().getUserAny()); Unite *unite = dynamic_cast<Unite *>(worldObj); foundUnits.push_back(unite); } catch (...) { } }); return foundUnits; }