root/src/mesh/CylinderMesh.cpp

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

DEFINITIONS

This source file includes following definitions.
  1. unit
  2. angle

   1 #include "mesh/CylinderMesh.hpp"
   2 #include <osgUtil/SmoothingVisitor>
   3 
   4 CylinderMesh::CylinderMesh()
   5 { }
   6 
   7 const tuple< const Vec3Array * const
   8            , const DrawElementsUShort * const
   9            , const Vec3Array * const
  10            >
  11 CylinderMesh::unit(unsigned int points)
  12 {
  13     //points should always be even
  14 
  15     // First check if cylinder with the required number of points already exists.
  16     auto result = cylinders.find(points);
  17     if(result != cylinders.end()) { return result -> second; }
  18 
  19     // If a cylinder is not found then create, cache and return it.
  20 
  21     unsigned int vertex_count   = 2 * points;
  22     unsigned int triangle_count = 12 * points - 12;
  23 
  24     unsigned int triangle_index = 0;
  25 
  26     unsigned int i, j;
  27     float theta;
  28 
  29     float theta_delta = 2.0 * M_PI / points;
  30     float z;
  31     float radius;
  32 
  33     Vec3Array          * vertices = new Vec3Array(2 * vertex_count);
  34     Vec3Array          * normals  = new Vec3Array(2 * vertex_count);
  35     DrawElementsUShort * indices  = new DrawElementsUShort(GL_TRIANGLES, triangle_count);
  36 
  37     float x, y;
  38     // const float COS_DELTA_THETA         = cos(theta_delta);
  39     // const float COS_DELTA_THETA_HALF    = cos(theta_delta / 2);
  40     // const float NORMAL_MAGNITUDE        = sqrt(COS_DELTA_THETA + 3);
  41     // float x, y, nx, ny;
  42     // const float NZ = M_SQRT2 / NORMAL_MAGNITUDE;
  43     // const float NC = M_SQRT2 * COS_DELTA_THETA_HALF / NORMAL_MAGNITUDE;
  44 
  45     for(i = 0; i < points; ++i)
  46     {
  47         theta = i * theta_delta;
  48         x = cos(theta);
  49         y = sin(theta);
  50 
  51         // nx = NC * x;
  52         // ny = NC * y;
  53 
  54         (*vertices)[i]          = Vec3f(x, y,  0.5f);
  55         (*vertices)[i + points] = Vec3f(x, y, -0.5f);
  56         (*vertices)[i + 2 * points] = Vec3f(x, y,  0.5f);
  57         (*vertices)[i + 3 * points] = Vec3f(x, y, -0.5f);
  58 
  59         // (*normals)[i]           = Vec3f(nx, ny,  NZ);
  60         // (*normals)[i + points]  = Vec3f(nx, ny, -NZ);
  61         (*normals)[i]           = Vec3f(x,y,0.0f);
  62         (*normals)[i + points]  = Vec3f(x,y,0.0f);
  63         (*normals)[i + 2 * points] = Vec3f(0.0f, 0.0f, 1.0f);
  64         (*normals)[i + 3 * points]  = Vec3f( 0.0f, 0.0f, -1.0f);
  65 
  66         // (*normals)[i + points] -> normalize();
  67         // (*normals)[i]           = Vec3f(nx, ny,  0);
  68         // (*normals)[i + points]  = Vec3f(nx, ny,  0);
  69     }
  70 
  71     for(i = 0; i < points; ++i)
  72     {
  73         (*indices)[triangle_index    ] = i;
  74         (*indices)[triangle_index + 1] = i + points;
  75         (*indices)[triangle_index + 2] = i + 1;
  76 
  77         (*indices)[triangle_index + 3] = i + points;
  78         (*indices)[triangle_index + 4] = i + 1 + points;
  79         (*indices)[triangle_index + 5] = i + 1;
  80 
  81         triangle_index += 6;
  82     }
  83 
  84     (*indices)[triangle_index - 1]     = 0;
  85     (*indices)[triangle_index - 2]     = points;
  86     (*indices)[triangle_index - 4]     = 0;
  87 
  88     for(i = 2 * points + 1; i < 3 * points - 1; ++i)
  89     {
  90         (*indices)[triangle_index    ] = 2 * points;
  91         (*indices)[triangle_index + 1] = i;
  92         (*indices)[triangle_index + 2] = i + 1;
  93         triangle_index += 3;
  94     }
  95 
  96     for(i = 3 * points + 1; i < 4 * points - 1; ++i)
  97     {
  98         (*indices)[triangle_index    ] = i + 1;
  99         (*indices)[triangle_index + 1] = i;
 100         (*indices)[triangle_index + 2] = 3 * points;
 101         triangle_index += 3;
 102     }
 103 
 104     auto insert_position =
 105         cylinders.insert( make_pair( points
 106                                    , make_tuple( vertices
 107                                                , indices
 108                                                , normals
 109                                                )
 110                                    )
 111                         );
 112     return insert_position.first -> second;
 113 }
 114 
 115 float
 116 CylinderMesh::angle(Vec3f& vector1, Vec3f& vector2)
 117 {
 118     float dot = vector1 * vector2;
 119     float det = vector1.x() * vector2.y() - vector1.y() * vector2.x();
 120     RECORD_INFO(string("angle =>") + to_string(atan2(det, dot)));
 121     return atan2(det, dot);
 122 }
 123 
 124 void
 125 CylinderMesh::operator()( Vec3f        center
 126                         , float        upper_radius
 127                         , float        lower_radius
 128                         , float        height
 129                         , Vec3f        direction
 130                         , Geometry  *  geometry
 131                         , unsigned int points
 132                         , const Vec4&  color
 133                         , Vec3f        parent
 134                         )
 135 {
 136     const auto arrays = unit(points);
 137 
 138     const auto unit_vertices = get<0>(arrays);
 139     const auto unit_indices  = get<1>(arrays);
 140     const auto unit_normals  = get<2>(arrays);
 141 
 142     ref_ptr<Vec3Array> vertices(
 143         new Vec3Array(unit_vertices -> size())
 144                                );
 145     ref_ptr<Vec3Array> normals(
 146         new Vec3Array(unit_normals -> size())
 147                               );
 148     ref_ptr<DrawElementsUShort> indices(
 149         new DrawElementsUShort(*unit_indices)
 150                                        );
 151 
 152     unsigned int i, j;
 153     Vec3f temp_vertex;
 154 
 155 
 156 
 157     Quat rotate;
 158     rotate.makeRotate(parent, osg::Vec3f(0.0f, 0.0f, 1.0f));
 159     Vec3f side = osg::Vec3f(0.0f, 0.0f, 1.0f) ^ (rotate * direction);
 160     side.normalize();
 161     RECORD_INFO(string("side => ") + to_string(side[0]) + "," + to_string(side[1]) + "," + to_string(side[2]));
 162 
 163     float warp_angle = acos((parent * direction) / (parent.length() * direction.length()));
 164 
 165     float max_warp = lower_radius * tan(warp_angle);
 166 
 167     RECORD_INFO(to_string(warp_angle));
 168     // RECORD_INFO();
 169     if(parent.length() != 0.0)
 170     {
 171         RECORD_INFO("coming here!");
 172         for(i = 0; i < points; ++i)
 173         {
 174             temp_vertex.set( (*vertices)[i + points][0]
 175                            , (*vertices)[i + points][1]
 176                            , 0.0
 177                            );
 178             float proportion = angle(side, temp_vertex) / M_PI;
 179             RECORD_INFO( string("proportion => ") + to_string(proportion));
 180             if(proportion <= -0.5f)
 181             {
 182                 (*vertices)[i + 3 * points][2] = (*vertices)[i + points][2] =
 183                 -0.5 - 2 * (1 + proportion) * max_warp;
 184             }
 185             else if(proportion <= 0.0f)
 186             {
 187                 (*vertices)[i + 3 * points][2] = (*vertices)[i + points][2] =
 188                 -0.5 + 2 * proportion * max_warp;
 189             }
 190             else if(proportion <= 0.5f)
 191             {
 192                 (*vertices)[i + 3 * points][2] = (*vertices)[i + points][2] =
 193                 -0.5 + 2 * proportion * max_warp;
 194             }
 195             else if(proportion <= 1.0f)
 196             {
 197                 (*vertices)[i + 3 * points][2] = (*vertices)[i + points][2] =
 198                 -0.5 + 2 * (1.0 - proportion) * max_warp;
 199             }
 200         }
 201     }
 202 
 203     rotate.makeRotate(osg::Vec3f(0.0f, 0.0f, 1.0f), direction);
 204 
 205     for(i = 0; i < points; ++i)
 206     {
 207         temp_vertex.set( upper_radius * (*unit_vertices)[i][0]
 208                        , upper_radius * (*unit_vertices)[i][1]
 209                        , height/2.0f
 210                        );
 211         (*vertices)[i + 2 * points] = (*vertices)[i] = rotate * temp_vertex + center;
 212         (*normals)[i + points]  = (*normals)[i]  = rotate * (*unit_normals)[i];
 213         (*normals)[i + 2 * points] = direction;
 214         (*normals)[i + 3 * points] = -direction;
 215         j = i + points;
 216         temp_vertex.set( lower_radius * (*unit_vertices)[j][0]
 217                        , lower_radius * (*unit_vertices)[j][1]
 218                        , -height/2.0f
 219                        );
 220 
 221         (*vertices)[j + 2 * points] = (*vertices)[j] = rotate * temp_vertex + center;
 222     }
 223 
 224 
 225     // for(; i < unit_vertices -> size(); ++i)
 226     // {
 227     //     (*vertices)[i] = rotate * temp_vertex + center;
 228 
 229     //     (*normals)[i]  = rotate * (*unit_normals)[i];
 230     // }
 231 
 232     Vec4Array * colors = new Vec4Array();
 233     colors -> push_back(color); //color);
 234     // for(i = 0; i < vertices -> size(); ++i)
 235     // {
 236     // }
 237     geometry -> setNormalArray( normals.get()
 238                                        , Array::BIND_PER_VERTEX
 239                                        );
 240     // polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,0,6));
 241     geometry -> addPrimitiveSet(indices.get());
 242     geometry -> setVertexArray(vertices.get());
 243     geometry -> setColorArray(colors);
 244     geometry -> setColorBinding( osg::Geometry::BIND_OVERALL );
 245     // osgUtil::SmoothingVisitor::smooth(*geometry);
 246 }
 247 
 248 Geometry *
 249 CylinderMesh::operator()( Vec3f        center
 250                         , float        upper_radius
 251                         , float        lower_radius
 252                         , float        height
 253                         , Vec3f        direction
 254                         , unsigned int points
 255                         , const Vec4&  color
 256                         , Vec3f        parent
 257                         )
 258 {
 259 
 260     Geometry * geometry = new Geometry();
 261     operator()( center
 262               , upper_radius
 263               , lower_radius
 264               , height
 265               , direction
 266               , geometry
 267               , points
 268               , color
 269               , parent
 270               );
 271     return geometry;
 272 }
 273 
 274 
 275 void
 276 CylinderMesh::operator()( Vec4f        upper
 277                         , Vec4f        lower
 278                         , Geometry  *  geometry
 279                         , unsigned int points
 280                         , const Vec4&  color
 281                         , Vec3f        parent
 282                         )
 283 {
 284     Vec3f center( (upper[0] + lower[0]) / 2.0
 285                 , (upper[1] + lower[1]) / 2.0
 286                 , (upper[2] + lower[2]) / 2.0
 287                 );
 288 
 289     Vec3f direction( upper[0] - lower[0]
 290                    , upper[1] - lower[1]
 291                    , upper[2] - lower[2]
 292                    );
 293 
 294     float height  = direction.normalize();
 295     float upper_radius = upper[3];
 296     float lower_radius = lower[3];
 297 
 298     operator()( center
 299               , upper_radius
 300               , lower_radius
 301               , height
 302               , direction
 303               , geometry
 304               , points
 305               , color
 306               , parent
 307               );
 308 }
 309 
 310 Geometry *
 311 CylinderMesh::operator()( Vec4f        upper
 312                         , Vec4f        lower
 313                         , unsigned int points
 314                         , const Vec4&  color
 315                         , Vec3f        parent
 316                         )
 317 {
 318     Geometry * geometry = new Geometry();
 319     operator()( upper
 320               , lower
 321               , geometry
 322               , points
 323               , color
 324               , parent
 325               );
 326     return geometry;
 327 }

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