[osgearth][原]仿照谷歌,修改oe漫游器中focal(视角切换)功能
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(视角切换)功能的更多相关文章
- [原][osg][osgEarth]EarthManipulator关于oe漫游器的handle部分解读以及修改(仿照谷歌,修改oe漫游器中focal(视角切换)功能 续 二)
bool EarthManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) ...
- 【原】thinkphp修改Redis操作类,支持选择数据库功能及添加其他方法
版本3.2.2(ThinkPHP\Library\Think\Cache\Driver\Redis.class.php), 一:官方默认不支持选择数据库功能及,现就可选择数据库功能进行说明. 1 co ...
- [osg][osgEarth][原]基于OE自定义自由飞行漫游器(初级版)
由于受够了OE的漫游器,想搞个可以在全球飞行的漫游器,所以就做了一个: 请无视我的起名规则······ 类头文件:EarthWalkManipulator.h #pragma once //南水之源 ...
- [osg][osgEarth][原]基于OE自定义自由飞行漫游器(第二版)
在初级版上,进行新的漫游方式调整 头文件: #pragma once //南水之源 20180101 #include <osgGA/CameraManipulator> #include ...
- [osg][osgEarth][osgGA][原] EarthManipulator------基于oe的相机漫游器(浅析)
知识基础:osg漫游器基础 class OSGEARTHUTIL_EXPORT EarthManipulator : public osgGA::CameraManipulator EarthMani ...
- [原][osgEarth]添加自由飞行漫游器
//头文件里 #define MANIPULATOR_W 0x01#define MANIPULATOR_A 0x02#define MANIPULATOR_S 0x04#define MANIPUL ...
- [osg][原]自定义osgGA漫游器
相机矩阵变化基础:http://blog.csdn.net/popy007/article/details/5120158 osg漫游器原理:http://blog.csdn.net/csxiaosh ...
- 《Python cookbook》 “定义一个属性可由用户修改的装饰器” 笔记
看<Python cookbook>的时候,第9.5部分,"定义一个属性可由用户修改的装饰器",有个装饰器理解起来花了一些时间,做个笔记免得二刷这本书的时候忘了 完整代 ...
- python_如何修改装饰器中参数?
案例: 为分析程序内哪些函数执行时间开销较大,我们需定义一个带timeout参数的装饰器 需求: 统计被装饰函数的运行时间 时间大于timeout时,将此次函数调用记录到log日志中 运行时可以修改t ...
随机推荐
- table表格超出部分显示省略号
做table表格时,某一列字数比较多,希望超出宽度的部分以省略号显示 设置table的布局 默认automatic 以表格内容显示相应宽度 改成fixed 以表格列宽显示内容 table{ ta ...
- 模板(Template)系统
一.常用语法 官方文档 只需要记两种特殊符号: {{ }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 1.1变量 {{ 变量名 }} 变量名由字母数字和下划线组成. 点(.)在模板 ...
- 【新架构测试】Fiddler转发数据测试
跨域转发设置: 首先进行设置, AutoResponder--> 选中Enable rules和Unmatched requests passthrough 然后Import...导入fiddl ...
- Python2的一些问题及解决办法
1. 无法注释中文的解决办法 # -*- coding:utf8 -*- # 添加这一行就行了 from django.contrib import admin from myapp.models i ...
- python之字符编码(二)
一.字符编码的发展史 阶段一:现代计算机起源于美国,最早诞生也是基于英文考虑的ASCII ASCII:一个Bytes代表一个字符(英文字符/键盘上的所有其他字符),1Bytes=8bit,8bit可以 ...
- Node复习
简单复习下node,不过很多重要的知识点是图,文字无法展示出来. 1.Node的特点 异步I/O 事件与回调函数 单线程 跨平台(libuv) 2.Node的应用场景 I/O密集型(事件循环.异步I/ ...
- Codeforces 903G Yet Another Maxflow Problem - 线段树
题目传送门 传送门I 传送门II 传送门III 题目大意 给定一个网络.网络分为$A$,$B$两个部分,每边各有$n$个点.对于$A_{i} \ (1\leqslant i < n)$会向$A_ ...
- 学习Struts2的个人疑惑及问题解决
刚开始学习SSH框架中Struts2时,个人疑惑以及一些问题总结一下. 1.package节点namespace属性值决定访问路径问题 namespace不写或写namespace=&qu ...
- sudo用法记录
使用root用户,visudo命令(实际是编辑/etc/sudoers文件),用法和vim一样,末行模式:wq退出,如还有提示,使用大写"Q"保存退出,小写"e" ...
- 集合04_Set
Set集合总览 集合元素无序.不重复,三个实现类都是线程不安全的,最好在创建时通过Collections工具类的synchronizedSortedSet方法来包装Set集合,防止对set集合的意外非 ...