OSG绘制视锥体(升级版)

发布时间:2023年12月30日

OSG绘制视锥体,这一篇增加设置相机参数接口,支持通过eye、center、up设置相机参数。

代码如下:

#include "stdafx.h"
#include <osgViewer/Viewer>
#include <osg/ShapeDrawable>
#include <osg/Geode>
#include <osg/MatrixTransform>
#include <osg/Camera>
#include <osgUtil/PolytopeIntersector>
#include <osgUtil/LineSegmentIntersector>

// 在创建相机视锥体时计算视锥体顶点和设置边线
osg::ref_ptr<osg::Geode> createCameraFrustum(osg::Camera* camera) {
	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
	osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();

	// 获取相机的投影矩阵和视图矩阵
	osg::Matrixd projectionMatrix = camera->getProjectionMatrix();
	osg::Matrixd viewMatrix = camera->getViewMatrix();

	// 计算视锥体顶点坐标
	osg::Vec3Array* vertices = new osg::Vec3Array(9);
	double nearPlane, farPlane;
	// 获取近和远裁剪平面的值
	double fovY = 1;
	double aspectRatio = 0.5;
	projectionMatrix.getPerspective(fovY, aspectRatio, nearPlane, farPlane);//获取对称透视投影的截锥体设置
	//fovY=29
	//aspectRatio=1.24
	//nearPlane=0.9
	//farPlane=无穷大
	farPlane = 1.9;
	double tanFovY = tan(fovY * 0.5);
	double tanFovX = tanFovY * aspectRatio;

	// 近裁剪平面的四个顶点
	(*vertices)[0] = osg::Vec3(0.0, 0.0, 0.0);
	(*vertices)[1] = osg::Vec3(tanFovX * nearPlane, tanFovY * nearPlane, -nearPlane);
	(*vertices)[2] = osg::Vec3(-tanFovX * nearPlane, tanFovY * nearPlane, -nearPlane);
	(*vertices)[3] = osg::Vec3(-tanFovX * nearPlane, -tanFovY * nearPlane, -nearPlane);
	(*vertices)[4] = osg::Vec3(tanFovX * nearPlane, -tanFovY * nearPlane, -nearPlane);

	// 远裁剪平面的四个顶点
	(*vertices)[5] = osg::Vec3(tanFovX * farPlane, tanFovY * farPlane, -farPlane);
	(*vertices)[6] = osg::Vec3(-tanFovX * farPlane, tanFovY * farPlane, -farPlane);
	(*vertices)[7] = osg::Vec3(-tanFovX * farPlane, -tanFovY * farPlane, -farPlane);
	(*vertices)[8] = osg::Vec3(tanFovX * farPlane, -tanFovY * farPlane, -farPlane);

	// 设置视锥体的边线
	osg::ref_ptr<osg::DrawElementsUInt> edges = new osg::DrawElementsUInt(osg::PrimitiveSet::LINES, 24);
	// 给edges数组添加顶点索引来定义边线
	edges->push_back(0);
	edges->push_back(1);
	edges->push_back(0);
	edges->push_back(2);
	edges->push_back(0);
	edges->push_back(3);
	edges->push_back(0);
	edges->push_back(4);

	edges->push_back(1);
	edges->push_back(2);
	edges->push_back(3);
	edges->push_back(4);

	edges->push_back(1);
	edges->push_back(4);
	edges->push_back(2);
	edges->push_back(3);


	edges->push_back(0);
	edges->push_back(1 + 4);
	edges->push_back(0);
	edges->push_back(2 + 4);
	edges->push_back(0);
	edges->push_back(3 + 4);
	edges->push_back(0);
	edges->push_back(4 + 4);
	edges->push_back(1 + 4);
	edges->push_back(2 + 4);
	edges->push_back(3 + 4);
	edges->push_back(4 + 4);

	edges->push_back(1 + 4);
	edges->push_back(4 + 4);
	edges->push_back(2 + 4);
	edges->push_back(3 + 4);

	/*edges->push_back(0);
	edges->push_back(7);
	edges->push_back(0);
	edges->push_back(8);*/

	// 其他边线的索引添加类似的操作...

	// 设置几何体属性
	geometry->setVertexArray(vertices);
	geometry->addPrimitiveSet(edges);

	geode->addDrawable(geometry);

	return geode;
}

int main(int argc, char** argv) {
	osgViewer::Viewer viewer;

	// 创建相机并设置视图矩阵和投影矩阵
	osg::ref_ptr<osg::Camera> camera = viewer.getCamera();
	camera->setProjectionMatrixAsPerspective(45.0f, 1.0f, 0.1f, 100.0f); // 设置透视投影矩阵
	osg::Vec3 eye(0.0f, 0.0f, 5.0f);
	osg::Vec3 center(0.0f, 0.0f, 0.0f);
	osg::Vec3 up(0.0f, 1.0f, 0.0f);
	camera->setViewMatrixAsLookAt(eye, center, up); // 设置视图矩阵

	// 创建场景根节点
	osg::ref_ptr<osg::Group> root = new osg::Group;
	osg::ref_ptr<osg::Geode> frustumGeometry = createCameraFrustum(camera);

	root->addChild(frustumGeometry); // 将相机视锥体添加到根节点
	viewer.setSceneData(root);
	viewer.setUpViewInWindow(100, 100, 800, 600);
	return viewer.run();
}

?

文章来源:https://blog.csdn.net/cangqiongxiaoye/article/details/135310524
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。