// 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])); }
// draw a cone void POV3DisplayDevice::cone(float *a, float *b, float r, int /* resolution */) { 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); // check for degenerate cylinders if ( ((from[0]-to[0])*(from[0]-to[0]) + (from[1]-to[1])*(from[1]-to[1]) + (from[2]-to[2])*(from[2]-to[2])) < 1e-20 ) { degenerate_cones++; return; } // write_materials(); // Draw the cone fprintf(outfile, "VMD_cone (<%g,%g,%g>,<%g,%g,%g>,%.4f,", from[0], from[1], -from[2], to[0], to[1], -to[2], radius); fprintf(outfile, "rgbt<%.3f,%.3f,%.3f,%.3f>)\n", matData[colorIndex][0], matData[colorIndex][1], matData[colorIndex][2], 1 - mat_opacity); }
// draw a cylinder void X3DDisplayDevice::cylinder(float *a, float *b, float r, int filled) { float ta[3], tb[3], radius; // transform the coordinates (transMat.top()).multpoint3d(a, ta); (transMat.top()).multpoint3d(b, tb); radius = scale_radius(r); cylinder_noxfrm(ta, tb, radius, filled); }
// 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])); }
/***********************************************************************//** * @brief Update precomputation cache * * Computes the mass_radius calculation, determining the radius around * the halo that contains 99.99% of the mass. For an Burket halo profile, * this is just 80.0 * scale_radius. ***************************************************************************/ void GModelSpatialRadialProfileDMBurkert::update() const { // Update if scale radius has changed if (m_last_scale_radius != scale_radius() || m_last_scale_density != scale_density() ) { // Store last values m_last_scale_radius = scale_radius(); m_last_scale_density = scale_density(); // perform precomputations // set the mass radius to 80*scale_radius, meaning // 99.99% of the mass is contained within the mass radius, // and integration only needs to worry about whats inside this radius. m_mass_radius = 80.0 * scale_radius(); m_scale_density_squared = scale_density() * scale_density() ; } // Return return; }
// 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); }
/// draw a cylinder void RenderManDisplayDevice::cylinder(float *a, float *b, float r, int /* filled */ ) { float axis[3], vec1[3], vec2[3]; float R, phi, rxy, theta; float radius; // Transform the world coordinates (transMat.top()).multpoint3d(a, vec1); (transMat.top()).multpoint3d(b, vec2); radius = scale_radius(r); if (radius < DEFAULT_RADIUS) { radius = (float) DEFAULT_RADIUS; } // RenderMan's cylinders always run along the z axis, and must // be transformed to the proper position and rotation. This // code is taken from OpenGLRenderer.C. axis[0] = vec2[0] - vec1[0]; axis[1] = vec2[1] - vec1[1]; axis[2] = vec2[2] - vec1[2]; R = axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]; if (R <= 0) return; R = sqrtf(R); // evaluation of sqrt() _after_ early exit // determine phi rotation angle, amount to rotate about y phi = acosf(axis[2] / R); // determine theta rotation, amount to rotate about z rxy = sqrtf(axis[0] * axis[0] + axis[1] * axis[1]); if (rxy <= 0) { theta = 0; } else { theta = acosf(axis[0] / rxy); if (axis[1] < 0) theta = (float) (2.0 * VMD_PI) - theta; } // Write the cylinder fprintf(outfile, "TransformBegin\n"); write_materials(1); fprintf(outfile, " Translate %g %g %g\n", vec1[0], vec1[1], vec1[2]); if (theta) fprintf(outfile, " Rotate %g 0 0 1\n", (theta / VMD_PI) * 180); if (phi) fprintf(outfile, " Rotate %g 0 1 0\n", (phi / VMD_PI) * 180); fprintf(outfile, " Cylinder %g 0 %g 360\n", radius, R); fprintf(outfile, "TransformEnd\n"); }
/// draw a cylinder void GelatoDisplayDevice::cylinder(float *a, float *b, float r, int filled) { float vec1[3], vec2[3], radius; if (filled) { FileRenderer::cylinder(a, b, r, filled); return; } // Transform the world coordinates (transMat.top()).multpoint3d(a, vec1); (transMat.top()).multpoint3d(b, vec2); radius = scale_radius(r); cylinder_nurb_noxfrm(vec1, vec2, radius, filled); }
// 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 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])); }
// 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"); }
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"); }
// draw a sphere void ArtDisplayDevice::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 {\ncolour %f,%f,%f\n", matData[colorIndex][0], matData[colorIndex][1], matData[colorIndex][2]); fprintf(outfile, "radius %f\n", radius); fprintf(outfile, "center (%f,%f,%f)\n}\n", ORDER(vec[0], vec[1], vec[2])); }
// draw a sphere void POV3DisplayDevice::sphere(float * spdata) { float vec[3]; float radius; // transform the world coordinates (transMat.top()).multpoint3d(spdata, vec); radius = scale_radius(spdata[3]); // write_materials(); // Draw the sphere fprintf(outfile, "VMD_sphere(<%.4f,%.4f,%.4f>,%.4f,", vec[0], vec[1], -vec[2], radius); fprintf(outfile, "rgbt<%.3f,%.3f,%.3f,%.3f>)\n", matData[colorIndex][0], matData[colorIndex][1], matData[colorIndex][2], 1 - mat_opacity); }
/// draw a sphere void RenderManDisplayDevice::sphere(float * spdata) { float vec[3]; float radius; // Transform the world coordinates (transMat.top()).multpoint3d(spdata, vec); radius = scale_radius(spdata[3]); if (radius < DEFAULT_RADIUS) { radius = (float) DEFAULT_RADIUS; } // Draw the sphere fprintf(outfile, "TransformBegin\n"); write_materials(1); fprintf(outfile, " Translate %g %g %g\n", vec[0], vec[1], vec[2]); fprintf(outfile, " Sphere %g %g %g 360\n", radius, -radius, radius); fprintf(outfile, "TransformEnd\n"); }
/// draw a sphere void GelatoDisplayDevice::sphere(float * spdata) { float vec[3]; float radius; // Transform the world coordinates (transMat.top()).multpoint3d(spdata, vec); radius = scale_radius(spdata[3]); if (radius < DEFAULT_RADIUS) { radius = (float) DEFAULT_RADIUS; } // Draw the sphere fprintf(outfile, "PushTransform()\n"); write_materials(1); fprintf(outfile, "Translate(%g, %g, %g)\n", vec[0], vec[1], vec[2]); fprintf(outfile, "Sphere(%g, %g, %g, 360)\n", radius, -radius, radius); fprintf(outfile, "PopTransform()\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++; }
// draw a cone void ArtDisplayDevice::cone(float *a, float *b, float r) { float vec1[3], vec2[3]; // transform the world coordinates (transMat.top()).multpoint3d(a, vec1); (transMat.top()).multpoint3d(b, vec2); fprintf(outfile, "cone {\n"); fprintf(outfile, "colour %f,%f,%f\n", matData[colorIndex][0], matData[colorIndex][1], matData[colorIndex][2]); // second point fprintf(outfile, "vertex(%f,%f,%f)\n", ORDER(vec2[0], vec2[1], vec2[2])); // first point fprintf(outfile, "center(%f,%f,%f)\n", ORDER(vec1[0], vec1[1], vec1[2])); // radius fprintf(outfile, "radius %f\n}\n", scale_radius(r)); }
// draw a sphere array void TachyonDisplayDevice::sphere_array(int spnum, int spres, float *centers, float *radii, float *colors) { float vec[3]; float radius; int i, ind; ind = 0; for (i=0; i<spnum; i++) { // transform the world coordinates (transMat.top()).multpoint3d(¢ers[ind], vec); radius = scale_radius(radii[i]); // 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_colormaterial(&colors[ind], materialIndex); ind += 3; // next sphere } // set final color state after array has been drawn ind=(spnum-1)*3; super_set_color(nearest_index(colors[ind], colors[ind+1], colors[ind+2])); }
// XXX ignores material parameter, may need to improve this.. void TachyonDisplayDevice::write_colormaterial(float *rgb, int /* material */) { fprintf(outfile, "Texture\n"); if (materials_on) { fprintf(outfile, " Ambient %g Diffuse %g Specular %g Opacity %g\n", mat_ambient, mat_diffuse, mat_mirror, mat_opacity); } else { fprintf(outfile, " Ambient %g Diffuse %g Specular %g Opacity %g\n", 1.0, 0.0, 0.0, mat_opacity); } if (mat_transmode != 0) { fprintf(outfile, " TransMode R3D "); } if (mat_outline > 0.0) { fprintf(outfile, " Outline %g Outline_Width %g ", mat_outline, mat_outlinewidth); } fprintf(outfile, " Phong Plastic %g Phong_size %g ", mat_specular, mat_shininess); fprintf(outfile, "Color %g %g %g ", rgb[0], rgb[1], rgb[2]); /// generate volume texture definition, if necessary if (!involtex) { /// no volume texture, so we use a solid color fprintf(outfile, "TexFunc 0\n\n"); } else { /// Perform coordinate system transformations and emit volume texture float voluaxs[3]; ///< volume texture coordinate generation float volvaxs[3]; ///< parameters in world coordinates float volwaxs[3]; float volcent[3]; // transform the y/v/w texture coordinate axes from molecule // coordinates into world coordinates (transMat.top()).multplaneeq3d(xplaneeq, voluaxs); (transMat.top()).multplaneeq3d(yplaneeq, volvaxs); (transMat.top()).multplaneeq3d(zplaneeq, volwaxs); // undo the scaling operation applied by the transformation float invscale = 1.0f / scale_radius(1.0f); int i; for (i=0; i<3; i++) { voluaxs[i] *= invscale; volvaxs[i] *= invscale; volwaxs[i] *= invscale; } // compute the volume origin in molecule coordinates by // reverting the scaling factor that was previously applied // to the texture plane equation float volorgmol[3] = {0,0,0}; volorgmol[0] = -xplaneeq[3] / norm(xplaneeq); volorgmol[1] = -yplaneeq[3] / norm(yplaneeq); volorgmol[2] = -zplaneeq[3] / norm(zplaneeq); // transform the volume origin into world coordinates (transMat.top()).multpoint3d(volorgmol, volcent); // emit the texture to the scene file fprintf(outfile, "\n TexFunc 10 ::VMDVolTex%d\n", voltexID); fprintf(outfile, " Center %g %g %g\n", volcent[0], volcent[1], -volcent[2]); fprintf(outfile, " Rotate 0 0 0\n"); fprintf(outfile, " Scale 1 1 1\n"); fprintf(outfile, " Uaxis %g %g %g\n", voluaxs[0], voluaxs[1], -voluaxs[2]); fprintf(outfile, " Vaxis %g %g %g\n", volvaxs[0], volvaxs[1], -volvaxs[2]); fprintf(outfile, " Waxis %g %g %g\n", volwaxs[0], volwaxs[1], -volwaxs[2]); fprintf(outfile, "\n"); } }
void PSDisplayDevice::render(const VMDDisplayList *display_list) { DepthSortObject depth_obj; char *cmd_ptr; int draw; int tok; int nc; float a[3], b[3], c[3], d[3]; float cent[3]; float r; Matrix4 ident; float textsize=1.0f; // default text size // first we want to clear the transformation matrix stack while (transMat.num()) transMat.pop(); // push on the identity matrix transMat.push(ident); // load the display list's transformation matrix super_multmatrix(display_list->mat.mat); // Now we need to calculate the normalized position of the light // so we can compute angles of surfaces to that light for shading norm_light[0] = lightState[0].pos[0]; norm_light[1] = lightState[0].pos[1]; norm_light[2] = lightState[0].pos[2]; if (norm_light[0] || norm_light[1] || norm_light[2]) vec_normalize(norm_light); // Computer periodic images ResizeArray<Matrix4> pbcImages; find_pbc_images(display_list, pbcImages); int nimages = pbcImages.num(); for (int pbcimage = 0; pbcimage < nimages; pbcimage++) { transMat.dup(); super_multmatrix(pbcImages[pbcimage].mat); // Loop through the display list and add each object to our // depth-sort list for final rendering. VMDDisplayList::VMDLinkIter cmditer; display_list->first(&cmditer); while ((tok = display_list->next(&cmditer, cmd_ptr)) != DLASTCOMMAND) { draw = 0; nc = -1; switch (tok) { case DPOINT: // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 2); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 1; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(((DispCmdPoint *) cmd_ptr)->pos, a); memcpy(depth_obj.points, a, sizeof(float) * 2); // compute the distance to the eye depth_obj.dist = compute_dist(a); // valid object to depth sort draw = 1; break; case DSPHERE: { (transMat.top()).multpoint3d(((DispCmdSphere *) cmd_ptr)->pos_r, c); r = scale_radius(((DispCmdSphere *) cmd_ptr)->pos_r[3]); sphere_approx(c, r); break; } case DSPHEREARRAY: { DispCmdSphereArray *sa = (DispCmdSphereArray *) cmd_ptr; int cIndex, rIndex; // cIndex: index of colors & centers // rIndex: index of radii. float * centers; float * radii; float * colors; sa->getpointers(centers, radii, colors); set_sphere_res(sa->sphereres); for (cIndex = 0, rIndex=0; rIndex < sa->numspheres; cIndex+=3, rIndex++) { colorIndex = nearest_index(colors[cIndex], colors[cIndex+1], colors[cIndex+2]); (transMat.top()).multpoint3d(¢ers[cIndex] , c); r = scale_radius(radii[rIndex]); sphere_approx(c, r); } break; } case DLINE: // check for zero-length line (degenerate) if (!memcmp(((DispCmdLine *) cmd_ptr)->pos1, ((DispCmdLine *) cmd_ptr)->pos2, sizeof(float) * 3)) { // degenerate line break; } // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 4); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 2; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(((DispCmdLine *) cmd_ptr)->pos1, a); (transMat.top()).multpoint3d(((DispCmdLine *) cmd_ptr)->pos2, b); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0]) / 2; cent[1] = (a[1] + b[1]) / 2; cent[2] = (a[2] + b[2]) / 2; // compute the distance to the eye depth_obj.dist = compute_dist(cent); // valid object to depth sort draw = 1; break; case DLINEARRAY: { // XXX much replicated code from DLINE float *v = (float *)cmd_ptr; int nlines = (int)v[0]; v++; for (int i=0; i<nlines; i++) { // check for degenerate line if (!memcmp(v,v+3,3*sizeof(float))) break; // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 4); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 2; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(v, a); (transMat.top()).multpoint3d(v+3, b); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0]) / 2; cent[1] = (a[1] + b[1]) / 2; cent[2] = (a[2] + b[2]) / 2; // compute the distance to the eye depth_obj.dist = compute_dist(cent); // we'll add the object here, since we have multiple objects draw = 0; memusage += sizeof(float) * 2 * depth_obj.npoints; points += depth_obj.npoints; objects++; depth_list.append(depth_obj); v += 6; } } break; case DPOLYLINEARRAY: { // XXX much replicated code from DLINE / DLINEARRAY float *v = (float *)cmd_ptr; int nverts = (int)v[0]; v++; for (int i=0; i<nverts-1; i++) { // check for degenerate line if (!memcmp(v,v+3,3*sizeof(float))) break; // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 4); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 2; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(v, a); (transMat.top()).multpoint3d(v+3, b); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0]) / 2; cent[1] = (a[1] + b[1]) / 2; cent[2] = (a[2] + b[2]) / 2; // compute the distance to the eye depth_obj.dist = compute_dist(cent); // we'll add the object here, since we have multiple objects draw = 0; memusage += sizeof(float) * 2 * depth_obj.npoints; points += depth_obj.npoints; objects++; depth_list.append(depth_obj); v += 3; } } break; case DCYLINDER: { int res; (transMat.top()).multpoint3d((float *) cmd_ptr, a); (transMat.top()).multpoint3d(&((float *) cmd_ptr)[3], b); r = scale_radius(((float *) cmd_ptr)[6]); res = (int) ((float *) cmd_ptr)[7]; cylinder_approx(a, b, r, res, (int) ((float *) cmd_ptr)[8]); break; } case DCONE: { (transMat.top()).multpoint3d(((DispCmdCone *) cmd_ptr)->pos1, a); (transMat.top()).multpoint3d(((DispCmdCone *) cmd_ptr)->pos2, b); float r1 = scale_radius(((DispCmdCone *) cmd_ptr)->radius); float r2 = scale_radius(((DispCmdCone *) cmd_ptr)->radius2); // XXX current implementation can't draw truncated cones. if (r2 > 0.0f) { msgWarn << "PSDisplayDevice) can't draw truncated cones" << sendmsg; } cone_approx(a, b, r1); break; } case DTEXTSIZE: textsize = ((DispCmdTextSize *)cmd_ptr)->size; break; case DTEXT: { float* pos = (float *)cmd_ptr; #if 0 // thickness not implemented yet float thickness = pos[3]; // thickness is stored in 4th slot #endif char* txt = (char *)(pos+4); int txtlen = strlen(txt); // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 2); depth_obj.text = (char *) malloc(sizeof(char) * (txtlen+1)); if ( !(depth_obj.points || depth_obj.text) ) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 1; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(((DispCmdPoint *) cmd_ptr)->pos, a); memcpy(depth_obj.points, a, sizeof(float) * 2); strcpy(depth_obj.text , txt); // note scale factor, stored into "light_scale", so we didn't // have to add a new structure member just for this. depth_obj.light_scale = textsize * 15; // compute the distance to the eye depth_obj.dist = compute_dist(a); // valid object to depth sort draw = 1; break; } case DTRIANGLE: // check for degenerate triangle if (!memcmp(((DispCmdTriangle *) cmd_ptr)->pos1, ((DispCmdTriangle *) cmd_ptr)->pos2, sizeof(float) * 3) || !memcmp(((DispCmdTriangle *) cmd_ptr)->pos2, ((DispCmdTriangle *) cmd_ptr)->pos3, sizeof(float) * 3) || !memcmp(((DispCmdTriangle *) cmd_ptr)->pos2, ((DispCmdTriangle *) cmd_ptr)->pos3, sizeof(float) * 3)) { // degenerate triangle break; } // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 6); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 3; depth_obj.color = (nc >= 0) ? nc : colorIndex; (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos1, a); (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos2, b); (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos3, c); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); memcpy(&depth_obj.points[4], c, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0] + c[0]) / 3; cent[1] = (a[1] + b[1] + c[1]) / 3; cent[2] = (a[2] + b[2] + c[2]) / 3; // compute the distance to the eye for depth sorting depth_obj.dist = compute_dist(cent); // compute a light shading factor depth_obj.light_scale = compute_light(a, b, c); // valid object to depth sort draw = 1; break; case DTRIMESH_C4F_N3F_V3F: // call a separate routine to break up the mesh into // its component triangles decompose_mesh((DispCmdTriMesh *) cmd_ptr); break; case DTRISTRIP: // call a separate routine to break up the strip into // its component triangles decompose_tristrip((DispCmdTriStrips *) cmd_ptr); break; case DSQUARE: // check for degenerate quadrilateral if (!memcmp(((DispCmdSquare *) cmd_ptr)->pos1, ((DispCmdSquare *) cmd_ptr)->pos2, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos1, ((DispCmdSquare *) cmd_ptr)->pos3, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos1, ((DispCmdSquare *) cmd_ptr)->pos4, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos2, ((DispCmdSquare *) cmd_ptr)->pos3, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos2, ((DispCmdSquare *) cmd_ptr)->pos4, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos3, ((DispCmdSquare *) cmd_ptr)->pos4, sizeof(float) * 3)) { // degenerate quadrilateral break; } // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 8); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 4; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos1, a); (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos2, b); (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos3, c); (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos4, d); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); memcpy(&depth_obj.points[4], c, sizeof(float) * 2); memcpy(&depth_obj.points[6], d, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0] + c[0] + d[0]) / 4; cent[1] = (a[1] + b[1] + c[1] + d[1]) / 4; cent[2] = (a[2] + b[2] + c[2] + d[2]) / 4; // compute the distance to the eye for depth sorting depth_obj.dist = compute_dist(cent); // compute a light shading factor depth_obj.light_scale = compute_light(a, b, c); // valid object to depth sort draw = 1; break; case DCOLORINDEX: colorIndex = ((DispCmdColorIndex *) cmd_ptr)->color; break; case DSPHERERES: set_sphere_res(((int *) cmd_ptr)[0]); break; default: // unknown object, so just skip it break; } // if we have a valid object to add to the depth sort list if (draw && depth_obj.npoints) { memusage += sizeof(float) * 2 * depth_obj.npoints; if ( depth_obj.text ) memusage += sizeof(char) * (1+strlen(depth_obj.text)); points += depth_obj.npoints; objects++; depth_list.append(depth_obj); } depth_obj.npoints = 0; depth_obj.points = NULL; } // while (tok != DLASTCOMMAND) transMat.pop(); } // end for() [periodic images] }