查看: 6207|回复: 16

关于PagedLOD加载顺序的疑问

[复制链接]

该用户从未签到

发表于 2008-12-16 07:12:49 | 显示全部楼层 |阅读模式
最近花了些时间试图把基于自行开发的旧引擎的开发包(提供给二次开发商)移植到OSG上,其中比较困难、问题较多的部分就是“场景分页加载”功能。
DatabasePager目前只提供了本地文件和HTTP两种加载途径,过期数据剔算法则除是基于不活动帧数和时戳比较,和原有的方法(数据源基于关系数据库,根据内存池上限来剔除数据)存在一定差异,目前已经通过实现osgDB装载插件来从关系数据库读取模型,内存池算法也是在这一层完成,基本重现了原引擎的功能。
昨天测试时发现一个问题:DatabasePager装载PagedLOD节点顺序似乎并不是严格按照期望中Camera距离来决定的:当摄像机从视距外靠近时DatabasePager一次性加载了某个模型的全部细节层次,而不是期望中的最低细节模型。而且这个问题和PageLOD中细节模型定义顺序相关,如果按照从近(高精度)到远(低精度)顺序添加PagedLOD子节点则会在Viewer实例化过程加载全部模型,反之(从远到近添加子节点)则出现上述问题(从视距外进入视距后加载全部细节层次)。
重新看一遍DatabasePager和PagedLOD源码,找到了上述问题的答案:
1、View调用DatabasePager::updateSceneGraph中removeExpiredSubgraphs方法对活动PagedLODs做了一次筛选,通过PagedLOD::removeExpiredChildren找到过期子节点并释放,但此过程并不一定是按照从旧到新的LRU顺序删除,而是每次循环中释放某个PagedLOD最后一个超期子节点;
2、场景Update环节PagedLOD::traverse中needToLoadChild条件成立时加载第numChildren(_children.size())个_rangeList对应子节点,而当前面的过期节点剔除释放所有子节点时_children.size()=0,导致每次traverse只能按照递增顺序(_children.size()++)逐个(按照PagedLOD子节点添加顺序)将加载请求提交给DatabasePager加载线程,而并非是加载恰好进入视线的那个子节点。
在OSG的官方mail list上面转了一圈,看到其他人也提到DatabasePager的这一“特性”:当节点分级精度模型大小分别是20K/200K/2000K时,最远节点进入视线后实际加载数据量是20+200+2000K(子节点正序加入PagedLOD)或2000+200+20K(反向加入时),而不是我们所认为的20K。
请教用过PagedLOD的前辈们,上面所描述的behavior究竟算是OSG的一个feature还是flaw,实际使用中怎样才能够达到真正按需加载对应层次模型的目的?OSG为SVN版本(2.7.7),为了尽量描述清楚问题所以言语比较罗嗦,希望我说明白了:)
补充一个问题:俺这种情况是否更合适用ProxyNode配合自己实现的Pager?另外PagedLOD+DatabasePager方案似乎没有模型加载卸载、进入离开视线的通告回调机制...

[[i] 本帖最后由 lifc 于 2008-12-16 07:22 编辑 [/i]]

该用户从未签到

发表于 2008-12-16 08:38:28 | 显示全部楼层
楼主的水平真的很不一般~~并不是说接触OSG或者其它三维引擎的时间长短,而是这种坚持深入研究的兴趣和自我学习的能力。希望能看到lifc更多的分析文章。

我基本明白了楼主的问题,我想这应该算是一个可以提高的地方。1、不应简单地遍历子节点列表并加载全部LOD模型,而是应当采用map或者更好的映射方式,或者对数据进行排序(但这样计算量大),按照视距依次加载模型。2、加载卸载模型时应该增加一个PagerNoticeCallback回调,允许用户执行自己的操作。

此外,ProxyNode只能在第一次被DatabasePager自动加载,以后它就是一个普通的Node节点了,不会过期也不会被剔除和重新加载。我不知道这和楼主的情况是否吻合。

因为我自己这方面的见识有限,不能贸然断定哪些解决方案是必须的,建议lifc将自己的意见译成英文与osg-users进行讨论,也许目前的方法也有未发现的可取之处。如果能自行编写可行的代码并提交给osg-submissions,那更是对OSG社区的一大促进!

该用户从未签到

 楼主| 发表于 2008-12-16 10:11:21 | 显示全部楼层
先要谢谢array版主的肯定。因为Pager功能是我们产品的一个主要特性,所以对这部分关注更多些。关于ProxyNode的设想我再考虑一下,有结论之后会过来向大家汇报。
对OSG了解更深入一些之后也准备参加一些OSG的完善工作,只是之前和公司的合同对这方面有些限制,当初没有想清楚就随便签了(不签不行)。这次如果OSG的移植能够通过就争取以此说服老板动用更多资源来投入,一会单独开个帖子向大家请教一下这方面的经验~

