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