OSG加载倾斜摄影数据

如何应用osg技术解决战场态势显示问题? 并且OSG提供了丰富的示例,通过阅读这些示例可以很好的学习这些模块(学习例子对于学习OSG是非常重要的---FreeSouth注)。(OSG的粒子系统从OSG的1.2版本以来,鲜有改变,八年了,它没发展,推荐使用Spark粒子系统,其与OSG的结合array的osgXI还是osgRecipes中有示例--FreeSouth注)。OSG的核心支持所有的OpenGL扩展,哪怕是刚发布的最新扩展,对其进行封装,优化使得用户不用关注OpenGL那些底层的代码和扩展等,就可以快速的搭建基于最新特性的三维应用程序。 阅读详情

1. 概述

ContextCapture(Smart3D)生成的倾斜摄影模型数据一般都形如如下组织结构:
imglink1

在Data目录下包含了分块的瓦片数据,每个瓦片都是一个LOD文件夹。osg能够直接读取osgb格式,理论上只需要依次加载每个LOD的金字塔层级最高的osgb,整个倾斜摄影模型数据就加载进来了。不过有点麻烦的是这类数据缺乏一个整体加载的入口,如果每次加载都遍历整个文件夹加载的话,会影响加载的效率。所以一般的数据查看软件都会为其增加一个索引。

这里就给倾斜摄影数据添加一个osgb格式的索引文件,生成后就可以通过OSG直接加载整个倾斜摄影模型数据。

2. 实例

2.1. 代码

具体的实现代码如下:

#include <iostream>
#include <string>

#include <QDir>

#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>

using namespace std;

//查找目录下所有的文件夹
static void findDir(string dir, vector<string>& subDirs)
{
	//
	subDirs.clear();
	QDir fromDir(QString::fromLocal8Bit(dir.c_str()));
	QStringList filters;

	//
	QFileInfoList fileInfoList = fromDir.entryInfoList(filters, QDir::AllDirs | QDir::Files);
	foreach(QFileInfo fileInfo, fileInfoList)
	{
		if (fileInfo.fileName() == "." || fileInfo.fileName() == "..")
		{
			continue;
		}

		if (fileInfo.isDir())
		{
			QByteArray dir = fileInfo.filePath().toLocal8Bit();
			subDirs.push_back(dir.data());
		}
	}
}

//得到文件路径的文件名   C:\\b\\a(.txt) -> a
static std::string DirOrPathGetName(std::string filePath)
{
	size_t m = filePath.find_last_of('/');
	if (m == string::npos)
	{
		return filePath;
	}

	size_t p = filePath.find_last_of('.');
	if (p != string::npos && p > m)				//没有点号或者
	{
		filePath.erase(p);
	}

	std::string dirPath = filePath;
	dirPath.erase(0, m + 1);
	return dirPath;
}

void createObliqueIndexes(std::string fileDir)
{
	string dataDir = fileDir + "/Data";

	osg::ref_ptr<osg::Group> group = new osg::Group();
	vector<string> subDirs;
	findDir(dataDir, subDirs);

	for (size_t i = 0; i < subDirs.size(); i++)
	{
		string name = DirOrPathGetName(subDirs[i]);
		string path = subDirs[i] + "/" + name + ".osgb";

		osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(path);
		osg::ref_ptr<osg::PagedLOD> lod = new osg::PagedLOD();

		auto bs = node->getBound();
		auto c = bs.center();
		auto r = bs.radius();
		lod->setCenter(c);
		lod->setRadius(r);
		lod->setRangeMode(osg::LOD::RangeMode::PIXEL_SIZE_ON_SCREEN);
		osg::ref_ptr<osg::Geode> geode = new osg::Geode;
		geode->getOrCreateStateSet();
		lod->addChild(geode.get());

		std::string relativeFilePath = "./Data/" + name + "/" + name + ".osgb";  //相对路径

		lod->setFileName(0, "");
		lod->setFileName(1, relativeFilePath);

		lod->setRange(0, 0, 1.0);																							//第一层不可见
		lod->setRange(1, 1.0, FLT_MAX);

		lod->setDatabasePath("");

		group->addChild(lod);
	}
	std::string outputLodFile = fileDir + "/Data.osgb";
	osgDB::writeNodeFile(*group, outputLodFile);
}

int main(int argc, char *argv[])
{
	string fileDir = "D:/Data/scene/city";
	std::string outputLodFile = fileDir + "/Data.osgb";
	createObliqueIndexes(fileDir);

	osgViewer::Viewer viewer;
	osg::Node * node = new osg::Node;
	node = osgDB::readNodeFile(outputLodFile);
	viewer.setSceneData(node);

	return viewer.run();
}

2.2. 解析

