glc_cylinder.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00026
00027 #include "glc_cylinder.h"
00028 #include "../glc_openglexception.h"
00029 #include "../shading/glc_selectionmaterial.h"
00030 #include "../glc_state.h"
00031
00032 #include <QVector>
00033
00034
00035 quint32 GLC_Cylinder::m_ChunkId= 0xA705;
00036
00038
00040
00041 GLC_Cylinder::GLC_Cylinder(double dRadius, double dLength)
00042 :GLC_Mesh()
00043 , m_Radius(dRadius)
00044 , m_Length(dLength)
00045 , m_Discret(glc::GLC_POLYDISCRET)
00046 , m_EndedIsCaped(true)
00047 {
00048 Q_ASSERT((m_Radius > 0.0) && (m_Length > 0.0));
00049 }
00050
00051 GLC_Cylinder::GLC_Cylinder(const GLC_Cylinder& sourceCylinder)
00052 :GLC_Mesh(sourceCylinder)
00053 , m_Radius(sourceCylinder.m_Radius)
00054 , m_Length(sourceCylinder.m_Length)
00055 , m_Discret(sourceCylinder.m_Discret)
00056 , m_EndedIsCaped(sourceCylinder.m_EndedIsCaped)
00057 {
00058 Q_ASSERT((m_Radius > 0.0) && (m_Length > 0.0) && (m_Discret > 0));
00059
00060 }
00061 GLC_Cylinder::~GLC_Cylinder()
00062 {
00063
00064 }
00065
00067
00069
00070 quint32 GLC_Cylinder::chunckID()
00071 {
00072 return m_ChunkId;
00073 }
00074
00075
00076 GLC_Geometry* GLC_Cylinder::clone() const
00077 {
00078 return new GLC_Cylinder(*this);
00079 }
00080
00081
00082 const GLC_BoundingBox& GLC_Cylinder::boundingBox()
00083 {
00084 if (GLC_Mesh::isEmpty())
00085 {
00086 createMeshAndWire();
00087 }
00088 return GLC_Mesh::boundingBox();
00089 }
00090
00092
00094
00095 void GLC_Cylinder::setLength(double Length)
00096 {
00097 Q_ASSERT(Length > 0.0);
00098 m_Length= Length;
00099
00100 GLC_Mesh::clearMeshWireAndBoundingBox();
00101 }
00102
00103
00104 void GLC_Cylinder::setRadius(double Radius)
00105 {
00106 Q_ASSERT(Radius > 0.0);
00107 m_Radius= Radius;
00108
00109 GLC_Mesh::clearMeshWireAndBoundingBox();
00110 }
00111
00112
00113 void GLC_Cylinder::setDiscretion(int TargetDiscret)
00114 {
00115 Q_ASSERT(TargetDiscret > 0);
00116 if (TargetDiscret != m_Discret)
00117 {
00118 m_Discret= TargetDiscret;
00119 if (m_Discret < 6) m_Discret= 6;
00120
00121 GLC_Mesh::clearMeshWireAndBoundingBox();
00122 }
00123 }
00124
00125
00126 void GLC_Cylinder::setEndedCaps(bool CapsEnded)
00127 {
00128 if (m_EndedIsCaped != CapsEnded)
00129 {
00130 m_EndedIsCaped= CapsEnded;
00131
00132 GLC_Mesh::clearMeshWireAndBoundingBox();
00133 }
00134 }
00135
00137
00139
00140
00141 void GLC_Cylinder::glDraw(const GLC_RenderProperties& renderProperties)
00142 {
00143
00144 if (GLC_Mesh::isEmpty())
00145 {
00146 createMeshAndWire();
00147 }
00148
00149 GLC_Mesh::glDraw(renderProperties);
00150 }
00151
00152
00153 void GLC_Cylinder::createMeshAndWire()
00154 {
00155 Q_ASSERT(GLC_Mesh::isEmpty());
00156 Q_ASSERT(m_WireData.isEmpty());
00157
00158
00159 const int vertexNumber= m_Discret + 1;
00160
00161 QVector<float> cosNormalArray(vertexNumber);
00162 QVector<float> sinNormalArray(vertexNumber);
00163
00164 QVector<float> cosArray(vertexNumber);
00165 QVector<float> sinArray(vertexNumber);
00166
00167 const double angle= (2.0 * glc::PI) / static_cast<double>(m_Discret);
00168
00169 for (int i= 0; i < vertexNumber; ++i)
00170 {
00171 const double cosValue= cos(static_cast<double>(i) * angle);
00172 const double sinValue= sin(static_cast<double>(i) * angle);
00173
00174 cosNormalArray[i]= static_cast<GLfloat>(cosValue);
00175 sinNormalArray[i]= static_cast<GLfloat>(sinValue);
00176
00177 cosArray[i]= static_cast<GLfloat>(m_Radius * cosValue);
00178 sinArray[i]= static_cast<GLfloat>(m_Radius * sinValue);
00179 }
00180
00181
00182 GLfloatVector verticeVector;
00183 GLfloatVector normalsVector;
00184 GLfloatVector texelVector;
00185
00186
00187 GLfloatVector bottomWireData(vertexNumber * 3);
00188 GLfloatVector topWireData(vertexNumber * 3);
00189
00190 if (m_EndedIsCaped)
00191 {
00192 const int size= vertexNumber * 4;
00193 verticeVector.resize(3 * size);
00194 normalsVector.resize(3 * size);
00195 texelVector.resize(2 * size);
00196 }
00197 else
00198 {
00199 const int size= vertexNumber * 2;
00200 verticeVector.resize(3 * size);
00201 normalsVector.resize(3 * size);
00202 texelVector.resize(2 * size);
00203 }
00204 for (int i= 0; i < vertexNumber; ++i)
00205 {
00206
00207 verticeVector[3 * i]= cosArray[i];
00208 verticeVector[3 * i + 1]= sinArray[i];
00209 verticeVector[3 * i + 2]= 0.0f;
00210
00211 normalsVector[3 * i]= cosNormalArray[i];
00212 normalsVector[3 * i + 1]= sinNormalArray[i];
00213 normalsVector[3 * i + 2]= 0.0f;
00214
00215 texelVector[2 * i]= static_cast<float>(i) / static_cast<float>(m_Discret);
00216 texelVector[2 * i + 1]= 0.0f;
00217
00218
00219 bottomWireData[3 * i]= cosArray[i];
00220 bottomWireData[3 * i + 1]= sinArray[i];
00221 bottomWireData[3 * i + 2]= 0.0f;
00222
00223
00224 verticeVector[3 * i + 3 * vertexNumber]= cosArray[i];
00225 verticeVector[3 * i + 1 + 3 * vertexNumber]= sinArray[i];
00226 verticeVector[3 * i + 2 + 3 * vertexNumber]= static_cast<float>(m_Length);
00227
00228 normalsVector[3 * i + 3 * vertexNumber]= cosNormalArray[i];
00229 normalsVector[3 * i + 1 + 3 * vertexNumber]= sinNormalArray[i];
00230 normalsVector[3 * i + 2 + 3 * vertexNumber]= 0.0f;
00231
00232 texelVector[2 * i + 2 * vertexNumber]= texelVector[i];
00233 texelVector[2 * i + 1 + 2 * vertexNumber]= 1.0f;
00234
00235
00236 topWireData[3 * i]= cosArray[i];
00237 topWireData[3 * i + 1]= sinArray[i];
00238 topWireData[3 * i + 2]= static_cast<float>(m_Length);
00239
00240 if (m_EndedIsCaped)
00241 {
00242
00243 verticeVector[3 * i + 2 * 3 * vertexNumber]= cosArray[i];
00244 verticeVector[3 * i + 1 + 2 * 3 * vertexNumber]= sinArray[i];
00245 verticeVector[3 * i + 2 + 2 * 3 * vertexNumber]= 0.0f;
00246
00247 normalsVector[3 * i + 2 * 3 * vertexNumber]= 0.0f;
00248 normalsVector[3 * i + 1 + 2 * 3 * vertexNumber]= 0.0f;
00249 normalsVector[3 * i + 2 + 2 * 3 * vertexNumber]= -1.0f;
00250
00251 texelVector[2 * i + 2 * 2 * vertexNumber]= texelVector[i];
00252 texelVector[2 * i + 1 + 2 * 2 * vertexNumber]= 0.0f;
00253
00254
00255 verticeVector[3 * i + 3 * 3 * vertexNumber]= cosArray[i];
00256 verticeVector[3 * i + 1 + 3 * 3 * vertexNumber]= sinArray[i];
00257 verticeVector[3 * i + 2 + 3 * 3 * vertexNumber]= static_cast<float>(m_Length);
00258
00259 normalsVector[3 * i + 3 * 3 * vertexNumber]= 0.0f;
00260 normalsVector[3 * i + 1 + 3 * 3 * vertexNumber]= 0.0f;
00261 normalsVector[3 * i + 2 + 3 * 3 * vertexNumber]= 1.0f;
00262
00263 texelVector[2 * i + 3 * 2 * vertexNumber]= texelVector[i];
00264 texelVector[2 * i + 1 + 3 * 2 * vertexNumber]= 0.0f;
00265 }
00266 }
00267
00268
00269 GLC_Mesh::addVertice(verticeVector);
00270 GLC_Mesh::addNormals(normalsVector);
00271 GLC_Mesh::addTexels(texelVector);
00272
00273
00274 GLC_Geometry::addPolyline(bottomWireData);
00275 GLC_Geometry::addPolyline(topWireData);
00276
00277
00278 GLC_Material* pCylinderMaterial;
00279 if (hasMaterial())
00280 {
00281 pCylinderMaterial= this->firstMaterial();
00282 }
00283 else
00284 {
00285 pCylinderMaterial= new GLC_Material();
00286 }
00287
00288 IndexList circumferenceStrips;
00289
00290 for (int i= 0; i < vertexNumber; ++i)
00291 {
00292 circumferenceStrips.append(i + vertexNumber);
00293 circumferenceStrips.append(i);
00294 }
00295 addTrianglesStrip(pCylinderMaterial, circumferenceStrips);
00296
00297 if (m_EndedIsCaped)
00298 {
00299 IndexList bottomCap;
00300 IndexList topCap;
00301 int id1= 0;
00302 int id2= m_Discret - 1;
00303 const int size= m_Discret / 2 + (m_Discret % 2);
00304 for (int i= 0; i < size; ++i)
00305 {
00306 bottomCap.append(id1 + 2 * vertexNumber);
00307 topCap.append(id2 + 3 * vertexNumber);
00308
00309 bottomCap.append(id2 + 2 * vertexNumber);
00310 topCap.append(id1 + 3 * vertexNumber);
00311
00312 id1+= 1;
00313 id2-= 1;
00314 }
00315 addTrianglesStrip(pCylinderMaterial, bottomCap);
00316 addTrianglesStrip(pCylinderMaterial, topCap);
00317 }
00318
00319 finish();
00320 }