oe中的视角加速感觉好奇怪,就仿照谷歌方式去改了。

先看看oe原来的漫游器改变视角的接口:

void
CameraManipulator::setViewpoint(const Viewpoint& vp, double duration_seconds)
{
// If the manip is not set up, save the viewpoint for later.
if ( !established() )
{
_pendingViewpoint = vp;
_pendingViewpointDuration.set(duration_seconds, Units::SECONDS);
} else
{
// Save any existing tether node so we can properly invoke the callback.
osg::ref_ptr<osg::Node> oldEndNode;
if ( isTethering() && _tetherCallback.valid() )
_setVP1->getNode(oldEndNode); // starting viewpoint; all fields will be set:
_setVP0 = getViewpoint(); // ending viewpoint
_setVP1 = vp; // Reset the tethering offset quat.
_tetherRotationVP0 = _tetherRotation;
_tetherRotationVP1 = osg::Quat(); // Fill in any missing end-point data with defaults matching the current camera setup.
// Then all fields are guaranteed to contain usable data during transition.
double defPitch, defAzim;
getEulerAngles( _rotation, &defAzim, &defPitch ); if ( !_setVP1->heading().isSet() )
_setVP1->heading() = Angle(defAzim, Units::RADIANS); if ( !_setVP1->pitch().isSet() )
_setVP1->pitch() = Angle(defPitch, Units::RADIANS); if ( !_setVP1->range().isSet() )
_setVP1->range() = Distance(_distance, Units::METERS); if ( !_setVP1->nodeIsSet() && !_setVP1->focalPoint().isSet() )
{
osg::ref_ptr<osg::Node> safeNode;
if ( _setVP0->getNode( safeNode ) )
_setVP1->setNode( safeNode.get() );
else
_setVP1->focalPoint() = _setVP0->focalPoint().get();
} _setVPDuration.set( std::max(duration_seconds, 0.0), Units::SECONDS ); OE_DEBUG << LC << "setViewpoint:\n"
<< " from " << _setVP0->toString() << "\n"
<< " to " << _setVP1->toString() << "\n"; // access the new tether node if it exists:
osg::ref_ptr<osg::Node> endNode;
_setVP1->getNode(endNode); // Timed transition, we need to calculate some things:
if ( duration_seconds > 0.0 )
{
// Start point is the current manipulator center:
osg::Vec3d startWorld;
osg::ref_ptr<osg::Node> startNode;
startWorld = _setVP0->getNode(startNode) ? computeWorld(startNode.get()) : _center; _setVPStartTime.unset(); // End point is the world coordinates of the target viewpoint:
osg::Vec3d endWorld;
if ( endNode.valid() )
endWorld = computeWorld(endNode.get());
else
_setVP1->focalPoint()->transform( _srs.get() ).toWorld(endWorld); // calculate an acceleration factor based on the Z differential.
_setVPArcHeight = 0.0;
double range0 = _setVP0->range()->as(Units::METERS);
double range1 = _setVP1->range()->as(Units::METERS); double pitch0 = _setVP0->pitch()->as(Units::RADIANS);
double pitch1 = _setVP1->pitch()->as(Units::RADIANS); double h0 = range0 * sin( -pitch0 );
double h1 = range1 * sin( -pitch1 );
double dh = (h1 - h0); // calculate the total distance the focal point will travel and derive an arc height:
double de = (endWorld - startWorld).length(); // maximum height during viewpoint transition
if ( _settings->getArcViewpointTransitions() )
{
_setVPArcHeight = osg::maximum( de - fabs(dh), 0.0 );
} // calculate acceleration coefficients
if ( _setVPArcHeight > 0.0 )
{
// if we're arcing, we need seperate coefficients for the up and down stages
double h_apex = 2.0*(h0+h1) + _setVPArcHeight;
double dh2_up = fabs(h_apex - h0)/100000.0;
_setVPAccel = log10( dh2_up );
double dh2_down = fabs(h_apex - h1)/100000.0;
_setVPAccel2 = -log10( dh2_down );
}
else
{
// on arc => simple unidirectional acceleration:
double dh2 = (h1 - h0)/100000.0;
_setVPAccel = fabs(dh2) <= 1.0? 0.0 : dh2 > 0.0? log10( dh2 ) : -log10( -dh2 );
if ( fabs( _setVPAccel ) < 1.0 ) _setVPAccel = 0.0;
} // Adjust the duration if necessary.
if ( _settings->getAutoViewpointDurationEnabled() )
{
double maxDistance = _srs->getEllipsoid()->getRadiusEquator();
double ratio = osg::clampBetween( de/maxDistance, 0.0, 1.0 );
ratio = accelerationInterp( ratio, -4.5 );
double minDur, maxDur;
_settings->getAutoViewpointDurationLimits( minDur, maxDur );
_setVPDuration.set( minDur + ratio*(maxDur-minDur), Units::SECONDS );
}
} else
{
// Immediate transition? Just do it now.
_setVPStartTime->set( _time_s_now, Units::SECONDS );
setViewpointFrame( _time_s_now );
} // Fire a tether callback if required.
if ( _tetherCallback.valid() )
{
// starting a tether to a NEW node:
if ( isTethering() && oldEndNode.get() != endNode.get() )
(*_tetherCallback)( endNode.get() ); // breaking a tether:
else if ( !isTethering() && oldEndNode.valid() )
(*_tetherCallback)( 0L );
}
} // reset other global state flags.
_thrown = false;
_task->_type = TASK_NONE;
}

