说明
osgearth 原有漫游器EarthManipulator 不支持此功能,所以需要修改此漫游器代码,其中主要原理就是在缩放的同时也要改变当前漫游器中心焦点的位置,从而保持鼠标指定点的位置缩放是不改变。
核心代码修改部分
EarthManipulator 的头文件zoom方法添加参数view
/**
* Zoom the camera using deltas (dy only)
*/
virtual void zoom( double dx, double dy, osg::View* view);
EarthManipulator 的cpp 文件zoom方法修改
void
EarthManipulator::zoom( double dx, double dy, osg::View* view)
{
// in normal (non-tethered mode) we need a valid zoom point.
double scale = 1.0f + dy;
if ( !isTethering() )
{
recalculateCenterFromLookVector();
if (_ga_t0.valid() && _ga_t0->getEventType() == osgGA::GUIEventAdapter::EventType::SCROLL)
{
//鼠标的位置
osg::Vec3d worldPoint;
bool surce = screenToWorld(_ga_t0->getX(), _ga_t0->getY(), view, worldPoint);
if (surce)// 鼠标点的位置在球皮上
{
osg::Vec3d newCenter = worldPoint + (_center - worldPoint)*scale;//大致新的位置,此点不一定在球皮上
GeoPoint geopoint;
osg::Vec3d start, end, normal;
geopoint.fromWorld(_mapNode->getMapSRS(), newCenter);
geopoint.z() += 1000000;
geopoint.toWorld(start);
geopoint.z() -= 2000000;
geopoint.toWorld(end);
//求得球皮上交点过程,计算新的中心点
if (intersect(start, end, newCenter, normal))
{
setCenter(newCenter);
_centerRotation = computeCenterRotation(_center);
}
}
}
}
setDistance( _distance * scale );
collisionDetect();
}