如果直接读取每一块的LOD然后通过osgDB::writeNodeFile写入到一个osgb文件,这个文件就会保存所有块的LOD第一层信息。这样在第二册加载的时候还是会比较慢,所以这里就创建了一个空的节点,形成了索引所有LOD块的数据结构。对于每一块数据,新建两层LOD,第一层为自身的空白节点,第二层为分块LOD的第一层数据:

osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(path);
osg::ref_ptr<osg::PagedLOD> lod = new osg::PagedLOD();

auto bs = node->getBound();
auto c = bs.center();
auto r = bs.radius();
lod->setCenter(c);
lod->setRadius(r);
lod->setRangeMode(osg::LOD::RangeMode::PIXEL_SIZE_ON_SCREEN);
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->getOrCreateStateSet();
lod->addChild(geode.get());

std::string relativeFilePath = "./Data/" + name + "/" + name + ".osgb";  //相对路径

lod->setFileName(0, "");
lod->setFileName(1, relativeFilePath);

lod->setRange(0, 0, 1.0);																							//第一层不可见
lod->setRange(1, 1.0, FLT_MAX);

lod->setDatabasePath("");

group->addChild(lod);

LOD的Center和Radius都非常重要,需要预先设置好;setRangeMode设置了细节层级调度的模式,一般都为PIXEL_SIZE_ON_SCREEN;setFileName设置了每一层的数据路径,setRange确定了当前层级的范围。由于这个LOD只是个索引文件,所以会设置第二层为极大的可见范围值。

3. 结果

可以像加载普通OSGB文件一样加载这个索引文件,通过osgviewer加载的效果如下:
imglink2

OSG中使用png图片显示透明效果 常见的几种图片格式中只有png格式和gif格式的图片会有透明效果,其他tupi 阅读详情

相关推荐

保姆级教程:用OsgEarth批量加载ContextCapture生成的倾斜摄影模型(附完整C++代码)

本文提供了一套完整的OsgEarth集成ContextCapture倾斜摄影模型的解决方案,包括数据解析、场景构建和性能优化。通过详细的C++代码示例,帮助开发者实现高效批量加载倾斜摄影模型,解决坐标系不一致等常见问题,提升三维地理信息系统的开发效率。

weixin_30617695的博客 251

OSG显示图片的几种方法???????????????????????

方法一:没有几何体,直接显示图片(见王锐、钱学雷的《OSG三维渲染引擎设计与实践》P119 在场景中绘制位图): osfg::ref_ptr bmp= new osg::DrawPixels; bmp->setPosition( osg::Vec3( 0.0, 0.0, 0.0)); bmp->setImage( osgDB::readImageFile("***.png")); osg:

tmljs1988的专栏 1万+

保姆级教程:用OSG库在C++中加载台北倾斜模型OSGB文件(附完整代码与避坑指南)

本文提供了一份详细的教程,介绍如何使用OSG库在C++中加载台北倾斜模型的OSGB文件。内容涵盖环境配置、OSGB文件加载核心架构、高级渲染技术与性能优化,以及工业级应用开发技巧,帮助开发者高效处理三维地理数据。

weixin_26934905的博客 224

第38.1节 osg加载大tif-编译vpb

目录本节内容具体内容 本节内容 本节开始实现使用osg加载超大tif的功能,具体有多大的tif可以支持呢,就是要多大有多大。 要不是网友们提这个功能,我基本上已经忘记vpb了,它是osg早期关于使用影像和高程大图来生成瓦片地形的这么一个工具,它生成的数据是pagedLOD结构的,就像现在的倾斜摄影数据一样,是可以实现读取一个启动文件来分级加载的。 本节主要来讲vpb的编译和基于我随便画的两个图片来生成一个分页的地形数据。在下几节我们来详细讲vpb的应用。 本节代码在如下网盘中,根据章节编号有对应附件,请使用

一切皆可视 2589

Vue项目里用Cesium加载倾斜摄影模型,从OSGB到3DTiles的保姆级踩坑记录

本文详细记录了在Vue项目中利用Cesium加载倾斜摄影模型的全过程,从OSGB格式数据处理到3DTiles转换的实战经验。针对常见问题如文件结构规范化、Webpack配置优化、Cesium集成等提供了具体解决方案,特别适合需要快速实现三维可视化功能的前端开发者参考。

weixin_26798991的博客 369

OSG三维渲染引擎编程学习之七十:“第七章:OSG场景图形交互” 之 “7.1 OSG图形显示流程”

OSG三维渲染引擎编程学习;第七章:OSG场景图形交互;7.1 OSG图形显示流程

LuckyHanMo的博客 592

OSG 读取OSGB倾斜数据

OSGB数据是一个四叉树结构,本文测试使用OSG加载OSGB倾斜摄影测量数据。

GIS探索之路 4470

osgEarth加载大疆倾斜摄影测量数据(准确加载)

主要使用OSG3.6.3和OE2.10进行处理数据!

weixin_44769745的博客 319

C++中利用OSG加载OSGB倾斜摄影模型:从环境搭建到核心代码实现

在三维地理信息系统、数字孪生和游戏开发领域,大规模三维场景的构建离不开倾斜摄影模型。这类模型通过无人机航拍生成,具有细节丰富、还原度高的特点,而OSGB格式作为其主流的分块存储格式,广泛应用于ContextCapture、大疆智图等软件。其核心技术原理在于分块LOD(多层次细节)结构和地理空间信息的组织,能够实现高效的数据调度与渲染。从技术价值看,原生支持OSGB格式的OpenSceneGraph(OSG)库提供了高性能的三维图形处理能力,能自动解析分块结构、调度LOD并优化显存使用。在应用场景上,OSG结

weixin_31220401的博客 256

osgEarth处理汇总(C++长期更新版)

一、基础目录。

weixin_44769745的博客 454

osg的gis插件,能够读取、显示3dmax导出的具有Pbr材质的fbx文件

osg的gis插件,能够读取、显示3dmax导出的具有Pbr材质的fbx文件、导出gltf/glb文件、导出b3dm文件、读取/导出ktx2格式图片、读取/导出webp格式图片。 同时提供了如下子工具: b3dm转glb 3D模型转3dtiles ... osgdb_fbx 在osg的fbx的插件的基础上,参考了FBX2glTF项目,使得能够读取3dmax导出的带有Pbr材质的FBX文件,并能在osg中加载。 osgdb_gltf 支持导出gltf/glb,暂不支持读取。在osgEarth的gltf的插件基础上,增加了纹理压缩和顶点压缩功能,支持webp、ktx2格式纹理;使用draco对顶点、法线、纹理坐标进行压缩;同时支持对顶点绑定batchId。 osgdb_b3dm 支持导出b3dm,暂不支持读取。b3dm插件具有gltf插件的所有功能,同时能够导出UserData中的属性到b3dm中。 osgdb_webp 和osgEarth的webp插件一样。 osgdb_ktx 在王锐大神的osgVerse的ktx插件基础上进行了小改动,支持导出ktx2格式的纹理图片。

osg3.6.5加载b3dm格式的倾斜摄影数据

其中GLTF为1.0,或者2.0。

yincong9225的博客 14

osg中支持的立体视觉显示方式及效果图.docx

osg支持几种立体显示,包括左右、上下视差,红蓝色差等立体显示方式。文档测试了这几种方式的显示效果。希望对用OSG做VR的朋友有帮助。

Unity加载OSGB倾斜摄影数据

需要注意的是:文件夹加载方式并没有使用lod,所以加载的数据只是data文件夹下,瓦片文件夹下的同名osgb数据(效果如下图所示),并没有加载到层级osgb数据,显示并不尽如人意,需要自己再跟进一下(随后吧,我也没太清楚)!我们知道osgb的osg推出的倾斜摄影数据的数据结构,所以,osg引擎一定是支持osgb最好的三维引擎,研究osgb的加载,了解osg的库也就是必然项!然而但是,三维引擎方向,UE,Unity一定是主流中的主流了,怎么让osgb在这两个引擎中工作成了大家研究的一个侧重点。

原在路上的博客。 1203

OSGB模型3MX索引生成工具

可以将CC生成的OSGB模型,用3MX进行索引创建,便于浏览查看

【数据分析生命周期全揭秘】从零开始打造你的数据科学项目 | 最全指南

在当今数据驱动的世界中,数据科学正在颠覆传统行业,成为企业决策和价值创造的重要引擎。然而,如何科学、系统地开展一个数据分析项目?这是很多人关心的核心问题。本篇文章基于经典数据分析课程内容,深入解读数据分析生命周期的每个阶段,让你快速掌握从“发现问题”到“落地应用”的完整流程。如果你正在学习或准备从事数据分析领域,这篇文章一定会对你大有帮助!数据分析生命周期的六大阶段数据分析生命周期的六个阶段相辅相成,每个阶段都至关重要:发现问题:明确需求,提出假设。数据准备:清洗、转换和可视化数据。

AI手套的博客 1732
上一篇: Cesium案例解析(十)——CZML点
下一篇: three.js中的矩阵变换(模型视图投影变换)
charlee44
charlee44 新星创作者: 数据科学与机器学习技术领域 新星创作者: 数据科学与机器学习技术领域
博客等级 码龄16年 3901粉丝 326原创
评论 26
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

charlee44

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值