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

#include "ElevationGrid.H"
#include "renderer.H"

namespace xrml {

void ElevationGrid::set_height(const MFFloat&)
{
  Warning(NULL, "ElevationGrid::set_height(): not yet implemented");
}

void ElevationGrid::render(void)
{
  world->renderer->elevationGrid(this);
}

void ElevationGrid::discretize(void)
{
  int i,j,k;

  if (color) {col = &color->color;} else col = 0;
  if (normal) {norm = &normal->vector;} else norm = 0;
  if (texCoord) {texco = &texCoord->point;} else texco = 0;

  // compute coordinates
  if (co) 
    delete co;
  co = 0;

  if (xDimension < 0) {
    Warning(NULL, "%s.xDimension should be >0", name());
    xDimension = 0;
  }
  if (zDimension < 0) {
    Warning(NULL, "%s.zDimension should be >0", name());
    zDimension = 0;
  }
  if (xSpacing < 0) {
    Warning(NULL, "%s.xSpacing should be >0", name());
    xSpacing = 0;
  }
  if (zSpacing < 0) {
    Warning(NULL, "%s.zSpacing should be >0", name());
    zSpacing = 0;
  }

  co = new MFVec3f(xDimension * zDimension);
  co->size = xDimension * zDimension;

  k = 0;
  for (j=0; j<zDimension; j++) {
    for (i=0; i<xDimension; i++) {
      /* k = i + j * xDimension; */
      (*co)[k].x = xSpacing * i;
      (*co)[k].y = height[i + j*xDimension];
      (*co)[k].z = zSpacing * j;
      k++;
    }
  }

  // coordinate index array: also used for per vertex normals, colors 
  // and texture cordinates
  coordIndex.size = 0;
  coordIndex.grow(8 * (xDimension-1) * (zDimension-1));

  k = 0;
  for (j=0; j<zDimension-1; j++) {
    for (i=0; i<xDimension-1; i++) {   
      // make two triangles per quadrilateral: the quadrilaterals will in
      // general not be planar!
      coordIndex[k++] = i + j*xDimension;
      coordIndex[k++] = i + (j+1)*xDimension;
      coordIndex[k++] = (i+1) + j*xDimension;
      coordIndex[k++] = -1;	// end of face marker
      coordIndex[k++] = (i+1) + j*xDimension;
      coordIndex[k++] = i + (j+1)*xDimension;
      coordIndex[k++] = (i+1) + (j+1)*xDimension;
      coordIndex[k++] = -1;	// end of face marker
    }
  }

  if (norm && !normalPerVertex) {
    // per face normals: every quadrilateral was split in two triangles.
    normalIndex.size = 0;
    normalIndex.grow(2 * (xDimension-1) * (zDimension-1));
    for (k=0; k<(xDimension-1) * (zDimension-1); k++) {
      normalIndex[2*k] = k;
      normalIndex[2*k+1] = k;
    }
  }

  if (col && !colorPerVertex) {
    // per face normals: every quadrilateral was split in two triangles.
    colorIndex.size = 0;
    colorIndex.grow(2 * (xDimension-1) * (zDimension-1));
    for (k=0; k<(xDimension-1) * (zDimension-1); k++) {
      colorIndex[2*k] = k;
      colorIndex[2*k+1] = k;
    }
  }

  if (!texco) {
    // compute default texture coordinates
    texco = new MFVec2f(xDimension * zDimension);
    texco->size = xDimension * zDimension;
    k = 0;
    for (j=0; j<zDimension; j++) {
      for (i=0; i<xDimension; i++) {
	/* k = i + j * xDimension; */
	(*texco)[k].s = (float)i/(float)(xDimension-1);
	(*texco)[k].t = (float)j/(float)(zDimension-1);
	k++;
      }
    }
  }
}

}  // namespace xrml
