海量三维模型数据的可视化方法及系统与流程

文档序号:20358526发布日期:2020-04-10 23:30阅读:1064来源:国知局
海量三维模型数据的可视化方法及系统与流程

本发明涉三维模型数据可视化技术领域,具体涉及一种海量三维模型数据的可视化方法及系统。



背景技术:

目前海量三维模型数据实时绘制主要采用静态lod方法,即以离线方式预先对模型数据进行处理,生成一系列不同细节层次的网格模型,绘制时根据显示参数和硬件性能选择一个合适的层次进行绘制。

静态lod方法将耗费资源的数据生成过程作为预处理,对硬件性能要求较低,但在视点实时变换及细节层次突变的处理上不如动态lod方法。



技术实现要素:

有鉴于此,本申请提供一种海量三维模型数据的可视化方法及系统,能够解决或者至少部分解决上述存在的问题。

为解决以上技术问题,本发明提供的技术方案是一种海量三维模型数据的可视化方法,包括:

读取三维场景数据,根据其索引文件的属性数据和渲染数据构建地图对象;

根据地图对象构建地图节点加入三维场景进行渲染;

通过分页lod动态调度组织渲染;

通过可见性检测控制线程中渲染的当前浏览的三维模型数量。

优选的,所述根据地图对象构建地图节点加入三维场景进行渲染的方法包括:

采用四叉树结构管理三维场景,根据构建的地图对象生成包含地形节点、模型节点和覆盖模型节点的子树;

针对地形节点创建包含影像图层、高程图层和瓦片键值的瓦片模型,将该瓦片模型以分页lod形式加入根节点,其中瓦片键值包含瓦片模型的空间信息,用于确定数据在三维场景中的位置,且以四叉树形式被组织起来。

优选的,所述通过分页lod动态调度组织渲染的方法包括:

加载数据时根据地图对象或数据的profile属性实时进行分层瓦片化,通过分页lod动态调度选择加载区域瓦片数据;

加载模型时分页lod根据观察点与图像子节点的距离选择显示子节点,且每个模型采用单独的线程负责实时调度和加载。

优选的,所述通过可见性检测控制线程中渲染的当前浏览的三维模型数量的方法包括:

判断三维场景的视角是否改变,若是,则进入下一步,若否,则不动作;

进行视点高度检测,判断视点高度是否小于或等于预设可视高度,若否,则暂停所有模型对象的后台工作线程,若是,则进入下一步;

对于每个处于可视范围内的三维模型进行视口检测,判断其是否处在视口呈现的地表坐标范围内,若否,则暂停其对应的后台工作线程,若是,则进入下一步;

遍历每一个通过视点高度检测和视口检测的模型对象进行遮挡检测,判断模型对象与视点之间是否存在遮挡,若是,则暂停其对应后台工作线程,若否,则唤醒其对应后台线程。

优选的,所述通过可见性检测控制线程中渲染的当前浏览的三维模型数量的方法包括:

新增一个bool值控制可见性检测的计算频率;

每次在进入可见性检测计算前先判断该bool值是否为true,若为true,则进入可见性检测步骤,完成计算后再将该bool值设置为false;或者

通过事件回调机制来触发执行可见性检测,即在原有事件回调基础上新建一个事件回调来收集用户改变视角的操作信息,每当收集到触发视角改变的操作信息时,将可见性检测线程的bool值设置为ture,随后执行一次可见性检测计算。

本发明还提供一种海量三维模型数据的可视化系统,包括:

地图对象构建模块,用于读取三维场景数据,根据其索引文件的属性数据和渲染数据构建地图对象;

地图节点构建模块,用于根据地图对象构建地图节点加入三维场景进行渲染;

分页lod调度模块,用于通过分页lod动态调度组织渲染;

可见性检测模块,用于通过可见性检测控制线程中渲染的当前浏览的三维模型数量。

优选的,所述地图节点构建模块包括:

