void GLC_Sphere::createMesh() { Q_ASSERT(GLC_Mesh::isEmpty()); GLfloatVector verticeFloat; GLfloatVector normalsFloat; GLfloatVector texelVector; int currentIndex=0; float wishedThetaStep= glc::PI / m_Discret; float thetaRange= m_ThetaMax-m_ThetaMin; int nbThetaSteps= (int) (thetaRange / wishedThetaStep) + 1 ; float thetaStep= thetaRange / nbThetaSteps; float wishedPhiStep= wishedThetaStep; float phiRange= m_PhiMax-m_PhiMin; int nbPhiSteps= (int) (phiRange / wishedPhiStep) + 1 ; float phiStep= phiRange / nbPhiSteps; float cost, sint, cosp, sinp, cospp, sinpp; float xi, yi, zi, xf, yf, zf; float theta= m_ThetaMin; float phi= m_PhiMin; GLfloatVector thetaMinWire; GLfloatVector thetaMaxWire; GLfloatVector phiMinWire; GLfloatVector phiMaxWire; GLC_Material* pMaterial; if (hasMaterial()) pMaterial= this->firstMaterial(); else pMaterial= new GLC_Material(); // shaded face for (int p= 0; p < nbPhiSteps; ++p) { cosp= cos (phi); sinp= sin (phi); cospp= cos (phi + phiStep); sinpp= sin (phi + phiStep); zi = m_Radius * sinp; zf = m_Radius * sinpp; IndexList indexFace; theta = m_ThetaMin; int t; for (t= 0; t <= nbThetaSteps; ++t) { cost= cos( theta ); sint= sin( theta ); xi= m_Radius * cost * cosp; yi= m_Radius * sint * cosp; xf= m_Radius * cost * cospp; yf= m_Radius * sint * cospp; verticeFloat << xf << yf << zf << xi << yi << zi; normalsFloat << cost * cospp << sint * cospp << sinpp << cost * cosp << sint * cosp << sinp; texelVector << static_cast<double>(t) * 1.0 / static_cast<double>(nbThetaSteps) << static_cast<double>(p) * 1.0 / static_cast<double>(nbPhiSteps) << static_cast<double>(t) * 1.0 / static_cast<double>(nbThetaSteps) << static_cast<double>(p+1) * 1.0 / static_cast<double>(nbPhiSteps); indexFace << currentIndex + 2 * t << currentIndex + 2 * t + 1 ; theta+= thetaStep; } currentIndex+= 2 * t; addTrianglesStrip(pMaterial, indexFace); phi+= phiStep; } addVertice(verticeFloat); addNormals(normalsFloat); addTexels(texelVector); finish(); }
void GLC_Cone::createMeshAndWire() { Q_ASSERT(GLC_Mesh::isEmpty()); Q_ASSERT(m_WireData.isEmpty()); // Create cosinus and sinus array according to the discretion and radius const int vertexNumber= m_Discret + 1; // Normals values QVector<float> cosNormalArray(vertexNumber); QVector<float> sinNormalArray(vertexNumber); QVector<float> cosArray(vertexNumber); QVector<float> sinArray(vertexNumber); const double angle= (2.0 * glc::PI) / static_cast<double>(m_Discret); // Normal Z value GLC_Vector3d normalVector(1.0, 0.0, 0.0); GLC_Matrix4x4 rotation(glc::Y_AXIS, -atan(m_Radius / m_Length)); normalVector= rotation * normalVector; const float normalZ= static_cast<float>(normalVector.z()); const double factor= normalVector.x(); // Normailsation factor for (int i= 0; i < vertexNumber; ++i) { const double cosValue= cos(static_cast<double>(i) * angle); const double sinValue= sin(static_cast<double>(i) * angle); cosNormalArray[i]= static_cast<GLfloat>(factor * cosValue); sinNormalArray[i]= static_cast<GLfloat>(factor * sinValue); cosArray[i]= static_cast<GLfloat>(m_Radius * cosValue); sinArray[i]= static_cast<GLfloat>(m_Radius * sinValue); } // Mesh Data GLfloatVector verticeVector; GLfloatVector normalsVector; GLfloatVector texelVector; // Wire Data GLfloatVector bottomWireData(vertexNumber * 3); const int size= vertexNumber * 3; verticeVector.resize(3 * size); normalsVector.resize(3 * size); texelVector.resize(2 * size); for (int i= 0; i < vertexNumber; ++i) { // Bottom Mesh verticeVector[3 * i]= cosArray[i]; verticeVector[3 * i + 1]= sinArray[i]; verticeVector[3 * i + 2]= 0.0f; normalsVector[3 * i]= cosNormalArray[i]; normalsVector[3 * i + 1]= sinNormalArray[i]; normalsVector[3 * i + 2]= normalZ; texelVector[2 * i]= static_cast<float>(i) / static_cast<float>(m_Discret); texelVector[2 * i + 1]= 0.0f; // Bottom Wire bottomWireData[3 * i]= cosArray[i]; bottomWireData[3 * i + 1]= sinArray[i]; bottomWireData[3 * i + 2]= 0.0f; // Top verticeVector[3 * i + 3 * vertexNumber]= 0.0f; verticeVector[3 * i + 1 + 3 * vertexNumber]= 0.0f; verticeVector[3 * i + 2 + 3 * vertexNumber]= static_cast<float>(m_Length); normalsVector[3 * i + 3 * vertexNumber]= cosNormalArray[i]; normalsVector[3 * i + 1 + 3 * vertexNumber]= sinNormalArray[i]; normalsVector[3 * i + 2 + 3 * vertexNumber]= normalZ; texelVector[2 * i + 2 * vertexNumber]= texelVector[i]; texelVector[2 * i + 1 + 2 * vertexNumber]= 1.0f; // Bottom Cap ends verticeVector[3 * i + 2 * 3 * vertexNumber]= cosArray[i]; verticeVector[3 * i + 1 + 2 * 3 * vertexNumber]= sinArray[i]; verticeVector[3 * i + 2 + 2 * 3 * vertexNumber]= 0.0f; normalsVector[3 * i + 2 * 3 * vertexNumber]= 0.0f; normalsVector[3 * i + 1 + 2 * 3 * vertexNumber]= 0.0f; normalsVector[3 * i + 2 + 2 * 3 * vertexNumber]= -1.0f; texelVector[2 * i + 2 * 2 * vertexNumber]= texelVector[i]; texelVector[2 * i + 1 + 2 * 2 * vertexNumber]= 0.0f; } // Add bulk data in to the mesh GLC_Mesh::addVertice(verticeVector); GLC_Mesh::addNormals(normalsVector); GLC_Mesh::addTexels(texelVector); // Add polyline to wire data GLC_Geometry::addPolyline(bottomWireData); // Set the material to use GLC_Material* pCylinderMaterial; if (hasMaterial()) { pCylinderMaterial= this->firstMaterial(); } else { pCylinderMaterial= new GLC_Material(); } IndexList circumferenceStrips; // Create the index for (int i= 0; i < vertexNumber; ++i) { circumferenceStrips.append(i + vertexNumber); circumferenceStrips.append(i); } addTrianglesStrip(pCylinderMaterial, circumferenceStrips); { IndexList bottomCap; IndexList topCap; int id1= 0; int id2= m_Discret - 1; const int size= m_Discret / 2 + (m_Discret % 2); for (int i= 0; i < size; ++i) { bottomCap.append(id1 + 2 * vertexNumber); bottomCap.append(id2 + 2 * vertexNumber); id1+= 1; id2-= 1; } addTrianglesStrip(pCylinderMaterial, bottomCap); } finish(); }