Go to the documentation of this file.00001 #ifndef OPENTISSUE_UTILITY_TRACKBALL_SHOEMAKE_H
00002 #define OPENTISSUE_UTILITY_TRACKBALL_SHOEMAKE_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
00022 template<typename real_type_ = double>
00023 class Shoemake : public GenericTrackball<real_type_>
00024 {
00025 public:
00026
00027 typedef GenericTrackball<real_type_> base_type;
00028 typedef typename base_type::real_type real_type;
00029 typedef typename base_type::vector3_type vector3_type;
00030 typedef typename base_type::matrix3x3_type matrix3x3_type;
00031 typedef typename base_type::quaternion_type quaternion_type;
00032 typedef typename base_type::gl_transform_type gl_transform_type;
00033
00034 public:
00035
00036 Shoemake()
00037 : base_type()
00038 {
00039 reset();
00040 }
00041
00042 Shoemake(real_type const & radius)
00043 : base_type(radius)
00044 {
00045 reset();
00046 }
00047
00048 void reset()
00049 {
00050 base_type::reset();
00051 project_onto_surface(this->m_anchor_position);
00052 project_onto_surface(this->m_current_position);
00053 }
00054
00055 void begin_drag(real_type const & x, real_type const & y)
00056 {
00057 this->m_angle = 0.0;
00058 this->m_axis.clear();
00059
00060 this->m_xform_anchor = this->m_xform_current;
00061 this->m_xform_incremental = diag(1.0);
00062 this->m_xform_current = diag(1.0);
00063
00064 this->m_anchor_position = vector3_type(x,y,0);
00065 project_onto_surface(this->m_anchor_position);
00066 this->m_current_position = vector3_type(x,y,0);
00067 project_onto_surface(this->m_current_position);
00068 }
00069
00070 void drag(real_type const & x, real_type const & y)
00071 {
00072 this->m_current_position = vector3_type(x,y,0);
00073 project_onto_surface(this->m_current_position);
00074 compute_incremental(this->m_anchor_position,this->m_current_position,this->m_xform_incremental);
00075 }
00076
00077 void end_drag(real_type const & x, real_type const & y)
00078 {
00079 this->m_current_position = vector3_type(x,y,0);
00080 project_onto_surface(this->m_current_position);
00081 compute_incremental(this->m_anchor_position,this->m_current_position,this->m_xform_incremental);
00082 }
00083
00084 private:
00085
00086 void project_onto_surface(vector3_type & P)
00087 {
00088 using std::sqrt;
00089 const static real_type radius2 = this->m_radius * this->m_radius;
00090 real_type length2 = P(0)*P(0) + P(1)*P(1);
00091
00092 if (length2 <= radius2)
00093 P(2) = sqrt(radius2 - length2);
00094 else
00095 {
00096 P(0) *= this->m_radius / sqrt(length2);
00097 P(1) *= this->m_radius / sqrt(length2);
00098 P(2) = 0;
00099 }
00100 }
00101
00102 void compute_incremental(vector3_type const & anchor, vector3_type const & current, matrix3x3_type & transform)
00103 {
00104 quaternion_type Q_anchor ( 0, unit(anchor) );
00105 quaternion_type Q_current( 0, unit(current) );
00106 quaternion_type Q_rot = -prod(Q_current,Q_anchor);
00107 this->m_axis = Q_rot.v();
00108 this->m_angle = atan2(length(this->m_axis), Q_rot.s());
00109 transform = Q_rot;
00110
00111 }
00112 };
00113
00114 }
00115 }
00116 }
00117
00118
00119 #endif