这几天鼓捣了模型切片,遇到好多坑。特此记录。
1,切片切什么?
切的是模型,模型可以通过Nodevisitor转换为geode,而geode可以分为若干drawable,切的就是这些drawable。因此,要node->accept(visitor),在void apply(geode)里面写
如果是多个模型,则切的是整体空间,
2,如何切
这些drawable可以分为geometry,按照包围盒四叉树或者八叉树分。最后一级为geode,其余各级是PagedLod。
可以每个drawable一个文件夹,也可以按照总的包围盒把每个级别放到一个文件夹。
3,输出什么?
根据递归,生成一个group,group->addchild()各下层,不输出叶子节点。即只生成writeNode(group,theFileName),四叉树有4个孩子,八叉树有8个孩子。
不输出叶子节点的原因是,假设第n层是叶子节点,已经在n-1层的group里面写了。
4,各层Pagelod如何设置
本质是离得越近,越清楚,
如果中心模式是像素模式,则要把setrange设为大于某阈值,即pagedLod->setRange(0,阈值,无穷大或某个很大的值)因为越近像素才大;
同样,如果中心模式为离视点模式,则setrange设为(0,0,阈值)。
即,离视点越近,像素越大,所以这两种模式的阈值范围要相反。
第一个参数设置为0,是假设这个pagedLod->setFileName(0,theFileName) 这个theFiledName是本级的输出文件名称。由于是级别之间环环相扣,所以是相对路径。毕竟,这些切片要放在任意电脑的任意位置。
即,可以输出文件的本级是一个pagedLod,本级输出文件是一个group,
5,如何找模型的三角面。
感谢博主@MeteorChenBo,链接在https://blog.csdn.net/qq_31709249/article/details/94357183
对点和三角形的关系,索引缓冲区查找,写的很清楚。但是纹理坐标不对。只能用索引缓冲区。
6,八叉树何时结束,
参照osgCookbook,其实就是一个递归。直到某个最大级数,或者包围盒大小不超过某个阈值,或者包围盒内的三角形个数不超过一个阈值,此时递归结束。
当然,也可以自定义任何可以收敛的条件,总之,不能无限递归下去。
7,叶子节点如何设置
判断该三角形中心点是否在包围盒,把在该包围盒里的三角面数组用triangles模式,组成geode
8,如何加载
直接用osg::ref_ptr<osg;:Node> node = osgDB::readNode(第0级根文件),root->addChild(node)即可。
9,纹理问题
模型是有纹理的,这个在apply(StateSet)里写,
每个Stateset里包含texture,texture又和Image相关,从image里,又可以获取图片名称,从osg低版本源码上看,每个Image只有一个图片,
总之,
各层是环环相扣的。因为在pagelod->setFileName()中已经写好了所以只要加载根文件即可。