子树构建单元,用于采用四叉树结构管理三维场景,根据构建的地图对象生成包含地形节点、模型节点和覆盖模型节点的子树;

模型构建单元,用于针对地形节点创建包含影像图层、高程图层和瓦片键值的瓦片模型,将该瓦片模型以分页lod形式加入根节点,其中瓦片键值包含瓦片模型的空间信息,用于确定数据在三维场景中的位置,且以四叉树形式被组织起来。

优选的,所述分页lod调度模块包括:

加载数据单元,用于加载数据时根据地图对象或数据的profile属性实时进行分层瓦片化,通过分页lod动态调度选择加载区域瓦片数据;

加载模型单元,用于加载模型时分页lod根据观察点与图像子节点的距离选择显示子节点,且每个模型采用单独的线程负责实时调度和加载。

优选的,所述可见性检测模块包括:

视角判断单元,用于判断三维场景的视角是否改变,若是,则进入高度检测单元,若否,则不动作;

高度检测单元,用于进行视点高度检测,判断视点高度是否小于或等于预设可视高度,若否,则暂停所有模型对象的后台工作线程,若是,则进入视口检测单元;

视口检测单元,用于对于每个处于可视范围内的三维模型进行视口检测,判断其是否处在视口呈现的地表坐标范围内,若否,则暂停其对应的后台工作线程,若是,则进入遮挡检测单元;

遮挡检测单元,用于遍历每一个通过视点高度检测和视口检测的模型对象进行遮挡检测,判断模型对象与视点之间是否存在遮挡,若是,则暂停其对应后台工作线程,若否,则唤醒其对应后台线程。

本发明还提供一种海量三维模型数据的可视化系统,包括:

存储器,用于存储计算机程序;

处理器,用于执行所述计算机程序以实现如上述海量三维模型数据的可视化方法的步骤。

本申请与现有技术相比,其有益效果详细说明如下:本申请通过在读取三维场景数据后,首先根据其索引文件中存储的属性和渲染数据构建地图对象,然后通过该地图对象创建地图节点,将地图节点添加进三维场景进行渲染,通过分页lod机制动态调度选择加载区域瓦片数据以及三维模型,在实时渲染时通过可见性检测控制线程中渲染的当前浏览的三维模型数量的方法,提高了三维场景显示速度,提高了数据读取和三维模型显示浏览的速度。

附图说明

为了更清楚地说明本发明实施例,下面将对实施例中所需要使用的附图做简单的介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。

图1为本发明实施例提供的一种海量三维模型数据的可视化方法流程示意图;

图2为本发明实施例提供的一种通过可见性检测控制线程中渲染的当前浏览的三维模型数量的方法流程示意图;

图3为本发明实施例提供的海量三维模型数据的可视化系统结构示意图。

具体实施方式

下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下,所获得的所有其他实施例,都属于本发明保护范围。

为了使本领域的技术人员更好地理解本发明的技术方案,下面结合附图和具体实施例对本发明作进一步的详细说明。

如图1所示,本发明实施例提供一种海量三维模型数据的可视化方法,包括:

s11:读取三维场景数据,根据其索引文件的属性数据和渲染数据构建地图对象;

s12:根据地图对象构建地图节点加入三维场景进行渲染;

s13:通过分页lod动态调度组织渲染;

s14:通过可见性检测控制线程中渲染的当前浏览的三维模型数量。

具体的,本发明的发明思路是:在读取三维场景数据以及三维模型数据后,使用tilekey(瓦片键值)构建四叉树组织的瓦片模型,根据视点范围及距离,通过pagedlod(分页lod)机制,在三维渲染场景中动态调度选择加载区域瓦片节点以及三维模型,并通过可见性检测控制线程中渲染的当前浏览的三维模型数量。

