简单基于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;
 

}

原文地址:https://www.cnblogs.com/lizhengjin/p/1297859.html