|
World of Rigid Bodies (WoRB)
|
00001 /** 00002 * @file Utilities.cpp 00003 * @brief Implementation of the various GLUT utilites used 00004 * by the rigid body test-bed application. 00005 * @author Mikica Kocic 00006 * @version 0.5 00007 * @date 2012-05-08 00008 * @copyright GNU Public License. 00009 */ 00010 00011 #include "Utilities.h" 00012 00013 #include <cstdlib> // rand 00014 #include <cstdio> // vsprintf 00015 #include <cstdarg> // va_list 00016 #include <algorithm> // min/max 00017 00018 using namespace WoRB; 00019 00020 ///////////////////////////////////////////////////////////////////////////////////////// 00021 00022 // Gets a uniform real number in range [0,1) 00023 // 00024 double WoRB::RandomReal () 00025 { 00026 return double( rand() ) / RAND_MAX; 00027 }; 00028 00029 // Gets a quaternion with the given length but with random orientation. 00030 // 00031 Quaternion WoRB::RandomQuaternion( double length ) 00032 { 00033 return Quaternion( RandomReal (), RandomReal (), RandomReal (), RandomReal () ) 00034 .Normalize( length ); 00035 } 00036 00037 // Gets a random quaternion uniformly distributed in a 4D box 00038 // 00039 Quaternion WoRB::RandomQuaternion( const Quaternion& min, const Quaternion& max ) 00040 { 00041 return Quaternion( 00042 min.w + ( max.w - min.w ) * RandomReal (), 00043 min.x + ( max.x - min.x ) * RandomReal (), 00044 min.y + ( max.y - min.y ) * RandomReal (), 00045 min.z + ( max.z - min.z ) * RandomReal () 00046 ); 00047 } 00048 00049 ///////////////////////////////////////////////////////////////////////////////////////// 00050 00051 // Renders the given text to the given location in body-fixed space. 00052 // 00053 void WoRB::RenderText( double x, double y, double z, const char* text ) 00054 { 00055 void* font = GLUT_BITMAP_TIMES_ROMAN_10; 00056 00057 // Loop through characters displaying them. 00058 // 00059 glRasterPos3d( x, y, z ); 00060 for( const char* ch = text; *ch; ++ch ) 00061 { 00062 if ( *ch == '\n' ) { 00063 // If we meet a newline, then move down by the line-height 00064 y -= glutBitmapHeight( font ) * 1.2; 00065 glRasterPos3d( x, y, z ); 00066 } 00067 glutBitmapCharacter( font, *ch ); 00068 } 00069 } 00070 00071 ///////////////////////////////////////////////////////////////////////////////////////// 00072 00073 // Draws the geometry axes, angular velocity and angular momentum 00074 // 00075 void WoRB::RenderStateVariables( const RigidBody& body, const Quaternion& extent ) 00076 { 00077 double maxExtent = std::max( extent.x, std::max( extent.y, extent.z ) ) * 1.2; 00078 00079 Quaternion pos = body.Position; 00080 Quaternion w = body.AngularVelocity; 00081 Quaternion L = body.AngularMomentum; 00082 00083 glLineWidth( 2 ); 00084 00085 ///////////////////////////////////////////////////////////////////////////////////// 00086 // Display angular velocity 00087 00088 if ( w.ImSquaredNorm () > 1e-3 ) { 00089 w.Normalize( maxExtent ); 00090 glColor3d( 0, 0, 0 ); 00091 glBegin( GL_LINES ); 00092 glVertex3d( pos.x, pos.y, pos.z ); 00093 glVertex3d( pos.x + w.x, pos.y + w.y, pos.z + w.z ); 00094 glEnd (); 00095 00096 RenderText( pos.x + w.x, pos.y + w.y * 1.08, pos.z + w.z, "w" ); 00097 } 00098 00099 ///////////////////////////////////////////////////////////////////////////////////// 00100 // Display angular momentum 00101 00102 if ( L.ImSquaredNorm () > 1e-3 ) { 00103 L.Normalize( maxExtent ); 00104 glColor3d( 0.5, 0.5, 0.5 ); 00105 glBegin( GL_LINES ); 00106 glVertex3d( pos.x, pos.y, pos.z ); 00107 glVertex3d( pos.x + L.x, pos.y + L.y, pos.z + L.z ); 00108 glEnd (); 00109 00110 RenderText( pos.x + L.x, pos.y + L.y * 1.08, pos.z + L.z, "L" ); 00111 } 00112 00113 glLineWidth( 1 ); 00114 00115 GLTransform bodySpace( body ); 00116 00117 ///////////////////////////////////////////////////////////////////////////////////// 00118 // Display body's X-axis 00119 00120 glColor3d( 0.8, 0, 0 ); 00121 glBegin( GL_LINES ); 00122 glVertex3d( 0, 0, 0 ); 00123 glVertex3d( extent.x, 0, 0 ); 00124 glEnd (); 00125 RenderText( extent.x * 1.07, 0, 0, "X" ); 00126 00127 ///////////////////////////////////////////////////////////////////////////////////// 00128 // Display body's Y-axis 00129 00130 glColor3d( 0, 0.6, 0 ); 00131 glBegin( GL_LINES ); 00132 glVertex3d( 0, 0, 0 ); 00133 glVertex3d( 0, extent.y, 0 ); 00134 glEnd (); 00135 RenderText( 0, extent.y * 1.07, 0, "Y" ); 00136 00137 ///////////////////////////////////////////////////////////////////////////////////// 00138 // Display body's Z-axis 00139 00140 glColor3d( 0, 0, 0.8 ); 00141 glBegin( GL_LINES ); 00142 glVertex3d( 0, 0, 0 ); 00143 glVertex3d( 0, 0, extent.z ); 00144 glEnd (); 00145 RenderText( 0, 0, extent.z * 1.07, "Z" ); 00146 } 00147 00148 ///////////////////////////////////////////////////////////////////////////////////////// 00149 00150 // Draws the world axes 00151 // 00152 void WoRB::RenderAxes( double length ) 00153 { 00154 glLineWidth( 2 ); 00155 00156 ///////////////////////////////////////////////////////////////////////////////////// 00157 // Display X-axis for the world 00158 00159 glColor3d( 1, 0, 0 ); 00160 glBegin( GL_LINES ); 00161 glVertex3d( 0, 0, 0 ); 00162 glVertex3d( length, 0, 0 ); 00163 glEnd (); 00164 RenderText( length + 0.3, 0, 0, "X" ); 00165 00166 ///////////////////////////////////////////////////////////////////////////////////// 00167 // Display Y-axis for the world 00168 00169 glColor3d( 0, 0.8, 0 ); 00170 glBegin( GL_LINES ); 00171 glVertex3d( 0, 0, 0 ); 00172 glVertex3d( 0, length, 0 ); 00173 glEnd (); 00174 RenderText( 0, length + 0.3, 0, "Y" ); 00175 00176 ///////////////////////////////////////////////////////////////////////////////////// 00177 // Display Z-axis for the world 00178 00179 glColor3d( 0, 0, 1 ); 00180 glBegin( GL_LINES ); 00181 glVertex3d( 0, 0, 0 ); 00182 glVertex3d( 0, 0, length ); 00183 glEnd (); 00184 RenderText( 0, 0, length + 0.3, "Z" ); 00185 00186 glLineWidth( 1 ); 00187 } 00188 00189 ///////////////////////////////////////////////////////////////////////////////////////// 00190 00191 // Renders the given text to the given location in screen space on the window. 00192 // 00193 int WoRB::RenderPrintf( int x, int y, const char* format, ... ) 00194 { 00195 char buffer[ 2048 ]; 00196 va_list args; 00197 va_start( args, format ); 00198 00199 #ifdef _WIN32 00200 #pragma warning(disable:4996) 00201 #endif 00202 vsprintf( buffer, format, args ); 00203 00204 va_end( args ); 00205 00206 // Loop through characters displaying them. 00207 // 00208 void* font = GLUT_BITMAP_8_BY_13; // GLUT_BITMAP_HELVETICA_10 00209 glRasterPos2d( x, y ); 00210 for( const char* ch = buffer; *ch; ++ch ) 00211 { 00212 if ( *ch == '\n' ) { 00213 // Move down by the line-height on new-line 00214 y -= int( glutBitmapHeight( font ) * 1.2 ); 00215 glRasterPos2d( x, y ); 00216 } 00217 else { 00218 glutBitmapCharacter( font, *ch ); 00219 } 00220 } 00221 00222 return y -= int( glutBitmapHeight( font ) * 1.2 ); 00223 }