具体的,步骤s11中,读取earth文件并构建map对象(地图对象)。earth文件是构造整个三维场景时指定数据源的索引文件。earth文件以xml标签的形式指定了生成地形的坐标属性(地理坐标或投影坐标)以及影像数据、高程数据、矢量数据、模型数据、以及缓冲位置,软件通过读取earth文件中的属性数据和渲染数据来构建map对象,来指定将要创建的地形节点包含什么图层以及每个图层的名字和数据源。

需要说明的是,根据地图对象构建地图节点加入三维场景进行渲染的方法包括:

采用四叉树结构管理三维场景,根据构建的地图对象生成包含地形节点、模型节点和覆盖模型节点的子树;

针对地形节点创建包含影像图层、高程图层和瓦片键值的瓦片模型,将该瓦片模型以分页lod形式加入根节点,其中瓦片键值包含瓦片模型的空间信息,用于确定数据在三维场景中的位置,且以四叉树形式被组织起来。

具体的,构建mapnode节点(地图节点),加入三维场景开始渲染。本软件使用树结构管理场景,根据第一步中构建的map对象,生成包含了地形节点、模型节点和overlay模型(覆盖模型)节点的子树。重点在于地形节点,其主要内容为创建包含影像图层、高程图层及tilekey的瓦片模型,然后将这个瓦片模型以pagedlod形式加入根节点。其中tilekey包含模型的空间信息(lod,x,y),能正确确定数据在三维场景上的正确位置,且以四叉树形式被组织起来。pagedlod即分页lod,能根据视点范围动态选择加载哪些节点。

mapnode节点创建过程示例:

//创建地形节点:

_terrain=newterrainnode(_deadtiles.get());

this->addchild(_terrain);

//创建地形的第一层(lod为0),收集包括地形根瓦片的tilekeys:

std::vector<tilekey>keys;

_update_mapf->getprofile()->getallkeysatlod(*_terrainoptions.firstlod(),keys);

//为每个roottilekey创建一个root节点,在其中读取具体影像与高程,并放置在正确的位置:

node*node=factory->createrootnode(keys[i]);

if(node)_terrain->addchild(node);

//创建模型节点:

_models=newgroup();

_models->setname();

addchild(_models.get());

//创建overlay模型节点:

_overlaymodels=newgroup();

_overlaymodels->setname();

//创建overlaymodelsdecorator:

_overlaydecorator=newoverlaydecorator();

addterraindecorator(_overlaydecorator.get());

//加载预先存在的模型图层:

modellayervectormodellayers;

_map->getmodellayers(modellayers);

