GLC_lib  2.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
glc_sphere.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 
3  This file is part of the GLC-lib library.
4  Copyright (C) 2010 Laurent Bauer
5  Copyright (C) 2010 Laurent Ribon (laumaya@users.sourceforge.net)
6  http://glc-lib.sourceforge.net
7 
8  GLC-lib is free software; you can redistribute it and/or modify
9  it under the terms of the GNU Lesser General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  GLC-lib is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License
19  along with GLC-lib; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 
22  *****************************************************************************/
24 
25 #include "glc_sphere.h"
26 
27 // Class chunk id
28 quint32 GLC_Sphere::m_ChunkId= 0xA710;
29 
30 GLC_Sphere::GLC_Sphere(double radius, int discretization)
31 : GLC_Mesh()
32 , m_Radius (radius)
33 , m_Discret(discretization)
34 , m_ThetaMin (0.0)
35 , m_ThetaMax(2 * glc::PI)
36 , m_PhiMin(-glc::PI / 2.0)
37 , m_PhiMax(glc::PI / 2.0)
38 , m_Center()
39 {
40  createMesh();
41 }
42 
43 GLC_Sphere::GLC_Sphere(double radius, const GLC_Point3d& center, int discretization)
44 : GLC_Mesh()
45 , m_Radius (radius)
46 , m_Discret(discretization)
47 , m_ThetaMin (0.0)
48 , m_ThetaMax(2 * glc::PI)
49 , m_PhiMin(-glc::PI / 2.0)
50 , m_PhiMax(glc::PI / 2.0)
51 , m_Center(center)
52 {
53  createMesh();
54 }
55 
56 
58 :GLC_Mesh(sphere)
59 , m_Radius (sphere.m_Radius)
60 , m_Discret(sphere.m_Discret)
61 , m_ThetaMin (sphere.m_ThetaMin)
62 , m_ThetaMax(sphere.m_ThetaMax)
63 , m_PhiMin(sphere.m_PhiMin)
64 , m_PhiMax(sphere.m_PhiMax)
65 , m_Center(sphere.m_Center)
66 {
67  if (isEmpty()) createMesh();
68 }
69 
71 {
72 
73 }
74 
76 {
77  return new GLC_Sphere (*this);
78 }
79 
81 {
82  if ( GLC_Mesh::isEmpty() )
83  {
84  createMesh();
85  }
86  return GLC_Mesh::boundingBox();
87 }
88 
89 void GLC_Sphere::setRadius(double Radius)
90 {
91  Q_ASSERT(Radius > 0.0);
92  m_Radius= Radius;
93 
95 }
96 
97 
98 void GLC_Sphere::setDiscretion(int TargetDiscret)
99 {
100  Q_ASSERT(TargetDiscret > 0);
101  if (TargetDiscret != m_Discret)
102  {
103  m_Discret= TargetDiscret;
104  if (m_Discret < 6) m_Discret= 6;
105 
107  }
108 }
109 
111 {
112  if (pos != m_Center)
113  {
114  m_Center= pos;
115 
117  }
118 }
119 
120 void GLC_Sphere::glDraw(const GLC_RenderProperties& renderProperties)
121 {
122  if (GLC_Mesh::isEmpty())
123  {
124  createMesh();
125  }
126 
127  GLC_Mesh::glDraw(renderProperties);
128 }
129 
131 {
132 
133  Q_ASSERT(GLC_Mesh::isEmpty());
134 
135  GLfloatVector verticeFloat;
136  GLfloatVector normalsFloat;
138 
139  int currentIndex=0;
140 
141  float wishedThetaStep= glc::PI / m_Discret;
142  float thetaRange= m_ThetaMax-m_ThetaMin;
143  int nbThetaSteps= (int) (thetaRange / wishedThetaStep) + 1 ;
144  float thetaStep= thetaRange / nbThetaSteps;
145 
146  float wishedPhiStep= wishedThetaStep;
147  float phiRange= m_PhiMax-m_PhiMin;
148  int nbPhiSteps= (int) (phiRange / wishedPhiStep) + 1 ;
149  float phiStep= phiRange / nbPhiSteps;
150 
151  float cost, sint, cosp, sinp, cospp, sinpp;
152  float xi, yi, zi, xf, yf, zf;
153  float theta= m_ThetaMin;
154  float phi= m_PhiMin;
155 
156  GLfloatVector thetaMinWire;
157  GLfloatVector thetaMaxWire;
158  GLfloatVector phiMinWire;
159  GLfloatVector phiMaxWire;
160 
161  GLC_Material* pMaterial;
162  if (hasMaterial())
163  pMaterial= this->firstMaterial();
164  else
165  pMaterial= new GLC_Material();
166 
167  const double dx= m_Center.x();
168  const double dy= m_Center.y();
169  const double dz= m_Center.z();
170 
171  // shaded face
172  for (int p= 0; p < nbPhiSteps; ++p)
173  {
174  cosp= cos (phi);
175  sinp= sin (phi);
176  cospp= cos (phi + phiStep);
177  sinpp= sin (phi + phiStep);
178 
179  zi = m_Radius * sinp;
180  zf = m_Radius * sinpp;
181 
182  IndexList indexFace;
183 
184  theta = m_ThetaMin;
185  int t;
186  for (t= 0; t <= nbThetaSteps; ++t)
187  {
188  cost= cos( theta );
189  sint= sin( theta );
190 
191  xi= m_Radius * cost * cosp;
192  yi= m_Radius * sint * cosp;
193  xf= m_Radius * cost * cospp;
194  yf= m_Radius * sint * cospp;
195 
196  verticeFloat << (xf + dx) << (yf + dy) << (zf + dz) << (xi + dx) << (yi + dy) << (zi + dz);
197  normalsFloat << cost * cospp << sint * cospp << sinpp << cost * cosp << sint * cosp << sinp;
198  texelVector << static_cast<double>(t) * 1.0 / static_cast<double>(nbThetaSteps)
199  << static_cast<double>(p) * 1.0 / static_cast<double>(nbPhiSteps)
200  << static_cast<double>(t) * 1.0 / static_cast<double>(nbThetaSteps)
201  << static_cast<double>(p+1) * 1.0 / static_cast<double>(nbPhiSteps);
202 
203  indexFace << currentIndex + 2 * t << currentIndex + 2 * t + 1 ;
204  theta+= thetaStep;
205 
206  }
207 
208  currentIndex+= 2 * t;
209  addTrianglesStrip(pMaterial, indexFace);
210  phi+= phiStep;
211  }
212 
213  addVertice(verticeFloat);
214  addNormals(normalsFloat);
215  addTexels(texelVector);
216 
217  finish();
218 }
219 
220 

©2005-2013 Laurent Ribon