glc_disc.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021  *****************************************************************************/
00023 
00024 #include "glc_disc.h"
00025 
00026 GLC_Disc::GLC_Disc(double radius, double angle)
00027 : GLC_Mesh()
00028 , m_Radius(radius)
00029 , m_Discret(glc::GLC_POLYDISCRET)
00030 , m_Angle(angle)
00031 , m_Step(0)
00032 {
00033 
00034 }
00035 
00036 GLC_Disc::GLC_Disc(const GLC_Disc& disc)
00037 : GLC_Mesh(disc)
00038 , m_Radius(disc.m_Radius)
00039 , m_Discret(disc.m_Discret)
00040 , m_Angle(disc.m_Angle)
00041 , m_Step(disc.m_Step)
00042 {
00043 
00044 }
00045 
00046 GLC_Disc::~GLC_Disc()
00047 {
00048 
00049 }
00050 
00052 // Get Functions
00054 
00055 const GLC_BoundingBox& GLC_Disc::boundingBox()
00056 {
00057         if (GLC_Mesh::isEmpty())
00058         {
00059                 createMeshAndWire();
00060         }
00061         return GLC_Mesh::boundingBox();
00062 }
00063 
00064 GLC_Geometry* GLC_Disc::clone() const
00065 {
00066         return new GLC_Disc(*this);
00067 }
00068 
00070 // Set Functions
00072 GLC_Disc& GLC_Disc::operator=(const GLC_Disc& disc)
00073 {
00074         if (this != &disc)
00075         {
00076                 // Call the operator of the super class
00077                 GLC_Mesh::operator=(disc);
00078 
00079                 m_Radius= disc.m_Radius;
00080                 m_Discret= disc.m_Discret;
00081                 m_Angle= disc.m_Angle;
00082                 m_Step= disc.m_Step;
00083         }
00084         return *this;
00085 }
00086 
00087 void GLC_Disc::setRadius(double radius)
00088 {
00089         Q_ASSERT(radius > 0.0);
00090         m_Radius= radius;
00091 
00092         GLC_Mesh::clearMeshWireAndBoundingBox();
00093 }
00094 
00095 void GLC_Disc::setDiscretion(int targetDiscret)
00096 {
00097         Q_ASSERT(targetDiscret > 0);
00098         if (targetDiscret != m_Discret)
00099         {
00100                 m_Discret= targetDiscret;
00101                 if (m_Discret < 6) m_Discret= 6;
00102 
00103                 GLC_Mesh::clearMeshWireAndBoundingBox();
00104         }
00105 }
00106 
00107 void GLC_Disc::setAngle(double angle)
00108 {
00109         Q_ASSERT(angle > 0.0);
00110         m_Angle= angle;
00111 
00112         GLC_Mesh::clearMeshWireAndBoundingBox();
00113 }
00115 // Private Opengl functions
00117 void GLC_Disc::glDraw(const GLC_RenderProperties& renderProperties)
00118 {
00119 
00120         if (GLC_Mesh::isEmpty())
00121         {
00122                 createMeshAndWire();
00123         }
00124         GLC_Mesh::glDraw(renderProperties);
00125 }
00126 
00127 // Create the cylinder mesh
00128 void GLC_Disc::createMeshAndWire()
00129 {
00130         Q_ASSERT(GLC_Mesh::isEmpty());
00131         Q_ASSERT(m_WireData.isEmpty());
00132 
00133         m_Step= static_cast<GLuint>(static_cast<double>(m_Discret) * (m_Angle / (2 * glc::PI)));
00134         if (m_Step < 2) m_Step= 2;
00135 
00136         // Create cosinus and sinus array according to the discretion and radius
00137         const int vertexNumber= m_Step + 1;
00138 
00139         QVector<float> cosArray(vertexNumber);
00140         QVector<float> sinArray(vertexNumber);
00141 
00142         const double angle= m_Angle / static_cast<double>(m_Step);
00143         for (int i= 0; i < vertexNumber; ++i)
00144         {
00145                 const double cosValue= cos(static_cast<double>(i) * angle);
00146                 const double sinValue= sin(static_cast<double>(i) * angle);
00147 
00148                 cosArray[i]= static_cast<GLfloat>(m_Radius * cosValue);
00149                 sinArray[i]= static_cast<GLfloat>(m_Radius * sinValue);
00150         }
00151 
00152         // Mesh Data
00153         GLfloatVector verticeVector(vertexNumber * 3);
00154         GLfloatVector normalsVector(vertexNumber * 3);
00155         GLfloatVector texelVector(vertexNumber * 2);
00156 
00157         // Wire Data
00158         GLfloatVector wireData(vertexNumber * 3);
00159 
00160         for (int i= 0; i < vertexNumber; ++i)
00161         {
00162                 verticeVector[3 * i]= cosArray[i];
00163                 verticeVector[3 * i + 1]= sinArray[i];
00164                 verticeVector[3 * i + 2]= 0.0f;
00165 
00166                 normalsVector[3 * i]= 0.0f;
00167                 normalsVector[3 * i + 1]= 0.0f;
00168                 normalsVector[3 * i + 2]= 1.0f;
00169 
00170                 texelVector[2 * i]= texelVector[i];
00171                 texelVector[2 * i + 1]= 0.0f;
00172 
00173                 wireData[3 * i]= cosArray[i];
00174                 wireData[3 * i + 1]= sinArray[i];
00175                 wireData[3 * i + 2]= 0.0f;
00176         }
00177         // Center Point
00178         verticeVector << 0.0f << 0.0f << 0.0f;
00179         normalsVector << 0.0f << 0.0f << 1.0f;
00180         texelVector << 0.5f << 0.5f;
00181 
00182         if (!qFuzzyCompare(m_Angle, (2.0 * glc::PI)))
00183         {
00184                 wireData << 0.0f << 0.0f << 0.0f;
00185                 wireData << wireData[0] << wireData[1] << wireData[2];
00186         }
00187 
00188         // Add bulk data in to the mesh
00189         GLC_Mesh::addVertice(verticeVector);
00190         GLC_Mesh::addNormals(normalsVector);
00191         GLC_Mesh::addTexels(texelVector);
00192 
00193         // Add polyline to wire data
00194         GLC_Geometry::addVerticeGroup(wireData);
00195 
00196         // Set the material to use
00197         GLC_Material* pDiscMaterial;
00198         if (hasMaterial())
00199         {
00200                 pDiscMaterial= this->firstMaterial();
00201         }
00202         else
00203         {
00204                 pDiscMaterial= new GLC_Material();
00205         }
00206 
00207         IndexList discIndex;
00208         discIndex << vertexNumber;
00209         for (int i= 0; i < vertexNumber; ++i)
00210         {
00211                 discIndex << i;
00212         }
00213 
00214         addTrianglesFan(pDiscMaterial, discIndex);
00215 
00216         finish();
00217 }

SourceForge.net Logo

©2005-2011 Laurent Ribon