264 lines
8.2 KiB
C++
264 lines
8.2 KiB
C++
/****************************************************************************
|
|
* VCGLib o o *
|
|
* Visual and Computer Graphics Library o o *
|
|
* _ O _ *
|
|
* Copyright(C) 2004 \/)\/ *
|
|
* Visual Computing Lab /\/| *
|
|
* ISTI - Italian National Research Council | *
|
|
* \ *
|
|
* All rights reserved. *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
|
* for more details. *
|
|
* *
|
|
****************************************************************************/
|
|
/****************************************************************************
|
|
History
|
|
|
|
$Log: not supported by cvs2svn $
|
|
Revision 1.3 2004/03/31 15:08:03 ponchio
|
|
Fixed current_action initialization.
|
|
|
|
Revision 1.2 2004/03/25 14:55:25 ponchio
|
|
Adding copyright.
|
|
|
|
|
|
****************************************************************************/
|
|
|
|
#include "trackball.h"
|
|
#include <wrap/gl/math.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);
|
|
SetCurrentAction();
|
|
}
|
|
|
|
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.1f));
|
|
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() {
|
|
Matrix44f a = track.Matrix();
|
|
//Transpose(a);
|
|
glMultMatrix(a);
|
|
//glMultMatrix(track.Matrix());
|
|
//glMultMatrix(track);
|
|
}
|
|
|
|
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(float(x), float(y), 0)) - origin;
|
|
Point3f old_point = camera.ViewportToScreen(Point3f(float(last_x), float(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;
|
|
}
|
|
|
|
|