proto


  
  PROTO Nsphere [
     field SFInt32 latitudeLines 4
     field SFInt32 longitudeLines 4
     field SFFloat creaseAngle 3.14
  ]
  {
     DEF IFS IndexedFaceSet {
        coord DEF C Coordinate { }
        texCoord DEF TC TextureCoordinate { }
        creaseAngle IS creaseAngle
     }
     DEF S Script {
        field SFInt32 numLat IS latitudeLines
        field SFInt32 numLong IS longitudeLines
        eventOut MFVec3f c_changed
        eventOut MFVec2f tc_changed
        eventOut MFInt32 ci_changed
        url [
           "javascript:
           function initialize() {
              var r, angle, x, y, z;
              var i, j, polyIndex;
              // Compute coordinates, texture coordinates:
              for (i = 0; i < numLat; i++) {
                 y = 2 * ( i / (numLat-1) ) - 1;
                 r = Math.sqrt( 1 - y*y );
                 for (j = 0; j < numLong; j++) {
                    angle = 2 * Math.PI * j / numLong;
                    x = -Math.sin(angle)*r;
                    z = -Math.cos(angle)*r;
                    c_changed[i*numLong+j] = new SFVec3f(x,y,z);
                    tc_changed[i*numLong+j] = new SFVec2f( j/numLong, i/(numLat-1) );
                 }
              }
              // And compute indices:
              for (i = 0; i < numLat-1; i++) {
                 for (j = 0; j < numLong; j++) {
                    polyIndex = 5*(i*numLong+j);
                    ci_changed[polyIndex+0] = i*numLong+j;
                    ci_changed[polyIndex+1] = i*numLong+(j+1)\%numLong;
                    ci_changed[polyIndex+2] = (i+1)*numLong+(j+1)\%numLong;
                    ci_changed[polyIndex+3] = (i+1)*numLong+j;
                    ci_changed[polyIndex+4] = -1;  // End-of-polygon
                 }
              }
           }"
        ]
     }
     ROUTE S.c_changed TO C.set_point
     ROUTE S.tc_changed TO TC.set_point
     ROUTE S.ci_changed TO IFS.set_coordIndex
  }