ARGoS
3
A parallel, multi-engine simulator for swarm robotics
|
00001 00008 #include "qtopengl_user_functions.h" 00009 00010 namespace argos { 00011 00012 /****************************************/ 00013 /****************************************/ 00014 00015 CQTOpenGLUserFunctions::CQTOpenGLUserFunctions() : 00016 m_vecFunctionHolders(1), 00017 m_pcQTOpenGLWidget(NULL) { 00018 m_cThunks.Add<CEntity>((TThunk)NULL); 00019 } 00020 00021 /****************************************/ 00022 /****************************************/ 00023 00024 CQTOpenGLUserFunctions::~CQTOpenGLUserFunctions() { 00025 while(!m_vecFunctionHolders.empty()) { 00026 delete m_vecFunctionHolders.back(); 00027 m_vecFunctionHolders.pop_back(); 00028 } 00029 } 00030 00031 /****************************************/ 00032 /****************************************/ 00033 00034 void CQTOpenGLUserFunctions::DrawTriangle(const CVector3& c_center_offset, 00035 const CColor& c_color, 00036 const bool b_fill, 00037 const CQuaternion& c_orientation, 00038 Real f_base, 00039 Real f_height) { 00040 00041 glDisable(GL_LIGHTING); 00042 glDisable(GL_CULL_FACE); 00043 00044 glColor3ub(c_color.GetRed(), 00045 c_color.GetGreen(), 00046 c_color.GetBlue()); 00047 00048 if(b_fill) { 00049 glBegin(GL_POLYGON); 00050 } 00051 else { 00052 glBegin(GL_LINE_LOOP); 00053 } 00054 CVector3 cNormalDirection(0.0f, 0.0f, 1.0f); 00055 cNormalDirection.Rotate(c_orientation); 00056 glNormal3f(cNormalDirection.GetX(), 00057 cNormalDirection.GetY(), 00058 cNormalDirection.GetZ()); 00059 00060 CVector3 cVertex(f_height * 0.5f, 0.0f, 0.0f); 00061 cVertex.Rotate(c_orientation); 00062 glVertex3f(cVertex.GetX() + c_center_offset.GetX(), 00063 cVertex.GetY() + c_center_offset.GetY(), 00064 cVertex.GetZ() + c_center_offset.GetZ()); 00065 00066 cVertex.Set(-f_height * 0.5f, f_base * 0.5f, 0.0f); 00067 cVertex.Rotate(c_orientation); 00068 glVertex3f(cVertex.GetX() + c_center_offset.GetX(), 00069 cVertex.GetY() + c_center_offset.GetY(), 00070 cVertex.GetZ() + c_center_offset.GetZ()); 00071 00072 cVertex.Set(-f_height * 0.5f, -f_base * 0.5f, 0.0f); 00073 cVertex.Rotate(c_orientation); 00074 glVertex3f(cVertex.GetX() + c_center_offset.GetX(), 00075 cVertex.GetY() + c_center_offset.GetY(), 00076 cVertex.GetZ() + c_center_offset.GetZ()); 00077 glEnd(); 00078 00079 glEnable(GL_CULL_FACE); 00080 glEnable(GL_LIGHTING); 00081 } 00082 00083 /****************************************/ 00084 /****************************************/ 00085 00086 00087 void CQTOpenGLUserFunctions::DrawCircle(Real f_radius, 00088 const CVector3& c_center_offset, 00089 const CColor& c_color, 00090 const bool b_fill, 00091 const CQuaternion& c_orientation, 00092 GLuint un_vertices) { 00093 00094 glDisable(GL_LIGHTING); 00095 glDisable(GL_CULL_FACE); 00096 00097 glColor3ub(c_color.GetRed(), 00098 c_color.GetGreen(), 00099 c_color.GetBlue()); 00100 00101 CVector3 cVertex(f_radius, 0.0f, 0.0f); 00102 CRadians cAngle(CRadians::TWO_PI / un_vertices); 00103 00104 if(b_fill) { 00105 glBegin(GL_POLYGON); 00106 } 00107 else { 00108 glBegin(GL_LINE_LOOP); 00109 } 00110 CVector3 cNormalDirection(0.0f, 0.0f, 1.0f); 00111 cNormalDirection.Rotate(c_orientation); 00112 glNormal3f(cNormalDirection.GetX(), 00113 cNormalDirection.GetY(), 00114 cNormalDirection.GetZ()); 00115 00116 /* Compute the quaternion defining the rotation of the vertices used to draw the circle. */ 00117 CQuaternion cVertexRotation; 00118 CVector3 cVertexRotationAxis(0.0f, 0.0f, 1.0f); 00119 cVertexRotationAxis.Rotate(c_orientation); 00120 cVertexRotation.FromAngleAxis(cAngle, cVertexRotationAxis); 00121 00122 cVertex.Rotate(c_orientation); 00123 for(GLuint i = 0; i <= un_vertices; i++) { 00124 glVertex3f(cVertex.GetX() + c_center_offset.GetX(), 00125 cVertex.GetY() + c_center_offset.GetY(), 00126 cVertex.GetZ() + c_center_offset.GetZ()); 00127 cVertex.Rotate(cVertexRotation); 00128 } 00129 glEnd(); 00130 00131 glEnable(GL_CULL_FACE); 00132 glEnable(GL_LIGHTING); 00133 } 00134 00135 /****************************************/ 00136 /****************************************/ 00137 00138 void CQTOpenGLUserFunctions::DrawCylinder(Real f_radius, 00139 Real f_height, 00140 const CVector3& c_center_offset, 00141 const CColor& c_color, 00142 const CQuaternion& c_orientation, 00143 GLuint un_vertices) { 00144 00145 /* Draw top circle*/ 00146 CVector3 cCirclePos(0.0f, 0.0f, f_height * 0.5f); 00147 cCirclePos.Rotate(c_orientation); 00148 cCirclePos += c_center_offset; 00149 DrawCircle(f_radius, 00150 cCirclePos, 00151 c_color, 00152 true, 00153 c_orientation, 00154 un_vertices); 00155 00156 /* Draw bottom circle*/ 00157 cCirclePos.Set(0.0f, 0.0f, -f_height * 0.5f); 00158 cCirclePos.Rotate(c_orientation); 00159 cCirclePos += c_center_offset; 00160 DrawCircle(f_radius, 00161 cCirclePos, 00162 c_color, 00163 true, 00164 c_orientation, 00165 un_vertices); 00166 00167 /* Side surface */ 00168 CVector3 cVertex1(f_radius, 0.0f, f_height * 0.5f); 00169 CVector3 cVertex2(f_radius, 0.0f, -f_height * 0.5f); 00170 CRadians cAngle(CRadians::TWO_PI / un_vertices); 00171 00172 /* Compute the quaternion defining the rotation of the vertices used to draw the side surface. */ 00173 CQuaternion cVertexRotation; 00174 CVector3 cVertexRotationAxis(0.0f, 0.0f, 1.0f); 00175 cVertexRotationAxis.Rotate(c_orientation); 00176 cVertexRotation.FromAngleAxis(cAngle, cVertexRotationAxis); 00177 00178 glDisable(GL_LIGHTING); 00179 glColor3ub(c_color.GetRed(), 00180 c_color.GetGreen(), 00181 c_color.GetBlue()); 00182 00183 glBegin(GL_QUAD_STRIP); 00184 00185 /* Compute the normal direction of the starting edge. */ 00186 CVector3 cNormalDirection(cVertex1.GetX(), cVertex1.GetY(), 0.0f); 00187 cNormalDirection.Rotate(c_orientation); 00188 glNormal3f(cNormalDirection.GetX(), 00189 cNormalDirection.GetY(), 00190 cNormalDirection.GetZ()); 00191 00192 /* Rotate the endpoints of the first edge.*/ 00193 cVertex1.Rotate(c_orientation); 00194 cVertex2.Rotate(c_orientation); 00195 00196 for(GLuint i = 0; i <= un_vertices; i++) { 00197 glVertex3f(cVertex1.GetX() + c_center_offset.GetX(), 00198 c_center_offset.GetY() + cVertex1.GetY(), 00199 c_center_offset.GetZ() + cVertex1.GetZ() ); 00200 glVertex3f(cVertex2.GetX() + c_center_offset.GetX(), 00201 c_center_offset.GetY() + cVertex2.GetY(), 00202 c_center_offset.GetZ() + cVertex2.GetZ() ); 00203 /* Rotate the vertices and the normal direction, set the new normal. */ 00204 cVertex1.Rotate(cVertexRotation); 00205 cVertex2.Rotate(cVertexRotation); 00206 cNormalDirection.Rotate(cVertexRotation); 00207 glNormal3f(cNormalDirection.GetX(), 00208 cNormalDirection.GetY(), 00209 cNormalDirection.GetZ()); 00210 } 00211 00212 glEnd(); 00213 glEnable(GL_LIGHTING); 00214 00215 } 00216 00217 /****************************************/ 00218 /****************************************/ 00219 00220 void CQTOpenGLUserFunctions::DrawSegment(const CVector3& c_end_point, 00221 const CVector3& c_start_point, 00222 const CColor& c_segment_color, 00223 const Real& f_line_width, 00224 bool b_draw_end_point, 00225 bool b_draw_start_point, 00226 const CColor& c_end_point_color, 00227 const CColor& c_start_point_color) { 00228 00229 /* Draw the segment */ 00230 00231 glDisable(GL_LIGHTING); 00232 glColor3ub(c_segment_color.GetRed(), 00233 c_segment_color.GetGreen(), 00234 c_segment_color.GetBlue()); 00235 00236 glEnable (GL_LINE_SMOOTH); 00237 glLineWidth(f_line_width); 00238 00239 glBegin(GL_LINES); 00240 glVertex3f(c_start_point.GetX(), 00241 c_start_point.GetY(), 00242 c_start_point.GetZ() ); 00243 glVertex3f(c_end_point.GetX(), 00244 c_end_point.GetY(), 00245 c_end_point.GetZ() ); 00246 glEnd(); 00247 00248 /* Draw the end and start points if necessary */ 00249 00250 if(b_draw_end_point) { 00251 DrawPoint(c_end_point, c_end_point_color, 5.0); 00252 } 00253 00254 if(b_draw_start_point) { 00255 DrawPoint(c_start_point, c_start_point_color, 5.0); 00256 } 00257 00258 glPointSize(1.0); 00259 glEnable(GL_LIGHTING); 00260 } 00261 00262 /****************************************/ 00263 /****************************************/ 00264 00265 void CQTOpenGLUserFunctions::DrawPoint(const CVector3& c_position, 00266 const CColor& c_color, 00267 const Real f_point_diameter) { 00268 glDisable(GL_LIGHTING); 00269 glColor3ub(c_color.GetRed(), 00270 c_color.GetGreen(), 00271 c_color.GetBlue()); 00272 glPointSize(f_point_diameter); 00273 glBegin(GL_POINTS); 00274 glVertex3f(c_position.GetX(), c_position.GetY(), c_position.GetZ()); 00275 glEnd(); 00276 glPointSize(1.0); 00277 glEnable(GL_LIGHTING); 00278 00279 } 00280 00281 /****************************************/ 00282 /****************************************/ 00283 00284 void CQTOpenGLUserFunctions::DrawPolygon(const std::vector<CVector3>& vec_points, 00285 const CColor& c_color) { 00286 if (vec_points.size() > 2) 00287 { 00288 glDisable(GL_LIGHTING); 00289 glDisable(GL_CULL_FACE); 00290 00291 glColor3ub(c_color.GetRed(), 00292 c_color.GetGreen(), 00293 c_color.GetBlue()); 00294 00295 glBegin(GL_POLYGON); 00296 for (UInt32 i = 0; i < vec_points.size(); ++i) 00297 { 00298 glVertex3f(vec_points[i].GetX(), 00299 vec_points[i].GetY(), 00300 vec_points[i].GetZ()); 00301 } 00302 glEnd(); 00303 00304 glEnable(GL_CULL_FACE); 00305 glEnable(GL_LIGHTING); 00306 } 00307 } 00308 00309 /****************************************/ 00310 /****************************************/ 00311 00312 void CQTOpenGLUserFunctions::Call(CEntity& c_entity) { 00313 TThunk t_thunk = m_cThunks[c_entity.GetTag()]; 00314 if(t_thunk) (this->*t_thunk)(c_entity); 00315 } 00316 00317 /****************************************/ 00318 /****************************************/ 00319 00320 } 00321