00001 #include "vuSimpleTypes.h"
00002 #include <math.h>
00003 #include "vuMatrix.h"
00004 #include "vuVector.h"
00005 #include "vuArcBall.h"
00006
00008 vuArcBall::vuArcBall()
00009 {
00010 m_Camera = 0;
00011 }
00012
00014 void vuArcBall::attachCamera(vuCamera & camera)
00015 {
00016 m_Camera = &camera;
00017 }
00018
00020
00023 void vuArcBall::setWinSize(int maxX, int maxY)
00024 {
00025 m_Winx = maxX;
00026 m_Winy = maxY;
00027 }
00028
00030 void vuArcBall::setCenter(vuVector & center)
00031 {
00032 m_Center = center;
00033 }
00034
00035
00036
00037
00038 vuVector vuArcBall::spherePoint(int px,int py)
00039 {
00040 double d,t,screenmin;
00041 vuVector v;
00042 if(m_Winx>m_Winy)
00043 screenmin=m_Winy;
00044 else
00045 screenmin=m_Winx;
00046 if(screenmin<=0.0) return vuVector(0,0,0);
00047
00048 v[0]=(float)(2.0*(px-0.5*m_Winx)/screenmin);
00049 v[1]=(float)(2.0*(0.5*m_Winy-py)/screenmin);
00050 d=v[0]*v[0]+v[1]*v[1];
00051 if(d<0.75){
00052 v[2]=(float)sqrt(1.0-d);
00053 }
00054 else if(d<3.0){
00055 d=1.7320508008-sqrt(d);
00056 t=1.0-d*d;
00057 if(t<0.0) t=0.0;
00058 v[2]=(float)(1.0-sqrt(t));
00059 }
00060 else{
00061 v[2]=0.0;
00062 }
00063 return v.makeUnit();
00064 }
00065
00066
00067 void vuArcBall::turn(int ox,int oy,int nx,int ny)
00068 {
00069 if(m_Camera == 0 || (nx==ox && ny==oy) ) return;
00070 vuVector oldsp,newsp;
00071 oldsp=spherePoint(ox,oy);
00072 newsp=spherePoint(nx,ny);
00073 float ac = newsp.dot(oldsp);
00074 float phi = acos(ac)*M_1_PI*180;
00075 vuVector axis = (oldsp.cross(newsp)).mul(vuVector(-1,-1,1));
00076
00077 if(axis.norm2()<0.00001) return;
00078
00079
00080 vuMatrix cam = m_Camera->getViewMat();
00081 axis = cam*axis;
00082 axis.makeUnit();
00083 vuMatrix m;
00084 m.makeRotate(axis, phi);
00085
00086 m_Camera->transform(m);
00087 }
00088