ARGoS
3
A parallel, multi-engine simulator for swarm robotics
|
00001 00007 #include "qtopengl_cylinder.h" 00008 #include <argos3/core/utility/math/vector2.h> 00009 #include <argos3/plugins/simulator/entities/led_equipped_entity.h> 00010 #include <argos3/plugins/simulator/entities/cylinder_entity.h> 00011 #include <argos3/plugins/simulator/visualizations/qt-opengl/qtopengl_widget.h> 00012 00013 namespace argos { 00014 00015 /****************************************/ 00016 /****************************************/ 00017 00018 static const Real LED_RADIUS = 0.01f; 00019 const GLfloat MOVABLE_COLOR[] = { 0.0f, 1.0f, 0.0f, 1.0f }; 00020 const GLfloat NONMOVABLE_COLOR[] = { 0.7f, 0.7f, 0.7f, 1.0f }; 00021 const GLfloat SPECULAR[] = { 0.0f, 0.0f, 0.0f, 1.0f }; 00022 const GLfloat SHININESS[] = { 0.0f }; 00023 const GLfloat EMISSION[] = { 0.0f, 0.0f, 0.0f, 1.0f }; 00024 00025 /****************************************/ 00026 /****************************************/ 00027 00028 CQTOpenGLCylinder::CQTOpenGLCylinder() : 00029 m_unVertices(20) { 00030 00031 /* Reserve the needed display lists */ 00032 m_unBaseList = glGenLists(1); 00033 m_unBodyList = m_unBaseList; 00034 m_unLEDList = m_unBaseList + 1; 00035 00036 /* Make body list */ 00037 glNewList(m_unBodyList, GL_COMPILE); 00038 MakeBody(); 00039 glEndList(); 00040 00041 /* Make LED list */ 00042 glNewList(m_unLEDList, GL_COMPILE); 00043 MakeLED(); 00044 glEndList(); 00045 } 00046 00047 /****************************************/ 00048 /****************************************/ 00049 00050 CQTOpenGLCylinder::~CQTOpenGLCylinder() { 00051 glDeleteLists(m_unBaseList, 2); 00052 } 00053 00054 /****************************************/ 00055 /****************************************/ 00056 00057 void CQTOpenGLCylinder::DrawLEDs(CCylinderEntity& c_entity) { 00058 /* Draw the LEDs */ 00059 GLfloat pfColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; 00060 const GLfloat pfSpecular[] = { 0.0f, 0.0f, 0.0f, 1.0f }; 00061 const GLfloat pfShininess[] = { 100.0f }; 00062 const GLfloat pfEmission[] = { 0.0f, 0.0f, 0.0f, 1.0f }; 00063 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pfSpecular); 00064 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, pfShininess); 00065 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, pfEmission); 00066 CLEDEquippedEntity& cLEDEquippedEntity = c_entity.GetLEDEquippedEntity(); 00067 for(UInt32 i = 0; i < cLEDEquippedEntity.GetAllLEDs().size(); ++i) { 00068 glPushMatrix(); 00069 /* Set the material */ 00070 const CColor& cColor = cLEDEquippedEntity.GetLED(i).GetColor(); 00071 pfColor[0] = cColor.GetRed(); 00072 pfColor[1] = cColor.GetGreen(); 00073 pfColor[2] = cColor.GetBlue(); 00074 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, pfColor); 00075 /* Perform rototranslation */ 00076 const CVector3& cPosition = cLEDEquippedEntity.GetLEDOffsetPosition(i); 00077 glTranslatef(cPosition.GetX(), cPosition.GetY(), cPosition.GetZ()); 00078 /* Draw the LED */ 00079 glCallList(m_unLEDList); 00080 glPopMatrix(); 00081 } 00082 } 00083 00084 /****************************************/ 00085 /****************************************/ 00086 00087 void CQTOpenGLCylinder::Draw(CCylinderEntity& c_entity) { 00088 /* Draw the body */ 00089 if(c_entity.GetEmbodiedEntity().IsMovable()) { 00090 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, MOVABLE_COLOR); 00091 } 00092 else { 00093 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, NONMOVABLE_COLOR); 00094 } 00095 glPushMatrix(); 00096 glScalef(c_entity.GetRadius(), c_entity.GetRadius(), c_entity.GetHeight()); 00097 glCallList(m_unBodyList); 00098 glPopMatrix(); 00099 } 00100 00101 /****************************************/ 00102 /****************************************/ 00103 00104 void CQTOpenGLCylinder::MakeBody() { 00105 /* Since this shape can be stretched, 00106 make sure the normal vectors are unit-long */ 00107 glEnable(GL_NORMALIZE); 00108 00109 /* Set the material */ 00110 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, SPECULAR); 00111 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, SHININESS); 00112 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, EMISSION); 00113 00114 /* Let's start the actual shape */ 00115 /* Side surface */ 00116 CVector2 cVertex(1.0f, 0.0f); 00117 CRadians cAngle(CRadians::TWO_PI / m_unVertices); 00118 glBegin(GL_QUAD_STRIP); 00119 for(GLuint i = 0; i <= m_unVertices; i++) { 00120 glNormal3f(cVertex.GetX(), cVertex.GetY(), 0.0f); 00121 glVertex3f(cVertex.GetX(), cVertex.GetY(), 1.0f); 00122 glVertex3f(cVertex.GetX(), cVertex.GetY(), 0.0f); 00123 cVertex.Rotate(cAngle); 00124 } 00125 glEnd(); 00126 /* Top disk */ 00127 cVertex.Set(1.0f, 0.0f); 00128 glBegin(GL_POLYGON); 00129 glNormal3f(0.0f, 0.0f, 1.0f); 00130 for(GLuint i = 0; i <= m_unVertices; i++) { 00131 glVertex3f(cVertex.GetX(), cVertex.GetY(), 1.0f); 00132 cVertex.Rotate(cAngle); 00133 } 00134 glEnd(); 00135 /* Bottom disk */ 00136 cVertex.Set(1.0f, 0.0f); 00137 cAngle = -cAngle; 00138 glBegin(GL_POLYGON); 00139 glNormal3f(0.0f, 0.0f, -1.0f); 00140 for(GLuint i = 0; i <= m_unVertices; i++) { 00141 glVertex3f(cVertex.GetX(), cVertex.GetY(), 0.0f); 00142 cVertex.Rotate(cAngle); 00143 } 00144 glEnd(); 00145 /* The shape definition is finished */ 00146 00147 /* We don't need it anymore */ 00148 glDisable(GL_NORMALIZE); 00149 00150 } 00151 00152 /****************************************/ 00153 /****************************************/ 00154 00155 void CQTOpenGLCylinder::MakeLED() { 00156 CVector3 cNormal, cPoint; 00157 CRadians cSlice(CRadians::TWO_PI / m_unVertices); 00158 00159 glBegin(GL_TRIANGLE_STRIP); 00160 for(CRadians cInclination; cInclination <= CRadians::PI; cInclination += cSlice) { 00161 for(CRadians cAzimuth; cAzimuth <= CRadians::TWO_PI; cAzimuth += cSlice) { 00162 00163 cNormal.FromSphericalCoords(1.0f, cInclination, cAzimuth); 00164 cPoint = LED_RADIUS * cNormal; 00165 glNormal3f(cNormal.GetX(), cNormal.GetY(), cNormal.GetZ()); 00166 glVertex3f(cPoint.GetX(), cPoint.GetY(), cPoint.GetZ()); 00167 00168 cNormal.FromSphericalCoords(1.0f, cInclination + cSlice, cAzimuth); 00169 cPoint = LED_RADIUS * cNormal; 00170 glNormal3f(cNormal.GetX(), cNormal.GetY(), cNormal.GetZ()); 00171 glVertex3f(cPoint.GetX(), cPoint.GetY(), cPoint.GetZ()); 00172 00173 cNormal.FromSphericalCoords(1.0f, cInclination, cAzimuth + cSlice); 00174 cPoint = LED_RADIUS * cNormal; 00175 glNormal3f(cNormal.GetX(), cNormal.GetY(), cNormal.GetZ()); 00176 glVertex3f(cPoint.GetX(), cPoint.GetY(), cPoint.GetZ()); 00177 00178 cNormal.FromSphericalCoords(1.0f, cInclination + cSlice, cAzimuth + cSlice); 00179 cPoint = LED_RADIUS * cNormal; 00180 glNormal3f(cNormal.GetX(), cNormal.GetY(), cNormal.GetZ()); 00181 glVertex3f(cPoint.GetX(), cPoint.GetY(), cPoint.GetZ()); 00182 00183 } 00184 } 00185 glEnd(); 00186 } 00187 00188 /****************************************/ 00189 /****************************************/ 00190 00191 class CQTOpenGLOperationDrawCylinderNormal : public CQTOpenGLOperationDrawNormal { 00192 public: 00193 void ApplyTo(CQTOpenGLWidget& c_visualization, 00194 CCylinderEntity& c_entity) { 00195 static CQTOpenGLCylinder m_cModel; 00196 c_visualization.DrawPositionalEntity(c_entity.GetEmbodiedEntity()); 00197 m_cModel.Draw(c_entity); 00198 } 00199 }; 00200 00201 class CQTOpenGLOperationDrawCylinderSelected : public CQTOpenGLOperationDrawSelected { 00202 public: 00203 void ApplyTo(CQTOpenGLWidget& c_visualization, 00204 CCylinderEntity& c_entity) { 00205 c_visualization.DrawBoundingBox(c_entity.GetEmbodiedEntity()); 00206 } 00207 }; 00208 00209 REGISTER_QTOPENGL_ENTITY_OPERATION(CQTOpenGLOperationDrawNormal, CQTOpenGLOperationDrawCylinderNormal, CCylinderEntity); 00210 00211 REGISTER_QTOPENGL_ENTITY_OPERATION(CQTOpenGLOperationDrawSelected, CQTOpenGLOperationDrawCylinderSelected, CCylinderEntity); 00212 00213 /****************************************/ 00214 /****************************************/ 00215 00216 }