glc_sphere.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2010 Laurent Bauer
00005  Copyright (C) 2010 Laurent Ribon (laumaya@users.sourceforge.net)
00006  http://glc-lib.sourceforge.net
00007 
00008  GLC-lib is free software; you can redistribute it and/or modify
00009  it under the terms of the GNU Lesser General Public License as published by
00010  the Free Software Foundation; either version 3 of the License, or
00011  (at your option) any later version.
00012 
00013  GLC-lib is distributed in the hope that it will be useful,
00014  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  GNU Lesser General Public License for more details.
00017 
00018  You should have received a copy of the GNU Lesser General Public License
00019  along with GLC-lib; if not, write to the Free Software
00020  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00021 
00022  *****************************************************************************/
00024 
00025 #include "glc_sphere.h"
00026 
00027 // Class chunk id
00028 quint32 GLC_Sphere::m_ChunkId= 0xA710;
00029 
00030 GLC_Sphere::GLC_Sphere(double radius)
00031 : GLC_Mesh()
00032 , m_Radius (radius)
00033 , m_Discret(glc::GLC_POLYDISCRET)
00034 , m_ThetaMin (0.0)
00035 , m_ThetaMax(2 * glc::PI)
00036 , m_PhiMin(-glc::PI / 2.0)
00037 , m_PhiMax(glc::PI / 2.0)
00038 {
00039         createMesh();
00040 }
00041 
00042 
00043 GLC_Sphere::GLC_Sphere(const GLC_Sphere & sphere)
00044 :GLC_Mesh(sphere)
00045 , m_Radius (sphere.m_Radius)
00046 , m_Discret(sphere.m_Discret)
00047 , m_ThetaMin (sphere.m_ThetaMin)
00048 , m_ThetaMax(sphere.m_ThetaMax)
00049 , m_PhiMin(sphere.m_PhiMin)
00050 , m_PhiMax(sphere.m_PhiMax)
00051 {
00052         createMesh();
00053 }
00054 
00055 GLC_Sphere::~GLC_Sphere()
00056 {
00057 
00058 }
00059 
00060 GLC_Geometry* GLC_Sphere::clone() const
00061 {
00062         return new GLC_Sphere (*this);
00063 }
00064 
00065 const GLC_BoundingBox& GLC_Sphere::boundingBox()
00066 {
00067         if ( GLC_Mesh::isEmpty() )
00068         {
00069                 createMesh();
00070         }
00071         return GLC_Mesh::boundingBox();
00072 }
00073 
00074 void GLC_Sphere::setRadius(double Radius)
00075 {
00076         Q_ASSERT(Radius > 0.0);
00077         m_Radius= Radius;
00078 
00079         GLC_Mesh::clearMeshWireAndBoundingBox();
00080 }
00081 
00082 
00083 void GLC_Sphere::setDiscretion(int TargetDiscret)
00084 {
00085         Q_ASSERT(TargetDiscret > 0);
00086         if (TargetDiscret != m_Discret)
00087         {
00088                 m_Discret= TargetDiscret;
00089                 if (m_Discret < 6) m_Discret= 6;
00090 
00091                 GLC_Mesh::clearMeshWireAndBoundingBox();
00092         }
00093 }
00094 
00095 void GLC_Sphere::glDraw(const GLC_RenderProperties& renderProperties)
00096 {
00097         if (GLC_Mesh::isEmpty())
00098         {
00099                 createMesh();
00100         }
00101 
00102         GLC_Mesh::glDraw(renderProperties);
00103 }
00104 
00105 void GLC_Sphere::createMesh()
00106 {
00107 
00108         Q_ASSERT(GLC_Mesh::isEmpty());
00109 
00110         GLfloatVector verticeFloat;
00111         GLfloatVector normalsFloat;
00112         GLfloatVector texelVector;
00113 
00114         int currentIndex=0;
00115 
00116         float wishedThetaStep= glc::PI / m_Discret;
00117         float thetaRange= m_ThetaMax-m_ThetaMin;
00118         int nbThetaSteps= (int) (thetaRange / wishedThetaStep) + 1 ;
00119         float thetaStep= thetaRange / nbThetaSteps;
00120 
00121         float wishedPhiStep= wishedThetaStep;
00122         float phiRange= m_PhiMax-m_PhiMin;
00123         int nbPhiSteps= (int) (phiRange / wishedPhiStep) + 1 ;
00124         float phiStep= phiRange / nbPhiSteps;
00125 
00126         float cost, sint, cosp, sinp, cospp, sinpp;
00127         float xi, yi, zi, xf, yf, zf;
00128         float theta= m_ThetaMin;
00129         float phi= m_PhiMin;
00130 
00131         GLfloatVector thetaMinWire;
00132         GLfloatVector thetaMaxWire;
00133         GLfloatVector phiMinWire;
00134         GLfloatVector phiMaxWire;
00135 
00136         GLC_Material* pMaterial;
00137         if (hasMaterial())
00138                 pMaterial= this->firstMaterial();
00139         else
00140                 pMaterial= new GLC_Material();
00141 
00142         // shaded face
00143         for (int p= 0; p < nbPhiSteps; ++p)
00144         {
00145                 cosp= cos (phi);
00146                 sinp= sin (phi);
00147                 cospp= cos (phi + phiStep);
00148                 sinpp= sin (phi + phiStep);
00149 
00150                 zi = m_Radius * sinp;
00151                 zf = m_Radius * sinpp;
00152 
00153                 IndexList indexFace;
00154 
00155                 theta = m_ThetaMin;
00156                 int t;
00157                 for (t= 0; t <= nbThetaSteps; ++t)
00158                 {
00159                         cost= cos( theta );
00160                         sint= sin( theta );
00161 
00162                         xi= m_Radius * cost * cosp;
00163                         yi= m_Radius * sint * cosp;
00164                         xf= m_Radius * cost * cospp;
00165                         yf= m_Radius * sint * cospp;
00166 
00167                         verticeFloat << xf << yf << zf << xi << yi << zi;
00168                         normalsFloat << cost * cospp << sint * cospp << sinpp << cost * cosp << sint * cosp << sinp;
00169                         texelVector << static_cast<double>(t) * 1.0 / static_cast<double>(nbThetaSteps)
00170                                                 << static_cast<double>(p) * 1.0 / static_cast<double>(nbPhiSteps)
00171                                                 << static_cast<double>(t) * 1.0 / static_cast<double>(nbThetaSteps)
00172                                                 << static_cast<double>(p+1) * 1.0 / static_cast<double>(nbPhiSteps);
00173 
00174                         indexFace << currentIndex + 2 * t << currentIndex + 2 * t + 1 ;
00175                         theta+= thetaStep;
00176 
00177                 }
00178 
00179                 currentIndex+= 2 * t;
00180                 addTrianglesStrip(pMaterial, indexFace);
00181                 phi+= phiStep;
00182         }
00183 
00184         addVertice(verticeFloat);
00185         addNormals(normalsFloat);
00186         addTexels(texelVector);
00187 
00188         finish();
00189 }
00190 
00191 

SourceForge.net Logo

©2005-2011 Laurent Ribon