first release
This commit is contained in:
parent
fcdf344cf6
commit
7e2ee081ac
|
@ -0,0 +1,94 @@
|
|||
#ifndef FRUSTUM_H
|
||||
#define FRUSTUM_H
|
||||
|
||||
#include <wrap/gui/camera.h>
|
||||
#include <vcg/space/plane3.h>
|
||||
#include <vcg/space/line3.h>
|
||||
|
||||
|
||||
namespace vcg {
|
||||
|
||||
template <class T> class Frustum: public Camera {
|
||||
public:
|
||||
void GetView();
|
||||
bool IsOutside(Point3<T> &point);
|
||||
bool IsOutside(Point3<T> &point, T radius);
|
||||
T Distance(Point3<T> &point, int plane);
|
||||
Point3<T> ViewPoint();
|
||||
|
||||
protected:
|
||||
T resolution;
|
||||
Plane3<T> planes[6];
|
||||
Point3<T> view_point;
|
||||
};
|
||||
|
||||
|
||||
//Implementation
|
||||
template <class T> Point3<T> Frustum<T>::ViewPoint() {
|
||||
return view_point;
|
||||
}
|
||||
|
||||
template <class T> bool Frustum<T>::IsOutside(Point3<T> &point) {
|
||||
Point3<T> r = Project(point);
|
||||
if(r[0] < viewport[0] || r[0] > viewport[0]+viewport[2] ||
|
||||
r[1] < viewport[1] || r[1] > viewport[1]+viewport[3])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T> bool Frustum<T>::IsOutside(Point3<T> &point, T radius) {
|
||||
for(int i = 0; i < 4; i++) {
|
||||
T dist = Distance(point, i);
|
||||
if(dist < -radius)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T> T Frustum<T>::Distance(Point3<T> &point, int plane) {
|
||||
return Distance<T>(point, planes[plane]);
|
||||
}
|
||||
|
||||
template <class T> void Frustum<T>::GetView() {
|
||||
Camera::GetView();
|
||||
|
||||
Point3d NE, SE, SW, NW, ne, se, sw, nw;
|
||||
int t = viewport[1] + viewport[3];
|
||||
int b = viewport[1];
|
||||
int r = viewport[0] + viewport[2];
|
||||
int l = viewport[0];
|
||||
|
||||
Point3d NE, SE, SW, NW, ne, se, sw, nw;
|
||||
gluUnProject(l, b, 0, model_matrix, proj_matrix, viewport, &nw[0], &nw[1], &nw[2]);
|
||||
gluUnProject(l, t, 0, model_matrix, proj_matrix, viewport, &sw[0], &sw[1], &sw[2]);
|
||||
gluUnProject(r, b, 0, model_matrix, proj_matrix, viewport, &ne[0], &ne[1], &ne[2]);
|
||||
gluUnProject(r, t, 0, model_matrix, proj_matrix, viewport, &se[0], &se[1], &se[2]);
|
||||
gluUnProject(l, b, 1, model_matrix, proj_matrix, viewport, &NW[0], &NW[1], &NW[2]);
|
||||
gluUnProject(l, t, 1, model_matrix, proj_matrix, viewport, &SW[0], &SW[1], &SW[2]);
|
||||
gluUnProject(r, b, 1, model_matrix, proj_matrix, viewport, &NE[0], &NE[1], &NE[2]);
|
||||
gluUnProject(r, t, 1, model_matrix, proj_matrix, viewport, &SE[0], &SE[1], &SE[2]);
|
||||
|
||||
view_point = Camera::ViewPoint();
|
||||
|
||||
planes[0].init(view_point, Point3<T>().Import(nw), Point3<T>().Import(ne));
|
||||
planes[1].init(view_point, Point3<T>().Import(ne), Point3<T>().Import(se));
|
||||
planes[2].init(view_point, Point3<T>().Import(se), Point3<T>().Import(sw));
|
||||
planes[3].init(view_point, Point3<T>().Import(sw), Point3<T>().Import(nw));
|
||||
planes[4].init(Point3<T>().Import(se), Point3<T>().Import(sw), Point3<T>().Import(nw));
|
||||
planes[5].init(Point3<T>().Import(SW), Point3<T>().Import(SE), Point3<T>().Import(NE));
|
||||
|
||||
for(int i = 0; i < 6; i++)
|
||||
planes[i].Normalize();
|
||||
|
||||
//calcoliamo la risoluzione: dimenzione di un pixel a distanza 1 dal view_point
|
||||
resolution = (T)((ne + NE) - (nw + NW)).Norm() /( viewport[2] * ((ne + NE) - (nw + NW)).Norm());
|
||||
}
|
||||
|
||||
}//namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
#include "trackball.h"
|
||||
#include <wrap/gl/wrap.h>
|
||||
using namespace vcg;
|
||||
|
||||
#include <iostream> //debug!
|
||||
using namespace std;
|
||||
|
||||
Transform::Transform() {
|
||||
local.SetIdentity();
|
||||
track.SetIdentity();
|
||||
}
|
||||
|
||||
Trackball::Trackball(): current_button(0), last_x(-1), last_y(-1), dragging(false),
|
||||
spinnable(true), spinning(false), history_size(10) {
|
||||
//qui si aggiungono tutte le actions
|
||||
actions[0] = Action(LOCAL, NONE);
|
||||
actions[BUTTON_LEFT] = Action(VIEW, ROTATE);
|
||||
actions[BUTTON_LEFT | KEY_CTRL] = Action(VIEW, DRAG_XY);
|
||||
actions[BUTTON_LEFT | KEY_SHIFT] = Action(VIEW, SCALE);
|
||||
actions[WHEEL] = Action(SCREEN, SCALE);
|
||||
current_action = Action(LOCAL, NONE);
|
||||
}
|
||||
|
||||
void Trackball::SetIdentity() {
|
||||
local.SetIdentity();
|
||||
Reset();
|
||||
}
|
||||
void Trackball::SetPosition(const Similarityf &m, int millisec) {
|
||||
local = m;
|
||||
//millisec ignored at the moment.
|
||||
}
|
||||
|
||||
//operating
|
||||
void Trackball::GetView() {
|
||||
camera.GetView();
|
||||
|
||||
//lets get view matrix
|
||||
Similarityf m = local * last_track;
|
||||
Point3f c_obj = Point3f(0, 0, 0) * m; //coordinate of the center of the trackball in obj coords
|
||||
Point3f c_view = camera.Project(c_obj); //center of the trackball in screen coords.
|
||||
Point3f X, Y, Z, C;
|
||||
X = camera.UnProject(Point3f(c_view[0] + 100, c_view[1], c_view[2]));
|
||||
Y = camera.UnProject(Point3f(c_view[0], c_view[1] - 100, c_view[2]));
|
||||
Z = camera.UnProject(Point3f(c_view[0], c_view[1], c_view[2] + 0.1));
|
||||
C = c_obj;
|
||||
X = X - C; X.Normalize();
|
||||
Y = Y - C; Y.Normalize();
|
||||
Z = X ^ Y;
|
||||
|
||||
Matrix44f view_axis; //this is before applying last (or track...)
|
||||
view_axis.SetIdentity();
|
||||
view_axis.element(0, 0) = X[0]; view_axis.element(0, 1) = X[1]; view_axis.element(0, 2) = X[2];
|
||||
view_axis.element(1, 0) = Y[0]; view_axis.element(1, 1) = Y[1]; view_axis.element(1, 2) = Y[2];
|
||||
view_axis.element(2, 0) = Z[0]; view_axis.element(2, 1) = Z[1]; view_axis.element(2, 2) = Z[2];
|
||||
view.SetIdentity();
|
||||
view.FromMatrix(view_axis);
|
||||
//view = view * Inverse(Similarityf(track.rot));
|
||||
//spinning ignored
|
||||
}
|
||||
void Trackball::Apply() {
|
||||
glMultMatrix(track.Matrix());
|
||||
}
|
||||
|
||||
void Trackball::Draw() {
|
||||
glPushMatrix();
|
||||
glMultMatrix(local.Matrix());
|
||||
//Disegnamo un cubo:
|
||||
glColor3f(1, 0, 0);
|
||||
glScalef(0.5, 0.5, 0.5);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(-1, -1, -1);
|
||||
glVertex3f( 1, -1, -1);
|
||||
glVertex3f( 1, 1, -1);
|
||||
glVertex3f(-1, 1, -1);
|
||||
glVertex3f(-1, 1, 1);
|
||||
glVertex3f( 1, 1, 1);
|
||||
glVertex3f( 1, -1, 1);
|
||||
glVertex3f(-1, -1, 1);
|
||||
glVertex3f(-1, -1, 1);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
void Trackball::Reset() {
|
||||
track.SetIdentity();
|
||||
}
|
||||
|
||||
//interface
|
||||
void Trackball::MouseDown(int x, int y, Trackball::Button button) {
|
||||
current_button |= button;
|
||||
SetCurrentAction();
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
}
|
||||
|
||||
void Trackball::MouseMove(int x, int y) {
|
||||
if(current_action.motion == NONE) return;
|
||||
if(last_x == -1 && last_y == -1) { //changed mode in the middle of moving
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
return;
|
||||
}
|
||||
|
||||
Point3f origin = camera.ViewportToScreen(ScreenOrigin());
|
||||
Point3f new_point = camera.ViewportToScreen(Point3f(x, y, 0)) - origin;
|
||||
Point3f old_point = camera.ViewportToScreen(Point3f(last_x, last_y, 0)) - origin;
|
||||
new_point *= 2;
|
||||
old_point *= 2;
|
||||
|
||||
Similarityf u;
|
||||
TrackMode *mode = CurrentMode();
|
||||
Similarityf new_track = mode->Apply(new_point, u);
|
||||
Similarityf old_track = mode->Apply(old_point, u);
|
||||
delete mode;
|
||||
|
||||
Invert(old_track);
|
||||
new_track = old_track * new_track;
|
||||
|
||||
Similarityf diff;
|
||||
switch(current_action.system) {
|
||||
case VIEW:
|
||||
u = last_view * Similarityf((-local.tra) * Similarityf(last_track.rot)) * Similarityf(-last_track.tra);
|
||||
diff = Inverse(u) * new_track * u;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
track = diff * last_track;
|
||||
|
||||
}
|
||||
|
||||
void Trackball::MouseUp(int x, int y, Trackball::Button button) {
|
||||
current_button &= (~button);
|
||||
SetCurrentAction();
|
||||
}
|
||||
|
||||
void Trackball::MouseWheel(Trackball::Button notch) {
|
||||
}
|
||||
|
||||
void Trackball::ButtonDown(Trackball::Button button) {
|
||||
current_button |= button;
|
||||
SetCurrentAction();
|
||||
}
|
||||
|
||||
void Trackball::ButtonUp(Trackball::Button button) {
|
||||
current_button &= (~button);
|
||||
SetCurrentAction();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//spinning interface
|
||||
void Trackball::SetSpinnable(bool on){}
|
||||
bool Trackball::IsSpinnable() {
|
||||
return spinnable;
|
||||
}
|
||||
void Trackball::SetSpinning(Quaternionf &spin){}
|
||||
void Trackball::StopSpinning(){}
|
||||
bool Trackball::IsSpinning() {
|
||||
return spinning;
|
||||
}
|
||||
|
||||
//interfaccia navigation:
|
||||
void Trackball::Back(){}
|
||||
void Trackball::Forward(){}
|
||||
void Trackball::Home(){}
|
||||
void Trackball::HistorySize(int lenght){}
|
||||
|
||||
void Trackball::SetCurrentAction() {
|
||||
//I use strict matching.
|
||||
assert(actions.count(0));
|
||||
if(!actions.count(current_button))
|
||||
current_action = actions[0];
|
||||
else
|
||||
current_action = actions[current_button];
|
||||
|
||||
last_x = -1;
|
||||
last_y = -1;
|
||||
last_track = track;
|
||||
last_view = view;
|
||||
}
|
||||
|
||||
TrackMode *Trackball::CurrentMode() {
|
||||
Point3f x(1, 0, 0), y(0, 1, 0), z(0, 0, 1);
|
||||
TrackMode *mode = NULL;
|
||||
switch(current_action.motion) {
|
||||
case NONE: mode = new TrackMode(); break;
|
||||
case ROTATE: mode = new SphereMode(); break;
|
||||
case ROTATE_DUMMY: mode = new GravityMode(); break;
|
||||
case ROTATE_X: mode = new CylinderMode(x); break;
|
||||
case ROTATE_Y: mode = new CylinderMode(y); break;
|
||||
case ROTATE_Z: mode = new CylinderMode(z); break;
|
||||
case DRAG_X: mode = new LineMode(x); break;
|
||||
case DRAG_Y: mode = new LineMode(y); break;
|
||||
case DRAG_Z: mode = new LineMode(z); break;
|
||||
case DRAG_XY: mode = new PlaneMode(x, y); break;
|
||||
case DRAG_YZ: mode = new PlaneMode(y, z); break;
|
||||
case DRAG_XZ: mode = new PlaneMode(z, x); break;
|
||||
case SCALE: mode = new ScaleMode(); break;
|
||||
default: break;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
//return center of trackball in Screen coordinates.
|
||||
Point3f Trackball::ScreenOrigin() {
|
||||
return camera.Project(ModelOrigin());
|
||||
}
|
||||
|
||||
//return center of trackball in Model coordinates
|
||||
Point3f Trackball::ModelOrigin() {
|
||||
Similarityf m = local * last_track;
|
||||
return Point3f(0, 0, 0) * m;
|
||||
}
|
||||
|
||||
Matrix44f Trackball::ScreenToModel() {
|
||||
return camera.inverse;
|
||||
}
|
||||
|
||||
Similarityf Trackball::ModelToLocal() {
|
||||
Similarityf m = local * last_track;
|
||||
return m;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
#ifndef TRACKBALL_H
|
||||
#define TRACKBALL_H
|
||||
|
||||
#include <vcg/math/similarity.h>
|
||||
#include <wrap/gui/view.h>
|
||||
#include <wrap/gui/trackmode.h>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
namespace vcg {
|
||||
|
||||
class Transform {
|
||||
public:
|
||||
Transform();
|
||||
Similarityf track;
|
||||
Similarityf local;
|
||||
};
|
||||
|
||||
Transform interpolate(const Transform &a, const Transform &b, float t);
|
||||
|
||||
class Trackball: public Transform {
|
||||
public:
|
||||
enum Button { BUTTON_LEFT = 1, BUTTON_MIDDLE = 2, BUTTON_RIGHT = 4, WHEEL = 8,
|
||||
KEY_SHIFT = 16, KEY_CTRL = 32, KEY_ALT = 64, HANDLE = 128 };
|
||||
|
||||
Trackball();
|
||||
void SetIdentity();
|
||||
void SetPosition(const Similarityf &local, int millisec = 0);
|
||||
void SetTransform(const Transform &transform, int miilisec = 0);
|
||||
|
||||
//operating
|
||||
void GetView();
|
||||
void Apply();
|
||||
void Draw();
|
||||
void Reset();
|
||||
|
||||
//interface
|
||||
void MouseDown(int x, int y, Button button);
|
||||
void MouseMove(int x, int y);
|
||||
void MouseUp(int x, int y, Button button);
|
||||
void MouseWheel(Button notch);
|
||||
void ButtonUp(Button button);
|
||||
void ButtonDown(Button button);
|
||||
|
||||
//default sensitivity 1
|
||||
void SetSensitivity(float s);
|
||||
|
||||
//spinning interface
|
||||
void SetSpinnable(bool on);
|
||||
bool IsSpinnable();
|
||||
void SetSpinning(Quaternionf &spin);
|
||||
void StopSpinning();
|
||||
bool IsSpinning();
|
||||
|
||||
//interfaccia navigation:
|
||||
void Back();
|
||||
void Forward();
|
||||
void Home();
|
||||
void Store();
|
||||
void HistorySize(int lenght);
|
||||
|
||||
//internals
|
||||
|
||||
enum System { LOCAL, VIEW, SCREEN };
|
||||
|
||||
enum Motion { NONE = 0, ROTATE = 1, ROTATE_DUMMY = 2, //really makes sense only in VIEW system
|
||||
ROTATE_X = 3, ROTATE_Y = 4, ROTATE_Z = 5, // Axis Constrained Rotation
|
||||
DRAG_X = 6, DRAG_Y = 7, DRAG_Z = 8, // Drag constrained to an axis (trackball axis)
|
||||
DRAG_XY = 9, DRAG_YZ = 10, DRAG_XZ = 11, // Drag constrained to a plane
|
||||
SCALE = 12 //scale respect to center of trackball
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct Action {
|
||||
System system;
|
||||
Motion motion;
|
||||
Action() {}
|
||||
Action(System s, Motion m): system(s), motion(m) {}
|
||||
};
|
||||
///Find the current action ussing the current button
|
||||
void SetCurrentAction();
|
||||
|
||||
protected:
|
||||
View<float> camera;
|
||||
Similarityf view; //Rotate LOCAL coordinate into VIEW coordinates
|
||||
|
||||
int current_button;
|
||||
Action current_action;
|
||||
|
||||
TrackMode *CurrentMode();
|
||||
std::map<int, Action> actions;
|
||||
|
||||
Similarityf last_track;
|
||||
Similarityf last_view;
|
||||
int last_x, last_y;
|
||||
bool dragging;
|
||||
int button_mask;
|
||||
|
||||
Quaternionf spin;
|
||||
bool spinnable;
|
||||
bool spinning;
|
||||
|
||||
std::list<Transform> history;
|
||||
int history_size;
|
||||
|
||||
|
||||
Point3f ScreenOrigin(); //center of trackball in Screen coord
|
||||
Point3f ModelOrigin(); //center of trackball in Model coord
|
||||
|
||||
Matrix44f ScreenToModel(); //forse non serve.....
|
||||
Similarityf ModelToLocal();
|
||||
|
||||
//Point3f ScreenToLocal(const Point3f &p);
|
||||
//Point3f LocalToScreen(const Point3f &p);
|
||||
};
|
||||
|
||||
|
||||
}//namespace
|
||||
|
||||
#endif
|
|
@ -0,0 +1,72 @@
|
|||
#include "trackmode.h"
|
||||
#include <vcg/space/point3.h>
|
||||
#include <vcg/math/similarity.h>
|
||||
|
||||
using namespace vcg;
|
||||
|
||||
Similarityf SphereMode::Apply(const Point3f &p, const Similarityf &m) {
|
||||
float u = p[0];
|
||||
float w = p[1];
|
||||
float thr = 1/math::Sqrt(2.0f); //in the plane x-y distance from origin, above this use hyperboloid
|
||||
|
||||
float dist = math::Sqrt(u * u + w * w);
|
||||
Point3f result;
|
||||
if(dist < thr) { // First case: The ray is nearer to the sphere than r/sqrt(2)
|
||||
float z = math::Sqrt(1 - u * u - w* w);
|
||||
result = Point3f(u, w, z);
|
||||
} else { // Second case: The ray should hit the 1/d hyperboloid
|
||||
float a = thr;
|
||||
result = Point3f(u, w, -a*(u*u + w * w) + 3*a/2);
|
||||
result.Normalize();
|
||||
}
|
||||
if(result == Point3f(0, 0, 1))
|
||||
return Similarityf().SetIdentity();
|
||||
|
||||
Point3f axis = Point3f(0, 0, 1)^result; /* Axis of rotation */
|
||||
axis.Normalize();
|
||||
Point3f d = result - Point3f(0, 0, 1);
|
||||
float t = d.Norm() / 2.0f;
|
||||
if(t > thr)
|
||||
t += (t - thr) * 0.7f;
|
||||
if (t > 1.0f) t = 1.0f;
|
||||
if (t < -1.0f) t = -1.0f;
|
||||
float phi = 2 * math::Asin(t);
|
||||
//return Similarityf().SetRotate(phi * 180/(float)M_PI, axis);
|
||||
return Similarityf().SetRotate(phi, axis);
|
||||
}
|
||||
|
||||
Similarityf PlaneMode::Apply(const Point3f &p, const Similarityf &a) {
|
||||
return Similarityf(Point3f(p[0], p[1], 0));
|
||||
Point3f r = x * a;
|
||||
Point3f u = y * a;
|
||||
int leading = 0; //leadiing x.
|
||||
if(fabs(u[2]) < fabs(r[2])) //sceglie l'asse principale: quello che piu' e' parallelo al piano di vista.
|
||||
leading = 1;
|
||||
r[2] = 0;
|
||||
u[2] = 0;
|
||||
if(r == Point3f(0,0,0)) //casi degeneri: un asse e' perpendicolare al piano di vista.
|
||||
r = Point3f(0, 1, 0);
|
||||
if(u == Point3f(0,0,0))
|
||||
u = Point3f(0, 1, 0);
|
||||
r.Normalize();
|
||||
u.Normalize();
|
||||
float cu, cr;
|
||||
if(leading == 0) { //leading x
|
||||
if(u == r || u == -r) { //caso degenere: i due assi si proiettano sullo stesso
|
||||
u[0] = -r[1];
|
||||
u[1] = r[0];
|
||||
}
|
||||
u = u - r * (r * u);
|
||||
u.Normalize();
|
||||
} else {
|
||||
if(r == u || r == -u) { //caso degenere: i due assi si proiettano sullo stesso
|
||||
r[0] = -u[1];
|
||||
r[1] = u[0];
|
||||
}
|
||||
r = r - u * (u * r);
|
||||
r.Normalize();
|
||||
}
|
||||
cr = r * p;
|
||||
cu = u * p;
|
||||
return Similarityf(x * cr + y * cu);
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef TRACKMODE_H
|
||||
#define TRACKMODE_H
|
||||
|
||||
#include <vcg/space/point3.h>
|
||||
#include <vcg/math/similarity.h>
|
||||
|
||||
namespace vcg {
|
||||
|
||||
class TrackMode {
|
||||
public:
|
||||
virtual ~TrackMode() {}
|
||||
virtual void Draw() {}
|
||||
virtual Similarityf Apply(const Point3f &p, const Similarityf &a) { return Similarityf().SetIdentity(); }
|
||||
};
|
||||
|
||||
class SphereMode: public TrackMode {
|
||||
public:
|
||||
Similarityf Apply(const Point3f &p, const Similarityf &a);
|
||||
};
|
||||
|
||||
class GravityMode: public TrackMode {
|
||||
public:
|
||||
};
|
||||
|
||||
class CylinderMode: public TrackMode {
|
||||
public:
|
||||
CylinderMode(const Point3f _axis): axis(_axis) { axis.Normalize(); }
|
||||
protected:
|
||||
Point3f axis;
|
||||
};
|
||||
|
||||
class PlaneMode: public TrackMode {
|
||||
public:
|
||||
PlaneMode(const Point3f _x, const Point3f _y): x(_x), y(_y) { x.Normalize(); y.Normalize(); }
|
||||
Similarityf Apply(const Point3f &p, const Similarityf &a);
|
||||
protected:
|
||||
Point3f x;
|
||||
Point3f y;
|
||||
};
|
||||
|
||||
class LineMode: public TrackMode {
|
||||
public:
|
||||
LineMode(const Point3f _axis): axis(_axis) { axis.Normalize();}
|
||||
protected:
|
||||
Point3f axis;
|
||||
};
|
||||
|
||||
class ScaleMode: public TrackMode {
|
||||
public:
|
||||
};
|
||||
|
||||
}//namespace
|
||||
|
||||
#endif
|
|
@ -0,0 +1,108 @@
|
|||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
#include <vcg/space/point3.h>
|
||||
#include <vcg/math/Matrix44.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <GL/GL.h>
|
||||
|
||||
namespace vcg {
|
||||
|
||||
template <class T> class View {
|
||||
public:
|
||||
void GetView();
|
||||
void SetView();
|
||||
Point3<T> Project(const Point3<T> &p) const;
|
||||
Point3<T> UnProject(const Point3<T> &p) const;
|
||||
Point3<T> ViewPoint();
|
||||
//convert coordinates range 0-1 to range 0 viewport[2]
|
||||
Point3<T> ScreenToViewport(const Point3<T> &p) const;
|
||||
//viceversa
|
||||
Point3<T> ViewportToScreen(const Point3<T> &p) const;
|
||||
|
||||
Matrix44<T> proj;
|
||||
Matrix44<T> model;
|
||||
Matrix44<T> matrix;
|
||||
Matrix44<T> inverse;
|
||||
int viewport[4];
|
||||
};
|
||||
|
||||
template <class T> void View<T>::GetView() {
|
||||
double m[16];
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, m);
|
||||
for(int i = 0; i < 16; i++)
|
||||
proj[i] = (T)m[i];
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, m);
|
||||
for(int i = 0; i < 16; i++)
|
||||
model[i] = (T)m[i];
|
||||
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
|
||||
matrix = model * proj;
|
||||
inverse = matrix;
|
||||
Invert(inverse);
|
||||
}
|
||||
|
||||
template <class T> void View<T>::SetView() {
|
||||
|
||||
}
|
||||
|
||||
template <class T> Point3<T> View<T>::ViewPoint() {
|
||||
return inverse * Point3<T>(0, 0, 0);
|
||||
/*Matrix44d model(model_matrix);
|
||||
model.Invert();
|
||||
Point3d view = model * Point3d(0, 0, 0);
|
||||
return Point3<T>(view[0], view[1], view[2]); */
|
||||
}
|
||||
|
||||
template <class T> Point3<T> View<T>::Project(const Point3<T> &p) const {
|
||||
Point3<T> r;
|
||||
r = p * matrix;
|
||||
r[0] = (r[0]+1)*(viewport[2]/(T)2.0)+viewport[0];
|
||||
r[1] =(r[1]+1)*(viewport[3]/(T)2.0)+viewport[1];
|
||||
r[1] = viewport[3]-r[1];
|
||||
return r;
|
||||
/*double r[3];
|
||||
gluProject(p[0], p[1], p[2], model_matrix, proj_matrix, viewport, &r[0], &r[1], &r[2]);
|
||||
return Point3<T>((T)r[0], (T)r[1], (T)r[2]);*/
|
||||
}
|
||||
|
||||
template <class T> Point3<T> View<T>::UnProject(const Point3<T> &p) const {
|
||||
Point3<T> s = p;
|
||||
s[0] = (p[0]- viewport[0])/ (viewport[2]/(T)2.0) - 1;
|
||||
s[1] = (p[1]- viewport[1])/ (viewport[3]/(T)2.0) - 1;
|
||||
s[1] = -s[1];
|
||||
s[2] = p[2];
|
||||
//s[1] = -s[1]; // pezza aggiunta per il tan2.... ?????????????
|
||||
|
||||
s = s * inverse;
|
||||
return s;
|
||||
/*double r[3];
|
||||
gluUnProject(p[0], p[1], p[2], model_matrix, proj_matrix, viewport, &r[0], &r[1], &r[2]);
|
||||
return Point3<T>((T)r[0], (T)r[1], (T)r[2]);*/
|
||||
}
|
||||
|
||||
template <class T> Point3<T> View<T>::ScreenToViewport(const Point3<T> &p) const {
|
||||
Point3<T> a;
|
||||
a[0] = (p[0]+1)*(viewport[2]/(T)2.0)+viewport[0];
|
||||
a[1] =(p[1]+1)*(viewport[3]/(T)2.0)+viewport[1];
|
||||
a[1] = viewport[3] - a[1];
|
||||
a[2] = p[2];
|
||||
return a;
|
||||
}
|
||||
//viceversa
|
||||
template <class T> Point3<T> View<T>::ViewportToScreen(const Point3<T> &p) const {
|
||||
Point3<T> a;
|
||||
a[0] = (p[0]- viewport[0])/ (viewport[2]/(T)2.0) - 1;
|
||||
a[1] = (p[1]- viewport[1])/ (viewport[3]/(T)2.0) - 1;
|
||||
a[1] = -a[1];
|
||||
a[2] = p[2];
|
||||
//a[1] = -a[1]; // pezza aggiunta per il tan2.... ?????????????
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
}//namespace
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue