osg 中创建 球面全景模型,并将全景图像与点云叠加现实在一起

  1. 在移动测量中,采集点云时,通常也会采集全景图像,在 osg 中进行三维浏览展示时,将全景图像与点云叠加现实是一项基础需求,以下代码是在 osg 中创建一个球面模型,将全景图像作为纹理贴在球面上,并按照位置、姿态正确显示的示例代码,以供参考。
void createPanoramicSphere(const ImagePara& para)
{
	// 创建一个球行几何体
	osg::ref_ptr<osg::Sphere> sphere = new osg::Sphere(osg::Vec3(0.0f, 0.0f, 0.0f), 100.0f);
	osg::ref_ptr<osg::ShapeDrawable> sphereDrawable = new osg::ShapeDrawable(sphere.get());

	// 加载全景图像
	osg::ref_ptr<osg::Image> image = osgDB::readImageFile(para.imgName);
	if (!image)
	{
		ccLog::Error(QObject::tr("Failed to load image: ") + para.imgName.c_str());
		return;
	}

	// 创建纹理对象
	osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
	texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
	texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
	texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
	texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
	texture->setDataVariance(osg::Object::DYNAMIC);
	texture->setImage(image.get());

	//	设置纹理及属性
	osg::ref_ptr<osg::StateSet> stateSet = sphereDrawable->getOrCreateStateSet();
	stateSet->setTextureAttributeAndModes(0, texture.get(), osg::StateAttribute::ON);
	stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
	stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

	// 创建 Geode 并添加球形几何体
	osg::ref_ptr<osg::Geode> geode = new osg::Geode;
	geode->addDrawable(sphereDrawable.get());

    //  以下操比较巧妙 (来自于一位同事 MZ)
    //  1. 全景图像贴纹理后是反着的,取负号后,就是正的
    //  2. 贴纹理是自 x 轴开始,又 x 轴对应的是全景图像 3/4 位置, 故取反后加上 0.75 的偏移,纹理就完全对应了
	osg::Vec2Array* texCoordArray = dynamic_cast<osg::Vec2Array*>(sphereDrawable->getTexCoordArray(0));
	for (size_t i = 0; i < texCoordArray->size(); i++)
		texCoordArray->at(i).x() = 0.75 - texCoordArray->at(i).x();

	// 创建变换节点,设置全景球的位置和姿态 (注意: 读取时, roll/pitch 已取负,故此处负负得正)
	osg::Matrixd matrix;
	matrix.postMult(osg::Matrixd::rotate(-para.roll, osg::Vec3d(0, 1, 0)));
	matrix.postMult(osg::Matrixd::rotate(-para.pitch, osg::Vec3d(1, 0, 0)));
	matrix.postMult(osg::Matrixd::rotate(-para.Yaw, osg::Vec3d(0, 0, 1)));
	matrix.postMult(osg::Matrixd::translate(osg::Vec3f(para.x - ofx, para.y - ofy, para.z - ofz)));

	osg::ref_ptr<osg::MatrixTransform> panoMatrixTransform = new osg::MatrixTransform(matrix);
	panoMatrixTransform->setName("panorama_node");
	panoMatrixTransform->addChild(geode.get());

	_panoRoot->addChild(panoMatrixTransform);

	return;
}
  1. 全景与点云的叠加效果如图所示:
    在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值