// draw a line (cylinder) from a to b
void TachyonDisplayDevice::line(float *a, float*b) {
  int i, j, test;
  float dirvec[3], unitdirvec[3];
  float from[3], to[3], tmp1[3], tmp2[3];
    
  if (lineStyle == ::SOLIDLINE) {
    // transform the world coordinates
    (transMat.top()).multpoint3d(a, from);
    (transMat.top()).multpoint3d(b, to);
    
    // draw the cylinder
    fprintf(outfile, "FCylinder\n"); // flat-ended cylinder
    fprintf(outfile, "  Base %g %g %g\n", from[0], from[1], -from[2]); 
    fprintf(outfile, "  Apex %g %g %g\n", to[0], to[1], -to[2]);
    fprintf(outfile, "  Rad %g \n", float(lineWidth)*DEFAULT_RADIUS);
    write_cindexmaterial(colorIndex, materialIndex);

  } else if (lineStyle == ::DASHEDLINE) {
     // transform the world coordinates
    (transMat.top()).multpoint3d(a, tmp1);
    (transMat.top()).multpoint3d(b, tmp2);

    // how to create a dashed line
    vec_sub(dirvec, tmp2, tmp1);  // vector from a to b
    vec_copy(unitdirvec, dirvec);
    vec_normalize(unitdirvec);    // unit vector from a to b
    test = 1;
    i = 0;
    while (test == 1) {
      for (j=0; j<3; j++) {
        from[j] = (float) (tmp1[j] + (2*i    )*DASH_LENGTH*unitdirvec[j]);
          to[j] = (float) (tmp1[j] + (2*i + 1)*DASH_LENGTH*unitdirvec[j]);
      }
      if (fabsf(tmp1[0] - to[0]) >= fabsf(dirvec[0])) {
        vec_copy(to, tmp2);
        test = 0;
      }
    
      // draw the cylinder
      fprintf(outfile, "FCylinder\n"); // flat-ended cylinder
      fprintf(outfile, "  Base %g %g %g\n", from[0], from[1], -from[2]); 
      fprintf(outfile, "  Apex %g %g %g\n", to[0], to[1], -to[2]);
      fprintf(outfile, "  Rad %g \n", float(lineWidth)*DEFAULT_RADIUS);
      write_cindexmaterial(colorIndex, materialIndex);
      i++;
    }
  } else {
    msgErr << "TachyonDisplayDevice: Unknown line style " 
           << lineStyle << sendmsg;
  }
}
// draw a cylinder
void TachyonDisplayDevice::cylinder(float *a, float *b, float r, int filled) {
  float from[3], to[3], norm[3];
  float radius;
  filled = filled;  

  // transform the world coordinates
  (transMat.top()).multpoint3d(a, from);
  (transMat.top()).multpoint3d(b, to);
  radius = scale_radius(r);
   
 
  // draw the cylinder
  fprintf(outfile, "FCylinder\n"); // flat-ended cylinder
  fprintf(outfile, "  Base %g %g %g\n", from[0], from[1], -from[2]); 
  fprintf(outfile, "  Apex %g %g %g\n", to[0], to[1], -to[2]);
  fprintf(outfile, "  Rad %g\n", radius);
  write_cindexmaterial(colorIndex, materialIndex);

  // Cylinder caps?
  if (filled) {
    float div;

    norm[0] = to[0] - from[0];
    norm[1] = to[1] - from[1];
    norm[2] = to[2] - from[2];

    div = 1.0f / sqrtf(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]);
    norm[0] *= div;
    norm[1] *= div;
    norm[2] *= div;

    if (filled & CYLINDER_TRAILINGCAP) {
      fprintf(outfile, "Ring\n");
      fprintf(outfile, "Center %g %g %g \n", from[0], from[1], -from[2]);
      fprintf(outfile, "Normal %g %g %g \n", norm[0], norm[1], -norm[2]); 
      fprintf(outfile, "Inner 0.0  Outer %g \n", radius);
      write_cindexmaterial(colorIndex, materialIndex);
    }
  
    if (filled & CYLINDER_LEADINGCAP) {
      fprintf(outfile, "Ring\n");
      fprintf(outfile, "Center %g %g %g \n", to[0], to[1], -to[2]);
      fprintf(outfile, "Normal %g %g %g \n", -norm[0], -norm[1], norm[2]); 
      fprintf(outfile, "Inner 0.0  Outer %g \n", radius);
      write_cindexmaterial(colorIndex, materialIndex);
    }
  }
}
// draw a triangle
void RayShadeDisplayDevice::triangle(const float *a, const float *b, const float *c, const float *n1, const float *n2, const float *n3) {
  float vec1[3], vec2[3], vec3[3];
  float norm1[3], norm2[3], norm3[3];
  
  
  // transform the world coordinates
  (transMat.top()).multpoint3d(a, vec1);
  (transMat.top()).multpoint3d(b, vec2);
  (transMat.top()).multpoint3d(c, vec3);

  // and the normals
  (transMat.top()).multnorm3d(n1, norm1);
  (transMat.top()).multnorm3d(n2, norm2);
  (transMat.top()).multnorm3d(n3, norm3);

  write_cindexmaterial(colorIndex, materialIndex);
  fprintf(outfile, "triangle %5f %5f %5f %5f %5f %5f ", 
          scale_fix(vec1[0]), scale_fix(vec1[1]), scale_fix(vec1[2]),
          scale_fix(norm1[0]), scale_fix(norm1[1]), scale_fix(norm1[2]));
  fprintf(outfile, "%5f %5f %5f %5f %5f %5f ",
          scale_fix(vec2[0]), scale_fix(vec2[1]), scale_fix(vec2[2]),
          scale_fix(norm2[0]), scale_fix(norm2[1]), scale_fix(norm2[2]));
  fprintf(outfile, "%5f %5f %5f %5f %5f %5f\n",
          scale_fix(vec3[0]), scale_fix(vec3[1]), scale_fix(vec3[2]),
          scale_fix(norm3[0]), scale_fix(norm3[1]), scale_fix(norm3[2]));
}
// draw a triangle
void TachyonDisplayDevice::triangle(const float *a, const float *b, const float *c, const float *n1, const float *n2, const float *n3) {
  float vec1[3], vec2[3], vec3[3];
  float norm1[3], norm2[3], norm3[3];
  
  
  // transform the world coordinates
  (transMat.top()).multpoint3d(a, vec1);
  (transMat.top()).multpoint3d(b, vec2);
  (transMat.top()).multpoint3d(c, vec3);

  // and the normals
  (transMat.top()).multnorm3d(n1, norm1);
  (transMat.top()).multnorm3d(n2, norm2);
  (transMat.top()).multnorm3d(n3, norm3);

  // draw the triangle
  fprintf(outfile, "STri\n"); // triangle
  fprintf(outfile, "  V0 %g %g %g\n", vec1[0], vec1[1], -vec1[2]);
  fprintf(outfile, "  V1 %g %g %g\n", vec2[0], vec2[1], -vec2[2]); 
  fprintf(outfile, "  V2 %g %g %g\n", vec3[0], vec3[1], -vec3[2]);
  fprintf(outfile, "  N0 %.3f %.3f %.3f\n", -norm1[0], -norm1[1], norm1[2]);
  fprintf(outfile, "  N1 %.3f %.3f %.3f\n", -norm2[0], -norm2[1], norm2[2]); 
  fprintf(outfile, "  N2 %.3f %.3f %.3f\n", -norm3[0], -norm3[1], norm3[2]);
  write_cindexmaterial(colorIndex, materialIndex);
}
// use an efficient mesh primitve rather than individual triangles
// when possible.
void TachyonDisplayDevice::trimesh_c4u_n3b_v3f(unsigned char *c, char *n, float *v, int numfacets) {
  int i;
  float vec1[3];
  float norm1[3];
  int numverts = 3*numfacets;

  const float ci2f = 1.0f / 255.0f; // used for uchar2float and normal conv
  const float cn2f = 1.0f / 127.5f;

  fprintf(outfile, "VertexArray");
  fprintf(outfile, "  Numverts %d\n", numverts);

  fprintf(outfile, "\nCoords\n");
  for (i=0; i<numverts; i++) {
    int idx = i * 3;
    (transMat.top()).multpoint3d(v + idx, vec1);
    fprintf(outfile, "%g %g %g\n", vec1[0], vec1[1], -vec1[2]);
  } 

  fprintf(outfile, "\nNormals\n");
  for (i=0; i<numverts; i++) {
    float ntmp[3];
    int idx = i * 3;

    // conversion from GLbyte format, Table 2.6, p. 44 of OpenGL spec 1.2.1
    // float = (2c+1)/(2^8-1)
    ntmp[0] = n[idx  ] * cn2f + ci2f;
    ntmp[1] = n[idx+1] * cn2f + ci2f;
    ntmp[2] = n[idx+2] * cn2f + ci2f;
    (transMat.top()).multnorm3d(ntmp, norm1);
    fprintf(outfile, "%.3f %.3f %.3f\n", -norm1[0], -norm1[1], norm1[2]);
  } 

  // don't emit per-vertex colors when volumetric texturing is enabled
  if (!involtex) {
    fprintf(outfile, "\nColors\n");
    for (i=0; i<numverts; i++) {
      int idx = i * 4;

      // conversion from GLubyte format, Table 2.6, p. 44 of OpenGL spec 1.2.1
      // float = c/(2^8-1)
      fprintf(outfile, "%.3f %.3f %.3f\n", 
              c[idx  ] * ci2f,
              c[idx+1] * ci2f,
              c[idx+2] * ci2f);
    } 
  }

  // emit the texture to be used by the geometry that follows
  write_cindexmaterial(colorIndex, materialIndex);

  // loop over all of the facets in the mesh
  fprintf(outfile, "\nTriMesh %d\n", numfacets);
  for (i=0; i<numfacets*3; i+=3) {
    fprintf(outfile, "%d %d %d\n", i, i+1, i+2);
  }
 
  // terminate vertex array 
  fprintf(outfile, "\nEnd_VertexArray\n");
}
// draw a cylinder
void RayShadeDisplayDevice::cylinder(float *a, float *b, float r,int /*filled*/) {
  float from[3], to[3];
  float radius;
  
  // transform the world coordinates
  (transMat.top()).multpoint3d(a, from);
  (transMat.top()).multpoint3d(b, to);
  radius = scale_radius(r);
    
  write_cindexmaterial(colorIndex, materialIndex);
  fprintf(outfile, "cylinder %5f %5f %5f %5f %5f %5f %5f\n",
          scale_fix(radius),
          scale_fix(from[0]), scale_fix(from[1]), scale_fix(from[2]),
          scale_fix(to[0]), scale_fix(to[1]), scale_fix(to[2])); 

  // put disks on the ends
  fprintf(outfile, "disc %5f %5f %5f %5f %5f %5f %5f\n",
	  scale_fix(radius),
	  scale_fix(from[0]), scale_fix(from[1]), scale_fix(from[2]),
	  scale_fix(from[0]-to[0]), scale_fix(from[1]-to[1]), 
	  scale_fix(from[2]-to[2]));
  fprintf(outfile, "disc %5f %5f %5f %5f %5f %5f %5f\n",
	  scale_fix(radius),
	  scale_fix(to[0]), scale_fix(to[1]), scale_fix(to[2]),
	  scale_fix(to[0]-from[0]), scale_fix(to[1]-from[1]), 
	  scale_fix(to[2]-from[2]));
}
Exemple #7
0
// draw a color-per-vertex triangle
void X3DDisplayDevice::tricolor(const float * a, const float * b, const float * c, 
                                const float * n1, const float * n2, const float * n3,
                                const float *c1, const float *c2, const float *c3) {
  float ta[3], tb[3], tc[3], tn1[3], tn2[3], tn3[3];

  // transform the world coordinates
  (transMat.top()).multpoint3d(a, ta);
  (transMat.top()).multpoint3d(b, tb);
  (transMat.top()).multpoint3d(c, tc);

  // and the normals
  (transMat.top()).multnorm3d(n1, tn1);
  (transMat.top()).multnorm3d(n2, tn2);
  (transMat.top()).multnorm3d(n3, tn3);

  // ugly and wasteful, but it will work
  fprintf(outfile, "<Shape>\n");
  fprintf(outfile, "  ");
  write_cindexmaterial(colorIndex, materialIndex);
  fprintf(outfile, "  <IndexedFaceSet solid='false' coordIndex='0 1 2 -1'>\n");
  fprintf(outfile, "    <Coordinate point='%g %g %g, %g %g %g, %g %g %g'/>\n",
          ta[0], ta[1], ta[2], tb[0], tb[1], tb[2], tc[0], tc[1], tc[2]);
   
  fprintf(outfile, "    <Normal vector='%g %g %g, %g %g %g, %g %g %g'/>\n",
          tn1[0], tn1[1], tn1[2], tn2[0], tn2[1], tn2[2], tn3[0], tn3[1], tn3[2]);
  fprintf(outfile, "    <Color color='%g %g %g, %g %g %g, %g %g %g'/>\n", 
          c1[0], c1[1], c1[2], c2[0], c2[1], c2[2], c3[0], c3[1], c3[2]);
  fprintf(outfile, "  </IndexedFaceSet>\n");
  fprintf(outfile, "</Shape>\n");
}
void WavefrontDisplayDevice::triangle(const float *v1, const float *v2, const float *v3, 
                                      const float *n1, const float *n2, const float *n3) {
  float a[3], b[3], c[3];
  float norm1[3], norm2[3], norm3[3];

  // transform the world coordinates
  (transMat.top()).multpoint3d(v1, a);
  (transMat.top()).multpoint3d(v2, b);
  (transMat.top()).multpoint3d(v3, c);

  // and the normals
  (transMat.top()).multnorm3d(n1, norm1);
  (transMat.top()).multnorm3d(n2, norm2);
  (transMat.top()).multnorm3d(n3, norm3);

#ifdef VMDGENMTLFILE
  // set colors
  write_cindexmaterial(colorIndex, materialIndex);
#endif
                                                       
  // draw the triangle 
  fprintf(outfile,"v %f %f %f\n", a[0], a[1], a[2]);
  fprintf(outfile,"v %f %f %f\n", b[0], b[1], b[2]);
  fprintf(outfile,"v %f %f %f\n", c[0], c[1], c[2]);
  fprintf(outfile,"vn %f %f %f\n", norm1[0], norm1[1], norm1[2]);
  fprintf(outfile,"vn %f %f %f\n", norm2[0], norm2[1], norm2[2]);
  fprintf(outfile,"vn %f %f %f\n", norm3[0], norm3[1], norm3[2]);
  fprintf(outfile,"f -3//-3 -2//-2 -1//-1\n");
}
void WavefrontDisplayDevice::tristrip(int numverts, const float * cnv,
                                      int numstrips, const int *vertsperstrip,
                                      const int *facets) {
  int i, strip, t, v = 0;
  int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
  float vec1[3];
  float norm1[3];
  const float onethird = (1.0f / 3.0f);

  // write out list of vertices and normals
  for (i=0; i<numverts; i++) {
    int idx = i*10;

    (transMat.top()).multpoint3d(cnv + idx + 7, vec1);
    fprintf(outfile, "v %f %f %f\n", vec1[0], vec1[1], vec1[2]);

    (transMat.top()).multnorm3d(cnv + idx + 4, norm1);
    fprintf(outfile, "vn %f %f %f\n", norm1[0], norm1[1], norm1[2]);
  }

  // render triangle strips one triangle at a time
  // triangle winding order is:
  //   v0, v1, v2, then v2, v1, v3, then v2, v3, v4, etc.
  // loop over all of the triangle strips
  for (strip=0; strip < numstrips; strip++) {
    // loop over all triangles in this triangle strip
    for (t = 0; t < (vertsperstrip[strip] - 2); t++) {
      // render one triangle, using lookup table to fix winding order
      int v0 = facets[v + (stripaddr[t & 0x01][0])];
      int v1 = facets[v + (stripaddr[t & 0x01][1])];
      int v2 = facets[v + (stripaddr[t & 0x01][2])];

#ifdef VMDGENMTLFILE
      // The Wavefront format does not allow per-vertex colors/materials,
      // so we use per-facet coloring, averaging the three vertex colors and
      // selecting the closest color from the VMD color table.
      const float *c1 = cnv + v0 * 10;
      const float *c2 = cnv + v1 * 10;
      const float *c3 = cnv + v2 * 10;
      float r, g, b;
      r = (c1[0] + c2[0] + c3[0]) * onethird; // average three vertex colors
      g = (c1[1] + c2[1] + c3[1]) * onethird;
      b = (c1[2] + c2[2] + c3[2]) * onethird;

      int cindex = nearest_index(r, g, b);
      write_cindexmaterial(cindex, materialIndex);
#endif

      // use negative relative indices required for wavefront obj format
      v0 -= numverts;
      v1 -= numverts;
      v2 -= numverts;
      fprintf(outfile, "f %d//%d %d//%d %d//%d\n", v0, v0, v1, v1, v2, v2); 
      v++; // move on to next vertex
    }
    v+=2; // last two vertices are already used by last triangle
  }
}
Exemple #10
0
// use an efficient mesh primitve rather than individual triangles
// when possible.
void X3DDisplayDevice::tristrip(int numverts, const float * cnv,
                                int numstrips, const int *vertsperstrip,
                                const int *facets) {
  // render directly using the IndexedTriangleStripSet primitive 
  int i, strip, v = 0;
  fprintf(outfile, "<Shape>\n");
  fprintf(outfile, "  ");
  write_cindexmaterial(colorIndex, materialIndex);

  // loop over all of the facets in the mesh
  // emit vertex indices for each facet
  fprintf(outfile, "  <IndexedTriangleStripSet solid='false' index='");
  for (strip=0; strip < numstrips; strip++) {
    for (i=0; i<vertsperstrip[strip]; i++) {
      fprintf(outfile, "%d ", facets[v]);
      v++; // move on to next vertex
    }
    fprintf(outfile, "-1 "); // mark end of strip with a -1 index
  }
  fprintf(outfile, "'>\n");

  // loop over all of the vertices
  fprintf(outfile, "    <Coordinate point='");
  for (i=0; i<numverts; i++) {
    const float *v = cnv + i*10 + 7;
    float tv[3];
    (transMat.top()).multpoint3d(v, tv);
    fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tv[0], tv[1], tv[2]);
  }
  fprintf(outfile, "'/>\n");

  // loop over all of the colors
  fprintf(outfile, "    <Color color='");
  for (i=0; i<numverts; i++) {
    const float *c = cnv + i*10;
    fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', c[0], c[1], c[2]);
  }
  fprintf(outfile, "'/>\n");
  
  // loop over all of the normals
  fprintf(outfile, "    <Normal vector='");
  for (i=0; i<numverts; i++) {
    const float *n = cnv + i*10 + 4;
    float tn[3];
    (transMat.top()).multnorm3d(n, tn);
#if 1
    // reduce precision of surface normals to reduce X3D file size
    fprintf(outfile, "%c %.2f %.2f %.2f", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
#else
    // full precision surface normals
    fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
#endif
  }
  fprintf(outfile, "'/>\n");

  fprintf(outfile, "  </IndexedTriangleStripSet>\n");
  fprintf(outfile, "</Shape>\n");
}
// draw a point
void TachyonDisplayDevice::point(float * spdata) {
  float vec[3];
  // transform the world coordinates
  (transMat.top()).multpoint3d(spdata, vec);

  // draw a sphere to represent the point, since we can't really draw points
  fprintf(outfile, "Sphere \n");  // sphere
  fprintf(outfile, "  Center %g %g %g \n ", vec[0], vec[1], -vec[2]);
  fprintf(outfile, "  Rad %g \n",     float(lineWidth)*DEFAULT_RADIUS); 
  write_cindexmaterial(colorIndex, materialIndex);
}
Exemple #12
0
// draw a cylinder
void X3DDisplayDevice::cylinder_noxfrm(float *ta, float *tb, float radius, int filled) {
  if (ta[0] == tb[0] && ta[1] == tb[1] && ta[2] == tb[2]) {
    return;  // we don't serve your kind here
  }

  float height = distance(ta, tb);

  fprintf(outfile, "<Transform translation='%g %g %g' ",
          ta[0], ta[1] + (height / 2.0), ta[2]);

  float rotaxis[3];
  float cylaxdir[3];
  float yaxis[3] = {0.0, 1.0, 0.0};

  vec_sub(cylaxdir, tb, ta);
  vec_normalize(cylaxdir);
  float dp = dot_prod(yaxis, cylaxdir);

  cross_prod(rotaxis, cylaxdir, yaxis);
  vec_normalize(rotaxis);

  // if we have decent rotation vector, use it
  if ((rotaxis[0]*rotaxis[0] + 
      rotaxis[1]*rotaxis[1] + 
      rotaxis[2]*rotaxis[2]) > 0.5) { 
    fprintf(outfile, "center='0.0 %g 0.0' ", -(height / 2.0));
    fprintf(outfile, "rotation='%g %g %g  %g'", 
            rotaxis[0], rotaxis[1], rotaxis[2], -acos(dp));
  } else if (dp < -0.98) {
    // if we have denormalized rotation vector, we can assume it is
    // caused by a cylinder axis that is nearly coaxial with the Y axis.
    // If this is the case, we either perform no rotation in the case of a
    // angle cosine near 1.0, or a 180 degree rotation for a cosine near -1.
    fprintf(outfile, "center='0.0 %g 0.0' ", -(height / 2.0));
    fprintf(outfile, "rotation='0 0 -1 -3.14159'");
  }
  fprintf(outfile, ">\n");  
        
  fprintf(outfile, "  <Shape>\n");
  fprintf(outfile, "  ");
  write_cindexmaterial(colorIndex, materialIndex);

  // draw the cylinder
  fprintf(outfile, "    <Cylinder "
          "bottom='%s' height='%g' radius='%g' side='%s' top='%s' />\n", 
          filled ? "true" : "false",
          height,  
          radius, 
          "true",
          filled ? "true" : "false");

  fprintf(outfile, "  </Shape>\n");
  fprintf(outfile, "</Transform>\n");
}
// draw a point
void RayShadeDisplayDevice::point(float * spdata) {
  float vec[3];

  // transform the world coordinates
  (transMat.top()).multpoint3d(spdata, vec);
  
  write_cindexmaterial(colorIndex, materialIndex);
  // draw the sphere
  fprintf(outfile, "sphere %5f %5f %5f %5f\n", 
          scale_fix(float(lineWidth)*DEFAULT_RADIUS),
          scale_fix(vec[0]), scale_fix(vec[1]), scale_fix(vec[2]));
}
Exemple #14
0
// use an efficient mesh primitve rather than individual triangles
// when possible.
void X3DDisplayDevice::trimesh_c4n3v3(int numverts, float * cnv,
                                      int numfacets, int * facets) {
  int i;

  fprintf(outfile, "<Shape>\n");
  fprintf(outfile, "  ");
  write_cindexmaterial(colorIndex, materialIndex);

  // loop over all of the facets in the mesh
  fprintf(outfile, "  <IndexedTriangleSet solid='false' index='");
  for (i=0; i<numfacets*3; i+=3) {
    fprintf(outfile, "%d %d %d ", facets[i], facets[i+1], facets[i+2]);
  }
  fprintf(outfile, "'>\n");

  // loop over all of the vertices
  fprintf(outfile, "    <Coordinate point='");
  for (i=0; i<numverts; i++) {
    const float *v = cnv + i*10 + 7;
    float tv[3];
    (transMat.top()).multpoint3d(v, tv);
    fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tv[0], tv[1], tv[2]);
  }
  fprintf(outfile, "'/>\n");

  // loop over all of the colors
  fprintf(outfile, "    <Color color='");
  for (i=0; i<numverts; i++) {
    const float *c = cnv + i*10;
    fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', c[0], c[1], c[2]);
  }
  fprintf(outfile, "'/>\n");
   
  // loop over all of the normals
  fprintf(outfile, "    <Normal vector='");
  for (i=0; i<numverts; i++) {
    const float *n = cnv + i*10 + 4;
    float tn[3];
    (transMat.top()).multnorm3d(n, tn);
#if 1
    // reduce precision of surface normals to reduce X3D file size
    fprintf(outfile, "%c %.2f %.2f %.2f", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
#else
    // full precision surface normals
    fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
#endif
  }
  fprintf(outfile, "'/>\n");

  fprintf(outfile, "  </IndexedTriangleSet>\n");
  fprintf(outfile, "</Shape>\n");
}
// draw a sphere
void RayShadeDisplayDevice::sphere(float * spdata) {
  float vec[3];
  float radius;
    
  // transform the world coordinates
  (transMat.top()).multpoint3d(spdata, vec);
  radius = scale_radius(spdata[3]);
  
  write_cindexmaterial(colorIndex, materialIndex);
  // draw the sphere
  fprintf(outfile, "sphere %5f %5f %5f %5f\n", scale_fix(radius), 
          scale_fix(vec[0]), scale_fix(vec[1]), scale_fix(vec[2]));
}
// draw a sphere
void TachyonDisplayDevice::sphere(float * spdata) {
  float vec[3];
  float radius;
    
  // transform the world coordinates
  (transMat.top()).multpoint3d(spdata, vec);
  radius = scale_radius(spdata[3]);
   
  // draw the sphere
  fprintf(outfile, "Sphere \n");  // sphere
  fprintf(outfile, "  Center %g %g %g \n ", vec[0], vec[1], -vec[2]);
  fprintf(outfile, "  Rad %g \n", radius ); 
  write_cindexmaterial(colorIndex, materialIndex);
}
void TachyonDisplayDevice::tristrip(int numverts, const float * cnv,
                                   int numstrips, const int *vertsperstrip,
                                   const int *facets) {
  int i, strip, v=0;
  float vec1[3];
  float norm1[3];

  fprintf(outfile, "VertexArray");
  fprintf(outfile, "  Numverts %d\n", numverts);

  fprintf(outfile, "\nCoords\n");
  for (i=0; i<numverts; i++) {
    (transMat.top()).multpoint3d(cnv + i*10 + 7, vec1);
    fprintf(outfile, "%g %g %g\n", vec1[0], vec1[1], -vec1[2]);
  } 

  fprintf(outfile, "\nNormals\n");
  for (i=0; i<numverts; i++) {
    (transMat.top()).multnorm3d(cnv + i*10 + 4, norm1);
    fprintf(outfile, "%.3f %.3f %.3f\n", -norm1[0], -norm1[1], norm1[2]);
  } 

  // don't emit per-vertex colors when volumetric texturing is enabled
  if (!involtex) {
    fprintf(outfile, "\nColors\n");
    for (i=0; i<numverts; i++) {
      int idx = i * 10;
      fprintf(outfile, "%.3f %.3f %.3f\n", cnv[idx], cnv[idx+1], cnv[idx+2]);
    } 
  }

  // emit the texture to be used by the geometry that follows
  write_cindexmaterial(colorIndex, materialIndex);

  // loop over all of the triangle strips
  v=0;
  for (strip=0; strip < numstrips; strip++) {
    fprintf(outfile, "\nTriStrip %d\n", vertsperstrip[strip]);

    // loop over all triangles in this triangle strip
    for (i = 0; i < vertsperstrip[strip]; i++) {
      fprintf(outfile, "%d ", facets[v]);
      v++; // move on to the next triangle
    }
  }
 
  // terminate vertex array 
  fprintf(outfile, "\nEnd_VertexArray\n");
}
void MayaDisplayDevice::triangle(const float *v1, const float *v2, const float *v3, 
                                 const float *n1, const float *n2, const float *n3) {
  float a[3], b[3], c[3];
  float norm1[3], norm2[3], norm3[3];

  // transform the world coordinates
  (transMat.top()).multpoint3d(v1, a);
  (transMat.top()).multpoint3d(v2, b);
  (transMat.top()).multpoint3d(v3, c);

  // and the normals
  (transMat.top()).multnorm3d(n1, norm1);
  (transMat.top()).multnorm3d(n2, norm2);
  (transMat.top()).multnorm3d(n3, norm3);

  // draw the triangle
  fprintf(outfile, "createNode transform -n \"vmd%d\";\n", objnameindex);
  fprintf(outfile, "createNode mesh -n \"vmd%dShape\" -p \"vmd%d\";\n", objnameindex, objnameindex);
  fprintf(outfile, "  setAttr -k off \".v\";\n");
  fprintf(outfile, "  setAttr -s 1 \".iog[0].og\";\n");
  fprintf(outfile, "  setAttr \".iog[0].og[0].gcl\" -type \"componentList\" 1 \"f[0]\";\n");
  fprintf(outfile, "  setAttr \".uvst[0].uvsn\" -type \"string\" \"map1\";\n");
  fprintf(outfile, "  setAttr \".cuvs\" -type \"string\" \"map1\";\n");
  fprintf(outfile, "  setAttr \".dcc\" -type \"string\" \"Ambient+Diffuse\";\n");
  fprintf(outfile, "  setAttr -s 3 \".vt[0:2]\" \n"); 
  fprintf(outfile, "    %f %f %f\n", a[0], a[1], a[2]);
  fprintf(outfile, "    %f %f %f\n", b[0], b[1], b[2]);
  fprintf(outfile, "    %f %f %f ;\n", c[0], c[1], c[2]);
  fprintf(outfile, "  setAttr -s 3 \".ed[0:2]\"  \n");
  fprintf(outfile, "    0 1 0\n");
  fprintf(outfile, "    1 2 0\n");
  fprintf(outfile, "    2 0 0 ;\n");
  fprintf(outfile, "  setAttr -s 3 \".n[0:2]\" -type \"float3\"  \n");
  fprintf(outfile, "    %f %f %f\n", norm1[0], norm1[1], norm1[2]);
  fprintf(outfile, "    %f %f %f\n", norm2[0], norm2[1], norm2[2]);
  fprintf(outfile, "    %f %f %f ;\n", norm3[0], norm3[1], norm3[2]);
  fprintf(outfile, "  setAttr -s 1 \".fc[0]\" -type \"polyFaces\"\n"); 
  fprintf(outfile, "    f 3 0 1 2 ;\n");
  fprintf(outfile, "  setAttr \".cd\" -type \"dataPolyComponent\" Index_Data Edge 0 ;\n");
  fprintf(outfile, "  setAttr \".cvd\" -type \"dataPolyComponent\" Index_Data Vertex 0 ;\n");

  char strbuf[1024];
  sprintf(strbuf, "|vmd%d|vmd%dShape", objnameindex, objnameindex);
  write_cindexmaterial(strbuf, colorIndex, materialIndex);

  // increment object name counter
  objnameindex++;
}
// draw a cone
void RayShadeDisplayDevice::cone(float *a, float *b, float r) {
  float from[3], to[3];
  float radius;
  
  // transform the world coordinates
  (transMat.top()).multpoint3d(a, from);
  (transMat.top()).multpoint3d(b, to);
  radius = scale_radius(r);
    
  write_cindexmaterial(colorIndex, materialIndex);
  fprintf(outfile, "cone %5f %5f %5f %5f %5f %5f %5f %5f\n",
          scale_fix(radius), 
          scale_fix(from[0]), scale_fix(from[1]), scale_fix(from[2]), 
          scale_fix(float(lineWidth)*DEFAULT_RADIUS), 
          scale_fix(to[0]), scale_fix(to[1]), scale_fix(to[2]));
}
Exemple #20
0
// draw a sphere
void X3DDisplayDevice::sphere(float *xyzr) {
  float cent[3], radius;

  // transform the coordinates
  (transMat.top()).multpoint3d(xyzr, cent);
  radius = scale_radius(xyzr[3]);

  fprintf(outfile, "<Transform translation='%g %g %g'>\n",
          cent[0], cent[1], cent[2]);
  fprintf(outfile, "  <Shape>\n");
  fprintf(outfile, "  ");
  write_cindexmaterial(colorIndex, materialIndex);
  fprintf(outfile, "  <Sphere radius='%g'/>\n", radius);
  fprintf(outfile, "  </Shape>\n");
  fprintf(outfile, "</Transform>\n");
}
// use an efficient mesh primitve rather than individual triangles
// when possible.
void WavefrontDisplayDevice::trimesh_c4n3v3(int numverts, float * cnv,
                                            int numfacets, int * facets) {
  int i;
  float vec1[3];
  float norm1[3];
  const float onethird = (1.0f / 3.0f);

  // write out list of vertices and normals
  for (i=0; i<numverts; i++) {
    int idx = i*10;

    (transMat.top()).multpoint3d(cnv + idx + 7, vec1);
    fprintf(outfile, "v %f %f %f\n", vec1[0], vec1[1], vec1[2]);

    (transMat.top()).multnorm3d(cnv + idx + 4, norm1);
    fprintf(outfile, "vn %f %f %f\n", norm1[0], norm1[1], norm1[2]);
  }

  // loop over all of the facets in the mesh
  for (i=0; i<numfacets*3; i+=3) {
    int v0 = facets[i    ];
    int v1 = facets[i + 1];
    int v2 = facets[i + 2];

#ifdef VMDGENMTLFILE
    // The Wavefront format does not allow per-vertex colors/materials,
    // so we use per-facet coloring, averaging the three vertex colors and
    // selecting the closest color from the VMD color table.
    const float *c1 = cnv + v0 * 10;
    const float *c2 = cnv + v1 * 10;
    const float *c3 = cnv + v2 * 10;
    float r, g, b;
    r = (c1[0] + c2[0] + c3[0]) * onethird; // average three vertex colors
    g = (c1[1] + c2[1] + c3[1]) * onethird;
    b = (c1[2] + c2[2] + c3[2]) * onethird;

    int cindex = nearest_index(r, g, b);
    write_cindexmaterial(cindex, materialIndex);
#endif

    // use negative relative indices required for wavefront obj format
    v0 -= numverts;
    v1 -= numverts;
    v2 -= numverts;
    fprintf(outfile, "f %d//%d %d//%d %d//%d\n", v0, v0, v1, v1, v2, v2);
  }
}
Exemple #22
0
void X3DDisplayDevice::cone(float *a, float *b, float r) {
  float ta[3], tb[3], radius;

  if (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) {
    return;  // we don't serve your kind here
  }

  // transform the coordinates
  (transMat.top()).multpoint3d(a, ta);
  (transMat.top()).multpoint3d(b, tb);
  radius = scale_radius(r);

  float height = distance(a, b);

  fprintf(outfile, "<Transform translation='%g %g %g' ", 
          ta[0], ta[1] + (height / 2.0), ta[2]);

  float rotaxis[3];
  float cylaxdir[3];
  float yaxis[3] = {0.0, 1.0, 0.0};

  vec_sub(cylaxdir, tb, ta);
  vec_normalize(cylaxdir);
  float dp = dot_prod(yaxis, cylaxdir);

  cross_prod(rotaxis, cylaxdir, yaxis);
  vec_normalize(rotaxis);

  if ((rotaxis[0]*rotaxis[0] + 
      rotaxis[1]*rotaxis[1] + 
      rotaxis[2]*rotaxis[2]) > 0.5) { 
    fprintf(outfile, "center='0.0 %g 0.0' ", -(height / 2.0));
    fprintf(outfile, "rotation='%g %g %g  %g'", 
            rotaxis[0], rotaxis[1], rotaxis[2], -acos(dp));
  }
  fprintf(outfile, ">\n");  
          
  fprintf(outfile, "  <Shape>\n");
  fprintf(outfile, "  ");
  write_cindexmaterial(colorIndex, materialIndex);

  // draw the cone
  fprintf(outfile, "  <Cone bottomRadius='%g' height='%g'/>\n", radius, height);

  fprintf(outfile, "  </Shape>\n");
  fprintf(outfile, "</Transform>\n");
}
// use an efficient mesh primitve rather than individual triangles
// when possible.
void TachyonDisplayDevice::trimesh_c4n3v3(int numverts, float * cnv,
                                          int numfacets, int * facets) {
  int i;
  float vec1[3];
  float norm1[3];

  fprintf(outfile, "VertexArray");
  fprintf(outfile, "  Numverts %d\n", numverts);

  fprintf(outfile, "\nCoords\n");
  for (i=0; i<numverts; i++) {
    (transMat.top()).multpoint3d(cnv + i*10 + 7, vec1);
    fprintf(outfile, "%g %g %g\n", vec1[0], vec1[1], -vec1[2]);
  } 

  fprintf(outfile, "\nNormals\n");
  for (i=0; i<numverts; i++) {
    (transMat.top()).multnorm3d(cnv + i*10 + 4, norm1);
    fprintf(outfile, "%.3f %.3f %.3f\n", -norm1[0], -norm1[1], norm1[2]);
  } 

  // don't emit per-vertex colors when volumetric texturing is enabled
  if (!involtex) {
    fprintf(outfile, "\nColors\n");
    for (i=0; i<numverts; i++) {
      int idx = i * 10;
      fprintf(outfile, "%.3f %.3f %.3f\n", cnv[idx], cnv[idx+1], cnv[idx+2]);
    } 
  }

  // emit the texture to be used by the geometry that follows
  write_cindexmaterial(colorIndex, materialIndex);

  // loop over all of the facets in the mesh
  fprintf(outfile, "\nTriMesh %d\n", numfacets);
  for (i=0; i<numfacets*3; i+=3) {
    fprintf(outfile, "%d %d %d\n", facets[i], facets[i+1], facets[i+2]);
  }
 
  // terminate vertex array 
  fprintf(outfile, "\nEnd_VertexArray\n");
}
// draw a sphere
void MayaDisplayDevice::sphere(float * spdata) {
  float vec[3];
  float radius;
   
  // transform the world coordinates
  (transMat.top()).multpoint3d(spdata, vec);
  radius = scale_radius(spdata[3]);
  
  // draw the sphere
  fprintf(outfile, "createNode transform -n \"vmd%d\";\n", objnameindex);
  fprintf(outfile, "  setAttr \".s\" -type \"double3\" %f %f %f;\n", radius, radius, radius);
  fprintf(outfile, "  setAttr \".t\" -type \"double3\" %f %f %f;\n", vec[0], vec[1], vec[2]);
  fprintf(outfile, "parent -s -nc -r -add \"|VMDNurbSphere|nurbsSphereShape1\" \"vmd%d\";\n", objnameindex);

  char strbuf[1024];
  sprintf(strbuf, "|vmd%d|nurbsSphereShape1", objnameindex);
  write_cindexmaterial(strbuf, colorIndex, materialIndex);

  // increment object name counter
  objnameindex++;
}
Exemple #25
0
///////////////////////// protected nonvirtual routines
void X3DDisplayDevice::set_color(int mycolorIndex) {
#if 0
  write_cindexmaterial(mycolorIndex, materialIndex);
#endif
}
Exemple #26
0
// Use a less-efficient, but X3DOM-compatible 
// IndexedTriangleSet primitve rather than triangle strips.
void X3DOMDisplayDevice::tristrip(int numverts, const float * cnv,
                                  int numstrips, const int *vertsperstrip,
                                  const int *facets) {
  // render triangle strips one triangle at a time
  // triangle winding order is:
  //   v0, v1, v2, then v2, v1, v3, then v2, v3, v4, etc.
  int i, strip, v = 0;
  int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };

  fprintf(outfile, "<Shape>\n");
  fprintf(outfile, "  ");
  write_cindexmaterial(colorIndex, materialIndex);

  // loop over all of the facets in the mesh
  // emit vertex indices for each facet
  fprintf(outfile, "  <IndexedTriangleSet solid='false' index='");
  for (strip=0; strip < numstrips; strip++) {
    for (i=0; i<(vertsperstrip[strip] - 2); i++) {
      // render one triangle, using lookup table to fix winding order
      fprintf(outfile, "%d %d %d ",
              facets[v + (stripaddr[i & 0x01][0])],
              facets[v + (stripaddr[i & 0x01][1])],
              facets[v + (stripaddr[i & 0x01][2])]);
      v++; // move on to next vertex
    }
    v+=2; // last two vertices are already used by last triangle
  }
  fprintf(outfile, "'>\n");

  // loop over all of the vertices
  fprintf(outfile, "    <Coordinate point='");
  for (i=0; i<numverts; i++) {
    const float *v = cnv + i*10 + 7;
    float tv[3];
    (transMat.top()).multpoint3d(v, tv);
    fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tv[0], tv[1], tv[2]);
  }
  fprintf(outfile, "'/>\n");

  // loop over all of the colors
  fprintf(outfile, "    <Color color='");
  for (i=0; i<numverts; i++) {
    const float *c = cnv + i*10;
    fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', c[0], c[1], c[2]);
  }
  fprintf(outfile, "'/>\n");

  // loop over all of the normals
  fprintf(outfile, "    <Normal vector='");
  for (i=0; i<numverts; i++) {
    const float *n = cnv + i*10 + 4;
    float tn[3];
    (transMat.top()).multnorm3d(n, tn);
#if 1
    // reduce precision of surface normals to reduce X3D file size
    fprintf(outfile, "%c %.2f %.2f %.2f", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
#else
    // full precision surface normals
    fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
#endif
  }
  fprintf(outfile, "'/>\n");

  fprintf(outfile, "  </IndexedTriangleSet>\n");
  fprintf(outfile, "</Shape>\n");
}
void MayaDisplayDevice::tricolor(const float *v1, const float *v2, const float *v3, 
                                 const float *n1, const float *n2, const float *n3,
                                 const float *c1, const float *c2, const float *c3) {
  float a[3], b[3], c[3];
  float norm1[3], norm2[3], norm3[3];

  // transform the world coordinates
  (transMat.top()).multpoint3d(v1, a);
  (transMat.top()).multpoint3d(v2, b);
  (transMat.top()).multpoint3d(v3, c);

  // and the normals
  (transMat.top()).multnorm3d(n1, norm1);
  (transMat.top()).multnorm3d(n2, norm2);
  (transMat.top()).multnorm3d(n3, norm3);

  // draw the triangle
  fprintf(outfile, "createNode transform -n \"vmd%d\";\n", objnameindex);
  fprintf(outfile, "createNode mesh -n \"vmd%dShape\" -p \"vmd%d\";\n", objnameindex, objnameindex);
  fprintf(outfile, "  setAttr -k off \".v\";\n");
  fprintf(outfile, "  setAttr -s 1 \".iog[0].og\";\n");
  fprintf(outfile, "  setAttr \".iog[0].og[0].gcl\" -type \"componentList\" 1 \"f[0]\";\n");
  fprintf(outfile, "  setAttr \".uvst[0].uvsn\" -type \"string\" \"map1\";\n");
  fprintf(outfile, "  setAttr \".cuvs\" -type \"string\" \"map1\";\n");

  fprintf(outfile, "  setAttr \".dcol\" yes;\n");
  fprintf(outfile, "  setAttr \".dcc\" -type \"string\" \"Ambient+Diffuse\";\n");
// ????
  fprintf(outfile, "  setAttr \".ccls\" -type \"string\" \"colorSet1\";\n");
  fprintf(outfile, "  setAttr \".clst[0].clsn\" -type \"string\" \"colorSet1\";\n");

#if 0
  fprintf(outfile, "  setAttr -s 3 \".clst[0].clsp[0:2]\" -type \"colorSet1\" \n");
  fprintf(outfile, "    %f %f %f 1.0\n", c1[0], c1[1], c1[2]);
  fprintf(outfile, "    %f %f %f 1.0\n", c2[0], c2[1], c2[2]);
  fprintf(outfile, "    %f %f %f 1.0 ;\n", c3[0], c3[1], c3[2]);
#elif 0
  fprintf(outfile, "  setAttr -s 3 \".vclr[0].vfcl\";\n");
  fprintf(outfile, "  setAttr \".vclr[0].vfcl[0].frgb\" -type \"float3\" %f %f %f ;\n", c1[0], c1[1], c1[2]);
  fprintf(outfile, "  setAttr \".vclr[0].vfcl[1].frgb\" -type \"float3\" %f %f %f ;\n", c2[0], c2[1], c2[2]);
  fprintf(outfile, "  setAttr \".vclr[0].vfcl[2].frgb\" -type \"float3\" %f %f %f ;\n", c3[0], c3[1], c3[2]);
#elif 0
  fprintf(outfile, "  setAttr \".vclr[0].vrgb\" -type \"float3\" ");
  fprintf(outfile, "    %f %f %f ;\n", c1[0], c1[1], c1[2]);
  fprintf(outfile, "  setAttr \".vclr[1].vrgb\" -type \"float3\" ");
  fprintf(outfile, "    %f %f %f ;\n", c2[0], c2[1], c2[2]);
  fprintf(outfile, "  setAttr \".vclr[2].vrgb\" -type \"float3\" "); 
  fprintf(outfile, "    %f %f %f ;\n", c3[0], c3[1], c3[2]);
#endif

  fprintf(outfile, "  setAttr -s 3 \".vt[0:2]\" \n"); 
  fprintf(outfile, "    %f %f %f\n", a[0], a[1], a[2]);
  fprintf(outfile, "    %f %f %f\n", b[0], b[1], b[2]);
  fprintf(outfile, "    %f %f %f ;\n", c[0], c[1], c[2]);

#if 1
  fprintf(outfile, "  setAttr -s 3 \".clr[0:2]\" \n");
  fprintf(outfile, "    %f %f %f 1\n", c1[0], c1[1], c1[2]);
  fprintf(outfile, "    %f %f %f 1\n", c2[0], c2[1], c2[2]);
  fprintf(outfile, "    %f %f %f 1 ;\n", c3[0], c3[1], c3[2]);
#endif

  fprintf(outfile, "  setAttr -s 3 \".ed[0:2]\"  \n");
  fprintf(outfile, "    0 1 0\n");
  fprintf(outfile, "    1 2 0\n");
  fprintf(outfile, "    2 0 0 ;\n");
  fprintf(outfile, "  setAttr -s 3 \".n[0:2]\" -type \"float3\"  \n");
  fprintf(outfile, "    %f %f %f\n", norm1[0], norm1[1], norm1[2]);
  fprintf(outfile, "    %f %f %f\n", norm2[0], norm2[1], norm2[2]);
  fprintf(outfile, "    %f %f %f ;\n", norm3[0], norm3[1], norm3[2]);
  fprintf(outfile, "  setAttr -s 1 \".fc[0]\" -type \"polyFaces\"\n"); 
  fprintf(outfile, "    f 3 0 1 2 ;\n");
  fprintf(outfile, "  setAttr \".cd\" -type \"dataPolyComponent\" Index_Data Edge 0 ;\n");
  fprintf(outfile, "  setAttr \".cvd\" -type \"dataPolyComponent\" Index_Data Vertex 0 ;\n");

#if 0
  fprintf(outfile, "createNode polyColorPerVertex -n \"polyColorPerVertex%d\";\n", objnameindex);
  fprintf(outfile, "  setAttr \".uopa\" yes;\n");
  fprintf(outfile, "  setAttr -s 3 \".vclr\";\n");
  fprintf(outfile, "  setAttr -s 1 \".vclr[0].vfcl\";\n");
  fprintf(outfile, "  setAttr \".vclr[0].vfcl[0].frgb\" -type \"float3\" %f %f %f ;\n", c1[0], c1[1], c1[2]);
  fprintf(outfile, "  setAttr \".vclr[1].vfcl[0].frgb\" -type \"float3\" %f %f %f ;\n", c2[0], c2[1], c2[2]);
  fprintf(outfile, "  setAttr \".vclr[1].vfcl[0].frgb\" -type \"float3\" %f %f %f ;\n", c3[0], c3[1], c3[2]);
  fprintf(outfile, "  setAttr \".cn\" -type \"string\" \"colorSet1\";\n");
  fprintf(outfile, "  setAttr \".clam\" no;\n");
//  fprintf(outfile, "  connectAttr \"polyColorPerVertex%d.out\" \"vmd%dShape.i\";\n", objnameindex, objnameindex);
//  fprintf(outfile, "  connectAttr \"vmd%d.out\" \"polyColorPerVertex%d.ip\";\n", objnameindex, objnameindex);
#endif


  char strbuf[1024];
  sprintf(strbuf, "|vmd%d|vmd%dShape", objnameindex, objnameindex);
  write_cindexmaterial(strbuf, colorIndex, materialIndex);

  // increment object name counter
  objnameindex++;
}
void TachyonDisplayDevice::text(float *pos, float size, float thickness, 
                                const char *str) {
  float textpos[3];
  float textsize, textthickness;
  hersheyhandle hh;

  // transform the world coordinates
  (transMat.top()).multpoint3d(pos, textpos);
  textsize = size * 1.5f;
  textthickness = thickness*DEFAULT_RADIUS;

  while (*str != '\0') {
    float lm, rm, x, y, ox, oy;
    int draw, odraw;
    ox=oy=x=y=0.0f;
    draw=odraw=0;

    hersheyDrawInitLetter(&hh, *str, &lm, &rm);
    textpos[0] -= lm * textsize;

    while (!hersheyDrawNextLine(&hh, &draw, &x, &y)) {
      float oldpt[3], newpt[3];
      if (draw) {
        newpt[0] = textpos[0] + textsize * x;
        newpt[1] = textpos[1] + textsize * y;
        newpt[2] = textpos[2];

        if (odraw) {
          // if we have both previous and next points, connect them...
          oldpt[0] = textpos[0] + textsize * ox;
          oldpt[1] = textpos[1] + textsize * oy;
          oldpt[2] = textpos[2];

          fprintf(outfile, "FCylinder\n"); // flat-ended cylinder
          fprintf(outfile, "  Base %g %g %g\n", oldpt[0], oldpt[1], -oldpt[2]); 
          fprintf(outfile, "  Apex %g %g %g\n", newpt[0], newpt[1], -newpt[2]);
          fprintf(outfile, "  Rad %g \n", textthickness);
          write_cindexmaterial(colorIndex, materialIndex);

          fprintf(outfile, "Sphere \n");  // sphere
          fprintf(outfile, "  Center %g %g %g \n", newpt[0], newpt[1], -newpt[2]);
          fprintf(outfile, "  Rad %g \n", textthickness); 
          write_cindexmaterial(colorIndex, materialIndex);
        } else {
          // ...otherwise, just draw the next point
          fprintf(outfile, "Sphere \n");  // sphere
          fprintf(outfile, "  Center %g %g %g \n", newpt[0], newpt[1], -newpt[2]);
          fprintf(outfile, "  Rad %g \n", textthickness); 
          write_cindexmaterial(colorIndex, materialIndex);
        }
      }

      ox=x;
      oy=y;
      odraw=draw;
    }
    textpos[0] += rm * textsize;

    str++;
  }
}
///////////////////////// protected nonvirtual routines
void VrmlDisplayDevice::set_color(int mycolorIndex) {
  write_cindexmaterial(mycolorIndex, materialIndex);
}
Exemple #30
0
/// draw a line from a to b
void X3DDisplayDevice::line(float *a, float*b) {
  float ta[3], tb[3];

  if (lineStyle == ::SOLIDLINE) {
    // transform the coordinates
    (transMat.top()).multpoint3d(a, ta);
    (transMat.top()).multpoint3d(b, tb);

    // ugly and wasteful, but it will work
    fprintf(outfile, "<Shape>\n");
    fprintf(outfile, "  ");
    write_cindexmaterial(colorIndex, materialIndex);

    fprintf(outfile, "  <IndexedLineSet coordIndex='0 1 -1'>\n");
    fprintf(outfile, "    <Coordinate point='%g %g %g, %g %g %g'/>\n",
            ta[0], ta[1], ta[2], tb[0], tb[1], tb[2]);
  
    float col[3];
    vec_copy(col, matData[colorIndex]);
    fprintf(outfile, "    <Color color='%g %g %g, %g %g %g'/>\n", 
            col[0], col[1], col[2], col[0], col[1], col[2]);
    fprintf(outfile, "  </IndexedLineSet>\n");
    fprintf(outfile, "</Shape>\n");
  } else if (lineStyle == ::DASHEDLINE) {
    float dirvec[3], unitdirvec[3], tmp1[3], tmp2[3];
    int i, j, test;

     // transform the world coordinates
    (transMat.top()).multpoint3d(a, tmp1);
    (transMat.top()).multpoint3d(b, tmp2);

    // how to create a dashed line
    vec_sub(dirvec, tmp2, tmp1);  // vector from a to b
    vec_copy(unitdirvec, dirvec);
    vec_normalize(unitdirvec);    // unit vector from a to b
    test = 1;
    i = 0;
    while (test == 1) {
      for (j=0; j<3; j++) {
        ta[j] = (float) (tmp1[j] + (2*i    )*DASH_LENGTH*unitdirvec[j]);
        tb[j] = (float) (tmp1[j] + (2*i + 1)*DASH_LENGTH*unitdirvec[j]);
      }
      if (fabsf(tmp1[0] - tb[0]) >= fabsf(dirvec[0])) {
        vec_copy(tb, tmp2);
        test = 0;
      }

      // ugly and wasteful, but it will work
      fprintf(outfile, "<Shape>\n");
      fprintf(outfile, "  ");
      write_cindexmaterial(colorIndex, materialIndex);

      fprintf(outfile, "  <IndexedLineSet coordIndex='0 1 -1'>\n");
      fprintf(outfile, "    <Coordinate point='%g %g %g, %g %g %g'/>\n",
              ta[0], ta[1], ta[2], tb[0], tb[1], tb[2]);
  
      float col[3];
      vec_copy(col, matData[colorIndex]);
      fprintf(outfile, "    <Color color='%g %g %g, %g %g %g'/>\n", 
              col[0], col[1], col[2], col[0], col[1], col[2]);
      fprintf(outfile, "  </IndexedLineSet>\n");
      fprintf(outfile, "</Shape>\n");
      i++;
    }
  } else {
    msgErr << "X3DDisplayDevice: Unknown line style "
           << lineStyle << sendmsg;
  }
}