/* Cylinder.C: Cylinder nodes (public source) */

#include "Cylinder.H"
#include "renderer.H"

namespace xrml {

void Cylinder::render(void)
{
  world->renderer->cylinder(this);
}


void Cylinder::discretize(void)
{
  int nqcd = world->renderer->nrQuartCircleDivisions, n = 4*nqcd;

  if (co) delete co;
  co = new MFVec3f(2*n+2);
  co->size = 2*n+2;
  if (norm) delete norm;
  norm = new MFVec3f(n+2);
  norm->size = n+2;
  if (texco) delete texco;
  texco = new MFVec2f(4*n+1);
  texco->size = 4*n+1;

  float h = height/2.;
  
  for (int i=0; i<n; i++) {
    float t = (float)i/(float)n;
    float s = -sin(2.*M_PI*t);
    float c = -cos(2.*M_PI*t);
    (*co)[  i]      = SFVec3f(radius * s, -h, radius * c);
    (*co)[n+i]      = SFVec3f(radius * s, +h, radius * c);
    (*norm)[i]      = SFVec3f(s, 0., c);
    (*texco)[    i] = SFVec2f(t, 0.);
    (*texco)[n  +i] = SFVec2f(t, 1.);
    (*texco)[2*n+i] = SFVec2f((1.+c)/2., (1.+s)/2.);
    (*texco)[3*n+i] = SFVec2f((1.-c)/2., (1.-s)/2.);
  }
  (*co)[2*n  ] = SFVec3f(0., -h, 0.);
  (*co)[2*n+1] = SFVec3f(0., +h, 0.);
  (*norm)[n  ] = SFVec3f(0., -1., 0.);
  (*norm)[n+1] = SFVec3f(0., +1., 0.);
  (*texco)[4*n] = SFVec2f(0.5, 0.5);

  int nrindices = (side ? 5*n : 0) + (top ? 4*n : 0) + (bottom ? 4*n : 0);

  coordIndex.size = 0;
  coordIndex.grow(nrindices);
  normalIndex.size = 0;
  normalIndex.grow(nrindices);
  texCoordIndex.size = 0;
  texCoordIndex.grow(nrindices);
  
  int k = 0;
  if (side) {
    for (int i=0; i<n; i++, k+=5) {
      coordIndex[k  ] = i;
      coordIndex[k+1] = (i+1)%n;
      coordIndex[k+2] = n+(i+1)%n;
      coordIndex[k+3] = n+i;
      coordIndex[k+4] = -1;	// end of face marker

      normalIndex[k  ] = i;
      normalIndex[k+1] = (i+1)%n;
      normalIndex[k+2] = (i+1)%n;
      normalIndex[k+3] = i;
      normalIndex[k+4] = -1;

      texCoordIndex[k  ] = i;
      texCoordIndex[k+1] = (i+1)%n;
      texCoordIndex[k+2] = n+(i+1)%n;
      texCoordIndex[k+3] = n+i;
      texCoordIndex[k+4] = -1;
    }
  }
  if (bottom) {
    for (int i=0; i<n; i++, k+=4) {
      coordIndex[k  ] = (i+1)%n;
      coordIndex[k+1] = i;
      coordIndex[k+2] = 2*n;
      coordIndex[k+3] = -1;

      normalIndex[k  ] = n;
      normalIndex[k+1] = n;
      normalIndex[k+2] = n;
      normalIndex[k+3] = -1;

      texCoordIndex[k  ] = 2*n + (i+1)%n;
      texCoordIndex[k+1] = 2*n + i;
      texCoordIndex[k+2] = 4*n;
      texCoordIndex[k+3] = -1;
    }
  }
  if (top) {
    for (int i=0; i<n; i++, k+=4) {
      coordIndex[k  ] = n+i;
      coordIndex[k+1] = n+(i+1)%n;
      coordIndex[k+2] = 2*n+1;
      coordIndex[k+3] = -1;

      normalIndex[k  ] = n+1;
      normalIndex[k+1] = n+1;
      normalIndex[k+2] = n+1;
      normalIndex[k+3] = -1;

      texCoordIndex[k  ] = 3*n + i;
      texCoordIndex[k+1] = 3*n + (i+1)%n;
      texCoordIndex[k+2] = 4*n;
      texCoordIndex[k+3] = -1;
    }
  }
}

}  // namespace xrml
