Main Page | Class Hierarchy | Class List | Directories | File List | Class Members

ArcBall.cpp

00001 
00018 /*************************************************************/
00019 
00020 #include <windows.h>                                                                                    // Header File For Windows
00021 #include <gl\gl.h>                                                                                              // Header File For The OpenGL32 Library
00022 #include <gl\glu.h>                                                                                             // Header File For The GLu32 Library
00023 #include <gl\glaux.h>                                                                                   // Header File For The GLaux Library
00024 
00025 #include "math.h"                                               // Needed for sqrtf
00026 
00027 #include "ArcBall.h"                                            // ArcBall header
00028 
00029 //Arcball sphere constants:
00030 //Diameter is       2.0f
00031 //Radius is         1.0f
00032 //Radius squared is 1.0f
00033 
00034 void ArcBall_t::_mapToSphere(const Point2fT* NewPt, Vector3fT* NewVec) const
00035 {
00036     Point2fT TempPt;
00037     GLfloat length;
00038 
00039     //Copy paramter into temp point
00040     TempPt = *NewPt;
00041 
00042     //Adjust point coords and scale down to range of [-1 ... 1]
00043     TempPt.s.X  =        (TempPt.s.X * this->AdjustWidth)  - 1.0f;
00044     TempPt.s.Y  = 1.0f - (TempPt.s.Y * this->AdjustHeight);
00045 
00046     //Compute the square of the length of the vector to the point from the center
00047     length      = (TempPt.s.X * TempPt.s.X) + (TempPt.s.Y * TempPt.s.Y);
00048 
00049     //If the point is mapped outside of the sphere... (length > radius squared)
00050     if (length > 1.0f)
00051     {
00052         GLfloat norm;
00053 
00054         //Compute a normalizing factor (radius / sqrt(length))
00055         norm    = 1.0f / FuncSqrt(length);
00056 
00057         //Return the "normalized" vector, a point on the sphere
00058         NewVec->s.X = TempPt.s.X * norm;
00059         NewVec->s.Y = TempPt.s.Y * norm;
00060         NewVec->s.Z = 0.0f;
00061     }
00062     else    //Else it's on the inside
00063     {
00064         //Return a vector to a point mapped inside the sphere sqrt(radius squared - length)
00065         NewVec->s.X = TempPt.s.X;
00066         NewVec->s.Y = TempPt.s.Y;
00067         NewVec->s.Z = FuncSqrt(1.0f - length);
00068     }
00069 }
00070 
00071 //Create/Destroy
00072 ArcBall_t::ArcBall_t(GLfloat NewWidth, GLfloat NewHeight)
00073 {
00074     //Clear initial values
00075     this->StVec.s.X     =
00076     this->StVec.s.Y     = 
00077     this->StVec.s.Z     = 
00078 
00079     this->EnVec.s.X     =
00080     this->EnVec.s.Y     = 
00081     this->EnVec.s.Z     = 0.0f;
00082 
00083     //Set initial bounds
00084     this->setBounds(NewWidth, NewHeight);
00085 }
00086 
00087 //Mouse down
00088 void    ArcBall_t::click(const Point2fT* NewPt)
00089 {
00090     //Map the point to the sphere
00091     this->_mapToSphere(NewPt, &this->StVec);
00092 }
00093 
00094 //Mouse drag, calculate rotation
00095 void    ArcBall_t::drag(const Point2fT* NewPt, Quat4fT* NewRot)
00096 {
00097     //Map the point to the sphere
00098     this->_mapToSphere(NewPt, &this->EnVec);
00099 
00100     //Return the quaternion equivalent to the rotation
00101     if (NewRot)
00102     {
00103         Vector3fT  Perp;
00104 
00105         //Compute the vector perpendicular to the begin and end vectors
00106         Vector3fCross(&Perp, &this->StVec, &this->EnVec);
00107 
00108         //Compute the length of the perpendicular vector
00109         if (Vector3fLength(&Perp) > Epsilon)    //if its non-zero
00110         {
00111             //We're ok, so return the perpendicular vector as the transform after all
00112             NewRot->s.X = Perp.s.X;
00113             NewRot->s.Y = Perp.s.Y;
00114             NewRot->s.Z = Perp.s.Z;
00115             //In the quaternion values, w is cosine (theta / 2), where theta is rotation angle
00116             NewRot->s.W= Vector3fDot(&this->StVec, &this->EnVec);
00117         }
00118         else                                    //if its zero
00119         {
00120             //The begin and end vectors coincide, so return an identity transform
00121             NewRot->s.X = 
00122             NewRot->s.Y = 
00123             NewRot->s.Z = 
00124             NewRot->s.W = 0.0f;
00125         }
00126     }
00127 }
00128 

Generated on Mon Dec 12 15:20:26 2005 for CCube by  doxygen 1.4.1