void OgreWidget::mouseMoveEvent(QMouseEvent * e) { if (m_oldPos != InvalidMousePoint) { Ogre::Real deltaX = e->pos().x() - m_oldPos.x(); Ogre::Real deltaY = e->pos().y() - m_oldPos.y(); if (m_mouseButtonsPressed.testFlag(Qt::MiddleButton)) { if(e->modifiers().testFlag(Qt::ControlModifier)) m_camera->zoom(-deltaY); else if (e->modifiers().testFlag(Qt::ShiftModifier)) m_camera->rotate(deltaX, -deltaY); else m_camera->shift(-deltaX, -deltaY); } else if (m_mouseButtonsPressed.testFlag(Qt::LeftButton) && !m_selectionManager.isEmpty()) { if (m_constraintedX && e->modifiers().testFlag(Qt::ShiftModifier)) m_selectionManager.pitch(Ogre::Degree(deltaX)); else if (m_constraintedY && e->modifiers().testFlag(Qt::ShiftModifier)) m_selectionManager.yaw(Ogre::Degree(deltaX)); else if (m_constraintedZ && e->modifiers().testFlag(Qt::ShiftModifier)) m_selectionManager.roll(Ogre::Degree(deltaX)); else { Ogre::Plane plane; if (m_constraintedX) plane.redefine(Ogre::Vector3(1, 0, 0), m_selectionManager.getPosition()); else if (m_constraintedY) plane.redefine(Ogre::Vector3(0, 1, 0), m_selectionManager.getPosition()); else if (m_constraintedZ) plane.redefine(Ogre::Vector3(0, 0, 1), m_selectionManager.getPosition()); Ogre::Ray oldRay = m_camera->getCamera()->getCameraToViewportRay(e->pos().x() / (float)width(), e->pos().y() / (float)height()); Ogre::Ray ray = m_camera->getCamera()->getCameraToViewportRay(m_oldPos.x() / (float)width(), m_oldPos.y() / (float)height()); std::pair<bool, Ogre::Real> oldResult = oldRay.intersects(plane); std::pair<bool, Ogre::Real> result = ray.intersects(plane); if (result.first && oldResult.first) { Ogre::Vector3 point; point = oldRay.getPoint(oldResult.second) - ray.getPoint(result.second); m_selectionManager.translate(point.x, point.y, point.z); } } emit itemMoved(); } m_oldPos = e->pos(); update(); e->accept(); } else { e->ignore(); } }
bool Renderer::RaycastPickScreen(const Vec2& screenPosition, float depth, Camera* camera, RendererRaycastResult& result) { // Set up the ray query object Ogre::Camera* ogreCamera = camera->GetOgreCamera(); Ogre::Ray ray = ogreCamera->getCameraToViewportRay(screenPosition.x, screenPosition.y); mRaySceneQuery->setRay(ray); mRaySceneQuery->setQueryMask(~UNIVERSE_OBJECT); // Execute the ray query Ogre::RaySceneQueryResult& rayQuery = mRaySceneQuery->execute(); for (auto i = rayQuery.begin(); i != rayQuery.end(); ++i) { Ogre::Entity* entity = dynamic_cast<Ogre::Entity*>((*i).movable); if (entity && (*i).distance > 0.0f) { result.hit = true; result.entity = entity; result.position = Position::FromCameraSpace(camera, ray.getPoint((*i).distance)); result.normal = Vec3::zero; return true; } } // At this point - the ray didn't hit anything of interest result.hit = false; result.entity = nullptr; result.position = Position::FromCameraSpace(camera, ray.getPoint(depth)); result.normal = Vec3::zero; return false; }
bool CPlayerController::mousePressed(const InputListener::CMouseState &mouseState) { if(m_avatar){ CEGUI::Vector2f mousePos = CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().getPosition(); Ogre::Ray mouseRay = m_avatar->getScene()->getSceneCamera()->getCameraToViewportRay(mousePos.d_x/float(mouseState.width),mousePos.d_y/float(mouseState.height)); float dist(1300.0f); Ogre::Vector3 point = mouseRay.getPoint(Ogre::Real(dist)); int i =0; while((point.y > -295.0 || point.y < -305.0) && i < 20){ dist += 300.0 + point.y; point = mouseRay.getPoint(Ogre::Real(dist)); i+=1; } point.y = -300.0f; auto it (m_mouseCommands.find(mouseState.button)); if(it != m_mouseCommands.end()){ m_mouseCommands[mouseState.button]->execute (Common::Input::Action::MOUSE_PRESSED,m_avatar,point); //return true; //We're not returning true because we want the mouse event to get to the GUI } } return false; }
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len) { Ogre::Ray ray = Ogre::Ray(orig, dir); Ogre::Vector3 to = ray.getPoint(len); btVector3 btFrom = btVector3(orig.x, orig.y, orig.z); btVector3 btTo = btVector3(to.x, to.y, to.z); std::pair<std::string, float> test = mEngine->rayTest(btFrom, btTo); if (test.first == "") { return std::make_pair(false, Ogre::Vector3()); } return std::make_pair(true, ray.getPoint(len * test.second)); }
bool InteractiveMarkerControl::intersectSomeYzPlane( const Ogre::Ray& mouse_ray, const Ogre::Vector3& point_on_plane, const Ogre::Quaternion& plane_orientation, Ogre::Vector3& intersection_3d, Ogre::Vector2& intersection_2d, float& ray_t ) { Ogre::Vector3 normal = plane_orientation * control_orientation_.xAxis(); Ogre::Vector3 axis_1 = plane_orientation * control_orientation_.yAxis(); Ogre::Vector3 axis_2 = plane_orientation * control_orientation_.zAxis(); Ogre::Plane plane(normal, point_on_plane); Ogre::Vector2 origin_2d(point_on_plane.dotProduct(axis_1), point_on_plane.dotProduct(axis_2)); std::pair<bool, Ogre::Real> intersection = mouse_ray.intersects(plane); if (intersection.first) { intersection_3d = mouse_ray.getPoint(intersection.second); intersection_2d = Ogre::Vector2(intersection_3d.dotProduct(axis_1), intersection_3d.dotProduct(axis_2)); intersection_2d -= origin_2d; ray_t = intersection.second; return true; } ray_t = 0; return false; }
/** Find the closest point on target_ray to mouse_ray. * @returns false if rays are effectively parallel, true otherwise. */ bool InteractiveMarkerControl::findClosestPoint( const Ogre::Ray& target_ray, const Ogre::Ray& mouse_ray, Ogre::Vector3& closest_point ) { // Find the closest point on target_ray to any point on mouse_ray. // // Math taken from http://paulbourke.net/geometry/lineline3d/ // line P1->P2 is target_ray // line P3->P4 is mouse_ray Ogre::Vector3 v13 = target_ray.getOrigin() - mouse_ray.getOrigin(); Ogre::Vector3 v43 = mouse_ray.getDirection(); Ogre::Vector3 v21 = target_ray.getDirection(); double d1343 = v13.dotProduct( v43 ); double d4321 = v43.dotProduct( v21 ); double d1321 = v13.dotProduct( v21 ); double d4343 = v43.dotProduct( v43 ); double d2121 = v21.dotProduct( v21 ); double denom = d2121 * d4343 - d4321 * d4321; if( fabs( denom ) <= Ogre::Matrix3::EPSILON ) { return false; } double numer = d1343 * d4321 - d1321 * d4343; double mua = numer / denom; closest_point = target_ray.getPoint( mua ); return true; }
bool OgreMesh::intersectTri(const Ogre::Ray &ray, IntersectResult &rtn, Triangle*itr, bool isplane) { std::pair<bool, Real> hit = isplane ? Ogre::Math::intersects(ray, Ogre::Plane(itr->v1.coord, itr->v2.coord,itr->v3.coord)) : Ogre::Math::intersects(ray, itr->v1.coord, itr->v2.coord,itr->v3.coord, true, false); rtn.u = 0; rtn.v = 0; if (hit.first && hit.second < rtn.distance) { rtn.intersected = hit.first; rtn.distance = hit.second; Ogre::Vector3 nml=(itr->v1.coord-itr->v2.coord). crossProduct(itr->v3.coord-itr->v2.coord); rtn.normal.x=nml.x; rtn.normal.y=nml.y; rtn.normal.z=nml.z; rtn.tri = *itr; Ogre::Vector3 intersect = ray.getPoint(hit.second) - rtn.tri.v2.coord; Ogre::Vector3 aVec = (rtn.tri.v1.coord - rtn.tri.v2.coord); Ogre::Vector3 bVec = (rtn.tri.v3.coord - rtn.tri.v2.coord); if (aVec.length() > 1.0e-10 && bVec.length() > 1.0e-10) { rtn.u = rtn.tri.v2.u + (rtn.tri.v1.u - rtn.tri.v2.u)*cos(aVec.angleBetween(intersect).valueRadians())*intersect.length()/aVec.length(); rtn.v = rtn.tri.v2.v + (rtn.tri.v3.v - rtn.tri.v2.v)*cos(bVec.angleBetween(intersect).valueRadians())*intersect.length()/bVec.length(); } } return rtn.intersected; }
/* * Heuristic method for raycasting using axis-aligned bounding boxes. * * The output of this method is the location the ray hit the first bounding box * belonging to the robot model or an interactive marker, where the bounding * boxes are sorted in order of the distance to the ray. * * This is not very accurate, and is designed to determine if the ray hits a * point that is "close enough" to some target point. For polygon-level * raytracing, see the * OGRE Wiki at goo.gl/YLKQEo. * * Input: * ray: The ray to check. * * Output: * hit: The median AABB point the ray hit, if any. * * Returns: True if the ray hit anything. */ bool VisibilityChecker::RaycastAABB(const Ogre::Ray& ray, Ogre::Vector3* hit) { if (!ray_scene_query_) { return false; } ray_scene_query_->clearResults(); ray_scene_query_->setRay(ray); Ogre::RaySceneQueryResult& query_results = ray_scene_query_->execute(); if (query_results.size() <= 0) { return false; } // The query results are ordered by distance along the ray. However, for some // reason, some of the results have zero distance. We ignore these when // finding the median. for (const auto& result : query_results) { auto name = result.movable->getName(); // TODO: have the visibility checker pass in what we're looking for, // exactly. if (result.distance > 0 && (name.find("Robot Link") != -1 || name.find("Shape") != -1)) { *hit = ray.getPoint(result.distance); return true; } } return false; }
void GodRaysManager::_updateProjector() { const Ogre::Vector3& SunPosition = mHydrax->getSunPosition(); const Ogre::Vector3& CameraPosition = mHydrax->getCamera()->getDerivedPosition(); Ogre::Plane WaterPlane = Ogre::Plane(Ogre::Vector3(0, 1, 0), mHydrax->getPosition()); Ogre::Ray SunToCameraRay = Ogre::Ray(SunPosition, CameraPosition - SunPosition); Ogre::Vector3 WaterProjectionPoint = SunToCameraRay.getPoint(SunToCameraRay.intersects(WaterPlane).second); Ogre::Vector3 WaterPosition = Ogre::Vector3(WaterProjectionPoint.x, mHydrax->getHeigth(WaterProjectionPoint), WaterProjectionPoint.z); mProjectorSN->setPosition(WaterProjectionPoint); mProjectorCamera->setFarClipDistance((WaterProjectionPoint - CameraPosition).length()); mProjectorSN->setDirection(-(WaterProjectionPoint - CameraPosition).normalisedCopy(), Ogre::Node::TS_WORLD); }
/* *Build Ray Query for getting 3d mouse position */ const Ogre::Vector3 MyFrameListener::getMouse3DPoint() { int x = _mouse->getMouseState().X.abs; int y = _mouse->getMouseState().Y.abs; Ogre::Ray ray = this->setRayQuery(x, y); _rayScnQueryDD->setRay(ray); _rayScnQueryDD->setSortByDistance(true); _rayScnQueryDD-> setQueryMask(PLANE_DRAG_DROP); Ogre::RaySceneQueryResult &result = _rayScnQueryDD->execute(); Ogre::RaySceneQueryResult::iterator it = result.begin(); return ray.getPoint(it->distance); }
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY) { Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay( mouseX, mouseY); Ogre::Vector3 from = ray.getOrigin(); Ogre::Vector3 to = ray.getPoint(200); /// \todo make this distance (ray length) configurable btVector3 _from, _to; // OGRE to MW coordinates _from = btVector3(from.x, -from.z, from.y); _to = btVector3(to.x, -to.z, to.y); std::pair<std::string, float> result = mEngine->rayTest(_from, _to); if (result.first == "") return std::make_pair(false, Ogre::Vector3()); else { return std::make_pair(true, ray.getPoint(200*result.second)); /// \todo make this distance (ray length) configurable } }
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; }
void AuthoringVisualizationCollisionDetector::testCollision(Ogre::Ray& ray, CollisionResult& result) { std::pair<bool, Ogre::Real> intersectionResult(Ogre::Math::intersects(ray, mEntity.getWorldBoundingBox())); if (intersectionResult.first) { // raycast success result.collided = true; result.position = ray.getPoint(intersectionResult.second); result.distance = intersectionResult.second; result.isTransparent = true; //The authoring selector should always be transparent so that we can select things behind it } else { // raycast failed result.collided = false; } }
bool SceneObject::isIntersectMesh(int& _x, int& _y, const Ogre::Ray& _ray, int _texture_width, int _texture_height) const { Ogre::Real closest_distance = -1.0f; Ogre::Vector3 closest_result; // test for hitting individual triangles on the mesh bool new_closest_found = false; int index_found = 0; for (int i = 0; i < static_cast<int>(mIndexCount); i += 3) { // check for a hit against this triangle std::pair<bool, Ogre::Real> hit = Ogre::Math::intersects(_ray, mVertices[mIndices[i]], mVertices[mIndices[i+1]], mVertices[mIndices[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; index_found = i; new_closest_found = true; } } } if (new_closest_found) { closest_result = _ray.getPoint(closest_distance); // return the result if (closest_distance >= 0.0f) { // raycast success Ogre::Vector2 point = getCoordByTriangle(closest_result, mVertices[mIndices[index_found]], mVertices[mIndices[index_found+1]], mVertices[mIndices[index_found+2]]); Ogre::Vector2 point2 = getCoordByRel(point, mTextureCoords[mIndices[index_found]], mTextureCoords[mIndices[index_found+1]], mTextureCoords[mIndices[index_found+2]]); _x = (int)(point2.x * _texture_width); _y = (int)(point2.y * _texture_height); return true; } } // raycast failed return false; }
//----------------------------------------------------------------------- void OrthoCameraGizmo::cameraPreRenderScene (Ogre::Camera *camera) { // Adjust the ortho camera gizmo Ogre::SceneNode* node = mOrthoCameraNodeBox->getParentSceneNode(); if (node) { // Reposition according to the actual viewport Ogre::Ray ray = camera->getCameraToViewportRay(0.9f, 0.1f); Ogre::Vector3 position = ray.getPoint(80.0f); //position = camera->getDerivedOrientation().Inverse() * (position - camera->getDerivedPosition()); // Transform from world to local (camera) position node->setPosition(position); // Adjust the scale Ogre::Real scaleFactor = Gizmo::SCALE_NODE_ORTHOZOOM_FACTOR * camera->getOrthoWindowWidth() / camera->getViewport()->getActualWidth(); setScale(scaleFactor); } }
bool XYOrbitViewController::intersectGroundPlane( Ogre::Ray mouse_ray, Ogre::Vector3 &intersection_3d ) { //convert rays into reference frame mouse_ray.setOrigin( target_scene_node_->convertWorldToLocalPosition( mouse_ray.getOrigin() ) ); mouse_ray.setDirection( target_scene_node_->convertWorldToLocalOrientation( Ogre::Quaternion::IDENTITY ) * mouse_ray.getDirection() ); Ogre::Plane ground_plane( Ogre::Vector3::UNIT_Z, 0 ); std::pair<bool, Ogre::Real> intersection = mouse_ray.intersects(ground_plane); if (!intersection.first) { return false; } intersection_3d = mouse_ray.getPoint(intersection.second); return true; }
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); }
void OgreNewtonFrameListener::dragCallback( OgreNewt::Body* me, float timestep, int threadindex ) { // first find the global point the mouse is at... CEGUI::Point mouse = CEGUI::MouseCursor::getSingleton().getPosition(); CEGUI::Renderer* rend = CEGUI::System::getSingleton().getRenderer(); Ogre::Real mx,my; mx = mouse.d_x / rend->getWidth(); my = mouse.d_y / rend->getHeight(); Ogre::Ray camray = mCamera->getCameraToViewportRay( mx, my ); Ogre::Vector3 campt = camray.getPoint( dragDist ); // now find the global point on the body: Ogre::Quaternion bodorient; Ogre::Vector3 bodpos; me->getPositionOrientation( bodpos, bodorient ); Ogre::Vector3 bodpt = (bodorient * dragPoint) + bodpos; // apply the spring force! Ogre::Vector3 inertia; Ogre::Real mass; me->getMassMatrix( mass, inertia ); Ogre::Vector3 dragForce = ((campt - bodpt) * mass * 8.0) - me->getVelocity(); // draw a 3D line between these points for visual effect :) remove3DLine(); mDragLine->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_LIST ); mDragLine->position( campt ); mDragLine->position( bodpt ); mDragLine->end(); mDragLineNode->attachObject( mDragLine ); // Add the force! me->addGlobalForce( dragForce, bodpt ); Ogre::Vector3 gravity = Ogre::Vector3(0,-9.8,0) * mass; me->addForce( gravity ); }
void WaterStar::followMouseRay(const Ogre::Ray& mouseRay) { std::pair<bool, Real> intersectR = Math::intersects(mouseRay, *_waterPlane); if (intersectR.first) { Vector3 pos = mouseRay.getPoint(intersectR.second); /*if (pos.x < -50) pos.x = -50; if (pos.x > 50) pos.x = 50; if (pos.z > 50) pos.z = 50; if (pos.z < -50) pos.z = - 50;*/ std::cout<< " x " << pos.x << " y " << pos.y << " z " << pos.z << std::endl; _node->setPosition(pos); } }
void OgreWidget::wheelEvent( QWheelEvent * event ) { mOgreWindow->getViewport(0)->getCamera()->moveRelative(Ogre::Vector3(0.0f,0.0f,event->delta() * -0.1f)); float WindowWidth = this->width(); float WindowHeight = this->height(); Ogre::Ray mouseRay = mCamera->getCameraToViewportRay((WindowWidth-60)/WindowWidth,(WindowHeight-WindowHeight+60)/WindowHeight); GizmoManager::getCameraGizmo()->setPosition(Ogre::Vector3(mouseRay.getPoint(mCamera->getNearClipDistance()).x,mouseRay.getPoint(mCamera->getNearClipDistance()).y,mouseRay.getPoint(mCamera->getNearClipDistance()).z)); if(mCurrentNode) { GizmoManager::UpdateAxisSize(GizmoManager::getTranslateGizmo(),mCurrentNode,"",0); GizmoManager::UpdateAxisSize(GizmoManager::getRotateGizmo(),mCurrentNode,"",0); GizmoManager::UpdateAxisSize(GizmoManager::getScaleGizmo(),mCurrentNode,"",0); } }
Vector3 TransformInventoryUtil::getOriginPositionPlane() { Camera* player_camera = GameFramework::getSingletonPtr()->camera; Plane far_plane = player_camera->getFrustumPlane(1); float x_percent = 0.5; //((float)x / player_camera->getViewport()->getActualWidth()); float y_percent = 0.5; //((float)y / player_camera->getViewport()->getActualHeight()); Ogre::Ray ray = player_camera->getCameraToViewportRay(x_percent, y_percent); std::pair<bool, Real> result = ray.intersects(far_plane); if (result.first) { Vector3 origin_plane = /*ray.getOrigin() + ray.getDirection() * 1000*/ray.getPoint(result.second * 0.9); return origin_plane; } return Vector3::ZERO; }
bool Skeleton::notifyMoved(const OIS::MouseEvent &evt, const Ogre::Ray &ray) { if(evt.state.buttonDown(OIS::MB_Left)) { Ogre::Vector3 shift = ray.getPoint(mCollsionDepth); shift -= mPressedPosition; //pos if(AnimationEditorPanel::getSingletonPtr()->isFixXAxis()) shift.x = 0; if(AnimationEditorPanel::getSingletonPtr()->isFixYAxis()) shift.y = 0; if(AnimationEditorPanel::getSingletonPtr()->isFixZAxis()) shift.z = 0; mPressedPosition += shift; AnimationEditor* editor = static_cast<AnimationEditor*>(mPickEventHandle); editor->updateShiftValue(shift); } return true; }
bool SceneEntity::notifyMoved(const OIS::MouseEvent &evt, const Ogre::Ray &ray) { if(evt.state.buttonDown(OIS::MB_Left)) { Ogre::Vector3 position = ray.getPoint(mCollsionDepth) + mPickedNodeOffset; Ogre::Vector3 pos = position - mSceneNode->getPosition(); float dis = pos.length(); if(dis < 500) { if(mIsXFixed) position.x = mSceneNode->getPosition().x; if(mIsYFixed) position.y = mSceneNode->getPosition().y; if(mIsZFixed) position.z = mSceneNode->getPosition().z; mSceneNode->setPosition(position); AxisEntity::getSingletonPtr()->setPosition(position); AxisEntity::getSingletonPtr()->setVisible(true); } } return true; }
void ClientGame::UpdateTileUnderCursor(Ogre::Ray aRay) { Ogre::Real radius = mTiles[0]->GetPosition().length(); Ogre::Sphere sphere(Ogre::Vector3::ZERO, radius); std::pair<bool, Ogre::Real> res = aRay.intersects(sphere); if (res.first) { Ogre::Vector3 position(aRay.getPoint(res.second)); mTileUnderCursor = mTileUnderCursor->GetTileAtPosition(position); if (mSelectionMarker->getParent()) { mSelectionMarker->getParent()->removeChild(mSelectionMarker); } if (mTileUnderCursor->GetTile()) { mTileUnderCursor->GetTile()->GetNode().addChild(mSelectionMarker); } } mSelectionMarker->setVisible(res.first); }
void OgreWidget::CameraLooking(float x, float y, float currentX, float currentY) { float deltaX=currentX-x; float deltaY=currentY-y; if(x<currentX) { mCamera->yaw(Ogre::Radian(deltaX) * 0.006f); GizmoManager::getCameraGizmo()->NodeCameraGizmoSupport->rotate( Ogre::Vector3::UNIT_Y,Ogre::Radian(deltaX) * 0.006f, Ogre::Node::TS_PARENT); GizmoManager::getCameraGizmo()->Rotate( Ogre::Vector3::UNIT_Y,Ogre::Radian(-deltaX) * 0.006f, Ogre::Node::TS_LOCAL); } else { mCamera->yaw(Ogre::Radian(deltaX) * 0.006f); GizmoManager::getCameraGizmo()->NodeCameraGizmoSupport->rotate( Ogre::Vector3::UNIT_Y,Ogre::Radian(deltaX) * 0.006f, Ogre::Node::TS_PARENT); GizmoManager::getCameraGizmo()->Rotate( Ogre::Vector3::UNIT_Y,Ogre::Radian(-deltaX) * 0.006f, Ogre::Node::TS_LOCAL); } if(y<currentY) { mCamera->pitch(Ogre::Radian(deltaY) * 0.006f); GizmoManager::getCameraGizmo()->NodeCameraGizmoSupport->rotate( mCamera->getRealOrientation()*Ogre::Vector3(1,0,0),Ogre::Radian(deltaY) * 0.006f, Ogre::Node::TS_PARENT); GizmoManager::getCameraGizmo()->Rotate( mCamera->getRealOrientation()*Ogre::Vector3(1,0,0),Ogre::Radian(-deltaY) * 0.006f, Ogre::Node::TS_PARENT); } else { mCamera->pitch(Ogre::Radian(deltaY) * 0.006f); GizmoManager::getCameraGizmo()->NodeCameraGizmoSupport->rotate( mCamera->getRealOrientation()*Ogre::Vector3(1,0,0),Ogre::Radian(deltaY) * 0.006f, Ogre::Node::TS_PARENT); GizmoManager::getCameraGizmo()->Rotate( mCamera->getRealOrientation()*Ogre::Vector3(1,0,0),Ogre::Radian(-deltaY) * 0.006f, Ogre::Node::TS_PARENT); } float WindowWidth = this->width(); float WindowHeight = this->height(); Ogre::Ray mouseRay = mCamera->getCameraToViewportRay((WindowWidth-60)/WindowWidth,(WindowHeight-WindowHeight+60)/WindowHeight); GizmoManager::getCameraGizmo()->setPosition(Ogre::Vector3(mouseRay.getPoint(mCamera->getNearClipDistance()).x,mouseRay.getPoint(mCamera->getNearClipDistance()).y,mouseRay.getPoint(mCamera->getNearClipDistance()).z)); }
//------------------------------------------------------- std::pair<bool, Ogre::Vector3> Ground::GetIntersectionLocalSpace(const Ogre::Ray & ray) const { if (ray.intersects(mGlobalBoundingBox).first) { float intersection = -1.0f; for (const auto & region : mEntities) { auto hit = ray.intersects(region->getBoundingBox()); if (hit.first) { auto meshHit = GetVertexIntersection(ray, region->getMesh()->getSubMesh(0)); if (meshHit.first && (intersection < 0.0f || meshHit.second < intersection)) { intersection = meshHit.second; } } } if (intersection >= 0.0f) { return std::make_pair(true, ray.getPoint(intersection)); } } return std::make_pair(false, Ogre::Vector3::ZERO); }
void OgreWidget::paintEvent(QPaintEvent* event) { // qDebug() << __PRETTY_FUNCTION__; if(!mOgreRenderWindow) { initializeOgre(); } QMutexLocker locker(&mMutex); if(!mOgreRoot) initializeOgre(); if(mTerrainGroup->isDerivedDataUpdateInProgress()) { if(mTerrainsImported) { qDebug() << "OgreWidget::paintEvent(): DerivedDataUpdateInProgress, building terrain, please wait"; mSimulator->statusBar()->showMessage("Building terrain, please wait..."); } else { qDebug() << "OgreWidget::paintEvent(): DerivedDataUpdateInProgress, updating textures, please wait"; mSimulator->statusBar()->showMessage("Updating textures, patience..."); } } else { if(mTerrainsImported) { qDebug() << "OgreWidget::paintEvent(): saving terrains "; mSimulator->statusBar()->showMessage("Saving all terrains."); mTerrainGroup->saveAllTerrains(true); mTerrainsImported = false; //mSimulator->statusBar()->hide(); } } mOgreRoot->_fireFrameStarted(); // this should be IN a frame listener! animation currently unused // if(mVehicleAnimationState) mVehicleAnimationState->addTime(0.1); // qDebug() << "now rendering"; // Construct all laserscanner rays before rendering QList<LaserScanner*> *laserScanners = mSimulator->mLaserScanners; for(int i = 0; i < laserScanners->size(); ++i) { LaserScanner* scanner = laserScanners->at(i); Ogre::Ray beam = scanner->getCurrentLaserBeam(); Q_ASSERT(scanner->getSceneNode()->getParent() == mVehicleNode); // scanner->getSceneNode()->_update(false, true); scanner->mRayObject->clear(); if(scanner->isScanning()) { scanner->mRayObject->begin(QString("RayFrom_" + scanner->objectName() + "_material").toStdString(), Ogre::RenderOperation::OT_LINE_LIST); // scanner->mRayObject->position(mVehicleNode->_getDerivedPosition() + mVehicleNode->getOrientation() * scanner->getSceneNode()->getPosition()); scanner->mRayObject->position(scanner->getSceneNode()->_getDerivedPosition()); // scanner->mRayObject->position(beam.getPoint(0.0)); scanner->mRayObject->position(beam.getPoint(scanner->range())); scanner->mRayObject->end(); } } mOgreRenderWindow->update(); // qDebug() << "rendering done"; mOgreRoot->_fireFrameEnded(); if(mFrameCount++ % 25 == 0) emit currentRenderStatistics(size(), mOgreRenderWindow->getTriangleCount(), mOgreRenderWindow->getLastFPS()); event->accept(); }
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(); 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 or // ManualObject. if ((query_result[qr_idx].movable != NULL) && (query_result[qr_idx].movable->isVisible()) && ((query_result[qr_idx].movable->getMovableType().compare("Entity") == 0) || (query_result[qr_idx].movable->getMovableType().compare("ManualObject") == 0))) { // get the entity to check Ogre::MovableObject *pmovable = static_cast<Ogre::MovableObject*>(query_result[qr_idx].movable); Ogre::MeshPtr mesh_ptr; if (query_result[qr_idx].movable->getMovableType().compare("Entity") == 0) { mesh_ptr = ((Ogre::Entity*)pmovable)->getMesh(); } else { // XXX: Does "Mesh" get replaced so we can get away with not // XXX: deleting it for now? mesh_ptr = ((Ogre::ManualObject*)pmovable)->convertToMesh("Mesh", "General"); } // mesh data to retrieve size_t vertex_count; size_t index_count; Ogre::Vector3 *vertices; Ogre::uint32 *indices; // get the mesh information GetMeshInformation(mesh_ptr, vertex_count, vertices, index_count, indices, pmovable->getParentNode()->_getDerivedPosition(), pmovable->getParentNode()->_getDerivedOrientation(), pmovable->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 = pmovable; 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 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); } }
void HeadsUpDisplay::tick(Ogre::Real timeDelta) { // window dimensions may have changed Application &app = Application::getSingleton(); Ogre::Real windowWidth = (Ogre::Real)app.getWindowWidth(); Ogre::Real windowHeight = (Ogre::Real)app.getWindowHeight(); // get mouse cursor and update absolute position from relative change OIS::Mouse *mouse = app.getMouse(); if (mouse != nullptr) { OIS::MouseState mouseState = mouse->getMouseState(); m_cursorX += mouseState.X.rel; m_cursorY += mouseState.Y.rel; m_cursorX = Math::clamp(m_cursorX, 0, windowWidth); m_cursorY = Math::clamp(m_cursorY, 0, windowHeight); // normalize cursor position and size from 0 to 1 Ogre::Real cursorX = m_cursorX / windowWidth; Ogre::Real cursorY = m_cursorY / windowHeight; m_cursorContainer->setPosition(cursorX, cursorY); m_cursorContainer->setWidth(CURSOR_WIDTH / windowWidth); m_cursorContainer->setHeight(CURSOR_HEIGHT / windowHeight); m_cursorContainer->show(); // project cursor ray into scene and get query results if (!m_mouseLeftLastDown && mouseState.buttonDown(OIS::MouseButtonID::MB_Left)) { Ogre::Ray mouseRay; getCamera()->getCameraToViewportRay(cursorX, cursorY, &mouseRay); m_rayQuery->setRay(mouseRay); m_objectFound = false; m_rayQuery->execute(this); if (!m_objectFound && (m_currentSelection != nullptr)) { // user selected nothing so clear current selection m_currentSelection->onDeselect(); } } if ((m_currentSelection != nullptr) && !m_mouseRightLastDown && mouseState.buttonDown(OIS::MouseButtonID::MB_Right)) { Ogre::Ray mouseRay; getCamera()->getCameraToViewportRay(cursorX, cursorY, &mouseRay); Ogre::Plane plane(Ogre::Vector3(0, 1, 0), Ogre::Vector3::ZERO); auto intersectResult = mouseRay.intersects(plane); if (intersectResult.first) { Ogre::Vector3 destination = mouseRay.getPoint(intersectResult.second); m_currentSelection->onMoveOrder(destination); } } m_mouseLeftLastDown = mouseState.buttonDown(OIS::MouseButtonID::MB_Left); m_mouseRightLastDown = mouseState.buttonDown(OIS::MouseButtonID::MB_Right); } else { m_cursorContainer->hide(); } }