for(){onmodellayeradded(k_>get(),modellayerindex};

_mapcallback=newmapnodemapcallbackproxy(this);

//注册mapnodemapcallback回调函数:

_map->addmapcallback(_mapcallback.get());

//获取状态:

//设置属性和模式:

//加载节点至场景树:

group*root=newosg::group();

root->addchild(mapnode.get()).

需要说明的是,通过分页lod动态调度组织渲染的方法包括:

加载数据时根据地图对象或数据的profile属性实时进行分层瓦片化,通过分页lod动态调度选择加载区域瓦片数据;

加载模型时分页lod根据观察点与图像子节点的距离选择显示子节点,且每个模型采用单独的线程负责实时调度和加载。

具体的,本发明中世界范围以经纬度来表示,若将球形表面剖开铺成平面,其最左为西经180度,最右为东经180度,最上为北纬90度,最下为南纬90度。实时加载时,软件根据map对象或数据的profile属性(数据配置文件属性)实时进行分层瓦片化。表1列出了profile中关于瓦片分层的全球影像数据的属性值。

numtileswideatlod0和numtileshighatlod0是确定最高一层的宽度与高度,即行数与列数。默认是宽度为2,高度为1。这个默认值正好将第一层的全球数据分成东西半球。然后软件将继续向下分层瓦片,随着一层层的深入,地形块就变得越来越小。当地形块大小比视点到块的距离还小时,便不再继续深入了。

每向下深入一层,每一个瓦片tilesource便会等分成四块。每一个瓦片tilesource均有一个tilekey进行管理,上一层的tilekey会有下一层的4个子key,由此体现了四叉树组织的思想。在本软件中,瓦片的左上角是原点,tilekey便是从左上角开始编码,一般为tilekey(lod,x,y)。随着瓦片的细化,每一块瓦片的范围也会逐渐变小。这些数值将被记录到这个瓦片的extent属性中,如表1所示,其对应值分别为west,east、south和north。当数据源在此范围内有数据时,此瓦片便会加载,否则不会加载。这样总的加载块数也不会那么多。同时根据这个范围,软件将会确定了模型数据所处位置。

表1map对象profile属性

传统的lod会一次性载入所有模型进入内存,进行有选择的绘制。为了避免这种一次性加入内存的浪费行为,本发明采用分页细节层次节点pagedlod实现动态分页加载,可根据需要来加载模型文件,加载过程中每个模型有单独的线程负责实时调度和加载。pagedlod根据观察点与图像子节点的距离选择显示子节点。当视点靠近物体时,用详细的细节表示,当视点远离物体时,用简化的模型来表示。

本发明默认根据模型包围盒中心来计算到视点的距离,也可以根据自己定义的点来计算这个值。本发明设定三个lod距离尺度:近(0-200米),中(200-1000米),远(1000米以上),分别对应模型的三种细节层次(高、中、低分辨率)。在pagedlod中使用半边折叠算法对加载模型进行简化得到中、低分辨率模型。

pagedlod使用示例:

//多线程使用,设置最大的pagedlod数量,一般在pagedlod节点未从内存中移除时设置,可以根据场景具体设置合适的值。

m_viewer->getdatabasepager()->setmaximumnumberofpagelod(intmax);

//每个pagedlod线程独自加载模型数据:

pagedlod::page=newpagedlod;

page->setcenter(vec3(x,y,z));

page->setrange(filename,floatmin,floatmax);

page->addchild(modle).

需要说明的是,如图2所示,通过可见性检测控制线程中渲染的当前浏览的三维模型数量的方法包括:

判断三维场景的视角是否改变,若是,则进入下一步,若否,则不动作;

进行视点高度检测,判断视点高度是否小于或等于预设可视高度,若否,则暂停所有模型对象的后台工作线程,若是,则进入下一步;

对于每个处于可视范围内的三维模型进行视口检测,判断其是否处在视口呈现的地表坐标范围内,若否,则暂停其对应的后台工作线程,若是,则进入下一步;

遍历每一个通过视点高度检测和视口检测的模型对象进行遮挡检测,判断模型对象与视点之间是否存在遮挡,若是,则暂停其对应后台工作线程,若否,则唤醒其对应后台线程。

具体的,当三维场景的视点信息变化后,即软件接收到漫游操作指令(鼠标操作信息如拖拽、长按等)后,进行模型可见性检测,对于未出现在当前可观察范围内的模型对象,应当暂停其后台线程处理,当其再次出现时再回复后台线程处理。本发明可见性检测分为三个步骤,即视点高度检测、视口检测和遮挡检测。

视点高度检测:实时获取视点离地高度h,假定设置的可视高度为h,当视点高度h大于可视高度h时,所有的三维模型对象信息已经无法辨认,则可直接暂停所有模型对象的后台线程处理;反之则进行下一步判断。

//改变线程中pagedlod的运行状态(暂停/唤醒)

m_viewer->getdatabasepager()->getpagedlod()->setmutex(lock);

m_viewer->getdatabasepager()->getpagedlod()->setmutex(unlock).

视口检测:在进行了视点高度检测后对于每个处于可视范围内的三维模型有必要进行视口检测。本发明设计一种基于牛顿法的迭代方法来获取当前视口内的地表坐标范围。将视口左下角到右上角的连线抽象为一个[0,1]的区域,0代表视口左下角点,1代表视口右上角点,t代表天际线与视口左侧边界的角点,假定其值为0.678,则[0,0.678]代表有值区域,(0.678,1]代表无值区域,假定精度判断步长为0.001,首先取0与1的中点t1=0.5,其所在位置有值,t1加上步长为0.501,仍处在有值区域,则未达到计算要求,进行下一步运算;取0.5与1的中点t2=0.75,其所在位置无值,下一步取0.5与0.75的中点t3=0.625,其所在位置有值,t3加上步长为0.626,仍处在有值区域,则未达到计算要求,进行下一步运算;按照此方法迭代计算,当找到满足误差精度的点或者达到设定迭代次数上限时,返回最后一个有值点作为临界点。其中有值无值的判断依据为视口中用于判断的点与场景地面间是否有交点,视口右侧也需按照此方法找到近似临界点坐标。通过这个办法即可获取到视口中有天空区域时的地表坐标范围,然后通过模型的包围盒中心坐标判断其是否处在视口呈现的地表坐标范围内,若不在则暂停其所对应的后台工作线程,若在范围内则继续进行下一步的遮挡检测。

遮挡检测:对于被三维场景和其他模型所遮挡的模型对象可以暂停其所对应的后台线程处理,当视角改变使得该模型再次可见时,恢复其后台线程处理。对于遍历中每一个通过视点高度检测和视口检测的模型对象,先计算对象p的包围盒中心c1,再将其与此刻的视点坐标c2相连,生成线段c1c2,将线段c1c2与场景数据进行相交运算,若相交结果大于零,则表示模型对象与视点之间存在遮挡,此时需暂停对应后台线程,反之,若相交结果为零,则表示模型对象与视点之间可以通视,不存在遮挡,此时唤醒对应后台线程。

需要说明的是,通过可见性检测控制线程中渲染的当前浏览的三维模型数量的方法包括:

新增一个bool值控制可见性检测的计算频率;

每次在进入可见性检测计算前先判断该bool值是否为true,若为true,则进入可见性检测步骤,完成计算后再将该bool值设置为false;或者

通过事件回调机制来触发执行可见性检测,即在原有事件回调基础上新建一个事件回调来收集用户改变视角的操作信息,每当收集到触发视角改变的操作信息时,将可见性检测线程的bool值设置为ture,随后执行一次可见性检测计算。

具体的,可见性检测调度策略:进行可见性检测的常见方法是创建一个计算线程,实时不断地对三维场景中所有的模型进行遍历,对其中每个模型对象就进行可见性检测,根据结果对相应后台线程进行暂停或者唤醒操作。此方法弊端在于视角固定时,计算线程仍在后台不断进行可见性检测,造成了计算资源的浪费。因此本发明在创建可见性检测线程时进行以下改进:

1)新增一个bool值来控制可见性检测的计算频率,每次只响应一次计算。

