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. leetcode [34] Find First and Last Position of Element in Sorted Array

    Given an array of integers nums sorted in ascending order, find the starting and ending position of ...

  2. css列表list、表格table

    列表list,无序列表ul,有序列表ol 1.列表项样式list-style-type 无列表默认为dist实心圆,有序列表默认为decimal阿拉伯数字(前面不带0) 其他无序列表常用none无样式 ...

  3. spring boot @Scheduled未生效原因以及相关坑、及相对其他定时任务架构的优势

    在spring boot中,支持多种定时执行模式(cron, fixRate, fixDelay),在Application或者其他Autoconfig上增加@EnableScheduling注解开启 ...

  4. 关于actor模型

    actor model是1973年就提出的一个分布式并发编程模型,在erlang语言中得到广泛支持和应用.目前Java中也出现了很多支持actor模型的库:akka.killim.jetlang等等, ...

  5. Linux 系统下安装 python-skimage

    Linux 系统下安装 python-skimage 安装必须的依赖 // python-mumpy // python-scipy // python-matplotlib $ sudo apt-g ...

  6. golang Format string by key.

    example: $ go get github.com/hoisie/mustache package main import ( "github.com/hoisie/mustache& ...

  7. Fedora 全局代理上网设置

    1.首先新建一个bash文件 vim /etc/profile.d/proxy.sh 加入以下内容 (有账号密码) export HTTP_PROXY="http://username:pa ...

  8. TensorFlow模型保存和加载方法

    TensorFlow模型保存和加载方法 模型保存 import tensorflow as tf w1 = tf.Variable(tf.constant(2.0, shape=[1]), name= ...

  9. rsync: read error: Connection reset by peer (104)

    Centos7    rsync守护进程上传文件失败 [root@nfs ~]# rsync -avz /etc rsync_backup@172.16.1.41::backupsending inc ...

  10. Hacker

    https://hackertarget.com/nikto-website-scanner/