• 简单基于OPENGL的三维CAD框架(1)照相机类


    开发一个照相机类,实现物体的平移,上下左右视图的观察,此类要被OPenGLDC类包含

    class GCamera {

    protected:
     //eye position
        CVector3D  m_eye;
     CVector3D  m_ref;
     CVector3D  m_vecUp;

     //viewing volume
        double  m_far, m_near;
     double   m_width,m_height;

     //viewport
     double  m_screen[2];

    public:
        GCamera();
     ~GCamera();

     void init();
       
     void projection();
     
     //set viewport acoording to window
     void set_screen( int x, int y);

     //set eye coordinate
     void set_eye(double eye_x,double eye_y,double eye_z);
     void set_ref(double ref_x,double ref_y,double ref_z);
     void set_vecUp(double up_dx,double up_dy,double up_dz);

     //set viewing volume
     void set_view_rect(double width,double height);
     void get_view_rect(double& width,double& height);

     //景物缩放
     void zoom(double scale);
     void zomm_all(double *d);


     //景物平移
     void move_view(double dpx, double dpy);
        //选择典型视图
     void set_view_type(int type);

    };

    具体实现照相机类

    GCamera::GCamera(void)
    {
    }

    GCamera::~GCamera()
    {
    }

    void GCamera::projection()
    {
     //switch to projection
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

     glRenderMode(GL_RENDER);

     //apply projective matrix
     double left  =  - m_width/2.0;
     double right =  m_width/2.0;
     double bottom =  - m_height/2.0;
     double top  =  m_height/2.0;

     glOrtho(left,right,bottom,top,m_near,m_far);

     glMatrixMode( GL_MODELVIEW );
     glLoadIdentity( );
     gluLookAt(m_eye.dx,m_eye.dy,m_eye.dz,m_ref.dx,m_ref.dy,m_ref.dz,m_vecUp.dx, m_vecUp.dy, m_vecUp.dz); 
    }

    void GCamera::init()
    {
     m_eye.dx = 0;
     m_eye.dy = 0;
     m_eye.dz = 1000.0;//移动到世界坐标1000处

     m_ref.dx = 0.0;
     m_ref.dy = 0.0;
     m_ref.dz = 0.0;

     m_far = 10000;////前端距离,后端距离
     m_near= 1;

     m_width = 1200.0;///视景体大小差不多
     m_height = 1200.0;

     m_vecUp.dx = 0.0;
     m_vecUp.dy = 1.0;
     m_vecUp.dz = 0.0;

     m_screen[0] = 400;
     m_screen[1] = 400;
    }

    void GCamera::set_screen( int x, int y)
    {
     glViewport(0,0,x,y);
     if(y==0) y=1;
     double ratio = (double)x/(double)y;
     m_width *= (double)x/m_screen[0];
     m_height *= (double)y/m_screen[1];
     m_width =  m_height*ratio;
     m_screen[0] = x;
     m_screen[1] = y;
    }

    void GCamera::set_eye(double eye_x,double eye_y,double eye_z)
    {
     m_eye.dx = eye_x;
     m_eye.dy = eye_y;
     m_eye.dz = eye_z;
    }

    void GCamera::set_ref(double ref_x,double ref_y,double ref_z)
    {
     m_ref.dx = ref_x;
     m_ref.dy = ref_y;
     m_ref.dz = ref_z;
    }

    void GCamera::set_vecUp(double up_dx,double up_dy,double up_dz)
    {
     m_vecUp.dx = up_dx;
     m_vecUp.dy = up_dy;
     m_vecUp.dz = up_dz;
    }

    void GCamera::set_view_rect(double width,double height)
    {
     m_width = width;
     m_height = height;
     double aspect = m_screen[0]/m_screen[1];
     m_width =  m_height*aspect;
    }

    void GCamera::get_view_rect(double& width,double& height)
    {
     width = m_width;
     height = m_height;
    }
    //放大与缩小
    void GCamera::zoom(double scale)
    {

     m_width *= scale;
     m_height *= scale;

    }

    void GCamera::move_view(double dpx, double dpy)//移动视点
    {
      CVector3D vec, x_direct, y_direct;
      vec = CVector3D(m_ref) - CVector3D(m_eye);
      vec.Normal();
      x_direct = vec * CVector3D(m_vecUp);
      y_direct = x_direct * vec;
     //先取得视线位置


      m_eye -= x_direct * m_width * dpx + y_direct * m_height *dpy;
      m_ref -= x_direct * m_width * dpx + y_direct * m_height *dpy;

     
     
    }

    void GCamera::set_view_type(int type)
    {
     double r = CVector3D(m_ref - m_eye).GetLength();

        switch(type)
     {
     case VIEW_RIGHT:
      m_eye = m_ref + CVector3D(r, 0, 0);
      m_vecUp = CVector3D(0, 1, 0);
      break;
     case VIEW_FRONT:
      m_eye = m_ref + CVector3D(0, 0, r);
      m_vecUp = CVector3D(0, 1, 0);
      break;
     }
      
    }

    void GCamera::zomm_all(double *d)//数组指针,使用AABB包容盒模型
    {
         double width = 0, height = 0;
      double box_width  = 0;//AABB长宽高
      double box_height = 0;
      double box_length = 0;

      box_width = d[3] - d[0];
      box_height= d[4] - d[1];
      box_length= d[5] - d[2];

      width  = max(max(box_width, box_height), box_length);
      height = max(max(box_width, box_height), box_length);

      set_view_rect(width, height);
        
         CVector3D vec = m_eye - m_ref;

      m_ref = CVector3D((d[0] + d[3])/2, (d[4] + d[1])/2, (d[5] + d[2])/2);
      m_eye = m_ref + vec;
     

    }

  • 相关阅读:
    《面试题 03.05. 栈排序》——惰性更新
    CTF<密码学> writeup 传统知识+古典密码
    有趣的数学(二)
    【】Dedecms友情链接去掉LI的方法介绍
    【】【】打工子弟学校学生们的中国梦何时圆?
    Discuz! 7.2 防注册机注册+发垃圾帖的解决方法
    Windows 8 常用快捷键
    Win7 64位系统下Auto CAD 2010注册激活,出现警告:Make sure you can write to current directory...
    怎么从EXCEL或WORD里提取图片?
    如何将windows xp系统下的outlook express6.0的邮件,帐号及通迅录导入Office Outlook xp/2003/2007中...
  • 原文地址:https://www.cnblogs.com/lizhengjin/p/1297859.html
Copyright © 2020-2023  润新知