00001 #ifndef OPENTISSUE_UTILITY_GL_GL_DRAW_BONE_H
00002 #define OPENTISSUE_UTILITY_GL_GL_DRAW_BONE_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/utility/gl/gl_util.h>
00013 #include <OpenTissue/core/math/math_constants.h>
00014
00015 #include <cassert>
00016
00017
00018 namespace OpenTissue
00019 {
00020
00021 namespace gl
00022 {
00023
00030 template<typename bone_type>
00031 inline void DrawBone(bone_type const & bone)
00032 {
00033 glPushMatrix();
00034 if(!bone.is_root())
00035 {
00036 Transform(bone.parent()->absolute());
00037 }
00038
00039
00040
00041 DrawVector(bone.relative().T());
00042 DrawFrame(bone.relative());
00043 glPopMatrix();
00044 }
00045
00059 template<typename bone_type>
00060 inline void DrawFancyBone(bone_type const & bone)
00061 {
00062 using std::sqrt;
00063 using std::acos;
00064 using std::cos;
00065 using std::sin;
00066
00067 typedef typename bone_type::math_types math_types;
00068 typedef typename math_types::real_type real_type;
00069 typedef typename math_types::vector3_type vector3_type;
00070 typedef typename math_types::quaternion_type quaternion_type;
00071 typedef typename math_types::value_traits value_traits;
00072
00073
00074 vector3_type const & T = bone.relative().T();
00075 quaternion_type Q;
00076 Q = bone.relative().Q();
00077 real_type length = sqrt( dot(T,T) );
00078 real_type radius = 0.075 * length;
00079
00080 glPushMatrix();
00081 if(!bone.is_root())
00082 {
00083 Transform(bone.convert(bone.parent()->absolute()));
00084 }
00085
00086 {
00087 glPushMatrix();
00088 Transform(T,Q);
00089 int const N = 24;
00090 real_type delta_theta = 2*value_traits::pi()/N;
00091
00092 real_type theta = 0;
00093
00094 ColorPicker(1,0,0,1);
00095 glBegin(GL_LINE_LOOP);
00096 for(int i=0;i<N;++i)
00097 {
00098 glNormal3f(1,0,0);
00099 glVertex3f( 0, radius*cos(theta),radius*sin(theta));
00100 theta += delta_theta;
00101 }
00102 glEnd();
00103 theta = 0;
00104 ColorPicker(0,1,0,1);
00105 glBegin(GL_LINE_LOOP);
00106 for(int i=0;i<N;++i)
00107 {
00108 glNormal3f(0,1,0);
00109 glVertex3f( radius*cos(theta),0,radius*sin(theta));
00110 theta += delta_theta;
00111 }
00112 glEnd();
00113 theta = 0;
00114 ColorPicker(0,0,1,1);
00115 glBegin(GL_LINE_LOOP);
00116 for(int i=0;i<N;++i)
00117 {
00118 glNormal3f(0,1,0);
00119 glVertex3f( radius*cos(theta), radius*sin(theta), 0);
00120 theta += delta_theta;
00121 }
00122 glEnd();
00123 glPopMatrix();
00124 }
00125 {
00126 if(!bone.is_root())
00127 {
00128 GLfloat angle = 0;
00129 GLfloat x = 1;
00130 GLfloat y = 0;
00131 GLfloat z = 0;
00132
00133 if ( ( T(0) == 0 ) && ( T(1) == 0 ) )
00134 {
00135 if ( T(2) > 0 )
00136 {
00137 angle = 0;
00138 }
00139 else
00140 {
00141 angle = 180;
00142 }
00143 }
00144 else
00145 {
00146 vector3_type v_unit;
00147 vector3_type axis;
00148
00149 v_unit = unit( T );
00150 axis = unit( cross( T, vector3_type(0,0,1 ) ) );
00151 angle = acos( dot(v_unit , vector3_type(0,0,1 ) ) );
00152 angle = -180.0 * angle / value_traits::pi();
00153 x = axis(0);
00154 y = axis(1);
00155 z = axis(2);
00156 }
00157
00158 glPushMatrix();
00159 glRotatef( angle, x, y, z );
00160 glRotatef( 45, 0, 0, 1 );
00161
00162 real_type base = radius / 2.0;
00163
00164 ColorPicker(0,0,.5,1);
00165 glBegin(GL_LINE_LOOP);
00166 glNormal3f(0,0,-1);
00167 glVertex3f( -base, -base, radius);
00168 glNormal3f(0,0,-1);
00169 glVertex3f( -base, base, radius);
00170 glNormal3f(0,0,-1);
00171 glVertex3f( base, base, radius);
00172 glNormal3f(0,0,-1);
00173 glVertex3f( base, -base, radius);
00174 glEnd();
00175
00176 glBegin(GL_LINE_LOOP);
00177 glNormal3f(0,-1,0);
00178 glVertex3f( -base, -base, radius);
00179 glNormal3f(0,-1,0);
00180 glVertex3f( base, -base, radius);
00181 glNormal3f(0,-1,0);
00182 glVertex3f( 0, 0, length-radius);
00183 glEnd();
00184
00185 glBegin(GL_LINE_LOOP);
00186 glNormal3f(1,0,0);
00187 glVertex3f( base, -base, radius);
00188 glNormal3f(1,0,0);
00189 glVertex3f( base, base, radius);
00190 glNormal3f(1,0,0);
00191 glVertex3f( 0, 0, length-radius);
00192 glEnd();
00193
00194 glBegin(GL_LINE_LOOP);
00195 glNormal3f(0,1,0);
00196 glVertex3f( base, base, radius);
00197 glNormal3f(0,1,0);
00198 glVertex3f( -base, base, radius);
00199 glNormal3f(0,1,0);
00200 glVertex3f( 0, 0, length-radius);
00201 glEnd();
00202
00203 glBegin(GL_LINE_LOOP);
00204 glNormal3f(-1,0,0);
00205 glVertex3f( -base, base, radius);
00206 glNormal3f(-1,0,0);
00207 glVertex3f( -base, -base, radius);
00208 glNormal3f(-1,0,0);
00209 glVertex3f( 0,0, length-radius);
00210 glEnd();
00211
00212 glPopMatrix();
00213
00214 }
00215 }
00216
00217 glPopMatrix();
00218 }
00219
00226 template<typename bone_type>
00227 inline void DrawStickBone(bone_type const & bone ,float red = 0.7,float green = 0.7,float blue = 0.7)
00228 {
00229 ColorPicker(red,green,blue,1.0);
00230 glPushMatrix();
00231 if(!bone.is_root())
00232 {
00233 Transform(bone.parent()->absolute());
00234 }
00235 DrawVector(bone.relative().T());
00236
00237 glPopMatrix();
00238 }
00239
00246 template<typename bone_type,typename capsule_type >
00247 inline void DrawFatBone(bone_type const & bone ,capsule_type capsule,float red = 0.7,float green = 0.7,float blue = 0.7,float thickness = 0.2)
00248 {
00249 typedef typename bone_type::math_types math_types;
00250 typedef typename math_types::vector3_type V;
00251 typedef typename math_types::real_type T;
00252 typedef typename math_types::value_traits value_traits;
00253
00254 V const zero = V(value_traits::zero(), value_traits::zero(), value_traits::zero());
00255
00256 glPushMatrix();
00257 if(!bone.is_root())
00258 {
00259 Transform(bone.parent()->absolute());
00260 ColorPicker(red,green,blue,1.0);
00261
00262
00263 if(length(bone.relative().T()) < 0.001)
00264 thickness = 0.3;
00265
00266 capsule.set(zero, bone.relative().T(), thickness);
00267
00268 DrawCapsule(capsule);
00269
00270
00271 }
00272 glPopMatrix();
00273 }
00274
00275
00276 }
00277
00278 }
00279
00280
00281 #endif