⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 camera.cpp

📁 最新osg包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* -*-c++-*- Producer - Copyright (C) 2001-2004  Don Burns * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version.  The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * OpenSceneGraph Public License for more details. */#ifdef WIN32#include <windows.h>#endif#include <string.h>#include <algorithm>#include "Camera.h"using namespace osgProducer;Camera::Camera( void ) {    _index = 0;    _projrectLeft   = 0.0;    _projrectRight  = 1.0;    _projrectBottom = 0.0;    _projrectTop    = 1.0;    osg::Matrix::value_type  id[] = {        1, 0, 0, 0,        0, 1, 0, 0,        0, 0, 1, 0,        0, 0, 0, 1    };    memcpy( _viewMatrix, id, sizeof(osg::Matrix::value_type[16]));    _offset._xshear = _offset._yshear = 0.0f;    memcpy( _offset._matrix, id, sizeof(osg::Matrix::value_type[16]));    _offset._multiplyMethod = Offset::PreMultiply;    _lens = new Lens;    _lens->setAutoAspect(true);    _rs = new RenderSurface;        _clear_color[0] = 0.2f;    _clear_color[1] = 0.2f;    _clear_color[2] = 0.4f;    _clear_color[3] = 1.0f;        _focal_distance = 1.0;        _shareLens = true;    _shareView = true;    _enabled = true;    _initialized = false;}Camera::~Camera( void ){}const osg::Matrix::value_type * Camera::getViewMatrix( void ) const{    return _viewMatrix;}void Camera::setViewByMatrix( const osg::Matrix &mat ){    osg::Matrix m;    if ( _offset._multiplyMethod == Offset::PostMultiply )      m = osg::Matrix( _offset._matrix ) * mat;    else if( _offset._multiplyMethod == Offset::PreMultiply )        m = mat * osg::Matrix( _offset._matrix );    memcpy( _viewMatrix, m.ptr(), sizeof( osg::Matrix::value_type[16] ));}void Camera::setViewByLookat( const osg::Vec3 &eye, const osg::Vec3 &center, const osg::Vec3 &up ){    osg::Matrix m;    m.makeLookAt(eye,center,up);    setViewByMatrix( m );}void Camera::setViewByLookat( float eyeX, float eyeY, float eyeZ,                              float centerX, float centerY, float centerZ,                              float upX, float upY, float upZ ){    setViewByLookat( osg::Vec3(eyeX, eyeY, eyeZ),                     osg::Vec3(centerX, centerY, centerZ ),                     osg::Vec3(upX, upY, upZ) );}Camera::Lens::Lens( void ){// original defaults.//     _left         = -0.5;//     _right        =  0.5;//     _bottom       = -0.5;//     _top          =  0.5;        // Setting of the frustum which are appropriate for    // a monitor which is 26cm high, 50cm distant from the    // viewer and an horzintal/vetical aspect ratio of 1.25.    // This assumed to be a reasonable average setting for end users.    _left         = -0.32;    _right        =  0.32;    _bottom       = -0.26;    _top          =  0.26;    _ortho_left   = -1.0;    _ortho_right  =  1.0;    _ortho_bottom = -1.0;    _ortho_top    =  1.0;    _nearClip     =  1.0;    _farClip      =  1e6;    _updateFOV();    _projection = Perspective;}void Camera::Lens::setAspectRatio( double aspectRatio ){    _aspect_ratio = aspectRatio;    _left  = -0.5 * (_top - _bottom) * _aspect_ratio;    _right =  0.5 * (_top - _bottom) * _aspect_ratio;    _ortho_left  = -0.5 * (_ortho_top - _ortho_bottom) * _aspect_ratio;    _ortho_right =  0.5 * (_ortho_top - _ortho_bottom) * _aspect_ratio;    if( _projection == Perspective )    _updateFOV();}void Camera::Lens::setPerspective( double hfov,   double vfov,                        double nearClip,   double farClip ){    _hfov = osg::DegreesToRadians(hfov);    _vfov = osg::DegreesToRadians(vfov);    _aspect_ratio = tan(0.5*_hfov)/tan(0.5*_vfov);    _nearClip = nearClip;    _farClip  = farClip;    _left   = -_nearClip * tan(_hfov/2.0);     _right  =  _nearClip * tan(_hfov/2.0);     _bottom = -_nearClip * tan(_vfov/2.0);    _top    =  _nearClip * tan(_vfov/2.0);    _projection = Perspective;    setAutoAspect(false);}void Camera::Lens::setFrustum( double left,   double right,                                   double bottom, double top,                    double nearClip,   double farClip ){    _left = left;    _right = right;    _bottom = bottom;    _top = top;    _nearClip = nearClip;    _farClip = farClip;    _projection = Perspective;    _updateFOV();    setAutoAspect(false);}void Camera::Lens::setOrtho( double left, double right,                double bottom, double top,                double nearClip, double farClip ){    _ortho_left = left;    _ortho_right = right;    _ortho_bottom = bottom;    _ortho_top = top;    _nearClip = nearClip;    _farClip = farClip;    _projection = Orthographic;    setAutoAspect(false);}void Camera::Lens::setMatrix( const osg::Matrix::value_type matrix[16] ){    memcpy( _matrix, matrix, sizeof(osg::Matrix::value_type[16]) );    _projection = Manual;    setAutoAspect(false);}bool Camera::Lens::getFrustum( double& left, double& right,                double& bottom, double& top,                double& zNear, double& zFar ) const{    //The following code was taken from osg's matrix implementation of getFrustum    if (_matrix[3]!=0.0 || _matrix[7]!=0.0 || _matrix[11]!=-1.0 || _matrix[15]!=0.0) return false;    zNear = _matrix[14] / (_matrix[10]-1.0);    zFar = _matrix[14] / (1.0+_matrix[10]);        left = zNear * (_matrix[8]-1.0) / _matrix[0];    right = zNear * (1.0+_matrix[8]) / _matrix[0];    top = zNear * (1.0+_matrix[9]) / _matrix[5];    bottom = zNear * (_matrix[9]-1.0) / _matrix[5];    return true;}bool Camera::Lens::getOrtho( double& left, double& right,                double& bottom, double& top,                double& zNear, double& zFar ) const{    //The following code was taken from osg's matrix implementation of getOrtho    if (_matrix[3]!=0.0 || _matrix[7]!=0.0 || _matrix[11]!=0.0 || _matrix[15]!=1.0) return false;    zNear = (_matrix[14]+1.0) / _matrix[10];    zFar = (_matrix[14]-1.0) / _matrix[10];        left = -(1.0+_matrix[12]) / _matrix[0];    right = (1.0-_matrix[12]) / _matrix[0];    bottom = -(1.0+_matrix[13]) / _matrix[5];    top = (1.0-_matrix[13]) / _matrix[5];    return true;}bool Camera::Lens::convertToOrtho( float d ){    if( _projection == Manual )    {        //Need to extract frustum values from manual matrix        if( !getFrustum(_left,_right,_bottom,_top,_nearClip,_farClip) )            return false;        _updateFOV();    }    double s = d * tan(_vfov*0.5);    _ortho_bottom = -s;    _ortho_top = s;    _ortho_left = -s*_aspect_ratio;    _ortho_right = s*_aspect_ratio;    _projection = Orthographic;    return true;}bool Camera::Lens::convertToPerspective( float d ){    if( _projection == Manual )    {        //Need to extract ortho values from manual matrix        if( !getOrtho(_ortho_left,_ortho_right,_ortho_bottom,_ortho_top,_nearClip,_farClip) )            return false;    }    double hfov = 2 * atan( 0.5 * (_ortho_right - _ortho_left)/d);    double vfov = 2 * atan( 0.5 * (_ortho_top - _ortho_bottom)/d);    _left   = -_nearClip * tan(hfov*0.5);    _right  =  _nearClip * tan(hfov*0.5);    _bottom = -_nearClip * tan(vfov*0.5);    _top    =  _nearClip * tan(vfov*0.5);    _projection = Perspective;    //_updateMatrix();    return true;}void Camera::Lens::apply(float xshear, float yshear){    osg::Matrix::value_type _matrix[16];    generateMatrix(xshear,yshear,_matrix);}void Camera::Lens::getParams( double &left, double &right, double &bottom, double &top,                double &nearClip, double &farClip ){    if( _projection == Perspective )    {        left   = _left;        right  = _right;        bottom = _bottom;        top    = _top;    }    else if( _projection == Orthographic )    {        left   = _ortho_left;        right  = _ortho_right;        bottom = _ortho_bottom;        top    = _ortho_top;    }    else if( _projection == Manual ) // could only be Manual, but best to make this clear    {        // Check if Manual matrix is either a valid perspective or orthographic matrix        // If neither, then return bogus values -- nothing better we can do        if(getFrustum(left,right,bottom,top,nearClip,farClip))            return;        if(getOrtho(left,right,bottom,top,nearClip,farClip))            return;        left   = _left;        right  = _right;        bottom = _bottom;        top    = _top;    }    nearClip   = _nearClip;    farClip    = _farClip;}void Camera::setProjectionRectangle( const float left, const float right,                    const float bottom, const float top ){    _projrectLeft   = left;        _projrectRight  = right;        _projrectBottom = bottom;        _projrectTop    = top;    }void Camera::getProjectionRectangle( float &left, float &right,                float &bottom, float &top ) const{    left   = _projrectLeft;    right  = _projrectRight;    bottom = _projrectBottom;    top    = _projrectTop;}void Camera::setProjectionRectangle( int x, int y, unsigned int width, unsigned int height ) {    int _x, _y;    unsigned int _w, _h;    _rs->getWindowRectangle( _x, _y, _w, _h );#if 0    if( _w == osgProducer::RenderSurface::UnknownDimension || _h == Producer::RenderSurface::UnknownDimension)    {        unsigned int ww;        unsigned int hh;        _rs->getScreenSize( ww, hh );        if( _w == osgProducer::RenderSurface::UnknownDimension )            _w = ww;        if( _h == osgProducer::RenderSurface::UnknownDimension )            _h = hh;    }#endif    _projrectLeft  = float(x - _x)/float(_w);    _projrectRight = float((x + width) - _x)/float(_w);    _projrectBottom = float(y - _y)/float(_h);    _projrectTop    = float((y+height) - _y)/float(_h);}void Camera::getProjectionRectangle( int &x, int &y, unsigned int &width, unsigned int &height ) const{    int _x, _y;    unsigned int _w, _h;    float fx, fy, fw, fh;    _rs->getWindowRectangle( _x, _y, _w, _h );#if 0    if( _w == Producer::RenderSurface::UnknownDimension || _h == Producer::RenderSurface::UnknownDimension )    {        unsigned int ww;        unsigned int hh;        _rs->getScreenSize( ww, hh );        if( _w == Producer::RenderSurface::UnknownDimension )            _w = ww;        if( _h == Producer::RenderSurface::UnknownDimension )            _h = hh;    }#endif    fx = _projrectLeft * _w;    fy = _projrectBottom * _h;    fw = _w * _projrectRight;    fh = _h * _projrectTop;    x = int(fx);    y = int(fy);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -