void ViewingCore::pickCenter( const double ndcX, const double ndcY ) { // Preserve the view direction. const osg::Vec3d lastPosition = getEyePosition(); osg::Matrixd p = computeProjection(); osg::Vec4d ccFarPoint( ndcX, ndcY, 1., 1. ); if( !getOrtho() ) { // Not ortho, so w != 1.0. Multiply by the far plane distance. // This yields a value in clip coords. double fovy, aspect, zNear, zFar; p.getPerspective( fovy, aspect, zNear, zFar ); ccFarPoint *= zFar; } // Get inverse view & proj matrices to back-transform the clip coord point. osg::Matrixd v = getMatrix(); p.invert( p ); osg::Vec4d wc = ccFarPoint * p * v; osg::Vec3d farPoint( wc.x(), wc.y(), wc.z() ); if( !( intersect( _viewCenter, farPoint ) ) ) osg::notify( osg::WARN ) << "ViewingCore::pickCenter: No intersections." << std::endl; _viewDistance = ( lastPosition - _viewCenter ).length(); }
//---------------------------------------------------------------------------------------------------------------------- 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; }
Util::Vector SteerLib::GJK_EPA::getFarPoint(const std::vector<Util::Vector>& shape, const Util::Vector& dir){ Util::Vector farPoint(0,0,0); float farDistance = 0; float farIndex = 0; for(int i = 0; i < shape.size(); i++){ float checkFar = dotProd(shape[i], dir); if (checkFar > farDistance){ farDistance = checkFar; farIndex = i; } } farPoint[0] = shape[farIndex][0]; farPoint[1] = shape[farIndex][1]; farPoint[2] = shape[farIndex][2]; return farPoint; }
osg::Vec3d ViewingCore::getFarPoint(const double ndcX, const double ndcY) { osg::Matrixd p = computeProjection(); osg::Vec4d ccFarPoint( ndcX, ndcY, 1., 1. ); if( !getOrtho() ) { // Not ortho, so w != 1.0. Multiply by the far plane distance. // This yields a value in clip coords. double fovy, aspect, zNear, zFar; p.getPerspective( fovy, aspect, zNear, zFar ); ccFarPoint *= zFar; } // Get inverse view & proj matrices to back-transform the clip coord point. osg::Matrixd v = getMatrix(); p.invert( p ); osg::Vec4d wc = ccFarPoint * p * v; osg::Vec3d farPoint( wc.x(), wc.y(), wc.z() ); return farPoint; }