- #include <osg/Group>
- #include <osg/Camera>
- #include <osgGA/CameraManipulator>
- #include <osgViewer/Viewer>
- #include <osgDB/ReadFile>
- #include <iostream>
- using namespace std;
- class Follow :public osgGA::CameraManipulator
- {
- public:
- Follow(){
- _position=osg::Vec3(0,0,3);
- _rotate=osg::Vec3(osg::PI_2,0,0);//一般让相机绕x轴旋转90度,否则相机会从上空看模型(一般,一般会这样,看你模型怎么方了)
- _speed=2.0;
- _angle=2.5;
- }
- virtual ~Follow(){
- }
- /*
- 在OSG里,所有的视图矩阵操作都是通过矩阵来完成的,不同摄像机之间的交互也通过矩阵,
- 这样就提供了一个通用的模型,不管你习惯使用gluLookAt方式的,还是习惯操作摄像机位置姿态方
- 式的,都可以很容易嵌入OSG的框架中,因为所有方式的最后结果就是矩阵
- */
- /** set the position of the matrix manipulator using a 4x4 Matrix.*/
- /*这个函数在从一个摄像机切换到另一个摄像机时调用,用来把上一个摄像机的视图矩阵传过来,
- 这样就可依此设定自己的初始位置了。*/
- virtual void setByMatrix(const osg::Matrixd& matrix){
- }
- /** set the position of the matrix manipulator using a 4x4 Matrix.*/
- /*这个方法当在外部直接调用Viewer的setViewByMatrix方法时,把设置的矩阵传过来,让
- 摄像机记住新更改的位置*/
- virtual void setByInverseMatrix(const osg::Matrixd& matrix){
- }
- /** get the position of the manipulator as 4x4 Matrix.*/
- /*SetByMatrix方法需要的矩阵就是用这个方法得到的,用来向下一个摄像机传递矩阵。*/
- virtual osg::Matrixd getMatrix() const {
- osg::Matrixd mat;
- mat.makeRotate(_rotate.x(),osg::Vec3(1,0,0),
- _rotate.y(),osg::Vec3(0,1,0),
- _rotate.z(),osg::Vec3(0,0,1));
- cout<<"getMatrix"<<endl;
- return mat*osg::Matrixd::translate(_position);
- }
- /** get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix.*/
- /*视图矩阵(观察矩阵)是变换矩阵的逆矩阵) 这个是最重要的方法,这个方法每帧会被调用,它返回当前的视图矩阵。
- 在这个方法里进行时间的处理,改变自己的状态,进而在 getInverseMatrix 被调用时,改变
- 场景内摄像机的位置姿态。这个函数在 void Viewer::updateTraversal()中被调用
- _camera->setViewMatrix(_cameraManipulator->getInverseMatrix());
- */
- virtual osg::Matrixd getInverseMatrix() const{
- osg::Matrixd mat;
- mat.makeRotate(_rotate.x(),osg::Vec3(1,0,0),
- _rotate.y(),osg::Vec3(0,1,0),
- _rotate.z(),osg::Vec3(0,0,1));
- return osg::Matrixd::inverse(mat*osg::Matrixd::translate(_position));
- }
- /*
- 在这个方法里,有两个参数,第一个是GUI事件的供给者,第二个参数用来handle方法对GUI
- 进行反馈,它可以让GUIEventHandler根据输入事件让GUI进行一些动作。
- 如果要进行事件处理,可以从GUIEventHandler继承出自己的类,然后覆盖handle方法,在里
- 面进行事件处理。osgProducer::Viewer类维护一个GUIEventHandler队列,事件在这个队列里依次传
- 递,handle的返回值决定这个事件是否继续让后面的GUIEventHandler处理,如果返回true,则停止
- 处理,如果返回false,后面的GUIEventHandler还有机会继续对这个事件进行响应。*/
- bool handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &aa){
- //操作逻辑
- return false;
- }
- private:
- osg::Vec3 _position;
- osg::Vec3 _rotate;
- float _speed;
- float _angle;
- };
- int main(int argc, char *argv[])
- {
- osg::ref_ptr<osgViewer::Viewer>viewer=new osgViewer::Viewer;
- viewer->setSceneData(osgDB::readNodeFile("ceep.ive"));
- viewer->setCameraManipulator(new Follow);
- return viewer->run();
- }
osg漫游器
最新推荐文章于 2024-07-10 20:16:35 发布