00001 #ifndef OPENTISSUE_UTILITY_TRACKBALL_GENERIC_TRACKBALL_H 00002 #define OPENTISSUE_UTILITY_TRACKBALL_GENERIC_TRACKBALL_H 00003 // 00004 // OpenTissue Template Library 00005 // - A generic toolbox for physics-based modeling and simulation. 00006 // Copyright (C) 2008 Department of Computer Science, University of Copenhagen. 00007 // 00008 // OTTL is licensed under zlib: http://opensource.org/licenses/zlib-license.php 00009 // 00010 #include <OpenTissue/configuration.h> 00011 00012 #include <OpenTissue/core/math/math_vector3.h> 00013 #include <OpenTissue/core/math/math_matrix3x3.h> 00014 #include <OpenTissue/core/math/math_quaternion.h> 00015 00016 00017 namespace OpenTissue 00018 { 00019 namespace utility 00020 { 00021 namespace trackball 00022 { 00023 00024 template<typename real_type_ = double> 00025 class GenericTrackball 00026 { 00027 public: 00028 00029 typedef real_type_ real_type; 00030 typedef math::Vector3<real_type> vector3_type; 00031 typedef math::Matrix3x3<real_type> matrix3x3_type; 00032 typedef math::Quaternion<real_type> quaternion_type; 00033 typedef real_type gl_transform_type[16]; 00034 00035 protected: 00036 00037 real_type m_radius; 00038 vector3_type m_anchor_position; 00039 vector3_type m_current_position; 00040 real_type m_angle; 00041 vector3_type m_axis; 00042 matrix3x3_type m_xform_anchor; 00043 matrix3x3_type m_xform_incremental; 00044 matrix3x3_type m_xform_current; 00045 gl_transform_type m_gl_xform_current; 00046 00047 public: 00048 00049 real_type & radius() { return m_radius; } 00050 real_type const & radius() const { return m_radius; } 00051 vector3_type & anchor() { m_anchor_position = unit(m_anchor_position); return m_anchor_position; } 00052 vector3_type const & anchor() const { m_anchor_position = unit(m_anchor_position); return m_anchor_position; } 00053 vector3_type & current() { m_current_position = unit(m_current_position); return m_current_position; } 00054 vector3_type const & current() const { m_current_position = unit(m_current_position); return m_current_position; } 00055 real_type & angle() { return m_angle; } 00056 real_type const & angle() const { return m_angle; } 00057 vector3_type & axis() { m_axis = unit(m_axis); return m_axis; } 00058 vector3_type const & axis() const { m_axis = unit(m_axis); return m_axis; } 00059 00060 matrix3x3_type const & get_current_rotation() 00061 { 00062 // Compute the the rotation from Panchor to Pcurrent, i.e. 00063 // the rotation form (Xanchor, Yanchor, Zanchor) to 00064 // (Xcurrent, Ycurrent, Zcurrent) along a great circle. 00065 // Multiply the IncrementalTransformation and the AnchorTransformation 00066 // to get the CurrentTransformation. 00067 m_xform_current = m_xform_incremental * m_xform_anchor; 00068 return m_xform_current; 00069 } 00070 00071 gl_transform_type const & get_gl_current_rotation() 00072 { 00073 // Compute the the rotation from Panchor to Pcurrent, i.e. 00074 // the rotation form (Xanchor, Yanchor, Zanchor) to 00075 // (Xcurrent, Ycurrent, Zcurrent) along a great circle. 00076 // Multiply the IncrementalTransformation and the AnchorTransformation 00077 // to get the CurrentTransformation. 00078 m_xform_current = m_xform_incremental * m_xform_anchor; 00079 00080 m_gl_xform_current[ 0 ] = m_xform_current[ 0 ][ 0 ]; 00081 m_gl_xform_current[ 1 ] = m_xform_current[ 1 ][ 0 ]; 00082 m_gl_xform_current[ 2 ] = m_xform_current[ 2 ][ 0 ]; 00083 m_gl_xform_current[ 3 ] = 0; 00084 m_gl_xform_current[ 4 ] = m_xform_current[ 0 ][ 1 ]; 00085 m_gl_xform_current[ 5 ] = m_xform_current[ 1 ][ 1 ]; 00086 m_gl_xform_current[ 6 ] = m_xform_current[ 2 ][ 1 ]; 00087 m_gl_xform_current[ 7 ] = 0; 00088 m_gl_xform_current[ 8 ] = m_xform_current[ 0 ][ 2 ]; 00089 m_gl_xform_current[ 9 ] = m_xform_current[ 1 ][ 2 ]; 00090 m_gl_xform_current[ 10 ] = m_xform_current[ 2 ][ 2 ]; 00091 m_gl_xform_current[ 11 ] = 0; 00092 m_gl_xform_current[ 12 ] = 0; 00093 m_gl_xform_current[ 13 ] = 0; 00094 m_gl_xform_current[ 14 ] = 0; 00095 m_gl_xform_current[ 15 ] = 1; 00096 00097 return m_gl_xform_current; 00098 } 00099 00100 matrix3x3_type const & get_incremental_rotation() const { return m_xform_incremental; } 00101 00102 public: 00103 00104 GenericTrackball() 00105 : m_radius(1.0) 00106 {} 00107 00108 GenericTrackball(real_type radius) 00109 : m_radius(radius) 00110 {} 00111 00112 virtual ~GenericTrackball(){} 00113 00114 virtual void reset() 00115 { 00116 m_anchor_position.clear(); 00117 m_current_position.clear(); 00118 m_axis.clear(); 00119 m_angle = real_type(0.0); 00120 m_xform_anchor = math::diag<real_type>(1.0); 00121 m_xform_incremental = math::diag<real_type>(1.0); 00122 m_xform_current = math::diag<real_type>(1.0); 00123 } 00124 00125 public: 00126 00127 virtual void begin_drag (real_type const & x, real_type const & y) = 0; 00128 virtual void drag (real_type const & x, real_type const & y) = 0; 00129 virtual void end_drag (real_type const & x, real_type const & y) = 0; 00130 00131 private: 00132 00133 virtual void compute_incremental(vector3_type const & anchor, vector3_type const & current, matrix3x3_type & transform) = 0; 00134 00135 }; 00136 00137 } // namespace trackball 00138 } // namespace utility 00139 } // namespace OpenTissue 00140 00141 // OPENTISSUE_UTILITY_TRACKBALL_GENERIC_TRACKBALL_H 00142 #endif