00001 /*************************************************************************** 00002 *cr 00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the 00004 *cr University of Illinois 00005 *cr All Rights Reserved 00006 *cr 00007 ***************************************************************************/ 00008 /*************************************************************************** 00009 * RCS INFORMATION: 00010 * 00011 * $RCSfile: ArtDisplayDevice.C,v $ 00012 * $Author: johns $ $Locker: $ $State: Exp $ 00013 * $Revision: 1.40 $ $Date: 2020年02月26日 03:51:30 $ 00014 * 00015 ***************************************************************************/ 00035 #include <stdio.h> 00036 #include <string.h> 00037 #include <math.h> 00038 #include "ArtDisplayDevice.h" 00039 #include "Matrix4.h" 00040 #include "DispCmds.h" 00041 #include "Inform.h" 00042 #include "utilities.h" 00043 00044 #define DEFAULT_RADIUS 0.002f 00045 #define DASH_LENGTH 0.02f 00046 00047 // Be careful when you modify the coordinates. To make things view the 00048 // right way, I have to rotate everything around the (x,y,z) = (1,1,1) 00049 // vector so that x->z, y->x, and z->y 00050 00051 #define ORDER(x,y,z) -z, -x, y 00052 //#define ORDER(x,y,z) x,y,z 00053 00055 00056 // constructor ... initialize some variables 00057 ArtDisplayDevice::ArtDisplayDevice() 00058 : FileRenderer("ART", "ART (VORT ray tracer)", "vmdscene.scn", "art %s 500 650"){ } 00059 00060 //destructor 00061 ArtDisplayDevice::~ArtDisplayDevice(void) { } 00062 00064 00065 // draw a point 00066 void ArtDisplayDevice::point(float * spdata) { 00067 float vec[3]; 00068 00069 // transform the world coordinates 00070 (transMat.top()).multpoint3d(spdata, vec); 00071 00072 // draw the sphere 00073 fprintf(outfile, "sphere {\ncolour %f,%f,%f\n", 00074 matData[colorIndex][0], 00075 matData[colorIndex][1], 00076 matData[colorIndex][2]); 00077 00078 fprintf(outfile, "radius %f\n", float(lineWidth) * DEFAULT_RADIUS); 00079 fprintf(outfile, "center (%f,%f,%f)\n}\n", ORDER(vec[0], vec[1], vec[2])); 00080 } 00081 00082 // draw a sphere 00083 void ArtDisplayDevice::sphere(float * spdata) { 00084 float vec[3]; 00085 float radius; 00086 00087 // transform the world coordinates 00088 (transMat.top()).multpoint3d(spdata, vec); 00089 radius = scale_radius(spdata[3]); 00090 00091 // draw the sphere 00092 fprintf(outfile, "sphere {\ncolour %f,%f,%f\n", 00093 matData[colorIndex][0], 00094 matData[colorIndex][1], 00095 matData[colorIndex][2]); 00096 00097 fprintf(outfile, "radius %f\n", radius); 00098 fprintf(outfile, "center (%f,%f,%f)\n}\n", ORDER(vec[0], vec[1], vec[2])); 00099 } 00100 00101 00102 // draw a line (cylinder) from a to b 00103 void ArtDisplayDevice::line(float *a, float *b) { 00104 int i, j, test; 00105 float dirvec[3], unitdirvec[3]; 00106 float from[3], to[3], tmp1[3], tmp2[3]; 00107 00108 if (lineStyle == ::SOLIDLINE) { 00109 // transform the world coordinates 00110 (transMat.top()).multpoint3d(a, from); 00111 (transMat.top()).multpoint3d(b, to); 00112 00113 // draw the cylinder 00114 fprintf(outfile, "cylinder {\n"); 00115 fprintf(outfile, "colour %f,%f,%f\n", 00116 matData[colorIndex][0], 00117 matData[colorIndex][1], 00118 matData[colorIndex][2]); 00119 fprintf(outfile, "center(%f,%f,%f)\n", 00120 ORDER(from[0], from[1], from[2])); // first point 00121 fprintf(outfile, "center(%f,%f,%f)\n", 00122 ORDER(to[0], to[1], to[2])); // second point 00123 fprintf(outfile, "radius %f\n}\n", 00124 float(lineWidth)*DEFAULT_RADIUS); // radius 00125 00126 } else if (lineStyle == ::DASHEDLINE) { 00127 // transform the world coordinates 00128 (transMat.top()).multpoint3d(a, tmp1); 00129 (transMat.top()).multpoint3d(b, tmp2); 00130 00131 // how to create a dashed line 00132 vec_sub(dirvec, tmp2, tmp1); // vector from a to b 00133 vec_copy(unitdirvec, dirvec); 00134 vec_normalize(unitdirvec); // unit vector from a to b 00135 test = 1; 00136 i = 0; 00137 while (test == 1) { 00138 for (j=0; j<3; j++) { 00139 from[j] = (float) (tmp1[j] + (2*i )*DASH_LENGTH*unitdirvec[j]); 00140 to[j] = (float) (tmp1[j] + (2*i + 1)*DASH_LENGTH*unitdirvec[j]); 00141 } 00142 if (fabsf(tmp1[0] - to[0]) >= fabsf(dirvec[0])) { 00143 vec_copy(to, tmp2); 00144 test = 0; 00145 } 00146 00147 // draw the cylinder 00148 fprintf(outfile, "cylinder {\n"); 00149 fprintf(outfile, "colour %f,%f,%f\n", 00150 matData[colorIndex][0], 00151 matData[colorIndex][1], 00152 matData[colorIndex][2]); 00153 00154 // first point 00155 fprintf(outfile, "center(%f,%f,%f)\n", ORDER(from[0], from[1], from[2])); 00156 // second point 00157 fprintf(outfile, "center(%f,%f,%f)\n", ORDER(to[0], to[1], to[2])); 00158 // radius 00159 fprintf(outfile, "radius %f\n}\n", float(lineWidth)*DEFAULT_RADIUS); 00160 i++; 00161 } 00162 } else { 00163 msgErr << "ArtDisplayDevice: Unknown line style " << lineStyle << sendmsg; 00164 } 00165 } 00166 00167 // draw a cylinder 00168 void ArtDisplayDevice::cylinder(float *a, float *b, float r,int /*filled*/) { 00169 00170 float vec1[3], vec2[3]; 00171 00172 // transform the world coordinates 00173 (transMat.top()).multpoint3d(a, vec1); 00174 (transMat.top()).multpoint3d(b, vec2); 00175 00176 // draw the cylinder 00177 fprintf(outfile, "cylinder {\n"); 00178 fprintf(outfile, "colour %f,%f,%f\n", 00179 matData[colorIndex][0], 00180 matData[colorIndex][1], 00181 matData[colorIndex][2]); 00182 // first point 00183 fprintf(outfile, "center(%f,%f,%f)\n", ORDER(vec1[0], vec1[1], vec1[2])); 00184 // second point 00185 fprintf(outfile, "center(%f,%f,%f)\n", ORDER(vec2[0], vec2[1], vec2[2])); 00186 // radius 00187 fprintf(outfile, "radius %f\n}\n", scale_radius(r)); 00188 } 00189 00190 // draw a cone 00191 void ArtDisplayDevice::cone(float *a, float *b, float r, int /* resolution */) { 00192 float vec1[3], vec2[3]; 00193 00194 // transform the world coordinates 00195 (transMat.top()).multpoint3d(a, vec1); 00196 (transMat.top()).multpoint3d(b, vec2); 00197 00198 fprintf(outfile, "cone {\n"); 00199 fprintf(outfile, "colour %f,%f,%f\n", 00200 matData[colorIndex][0], 00201 matData[colorIndex][1], 00202 matData[colorIndex][2]); 00203 // second point 00204 fprintf(outfile, "vertex(%f,%f,%f)\n", ORDER(vec2[0], vec2[1], vec2[2])); 00205 // first point 00206 fprintf(outfile, "center(%f,%f,%f)\n", ORDER(vec1[0], vec1[1], vec1[2])); 00207 // radius 00208 fprintf(outfile, "radius %f\n}\n", scale_radius(r)); 00209 } 00210 00211 // draw a triangle 00212 void ArtDisplayDevice::triangle(const float *a, const float *b, const float *c, const float *n1, 00213 const float *n2, const float *n3) { 00214 00215 float vec1[3], vec2[3], vec3[3]; 00216 float nor1[3], nor2[3], nor3[3]; 00217 00218 // transform the world coordinates 00219 (transMat.top()).multpoint3d(a, vec1); 00220 (transMat.top()).multpoint3d(b, vec2); 00221 (transMat.top()).multpoint3d(c, vec3); 00222 00223 // and the normals 00224 (transMat.top()).multnorm3d(n1, nor1); 00225 (transMat.top()).multnorm3d(n2, nor2); 00226 (transMat.top()).multnorm3d(n3, nor3); 00227 00228 // draw the triangle 00229 fprintf(outfile, "polygon {\n"); 00230 fprintf(outfile, "colour %f,%f,%f\n", 00231 matData[colorIndex][0], 00232 matData[colorIndex][1], 00233 matData[colorIndex][2]); 00234 00235 fprintf(outfile, "vertex (%f,%f,%f),(%f,%f,%f)\n", 00236 ORDER(vec1[0], vec1[1], vec1[2]), // point one 00237 ORDER(nor1[0], nor1[1], nor1[2])); 00238 00239 fprintf(outfile, "vertex (%f,%f,%f),(%f,%f,%f)\n", 00240 ORDER(vec2[0], vec2[1], vec2[2]), // point two 00241 ORDER(nor2[0], nor2[1], nor2[2])); 00242 fprintf(outfile, "vertex (%f,%f,%f),(%f,%f,%f)\n", 00243 ORDER(vec3[0], vec3[1], vec3[2]), // point three 00244 ORDER(nor3[0], nor3[1], nor3[2])); 00245 fprintf(outfile, "}\n"); 00246 } 00247 00248 // draw a square 00249 void ArtDisplayDevice::square(float *, float *a, float *b, float *c, float *d) { 00250 00251 float vec1[3], vec2[3], vec3[3], vec4[3]; 00252 00253 // transform the world coordinates 00254 (transMat.top()).multpoint3d(a, vec1); 00255 (transMat.top()).multpoint3d(b, vec2); 00256 (transMat.top()).multpoint3d(c, vec3); 00257 (transMat.top()).multpoint3d(d, vec4); 00258 00259 // draw the square 00260 fprintf(outfile, "polygon {\n"); 00261 fprintf(outfile, "colour %f,%f,%f\n", 00262 matData[colorIndex][0], 00263 matData[colorIndex][1], 00264 matData[colorIndex][2]); 00265 00266 fprintf(outfile, "vertex (%f,%f,%f)\n", 00267 ORDER(vec1[0], vec1[1], vec1[2])); // point one 00268 fprintf(outfile, "vertex (%f,%f,%f)\n", 00269 ORDER(vec2[0], vec2[1], vec2[2])); // point two 00270 fprintf(outfile, "vertex (%f,%f,%f)\n", 00271 ORDER(vec3[0], vec3[1], vec3[2])); // point three 00272 fprintf(outfile, "vertex (%f,%f,%f)\n", 00273 ORDER(vec4[0], vec4[1], vec4[2])); // point four 00274 fprintf(outfile, "}\n"); 00275 00276 } 00277 00278 void ArtDisplayDevice::comment(const char *s) 00279 { 00280 fprintf(outfile, "// %s\n", s); 00281 } 00282 00284 00285 // initialize the file for output 00286 void ArtDisplayDevice::write_header() { 00287 00288 Initialized = TRUE; 00289 00290 fprintf(outfile, "up(0, 0, 1) \n"); 00291 fprintf(outfile, "lookat(-1, 0, 0, 0, 0, 0, 0)\n"); 00292 fprintf(outfile, "fieldofview 45 \n"); 00293 00294 00295 // write the light sources 00296 // The light code doesn't work because at this point I don't have the 00297 // correct transformation matrix, so I'll leave only the one light source 00298 fprintf(outfile, "light {\n\tcolour 1, 1, 1\n" 00299 "\tlocation (-10, 0, 0)\n}\n"); 00300 00301 // set the background 00302 fprintf(outfile, "background %f, %f, %f\n", 00303 backColor[0], backColor[1], backColor[2]); 00304 00305 // everything is plastic-like 00306 fprintf(outfile, "material 0.0, 0.75, 0.25, 20.0\n"); 00307 } 00308 00309 00310 // clean up after yourself 00311 void ArtDisplayDevice::write_trailer() { 00312 fprintf(outfile, "//End of tokens \n"); 00313 msgInfo << "Art file generation finished" << sendmsg; 00314 } 00315