Rev 67 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#ifdef WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
#include <GL/glu.h>
#include "GLViewController.h"
using namespace std;
using namespace CGLA;
namespace Graphics
{
void GLViewController::reset_projection()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(FOV_DEG, aspect, znear, zfar);
glMatrixMode(GL_MODELVIEW);
}
GLViewController::GLViewController(int _WINX, int _WINY,
const CGLA::Vec3f& _centre, float _rad):
FOV_DEG(53),
FOV_RAD((FOV_DEG*M_PI)/180.0f),
WINX(_WINX), WINY(_WINY),
aspect(WINX/WINY),
centre(_centre), rad(_rad),
button_down(false),
spin(false)
{
float view_dist = rad/sin(FOV_RAD/2.0f);
ball = new QuatTrackBall(centre, view_dist, WINX, WINY);
znear = view_dist - rad;
zfar = view_dist + rad;
reset_projection();
}
void GLViewController::grab_ball(TrackBallAction action,
const CGLA::Vec2i& pos)
{
ball->grab_ball(action,pos);
if(action==ZOOM_ACTION)
set_near_and_far();
spin = false;
button_down = true;
last_action = action;
old_pos = pos;
}
void GLViewController::roll_ball(const CGLA::Vec2i& pos)
{
ball->roll_ball(pos);
if(last_action==ZOOM_ACTION)
set_near_and_far();
Vec2f dir = Vec2f(pos-old_pos);
spin = dir.length()>=1.1f;
old_pos = pos;
}
void GLViewController::release_ball()
{
ball->release_ball();
if(last_action==ZOOM_ACTION)
set_near_and_far();
}
bool GLViewController::try_spin()
{
if(spin && !ball->is_grabbed())
{
ball->do_spin();
return true;
}
return false;
}
void GLViewController::set_gl_modelview()
{
ball->set_gl_modelview();
}
void GLViewController::reshape(int W, int H)
{
WINX = W;
WINY = H;
aspect = WINX/static_cast<float>(WINY);
glViewport(0,0,WINX,WINY);
reset_projection();
ball->set_screen_window(WINX, WINY);
}
void GLViewController::set_near_and_far()
{
Vec3f eye, centre, up;
ball->get_view_param(eye, centre, up);
float len = (eye-centre).length();
znear = max(0.01f*rad, len-rad);
zfar = len+rad;
reset_projection();
}
bool GLViewController::load(std::ifstream& ifs)
{
if(ifs)
{
QuatTrackBall* ball_tmp = ball;
ifs.read(reinterpret_cast<char*>(this),
sizeof(GLViewController));
ball = ball_tmp;
ifs.read(reinterpret_cast<char*>(ball),sizeof(QuatTrackBall));
reset_projection();
ball->set_screen_window(WINX, WINY);
return true;
}
return false;
}
bool GLViewController::save(std::ofstream& ofs) const
{
if(ofs)
{
ofs.write(reinterpret_cast<const char*>(this),
sizeof(GLViewController));
ofs.write(reinterpret_cast<const char*>(ball),sizeof(QuatTrackBall));
return true;
}
return false;
}
}