开发一个照相机类,实现物体的平移,上下左右视图的观察,此类要被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;
}