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();
}