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

SourceForge.net Logo

©2005 Laurent Ribon