glc_cone.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_cone.h"
00025 
00026 // Class chunk id
00027 quint32 GLC_Cone::m_ChunkId= 0xA709;
00028 
00029 GLC_Cone::GLC_Cone(double dRadius, double dLength)
00030 :GLC_Mesh()
00031 , m_Radius(dRadius)
00032 , m_Length(dLength)
00033 , m_Discret(glc::GLC_POLYDISCRET)       // Default discretion
00034 {
00035         Q_ASSERT((m_Radius > 0.0) && (m_Length > 0.0));
00036         createMeshAndWire();
00037 }
00038 
00039 GLC_Cone::GLC_Cone(const GLC_Cone& sourceCone)
00040 :GLC_Mesh(sourceCone)
00041 , m_Radius(sourceCone.m_Radius)
00042 , m_Length(sourceCone.m_Length)
00043 , m_Discret(sourceCone.m_Discret)
00044 {
00045         createMeshAndWire();
00046 }
00047 
00048 GLC_Cone::~GLC_Cone()
00049 {
00050 
00051 }
00052 
00054 // Get Functions
00056 
00057 quint32 GLC_Cone::chunckID()
00058 {
00059         return m_ChunkId;
00060 }
00061 
00062 
00063 GLC_Geometry* GLC_Cone::clone() const
00064 {
00065         return new GLC_Cone(*this);
00066 }
00067 
00068 
00069 const GLC_BoundingBox& GLC_Cone::boundingBox()
00070 {
00071         if (GLC_Mesh::isEmpty())
00072         {
00073                 createMeshAndWire();
00074         }
00075         return GLC_Mesh::boundingBox();
00076 }
00077 
00079 // Set Functions
00081 
00082 void GLC_Cone::setLength(double Length)
00083 {
00084         Q_ASSERT(Length > 0.0);
00085         m_Length= Length;
00086 
00087         GLC_Mesh::clearMeshWireAndBoundingBox();
00088 }
00089 
00090 
00091 void GLC_Cone::setRadius(double Radius)
00092 {
00093         Q_ASSERT(Radius > 0.0);
00094         m_Radius= Radius;
00095 
00096         GLC_Mesh::clearMeshWireAndBoundingBox();
00097 }
00098 
00099 
00100 void GLC_Cone::setDiscretion(int TargetDiscret)
00101 {
00102         Q_ASSERT(TargetDiscret > 0);
00103         if (TargetDiscret != m_Discret)
00104         {
00105                 m_Discret= TargetDiscret;
00106                 if (m_Discret < 6) m_Discret= 6;
00107 
00108                 GLC_Mesh::clearMeshWireAndBoundingBox();
00109         }
00110 }
00111 
00113 // Private Opengl functions
00115 
00116 void GLC_Cone::glDraw(const GLC_RenderProperties& renderProperties)
00117 {
00118 
00119         if (GLC_Mesh::isEmpty())
00120         {
00121                 createMeshAndWire();
00122         }
00123 
00124         GLC_Mesh::glDraw(renderProperties);
00125 }
00126 
00127 
00128 void GLC_Cone::createMeshAndWire()
00129 {
00130         Q_ASSERT(GLC_Mesh::isEmpty());
00131         Q_ASSERT(m_WireData.isEmpty());
00132 
00133         // Create cosinus and sinus array according to the discretion and radius
00134         const int vertexNumber= m_Discret + 1;
00135         // Normals values
00136         QVector<float> cosNormalArray(vertexNumber);
00137         QVector<float> sinNormalArray(vertexNumber);
00138 
00139         QVector<float> cosArray(vertexNumber);
00140         QVector<float> sinArray(vertexNumber);
00141 
00142         const double angle= (2.0 * glc::PI) / static_cast<double>(m_Discret);
00143 
00144         // Normal Z value
00145         GLC_Vector3d normalVector(1.0, 0.0, 0.0);
00146         GLC_Matrix4x4 rotation(glc::Y_AXIS, -atan(m_Radius / m_Length));
00147         normalVector= rotation * normalVector;
00148         const float normalZ= static_cast<float>(normalVector.z());
00149         const double factor= normalVector.x(); // Normailsation factor
00150 
00151         for (int i= 0; i < vertexNumber; ++i)
00152         {
00153                 const double cosValue= cos(static_cast<double>(i) * angle);
00154                 const double sinValue= sin(static_cast<double>(i) * angle);
00155 
00156                 cosNormalArray[i]= static_cast<GLfloat>(factor * cosValue);
00157                 sinNormalArray[i]= static_cast<GLfloat>(factor * sinValue);
00158 
00159                 cosArray[i]= static_cast<GLfloat>(m_Radius * cosValue);
00160                 sinArray[i]= static_cast<GLfloat>(m_Radius * sinValue);
00161         }
00162 
00163 
00164         // Mesh Data
00165         GLfloatVector verticeVector;
00166         GLfloatVector normalsVector;
00167         GLfloatVector texelVector;
00168 
00169         // Wire Data
00170         GLfloatVector bottomWireData(vertexNumber * 3);
00171 
00172         const int size= vertexNumber * 3;
00173         verticeVector.resize(3 * size);
00174         normalsVector.resize(3 * size);
00175         texelVector.resize(2 * size);
00176 
00177         for (int i= 0; i < vertexNumber; ++i)
00178         {
00179                 // Bottom Mesh
00180                 verticeVector[3 * i]= cosArray[i];
00181                 verticeVector[3 * i + 1]= sinArray[i];
00182                 verticeVector[3 * i + 2]= 0.0f;
00183 
00184                 normalsVector[3 * i]= cosNormalArray[i];
00185                 normalsVector[3 * i + 1]= sinNormalArray[i];
00186                 normalsVector[3 * i + 2]= normalZ;
00187 
00188                 texelVector[2 * i]= static_cast<float>(i) / static_cast<float>(m_Discret);
00189                 texelVector[2 * i + 1]= 0.0f;
00190 
00191                 // Bottom Wire
00192                 bottomWireData[3 * i]= cosArray[i];
00193                 bottomWireData[3 * i + 1]= sinArray[i];
00194                 bottomWireData[3 * i + 2]= 0.0f;
00195 
00196                 // Top
00197                 verticeVector[3 * i + 3 * vertexNumber]= 0.0f;
00198                 verticeVector[3 * i + 1 + 3 * vertexNumber]= 0.0f;
00199                 verticeVector[3 * i + 2 + 3 * vertexNumber]= static_cast<float>(m_Length);
00200 
00201                 normalsVector[3 * i + 3 * vertexNumber]= cosNormalArray[i];
00202                 normalsVector[3 * i + 1 + 3 * vertexNumber]= sinNormalArray[i];
00203                 normalsVector[3 * i + 2 + 3 * vertexNumber]= normalZ;
00204 
00205                 texelVector[2 * i + 2 * vertexNumber]= texelVector[i];
00206                 texelVector[2 * i + 1 + 2 * vertexNumber]= 1.0f;
00207 
00208                 // Bottom Cap ends
00209                 verticeVector[3 * i + 2 * 3 * vertexNumber]= cosArray[i];
00210                 verticeVector[3 * i + 1 + 2 * 3 * vertexNumber]= sinArray[i];
00211                 verticeVector[3 * i + 2 + 2 * 3 * vertexNumber]= 0.0f;
00212 
00213                 normalsVector[3 * i + 2 * 3 * vertexNumber]= 0.0f;
00214                 normalsVector[3 * i + 1 + 2 * 3 * vertexNumber]= 0.0f;
00215                 normalsVector[3 * i + 2 + 2 * 3 * vertexNumber]= -1.0f;
00216 
00217                 texelVector[2 * i + 2 * 2 * vertexNumber]= texelVector[i];
00218                 texelVector[2 * i + 1 + 2 * 2 * vertexNumber]= 0.0f;
00219 
00220         }
00221 
00222         // Add bulk data in to the mesh
00223         GLC_Mesh::addVertice(verticeVector);
00224         GLC_Mesh::addNormals(normalsVector);
00225         GLC_Mesh::addTexels(texelVector);
00226 
00227         // Add polyline to wire data
00228         GLC_Geometry::addVerticeGroup(bottomWireData);
00229 
00230         // Set the material to use
00231         GLC_Material* pCylinderMaterial;
00232         if (hasMaterial())
00233         {
00234                 pCylinderMaterial= this->firstMaterial();
00235         }
00236         else
00237         {
00238                 pCylinderMaterial= new GLC_Material();
00239         }
00240 
00241         IndexList circumferenceStrips;
00242         // Create the index
00243         for (int i= 0; i < vertexNumber; ++i)
00244         {
00245                 circumferenceStrips.append(i + vertexNumber);
00246                 circumferenceStrips.append(i);
00247         }
00248         addTrianglesStrip(pCylinderMaterial, circumferenceStrips);
00249 
00250         {
00251                 IndexList bottomCap;
00252                 IndexList topCap;
00253                 int id1= 0;
00254                 int id2= m_Discret - 1;
00255                 const int size= m_Discret / 2 + (m_Discret % 2);
00256                 for (int i= 0; i < size; ++i)
00257                 {
00258                         bottomCap.append(id1 + 2 * vertexNumber);
00259                         bottomCap.append(id2 + 2 * vertexNumber);
00260 
00261                         id1+= 1;
00262                         id2-= 1;
00263                 }
00264                 addTrianglesStrip(pCylinderMaterial, bottomCap);
00265         }
00266 
00267         finish();
00268 }
00269 

SourceForge.net Logo

©2005-2011 Laurent Ribon