大數據量點雲顯示的技術絕對是各個行業急需解決的問題,也是一款點雲軟件是否具備競爭力不可或缺的條件,像開源的CloudCompare軟件也在近兩年加入了LOD技術(基於OpenGL),這樣大數據量點雲的顯示不在成爲困擾顯示引擎的絆腳石。國內激光點雲軟件的領跑者lidar360也率先在利用osg的lod技術實現了該項技術,目前博主也在本身默默的專研該項技術,博主對那些利用opengl來實現lod技術的開發團隊表示由衷的欽佩,同時也感慨這些開發團隊強大的創造力。OSG的強大之處在於其對於LOD技術進行了高度封裝,就好像你給外行用一句歸納LOD是什麼同樣,OSG的僅僅以簡單的幾句代碼就實現了該過程,可不能夠理解osg的出現就是爲了能把OpenGL用簡單易懂的話去歸納呢。大數據
固然因爲博主研究osg技術,還有其餘方面的難題沒有解決,對於點雲的lod顯示技術,其實還有十分重要的一步得實現,也是必須得實現的,否則lod依舊是一個夢,那就是對數據創建索引,你們能夠想象,隨着鼠標滾輪的滑動,隨着視點遠近變化而後來顯示與之相應的數據塊,因此每次顯示僅僅是全部點雲的一部分,因此顯示引擎的壓力大大減少。目前PCL提供了強大的octree技術,固然具體怎麼去實現,筆者還須要進一步去摸索,今天的博客僅僅是給你們提供一個具體的思路。讓LOD技術再也不神祕,優化
其實博主第一次在所裏聽到這個技術的時候,感受就像是那種世界級的科研難題,當時全部的「學者」好像都在提這個技術,可是具體是什麼好像卻沒人能說的清,又想起小時候課本上坐井觀天的故事了;「失業後」,點雲的lod技術目前基本處於爛大街的狀況了,只是看誰優化的更好而已。this
來一個形象的例子:spa
點雲的索引構建我會繼續研究的。code
來一個osg的例子: blog
來上一段能運行的代碼:索引
#include <osgViewer/Viewer> #include <osgViewer/ViewerEventHandlers> #include <osg/Node> #include <osg/Geode> #include <osg/Geometry> #include <osgDB/ReaderWriter> #include <osgDB/ReadFile> #include <osgDB/WriteFile> #include <osgGA/StateSetManipulator> #include <osgUtil/Optimizer> #include <osgUtil/DelaunayTriangulator> #include <osgUtil/DelaunayTriangulator> //建立視圖所需頭 #include <osgDB/Registry> #include <osgDB/ReadFile> #include <osgDB/ReaderWriter> #include <osgDB/WriteFile> #include <osg/Node> #include <osgViewer/Viewer> #include <osgDB/ReadFile> #include <osgDB/WriteFile> #include <osg/ShapeDrawable> #include <osg/Geode> #include <osgGA/StateSetManipulator> int main() { osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer(); //這裏仍是給顯示進行一下初始化來看看 { viewer->getCamera()->setClearColor(osg::Vec4(1, 1, 0.3, 0)); osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; traits->x = 40; traits->y = 40; traits->width = 600; traits->height = 480; traits->windowDecoration = true; traits->doubleBuffer = true; traits->sharedContext = 0; osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get()); osg::ref_ptr<osg::Camera> camera = new osg::Camera; camera->setGraphicsContext(gc.get()); camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height)); GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; camera->setDrawBuffer(buffer); camera->setReadBuffer(buffer); // add this slave camera to the viewer, with a shift left of the projection matrix viewer->addSlave(camera.get()); } osg::ref_ptr<osg::Group> root = new osg::Group(); osg::ref_ptr<osg::Geode> geode = new osg::Geode(); osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints; hints->setDetailRatio(0.05);//設置精細度 geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0, 0.0, 0.0), 100.0), hints.get())); osg::ref_ptr<osg::Geode> geode2 = new osg::Geode(); osg::ref_ptr<osg::TessellationHints> hints2 = new osg::TessellationHints; hints2->setDetailRatio(0.5); geode2->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0, 0.0, 0.0), 100.0), hints2.get())); osg::ref_ptr<osg::Geode> geode3 = new osg::Geode(); osg::ref_ptr<osg::TessellationHints> hint3 = new osg::TessellationHints; hint3->setDetailRatio(10); geode3->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0, 0.0, 0.0), 100.0), hint3.get())); osg::ref_ptr<osg::LOD> lod = new osg::LOD; lod->addChild(geode, 300, 400); lod->addChild(geode2, 400, 600); lod->addChild(geode3, 600, 5000); lod->setCenter(osg::Vec3(0.0, 0.0, 0.0)); root->addChild(lod); viewer->setSceneData(root.get()); viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet())); return viewer->run(); }