这里有几个重点参数:

osgEarth::optional<osgEarth::Viewpoint>  _setVP0和_setVP1 :开始视点,结束视点

double                  _setVPAccel, _setVPAccel2; 开始点去最高点加速度,最高点去结束点加速度

修改方案:https://www.cnblogs.com/lyggqm/p/8534619.html

[osgearth][原]仿照谷歌,修改oe漫游器中focal(视角切换)功能的更多相关文章

  1. [原][osg][osgEarth]EarthManipulator关于oe漫游器的handle部分解读以及修改(仿照谷歌,修改oe漫游器中focal(视角切换)功能 续 二)

    bool EarthManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) ...

  2. 【原】thinkphp修改Redis操作类,支持选择数据库功能及添加其他方法

    版本3.2.2(ThinkPHP\Library\Think\Cache\Driver\Redis.class.php), 一:官方默认不支持选择数据库功能及,现就可选择数据库功能进行说明. 1 co ...

  3. [osg][osgEarth][原]基于OE自定义自由飞行漫游器(初级版)

    由于受够了OE的漫游器,想搞个可以在全球飞行的漫游器,所以就做了一个: 请无视我的起名规则······ 类头文件:EarthWalkManipulator.h #pragma once //南水之源 ...

  4. [osg][osgEarth][原]基于OE自定义自由飞行漫游器(第二版)

    在初级版上,进行新的漫游方式调整 头文件: #pragma once //南水之源 20180101 #include <osgGA/CameraManipulator> #include ...

  5. [osg][osgEarth][osgGA][原] EarthManipulator------基于oe的相机漫游器(浅析)

    知识基础:osg漫游器基础 class OSGEARTHUTIL_EXPORT EarthManipulator : public osgGA::CameraManipulator EarthMani ...

  6. [原][osgEarth]添加自由飞行漫游器

    //头文件里 #define MANIPULATOR_W 0x01#define MANIPULATOR_A 0x02#define MANIPULATOR_S 0x04#define MANIPUL ...

  7. [osg][原]自定义osgGA漫游器

    相机矩阵变化基础:http://blog.csdn.net/popy007/article/details/5120158 osg漫游器原理:http://blog.csdn.net/csxiaosh ...

  8. 《Python cookbook》 “定义一个属性可由用户修改的装饰器” 笔记

    看<Python cookbook>的时候,第9.5部分,"定义一个属性可由用户修改的装饰器",有个装饰器理解起来花了一些时间,做个笔记免得二刷这本书的时候忘了 完整代 ...

  9. python_如何修改装饰器中参数?

    案例: 为分析程序内哪些函数执行时间开销较大,我们需定义一个带timeout参数的装饰器 需求: 统计被装饰函数的运行时间 时间大于timeout时,将此次函数调用记录到log日志中 运行时可以修改t ...

随机推荐

  1. Apache正向代理和反向代理

    一.正向代理 先说一正向代理(Forward Proxy),通常普通用户使用的比较多的,是正向代理.也就是在浏览器的网络连接属性框中,填写上一个代理服务器的ip和端口,即可通过代理服务器中转,去浏览网 ...

  2. mysql不常用但很有用的语句整理

    mysqld_multi多实例停止.启动 mysqld_multi --defaults-file=/etc/my.cnf start 1,2 mysqld_multi --defaults-file ...

  3. 【题解】Luogu P1503 鬼子进村

    平衡树好题 原题传送门 这道题要用Splay,我博客里有对Splay的详细介绍 这道题思维有点难,要把被摧毁的节点插入平衡树,而不是把没有摧毁的节点插入 先把0和n+1插入平衡树,作为边界 操作1:摧 ...

  4. android之csv导出

    import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...

  5. 使用ant对JS/CSS 进行压缩以提高网站性能

    减少HTTP请求是优化网站速度的一个重要手段, 所以对javascript/css两种文件进行压缩或合并都是非常必要的. 这里介绍利用ANT来自动进行文件合并和压缩. 3.1. javascript文 ...

  6. 寻找复杂背景下物体的轮廓(OpenCV / C++ - Filling holes)

    一.问题提出 这是一个来自"answerOpenCV"(http://answers.opencv.org/question/200422/opencv-c-filling-hol ...

  7. NOIP 2016 蚯蚓 (luogu 2827 & uoj 264) - 鬼畜的优化

    题目描述 本题中,我们将用符号\lfloor c \rfloor⌊c⌋表示对c向下取整,例如:\lfloor 3.0 \rfloor= \lfloor 3.1 \rfloor=\lfloor 3.9 ...

  8. Codeforces 825E Minimal Labels - 拓扑排序 - 贪心

    You are given a directed acyclic graph with n vertices and m edges. There are no self-loops or multi ...

  9. android 去掉主题

      1 可以在xml中配置2.0之后 <application android:allowBackup="true" android:icon="@drawable ...

  10. 【python018--函数参数】

    1.形参和实参 >>> def MyFirstFunction(name):    '函数定义过程中的name是叫形参'    #因为Ta只是一个形式,表示占据一个参数位置    p ...