Compositor: Fixed intersection checking for hotspots
This commit is contained in:
parent
4915b7d3a5
commit
b9e3ed67f0
1 changed files with 49 additions and 6 deletions
|
@ -830,23 +830,66 @@ osg::Camera* getGUICamera(CameraGroup* cgroup)
|
||||||
return cgroup->getGUICamera()->compositor->getPass(0)->camera;
|
return cgroup->getGUICamera()->compositor->getPass(0)->camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
computeCameraIntersection(const CameraGroup *cgroup,
|
||||||
|
const CameraInfo *cinfo,
|
||||||
|
const osg::Vec2d &windowPos,
|
||||||
|
osgUtil::LineSegmentIntersector::Intersections &intersections)
|
||||||
|
{
|
||||||
|
if (!(cinfo->flags & CameraInfo::DO_INTERSECTION_TEST))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const osg::Viewport *viewport = cinfo->compositor->getViewport();
|
||||||
|
SGRect<double> viewportRect(viewport->x(), viewport->y(),
|
||||||
|
viewport->x() + viewport->width() - 1.0,
|
||||||
|
viewport->y() + viewport->height()- 1.0);
|
||||||
|
double epsilon = 0.5;
|
||||||
|
if (!viewportRect.contains(windowPos.x(), windowPos.y(), epsilon))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
osg::Vec4d start(windowPos.x(), windowPos.y(), 0.0, 1.0);
|
||||||
|
osg::Vec4d end(windowPos.x(), windowPos.y(), 1.0, 1.0);
|
||||||
|
osg::Matrix windowMat = viewport->computeWindowMatrix();
|
||||||
|
osg::Matrix invViewMat = osg::Matrix::inverse(cinfo->viewMatrix);
|
||||||
|
osg::Matrix invProjMat = osg::Matrix::inverse(cinfo->projMatrix * windowMat);
|
||||||
|
start = start * invProjMat;
|
||||||
|
end = end * invProjMat;
|
||||||
|
start /= start.w();
|
||||||
|
end /= end.w();
|
||||||
|
start = start * invViewMat;
|
||||||
|
end = end * invViewMat;
|
||||||
|
|
||||||
|
osg::ref_ptr<osgUtil::LineSegmentIntersector> picker =
|
||||||
|
new osgUtil::LineSegmentIntersector(osgUtil::Intersector::MODEL,
|
||||||
|
osg::Vec3d(start.x(), start.y(), start.z()),
|
||||||
|
osg::Vec3d(end.x(), end.y(), end.z()));
|
||||||
|
osgUtil::IntersectionVisitor iv(picker);
|
||||||
|
iv.setTraversalMask(simgear::PICK_BIT);
|
||||||
|
|
||||||
|
const_cast<CameraGroup *>(cgroup)->getViewer()->getCamera()->accept(iv);
|
||||||
|
if (picker->containsIntersections()) {
|
||||||
|
intersections = picker->getIntersections();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool computeIntersections(const CameraGroup* cgroup,
|
bool computeIntersections(const CameraGroup* cgroup,
|
||||||
const osg::Vec2d& windowPos,
|
const osg::Vec2d& windowPos,
|
||||||
osgUtil::LineSegmentIntersector::Intersections& intersections)
|
osgUtil::LineSegmentIntersector::Intersections& intersections)
|
||||||
{
|
{
|
||||||
// test the GUI first
|
// test the GUI first
|
||||||
CameraInfo* guiCamera = cgroup->getGUICamera();
|
CameraInfo* guiCamera = cgroup->getGUICamera();
|
||||||
if (guiCamera && guiCamera->compositor->computeIntersection(windowPos, intersections))
|
if (guiCamera && computeCameraIntersection(cgroup, guiCamera, windowPos, intersections))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Find camera that contains event
|
// Find camera that contains event
|
||||||
for (const auto &info : cgroup->_cameras) {
|
for (const auto &cinfo : cgroup->_cameras) {
|
||||||
if (info == guiCamera)
|
if (cinfo == guiCamera)
|
||||||
continue;
|
|
||||||
if (!(info->flags & CameraInfo::DO_INTERSECTION_TEST))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (info->compositor->computeIntersection(windowPos, intersections))
|
if (computeCameraIntersection(cgroup, cinfo, windowPos, intersections))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue