//--------------------------------------------------------------------- void Camera::getCameraToViewportRay(Real screenX, Real screenY, Ray* outRay) const { Matrix4 inverseVP = (getProjectionMatrix() * getViewMatrix(true)).inverse(); #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 // We need to convert screen point to our oriented viewport (temp solution) Real tX = screenX; Real a = getOrientationMode() * Math::HALF_PI; screenX = Math::Cos(a) * (tX-0.5f) + Math::Sin(a) * (screenY-0.5f) + 0.5f; screenY = Math::Sin(a) * (tX-0.5f) + Math::Cos(a) * (screenY-0.5f) + 0.5f; if ((int)getOrientationMode()&1) screenY = 1.f - screenY; #endif Real nx = (2.0f * screenX) - 1.0f; Real ny = 1.0f - (2.0f * screenY); Vector3 nearPoint(nx, ny, -1.f); // Use midPoint rather than far point to avoid issues with infinite projection Vector3 midPoint (nx, ny, 0.0f); // Get ray origin and ray target on near plane in world space Vector3 rayOrigin, rayTarget; rayOrigin = inverseVP * nearPoint; rayTarget = inverseVP * midPoint; Vector3 rayDirection = rayTarget - rayOrigin; rayDirection.normalise(); outRay->setOrigin(rayOrigin); outRay->setDirection(rayDirection); }
//---------------------------------------------------------------------------------------------------------------------- ngl::Vec3 NGLDraw::getWorldSpace(const int _x, const int _y) { ngl::Mat4 m; m = m*m_mouseGlobalTX; ngl::Mat4 t=m_cam->getProjectionMatrix(); ngl::Mat4 v=m_cam->getViewMatrix(); // as ngl:: and OpenGL use different formats need to transpose the matrix. t.transpose(); v.transpose(); m.transpose(); ngl::Mat4 inverse=(t*v*m).inverse(); ngl::Vec4 tmp(0,0,-1.0f,1.0f); // convert into NDC tmp.m_x=(2.0f * _x) / m_width- 1.0f; tmp.m_y=1.0f - (2.0f * _y) / m_height; // scale by inverse MV * Project transform ngl::Vec4 near(tmp.m_x,tmp.m_y,-1.0f,1.0f); ngl::Vec4 far(tmp.m_x,tmp.m_y,1.0f,1.0f); //get world point on near and far clipping planes ngl::Vec4 obj_near=inverse*near; ngl::Vec4 obj_far=inverse*far; // Scale by w obj_near/=obj_near.m_w; obj_far/=obj_far.m_w; ngl::Vec3 nearPoint(obj_near.m_x,obj_near.m_y,obj_near.m_z); ngl::Vec3 farPoint(obj_far.m_x,obj_far.m_y,obj_far.m_z); //create ray ngl::Vec3 rayDir(farPoint-nearPoint); if(rayDir.lengthSquared() == 0.0f) { std::cout<<"Ray Direction in getWorldSpace equals zero, can't normalise"<<std::endl; } else { rayDir.normalize(); } //calculate distance to zx plane float dist = (-nearPoint.m_y)/rayDir.m_y; //set world space coordinate where y = 0 ngl::Vec3 obj(nearPoint.m_x + (dist*rayDir.m_x),nearPoint.m_y + (dist*rayDir.m_y),nearPoint.m_z + (dist*rayDir.m_z)); obj.m_y = 0.0; return obj; }
Ray Camera::GetScreenRay(float screenX, float screenY) const { Update(); Vertex3 nearPoint(screenX, screenY, -1); //in normalized device coordinates (Z goes from near = -1 to far = 1) Vertex3 farPoint(screenX, screenY, 0); //in normalized device coordinates Vertex3 nearWorldCoord = ScreenToWorld(nearPoint); Vertex3 farWorldCoord = ScreenToWorld(farPoint); Vector3 direction(farWorldCoord - nearWorldCoord); return Ray(nearWorldCoord, direction); }
Ray::Ray(const gfx::View* view, const gfx::ICamera* camera, const vec2& mousePos, float maxDist /*= FLT_MAX*/ ) { const RectI& viewPort(view->getViewport()); vec2 ndc(((mousePos.x - viewPort.x) / viewPort.width) * 2.0f - 1.0f, -((mousePos.y - viewPort.y ) / viewPort.height) * 2.0f + 1.0f); vec4 nearPoint(ndc, 0.0f, 1.0f); vec4 farPoint(ndc, 1.0f, 1.0f); mat44 unproject(camera->getViewProjection().inverse()); nearPoint = unproject * nearPoint; farPoint = unproject * farPoint; m_Origin = nearPoint.xyz() / nearPoint.w; m_Direction = normalize(farPoint.xyz() / farPoint.w - m_Origin); m_MaxDistance = maxDist; }
Ray Camera::getRay( float screenX, float screenY, Vector3* outFar ) const { //assert( activeView != nullptr ); if( !activeView ) return Ray(); Vector2i size = activeView->getSize(); Vector3 nearPoint(screenX, size.y - screenY, 0); Vector3 farPoint (screenX, size.y - screenY, 1); Vector3 rayOrigin = UnprojectViewPoint(nearPoint, activeView, this); Vector3 rayTarget = UnprojectViewPoint(farPoint, activeView, this); Vector3 rayDirection = rayTarget - rayOrigin; rayDirection.normalize(); if( outFar != nullptr ) *outFar = rayTarget; Ray pickRay(rayOrigin, rayDirection); return pickRay; }
//----------------------------------------------------------------------- Ray Camera::GetCameraToViewportRay(float screenX, float screenY) { Ray ret; Matrix4f inverseVP = GetProjViewMatrix().Inverse(); float nx = (2.0f * screenX) - 1.0f; float ny = 1.0f - (2.0f * screenY); Vector3f nearPoint(nx, ny, -1.f); // Use midPoint rather than far point to avoid issues with infinite projection Vector3f midPoint (nx, ny, 0.0f); // Get ray origin and ray target on near plane in world space Vector3f rayOrigin, rayTarget; rayOrigin = inverseVP * nearPoint; rayTarget = inverseVP * midPoint; Vector3f rayDirection = rayTarget - rayOrigin; rayDirection.Normalize(); ret.setOrigin(rayOrigin); ret.setDirection(rayDirection); return ret; }
bool Polygon::hit(Point pt) const { return nearPoint(pt, Robot_Radius); }
bool Rect::hit(Point pt) const { return nearPoint(pt, Robot_Radius); }