Menu

Diff of /arcball.cpp [000000] .. [r69]  Maximize  Restore

Switch to side-by-side view

--- a
+++ b/arcball.cpp
@@ -0,0 +1,131 @@
+/** KempoApi: The Turloc Toolkit *****************************/
+/** *    *                                                  **/
+/** **  **  Filename: ArcBall.cpp                           **/
+/**   **    Version:  Common                                **/
+/**   **                                                    **/
+/**                                                         **/
+/**  Arcball class for mouse manipulation.                  **/
+/**                                                         **/
+/**                                                         **/
+/**                                                         **/
+/**                                                         **/
+/**                              (C) 1999-2003 Tatewake.com **/
+/**   History:                                              **/
+/**   08/17/2003 - (TJG) - Creation                         **/
+/**   09/23/2003 - (TJG) - Bug fix and optimization         **/
+/**   09/25/2003 - (TJG) - Version for NeHe Basecode users  **/
+/**                                                         **/
+/*************************************************************/
+#include "stdafx.h"
+
+//#include <windows.h>	
+//#include "wx/glcanvas.h"// Header File For Windows
+#include <GL/gl.h>
+#include <GL/glu.h>
+//#include <GL/glaux.h>
+// Header File For The GLaux Library
+
+#include "math.h"                                               // Needed for sqrtf
+
+#include "arcball.h"                                            // ArcBall header
+
+//Arcball sphere constants:
+//Diameter is       2.0f
+//Radius is         1.0f
+//Radius squared is 1.0f
+
+void ArcBall_t::_mapToSphere(const Point2fT* NewPt, Vector3fT* NewVec) const
+{
+    Point2fT TempPt;
+    GLfloat length;
+
+    //Copy paramter into temp point
+    TempPt = *NewPt;
+
+    //Adjust point coords and scale down to range of [-1 ... 1]
+    TempPt.s.X  =        (TempPt.s.X * this->AdjustWidth)  - 1.0f;
+    TempPt.s.Y  = 1.0f - (TempPt.s.Y * this->AdjustHeight);
+
+    //Compute the square of the length of the vector to the point from the center
+    length      = (TempPt.s.X * TempPt.s.X) + (TempPt.s.Y * TempPt.s.Y);
+
+    //If the point is mapped outside of the sphere... (length > radius squared)
+    if (length > 1.0f)
+    {
+        GLfloat norm;
+
+        //Compute a normalizing factor (radius / sqrt(length))
+        norm    = 1.0f / FuncSqrt(length);
+
+        //Return the "normalized" vector, a point on the sphere
+        NewVec->s.X = TempPt.s.X * norm;
+        NewVec->s.Y = TempPt.s.Y * norm;
+        NewVec->s.Z = 0.0f;
+    }
+    else    //Else it's on the inside
+    {
+        //Return a vector to a point mapped inside the sphere sqrt(radius squared - length)
+        NewVec->s.X = TempPt.s.X;
+        NewVec->s.Y = TempPt.s.Y;
+        NewVec->s.Z = FuncSqrt(1.0f - length);
+    }
+}
+
+//Create/Destroy
+ArcBall_t::ArcBall_t(GLfloat NewWidth, GLfloat NewHeight)
+{
+    //Clear initial values
+    this->StVec.s.X     =
+    this->StVec.s.Y     = 
+    this->StVec.s.Z     = 
+
+    this->EnVec.s.X     =
+    this->EnVec.s.Y     = 
+    this->EnVec.s.Z     = 0.0f;
+
+    //Set initial bounds
+    this->setBounds(NewWidth, NewHeight);
+}
+
+//Mouse down
+void    ArcBall_t::click(const Point2fT* NewPt)
+{
+    //Map the point to the sphere
+    this->_mapToSphere(NewPt, &this->StVec);
+}
+
+//Mouse drag, calculate rotation
+void    ArcBall_t::drag(const Point2fT* NewPt, Quat4fT* NewRot)
+{
+    //Map the point to the sphere
+    this->_mapToSphere(NewPt, &this->EnVec);
+
+    //Return the quaternion equivalent to the rotation
+    if (NewRot)
+    {
+        Vector3fT  Perp;
+
+        //Compute the vector perpendicular to the begin and end vectors
+        Vector3fCross(&Perp, &this->StVec, &this->EnVec);
+
+        //Compute the length of the perpendicular vector
+        if (Vector3fLength(&Perp) > Epsilon)    //if its non-zero
+        {
+            //We're ok, so return the perpendicular vector as the transform after all
+            NewRot->s.X = Perp.s.X;
+            NewRot->s.Y = Perp.s.Y;
+            NewRot->s.Z = Perp.s.Z;
+            //In the quaternion values, w is cosine (theta / 2), where theta is rotation angle
+            NewRot->s.W= Vector3fDot(&this->StVec, &this->EnVec);
+        }
+        else                                    //if its zero
+        {
+            //The begin and end vectors coincide, so return an identity transform
+            NewRot->s.X = 
+            NewRot->s.Y = 
+            NewRot->s.Z = 
+            NewRot->s.W = 0.0f;
+        }
+    }
+}
+