Go to the documentation of this file.00001 #ifndef OPENTISSUE_UTILITY_TRACKBALL_TRACKBALL_H
00002 #define OPENTISSUE_UTILITY_TRACKBALL_TRACKBALL_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/utility/trackball/trackball_generic.h>
00013
00014 namespace OpenTissue
00015 {
00016 namespace utility
00017 {
00018 namespace trackball
00019 {
00020
00021 template<typename real_type_ = double>
00022 class Trackball : public GenericTrackball<real_type_>
00023 {
00024 public:
00025
00026 typedef GenericTrackball<real_type_> base_type;
00027 typedef typename base_type::real_type real_type;
00028 typedef typename base_type::vector3_type vector3_type;
00029 typedef typename base_type::matrix3x3_type matrix3x3_type;
00030 typedef typename base_type::quaternion_type quaternion_type;
00031 typedef typename base_type::gl_transform_type gl_transform_type;
00032
00033 public:
00034
00035 Trackball()
00036 : base_type()
00037 {
00038 reset();
00039 }
00040
00041 Trackball(real_type const & radius)
00042 : base_type(radius)
00043 {
00044 reset();
00045 }
00046
00047 void reset()
00048 {
00049 base_type::reset();
00050 project_onto_surface(this->m_anchor_position);
00051 project_onto_surface(this->m_current_position);
00052 }
00053
00054 void begin_drag(real_type const & x, real_type const & y)
00055 {
00056 this->m_angle = 0.0;
00057 this->m_axis.clear();
00058
00059 this->m_xform_anchor = this->m_xform_current;
00060 this->m_xform_incremental = math::diag<real_type>( 1.0 );
00061 this->m_xform_current = math::diag<real_type>( 1.0 );
00062
00063 this->m_anchor_position = vector3_type(x,y,0);
00064 project_onto_surface(this->m_anchor_position);
00065 this->m_current_position = vector3_type(x,y,0);
00066 project_onto_surface(this->m_current_position);
00067 }
00068
00069 void drag(real_type const & x, real_type const & y)
00070 {
00071 this->m_current_position = vector3_type(x,y,0);
00072 project_onto_surface(this->m_current_position);
00073 compute_incremental(this->m_anchor_position,this->m_current_position,this->m_xform_incremental);
00074 }
00075
00076 void end_drag(real_type const & x, real_type const & y)
00077 {
00078 this->m_current_position = vector3_type(x,y,0);
00079 project_onto_surface(this->m_current_position);
00080 compute_incremental(this->m_anchor_position,this->m_current_position,this->m_xform_incremental);
00081 }
00082
00083 private:
00084
00085 void project_onto_surface(vector3_type & P)
00086 {
00087 using std::sqrt;
00088 const static real_type radius2 = this->m_radius * this->m_radius;
00089 real_type length2 = P(0)*P(0) + P(1)*P(1);
00090 if (length2 <= radius2 / 2.0)
00091 P(2) = sqrt(radius2 - length2);
00092 else
00093 {
00094 P(2) = radius2 / (2.0 * sqrt(length2));
00095 real_type length = sqrt(length2 + P[2] * P[2]);
00096 P /= length;
00097 }
00098 P = unit(P);
00099 }
00100
00101 void compute_incremental(vector3_type const & anchor, vector3_type const & current, matrix3x3_type & transform)
00102 {
00103 vector3_type axis = anchor % current;
00104 this->m_axis = unit(axis);
00105 this->m_angle = atan2(length(axis), anchor * current );
00106 transform = Ru(this->m_angle,this->m_axis);
00107 }
00108
00109 };
00110 }
00111 }
00112 }
00113
00114
00115 #endif