该用户从未签到

发表于 2008-12-16 12:35:44 | 显示全部楼层
这个加载之后要剔除是有个等待时间的~~~你可以从另外一种角度来看,把同一个模型的不同LOD层次写入不同的模型来标识和加载~~~~

该用户从未签到

 楼主| 发表于 2008-12-17 21:59:23 | 显示全部楼层
这两天硬件发现问题一直在调试,闭上眼睛就会看到密密麻麻的0402的贴片器件和逻辑分析仪花花绿绿的探头,快要崩溃了,所以暂时没继续研究模型加载。
之前设想过把PagedLOD的Node(s)从父类Group移动到_rangeList中,避免遍历过程中对Group的std::vector<Node> _children执行erase/push_back操作,只是Group的addChild是virtual而removeChild和getChildIndex却是inline,暂时没想到非侵入性的修改方法。
楼上两位的方法没琢磨明白,通常每个模型的不同细节度本来不就是存放在不同文件(数据库记录)的吗,可否再说具体一点呢?能够简单解决是最好不过了...

[ 本帖最后由 lifc 于 2008-12-17 22:19 编辑 ]

该用户从未签到

发表于 2008-12-17 23:56:36 | 显示全部楼层
把同一个模型的不同LOD层次写入不同的模型来标识和加载~~~~注意使用索引文件头文件来~~~~~~~~~

该用户从未签到

 楼主| 发表于 2008-12-19 17:54:00 | 显示全部楼层
“把同一个模型的不同LOD层次写入不同的模型来标识和加载”是否可以理解为一个模型的多个LOD层次运行时当成多个模型分布在多个PagedLOD下面?

该用户从未签到

发表于 2008-12-20 00:10:13 | 显示全部楼层
可以理解为一个模型的的多个LOD层级作为多个模型来处理~~~~~~

该用户从未签到

 楼主| 发表于 2008-12-21 13:30:00 | 显示全部楼层
原帖由 simbaforrest 于 2008-12-20 16:17 发表
你是不是没有使用setFileNames那个方法,而是用的addChild啊?不然你的pagedlod的不同细节度在不同文件下的话,应该是可以看到效果的呀~~~
如果使用addChild,那么ms就和直接使用LOD一样了。。。

谢谢你的答复。开始确实不知道应该怎样使用PagedLOD,后来看过DatabasePager和PagedLOD源码之后才明白。我调用的是setRange和setFileName,而且确实看到了LOD的效果,只是DatabasePager内部加载的模型顺序和内存占用有疑问。
我在Linux下面用strace -t来跟踪系统调用,可以看到从视野外接近是一次性装载了某个模型的全部细节层次,PagedLOD::traverse代码段也证实了所观测到的这一“特性”...

该用户从未签到

 楼主| 发表于 2009-1-5 09:58:59 | 显示全部楼层
年底好忙,很多需求都集中在这段时间提出,一直没时间结贴。先调硬件,接着又改视频编码和模式识别,再后来做erlang重写分布服务的可行性报告。erlang方案本在osg之后提出,但因为有爱立信的背景竟然很快就通过了...
高层一直难以接受多重语言混合开发的模式,认为这样风险高。好不容易争取到用osg的机会,如果连客户端都只能用纯erlang就只好走erlang+esdl+opengl路线了。

言归正传,上次提出的PagedLOD加载问题年前就已经解决。因为没精力去改PagedLOD和DatabasePager所以只好暂时全部抛开重新实现了个LODNode,通过类似Switch节点的方法实现LOD场景节点加载。
LODNode里面实现了进入视野前的预加载以及离开视野后的延迟卸载以及事件通告,装载请求通过后台io线程调用osgDB::Registry::readNode异步完成,用std::map配合std::list实现了基本cache机制,核心代码才300行左右,但暂时看来已经可以满足测试引擎的需求了。

该用户从未签到

发表于 2009-1-5 10:30:07 | 显示全部楼层
lifc同志能否共享一下你写的LODNode呢? 大家一起学习研究一下?

该用户从未签到

发表于 2009-8-6 12:05:59 | 显示全部楼层
支持楼主共享"LODNode"代码,大家一起学习下!

该用户从未签到

发表于 2022-6-10 20:19:15 | 显示全部楼层
请问楼主还在进行OSG相关的开发吗?我现在仍然遇到这个问题,但是没有解决。请问楼主有新的解决方法吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表