root/src/mesh/SphereMesh.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. unit

   1 #include "mesh/SphereMesh.hpp"
   2 
   3 using namespace std;
   4 using namespace osg;
   5 
   6 SphereMesh::SphereMesh()
   7 { }
   8 
   9 const tuple< const Vec3Array * const
  10            , const DrawElementsUShort * const
  11            , const Vec3Array * const
  12            >
  13 SphereMesh::unit(unsigned int points)
  14 {
  15     //points should always be even
  16 
  17     // First check if sphere with the required number of points already exists.
  18     auto result = spheres.find(points);
  19     if(result != spheres.end()) { return result -> second; }
  20 
  21     // If a sphere is not found then create, cache and return it.
  22 
  23     unsigned int vertex_count   = (points * points) / 2 - points + 2;
  24     unsigned int triangle_count = 3 * points * points - 6 * points;
  25 
  26     unsigned int vertex_index   = 1;
  27     unsigned int triangle_index = 0;
  28 
  29     unsigned int i, j;
  30     unsigned int alpha, beta;
  31 
  32     float phi_delta   = 2.0 * M_PI / points;
  33     float theta_delta = 2.0 * M_PI / points;
  34     float z;
  35     float radius;
  36 
  37     Vec3Array          * vertices = new Vec3Array(vertex_count);
  38     Vec3Array          * normals  = new Vec3Array(vertex_count);
  39     DrawElementsUShort * indices  = new DrawElementsUShort(GL_TRIANGLES, triangle_count);
  40 
  41     // Excluding the topmost and bottommost vertices there will be n - 2 vertices
  42     // So there will be (n - 2)/2 vertices per side
  43     // There will be a angle delta of n/2 between each vertex.
  44 
  45     (*vertices)[0] = (*normals)[0] = Vec3f(0.0f, 0.0f, 1.0f);
  46 
  47     for(i = 1; i < points / 2; ++i)
  48     {
  49         z = cos( i * phi_delta);
  50         radius = sin( i * phi_delta );
  51         for(j = 0; j < points; ++j)
  52         {
  53             (*vertices)[vertex_index] =
  54             (*normals)[vertex_index] =
  55                 Vec3f( radius * cos(j * theta_delta)
  56                      , radius * sin(j * theta_delta)
  57                      , z
  58                      );
  59             ++vertex_index;
  60         }
  61     }
  62 
  63     (*vertices)[vertex_index] =
  64     (*normals)[vertex_index] = Vec3f(0.0f, 0.0f, -1.0f);
  65 
  66     for(i = 0; i < points; ++i)
  67     {
  68         (*indices)[triangle_index]     = 0;
  69         (*indices)[triangle_index + 1] = i + 1;
  70         (*indices)[triangle_index + 2] = i + 2;
  71         triangle_index += 3;
  72     }
  73 
  74     (*indices)[triangle_index - 1]     = 1;
  75 
  76     for(i = 1; i < points / 2 - 1; ++i)
  77     {
  78         alpha = 1 + points * (i - 1);
  79         beta  = 1 + points * i;
  80 
  81         for(j = 0; j < points; ++j)
  82         {
  83             (*indices)[triangle_index    ] = alpha + j;
  84             (*indices)[triangle_index + 1] = beta  + j;
  85             (*indices)[triangle_index + 2] = beta  + j + 1;
  86 
  87             (*indices)[triangle_index + 3] = alpha + j + 1;
  88             (*indices)[triangle_index + 4] = alpha + j;
  89             (*indices)[triangle_index + 5] = beta  + j + 1;
  90             triangle_index += 6;
  91         }
  92         (*indices)[triangle_index - 4] = beta;
  93         (*indices)[triangle_index - 3] = alpha;
  94         (*indices)[triangle_index - 1] = beta;
  95     }
  96 
  97     for(i = 0; i < points; ++i)
  98     {
  99         (*indices)[triangle_index    ] = vertex_count - 1;
 100         (*indices)[triangle_index + 1] = beta + i + 1;
 101         (*indices)[triangle_index + 2] = beta + i;
 102         triangle_index += 3;
 103     }
 104 
 105     (*indices)[triangle_index - 2]     = beta;
 106 
 107     auto insert_position = spheres.insert(make_pair( points
 108                             , make_tuple( vertices
 109                                         , indices
 110                                         , normals
 111                                         )
 112                             )
 113                   );
 114     return insert_position.first -> second;
 115 }
 116 
 117 Geometry *
 118 SphereMesh::operator()( Vec3f        center
 119                       , float        radius
 120                       , unsigned int points
 121                       , const Vec4&  color
 122                       )
 123 {
 124     Geometry * geometry = new Geometry();
 125     operator()( center
 126               , radius
 127               , geometry
 128               , points
 129               , color
 130               );
 131     return geometry;
 132 }
 133 
 134 void
 135 SphereMesh::operator()( Vec3f        center
 136                       , float        radius
 137                       , Geometry  *  geometry
 138                       , unsigned int points
 139                       , const Vec4&  color
 140                       )
 141 {
 142     const auto arrays = unit(points);
 143 
 144     const auto unit_vertices = get<0>(arrays);
 145     const auto unit_indices  = get<1>(arrays);
 146     const auto unit_normals  = get<2>(arrays);
 147 
 148     Vec3Array          * vertices = new Vec3Array(unit_vertices -> size());
 149     Vec3Array          * normals  = new Vec3Array(*unit_normals);
 150     DrawElementsUShort * indices  = new DrawElementsUShort(*unit_indices);
 151 
 152     std::transform( unit_vertices -> begin()
 153                   , unit_vertices -> end()
 154                   , vertices -> begin()
 155                   , [&](const Vec3f& vertex)
 156                     {
 157                         return vertex * radius + center;
 158                     }
 159                   );
 160 
 161     geometry -> setVertexArray(vertices);
 162     geometry -> setNormalArray(normals);
 163     geometry -> setNormalBinding(Geometry::BIND_PER_VERTEX);
 164     geometry -> addPrimitiveSet(indices);
 165     Vec4Array * colors = new Vec4Array();
 166     colors -> push_back(color); //color);
 167     geometry -> setColorArray(colors);
 168     geometry -> setColorBinding( osg::Geometry::BIND_OVERALL );
 169 }

/* [<][>][^][v][top][bottom][index][help] */