GLC_lib  2.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
glc_cone.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 
3  This file is part of the GLC-lib library.
4  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
5  http://glc-lib.sourceforge.net
6 
7  GLC-lib is free software; you can redistribute it and/or modify
8  it under the terms of the GNU Lesser General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  GLC-lib is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with GLC-lib; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21  *****************************************************************************/
23 
24 #include "glc_cone.h"
25 
26 // Class chunk id
27 quint32 GLC_Cone::m_ChunkId= 0xA709;
28 
29 GLC_Cone::GLC_Cone(double dRadius, double dLength, int discretization)
30 :GLC_Mesh()
31 , m_Radius(dRadius)
32 , m_Length(dLength)
33 , m_Discret(discretization) // Default discretion
34 {
35  Q_ASSERT((m_Radius > 0.0) && (m_Length > 0.0));
37 }
38 
39 GLC_Cone::GLC_Cone(const GLC_Cone& sourceCone)
40 :GLC_Mesh(sourceCone)
41 , m_Radius(sourceCone.m_Radius)
42 , m_Length(sourceCone.m_Length)
43 , m_Discret(sourceCone.m_Discret)
44 {
46 }
47 
49 {
50 
51 }
52 
54 // Get Functions
56 
58 {
59  return m_ChunkId;
60 }
61 
62 
64 {
65  return new GLC_Cone(*this);
66 }
67 
68 
70 {
71  if (GLC_Mesh::isEmpty())
72  {
74  }
75  return GLC_Mesh::boundingBox();
76 }
77 
79 // Set Functions
81 
82 void GLC_Cone::setLength(double Length)
83 {
84  Q_ASSERT(Length > 0.0);
85  m_Length= Length;
86 
88 }
89 
90 
91 void GLC_Cone::setRadius(double Radius)
92 {
93  Q_ASSERT(Radius > 0.0);
94  m_Radius= Radius;
95 
97 }
98 
99 
100 void GLC_Cone::setDiscretion(int TargetDiscret)
101 {
102  Q_ASSERT(TargetDiscret > 0);
103  if (TargetDiscret != m_Discret)
104  {
105  m_Discret= TargetDiscret;
106  if (m_Discret < 6) m_Discret= 6;
107 
109  }
110 }
111 
113 // Private Opengl functions
115 
116 void GLC_Cone::glDraw(const GLC_RenderProperties& renderProperties)
117 {
118 
119  if (GLC_Mesh::isEmpty())
120  {
122  }
123 
124  GLC_Mesh::glDraw(renderProperties);
125 }
126 
127 
129 {
130  Q_ASSERT(GLC_Mesh::isEmpty());
131  Q_ASSERT(m_WireData.isEmpty());
132 
133  // Create cosinus and sinus array according to the discretion and radius
134  const int vertexNumber= m_Discret + 1;
135  // Normals values
136  QVector<float> cosNormalArray(vertexNumber);
137  QVector<float> sinNormalArray(vertexNumber);
138 
139  QVector<float> cosArray(vertexNumber);
140  QVector<float> sinArray(vertexNumber);
141 
142  const double angle= (2.0 * glc::PI) / static_cast<double>(m_Discret);
143 
144  // Normal Z value
145  GLC_Vector3d normalVector(1.0, 0.0, 0.0);
146  GLC_Matrix4x4 rotation(glc::Y_AXIS, -atan(m_Radius / m_Length));
147  normalVector= rotation * normalVector;
148  const float normalZ= static_cast<float>(normalVector.z());
149  const double factor= normalVector.x(); // Normailsation factor
150 
151  for (int i= 0; i < vertexNumber; ++i)
152  {
153  const double cosValue= cos(static_cast<double>(i) * angle);
154  const double sinValue= sin(static_cast<double>(i) * angle);
155 
156  cosNormalArray[i]= static_cast<GLfloat>(factor * cosValue);
157  sinNormalArray[i]= static_cast<GLfloat>(factor * sinValue);
158 
159  cosArray[i]= static_cast<GLfloat>(m_Radius * cosValue);
160  sinArray[i]= static_cast<GLfloat>(m_Radius * sinValue);
161  }
162 
163 
164  // Mesh Data
165  GLfloatVector verticeVector;
166  GLfloatVector normalsVector;
168 
169  // Wire Data
170  GLfloatVector bottomWireData(vertexNumber * 3);
171 
172  const int size= vertexNumber * 3;
173  verticeVector.resize(3 * size);
174  normalsVector.resize(3 * size);
175  texelVector.resize(2 * size);
176 
177  for (int i= 0; i < vertexNumber; ++i)
178  {
179  // Bottom Mesh
180  verticeVector[3 * i]= cosArray[i];
181  verticeVector[3 * i + 1]= sinArray[i];
182  verticeVector[3 * i + 2]= 0.0f;
183 
184  normalsVector[3 * i]= cosNormalArray[i];
185  normalsVector[3 * i + 1]= sinNormalArray[i];
186  normalsVector[3 * i + 2]= normalZ;
187 
188  texelVector[2 * i]= static_cast<float>(i) / static_cast<float>(m_Discret);
189  texelVector[2 * i + 1]= 0.0f;
190 
191  // Bottom Wire
192  bottomWireData[3 * i]= cosArray[i];
193  bottomWireData[3 * i + 1]= sinArray[i];
194  bottomWireData[3 * i + 2]= 0.0f;
195 
196  // Top
197  verticeVector[3 * i + 3 * vertexNumber]= 0.0f;
198  verticeVector[3 * i + 1 + 3 * vertexNumber]= 0.0f;
199  verticeVector[3 * i + 2 + 3 * vertexNumber]= static_cast<float>(m_Length);
200 
201  normalsVector[3 * i + 3 * vertexNumber]= cosNormalArray[i];
202  normalsVector[3 * i + 1 + 3 * vertexNumber]= sinNormalArray[i];
203  normalsVector[3 * i + 2 + 3 * vertexNumber]= normalZ;
204 
205  texelVector[2 * i + 2 * vertexNumber]= texelVector[i];
206  texelVector[2 * i + 1 + 2 * vertexNumber]= 1.0f;
207 
208  // Bottom Cap ends
209  verticeVector[3 * i + 2 * 3 * vertexNumber]= cosArray[i];
210  verticeVector[3 * i + 1 + 2 * 3 * vertexNumber]= sinArray[i];
211  verticeVector[3 * i + 2 + 2 * 3 * vertexNumber]= 0.0f;
212 
213  normalsVector[3 * i + 2 * 3 * vertexNumber]= 0.0f;
214  normalsVector[3 * i + 1 + 2 * 3 * vertexNumber]= 0.0f;
215  normalsVector[3 * i + 2 + 2 * 3 * vertexNumber]= -1.0f;
216 
217  texelVector[2 * i + 2 * 2 * vertexNumber]= texelVector[i];
218  texelVector[2 * i + 1 + 2 * 2 * vertexNumber]= 0.0f;
219 
220  }
221 
222  // Add bulk data in to the mesh
223  GLC_Mesh::addVertice(verticeVector);
224  GLC_Mesh::addNormals(normalsVector);
225  GLC_Mesh::addTexels(texelVector);
226 
227  // Add polyline to wire data
228  GLC_Geometry::addVerticeGroup(bottomWireData);
229 
230  // Set the material to use
231  GLC_Material* pCylinderMaterial;
232  if (hasMaterial())
233  {
234  pCylinderMaterial= this->firstMaterial();
235  }
236  else
237  {
238  pCylinderMaterial= new GLC_Material();
239  }
240 
241  IndexList circumferenceStrips;
242  // Create the index
243  for (int i= 0; i < vertexNumber; ++i)
244  {
245  circumferenceStrips.append(i + vertexNumber);
246  circumferenceStrips.append(i);
247  }
248  addTrianglesStrip(pCylinderMaterial, circumferenceStrips);
249 
250  {
251  IndexList bottomCap;
252  IndexList topCap;
253  int id1= 0;
254  int id2= m_Discret - 1;
255  const int size= m_Discret / 2 + (m_Discret % 2);
256  for (int i= 0; i < size; ++i)
257  {
258  bottomCap.append(id1 + 2 * vertexNumber);
259  bottomCap.append(id2 + 2 * vertexNumber);
260 
261  id1+= 1;
262  id2-= 1;
263  }
264  addTrianglesStrip(pCylinderMaterial, bottomCap);
265  }
266 
267  finish();
268 }
269 

©2005-2013 Laurent Ribon