每次在进入可见性检测计算前先判断该bool值是否为true,若为true,则进入可见性检测步骤,完成计算后再将该bool值设置为false。

2)通过事件回调机制来触发执行可见性检测,在原有事件回调基础上新建一个事件回调来收集用户改变视角的鼠标操作信息(如拖拽、长按等),每当收集到触发摄像机视角改变的操作信息时,将可见性检测线程的bool值设置为ture,随后执行一次可见性检测计算,通过这种方式使得每一次移动视角就执行一次可见性检测计算,而当软件未操作时,可见性检测线程也会处于等待响应阶段,避免了无用的计算消耗。

综上,本发明在读取三维场景数据以及三维模型数据后,首先根据xml标签文件中存储的影像、高程、模型属性构建map对象,然后通过该map对象创建包含地形节点、模型节点等的mapnode节点,将mapnode节点添加进场景,渲染时使用tilekey构建四叉树组织,根据视点范围及距离,通过pagedlod机制动态调度选择加载区域瓦片数据以及三维模型,在实时渲染时通过可见性检测控制线程中渲染的当前浏览的三维模型数量。

本发明的主要优点:提高了三维场景显示速度,提高了数据读取和三维模型显示浏览的速度。

如图3所示,本发明实施例还提供一种海量三维模型数据的可视化系统,包括:

地图对象构建模块,用于读取三维场景数据,根据其索引文件的属性数据和渲染数据构建地图对象;

地图节点构建模块,用于根据地图对象构建地图节点加入三维场景进行渲染;

分页lod调度模块,用于通过分页lod动态调度组织渲染;

可见性检测模块,用于通过可见性检测控制线程中渲染的当前浏览的三维模型数量。

需要说明的是,地图节点构建模块包括:

子树构建单元,用于采用四叉树结构管理三维场景,根据构建的地图对象生成包含地形节点、模型节点和覆盖模型节点的子树;

模型构建单元,用于针对地形节点创建包含影像图层、高程图层和瓦片键值的瓦片模型,将该瓦片模型以分页lod形式加入根节点,其中瓦片键值包含瓦片模型的空间信息,用于确定数据在三维场景中的位置,且以四叉树形式被组织起来。

需要说明的是,分页lod调度模块包括:

加载数据单元,用于加载数据时根据地图对象或数据的profile属性实时进行分层瓦片化,通过分页lod动态调度选择加载区域瓦片数据;

加载模型单元,用于加载模型时分页lod根据观察点与图像子节点的距离选择显示子节点,且每个模型采用单独的线程负责实时调度和加载。

需要说明的是,可见性检测模块包括:

视角判断单元,用于判断三维场景的视角是否改变,若是,则进入高度检测单元,若否,则不动作;

高度检测单元,用于进行视点高度检测,判断视点高度是否小于或等于预设可视高度,若否,则暂停所有模型对象的后台工作线程,若是,则进入视口检测单元;

视口检测单元,用于对于每个处于可视范围内的三维模型进行视口检测,判断其是否处在视口呈现的地表坐标范围内,若否,则暂停其对应的后台工作线程,若是,则进入遮挡检测单元;

遮挡检测单元,用于遍历每一个通过视点高度检测和视口检测的模型对象进行遮挡检测,判断模型对象与视点之间是否存在遮挡,若是,则暂停其对应后台工作线程,若否,则唤醒其对应后台线程。

本发明实施例还提供一种海量三维模型数据的可视化系统,包括:存储器,用于存储计算机程序;处理器,用于执行计算机程序以实现如上述海量三维模型数据的可视化方法的步骤。

本发明实施例还提供一种可读存储介质,可读存储介质存储有计算机程序,计算机程序被处理器执行时实现如上述海量三维模型数据的可视化方法的步骤。

图3所对应实施例中特征的说明可以参见图1-图2所对应实施例的相关说明,这里不再一一赘述。

以上对本发明实施例所提供的一种海量三维模型数据的可视化方法、系统和可读存储介质进行了详细介绍。说明书中各个实施例采用递进的方式描述,每个实施例重点说明的都是与其他实施例的不同之处,各个实施例之间相同相似部分互相参见即可。对于实施例公开的系统而言,由于其与实施例公开的方法相对应,所以描述的比较简单,相关之处参见方法部分说明即可。应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以对本发明进行若干改进和修饰,这些改进和修饰也落入本发明权利要求的保护范围内。

专业人员还可以进一步意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、计算机软件或者二者的结合来实现,为了清楚地说明硬件和软件的可互换性,在上述说明中已经按照功能一般性地描述了各示例的组成及步骤。这些功能究竟以硬件还是软件方式来执行,取决于技术方案的特定应用和设计约束条件。专业技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本发明的范围。

结合本文中所公开的实施例描述的方法或算法的步骤可以直接用硬件、处理器执行的软件模块,或者二者的结合来实施。软件模块可以置于随机存储器(ram)、内存、只读存储器(rom)、电可编程rom、电可擦除可编程rom、寄存器、硬盘、可移动磁盘、cd-rom、或技术领域内所公知的任意其它形式的存储介质中。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1