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