00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <math.h>
00027 #include <stdlib.h>
00028
00029 #include "VrmlDisplayDevice.h"
00030 #include "Matrix4.h"
00031 #include "DispCmds.h"
00032 #include "Inform.h"
00033 #include "utilities.h"
00034
00035 #define DEFAULT_RADIUS 0.002
00036 #define DASH_LENGTH 0.02
00037
00039
00040
00041 VrmlDisplayDevice::VrmlDisplayDevice(void) :
00042 FileRenderer("VRML-1", "VRML 1.0 (VRML94)", "vmdscene.wrl", "true") {
00043
00044 tList = NULL;
00045 }
00046
00048 void VrmlDisplayDevice::set_color(int mycolorIndex) {
00049 write_cindexmaterial(mycolorIndex, materialIndex);
00050 }
00051
00052
00053 void VrmlDisplayDevice::sphere(float *xyzr) {
00054
00055
00056 fprintf(outfile, "Separator {\nTranslation { translation %f %f %f }\n",
00057 xyzr[0], xyzr[1], xyzr[2]);
00058
00059 fprintf(outfile, "Sphere { radius %f }\n}\n", xyzr[3]);
00060 }
00061
00064 void VrmlDisplayDevice::line(float *a, float*b) {
00065
00066
00067
00068 fprintf(outfile, "Coordinate3 {point [ %f %f %f, %f %f %f ] }\n",
00069 a[0], a[1], a[2], b[0], b[1], b[2]);
00070 fprintf(outfile, "IndexedLineSet { coordIndex [0, 1, -1] }\n");
00071 }
00072
00073 static Matrix4 convert_endpoints_to_matrix(float *a, float *b) {
00074
00075
00076 float c[3];
00077 vec_sub(c, b, a);
00078
00079 float len = distance(a,b);
00080 if (len == 0.0) {
00081 return Matrix4();
00082 }
00083
00084 Matrix4 trans;
00085 trans.translate( (a[0] + b[0]) / 2.0f, (a[1] + b[1]) / 2.0f,
00086 (a[2] + b[2]) / 2.0f);
00087
00088
00089
00090 Matrix4 rot;
00091 if (c[0] == 0.0 && c[1] == 0.0) {
00092
00093 if (c[2] > 0) {
00094 rot.rot(-90, 'y');
00095 } else {
00096 rot.rot(-90, 'y');
00097 }
00098 } else {
00099 float theta, phi;
00100 theta = (float) atan2(c[1], c[0]);
00101 phi = (float) atan2(c[2], sqrt(c[0]*c[0] + c[1]*c[1]));
00102 Matrix4 m1; m1.rot( (float) (-phi * 180.0f / VMD_PI), 'y');
00103 rot.rot( (float) (theta * 180.0f / VMD_PI), 'z');
00104 rot.multmatrix(m1);
00105 }
00106
00107
00108 Matrix4 mat(trans);
00109 mat.multmatrix(rot);
00110
00111
00112 mat.rot(-90, 'z');
00113
00114 return mat;
00115 }
00116
00117
00118 void VrmlDisplayDevice::cylinder(float *a, float *b, float r, int filled) {
00119 if (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) {
00120 return;
00121 }
00122
00123 push();
00124 Matrix4 mat = convert_endpoints_to_matrix(a, b);
00125 load(mat);
00126
00127
00128 fprintf(outfile, "Cylinder { \n"
00129 "radius %f\n"
00130 "height %f\n"
00131 "parts %s}\n",
00132 r, distance(a,b), filled ? "ALL" : "SIDES");
00133
00134
00135 pop();
00136 }
00137
00138
00139
00140 void VrmlDisplayDevice::cone(float *a, float *b, float r, int ) {
00141 if (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) {
00142 return;
00143 }
00144
00145 push();
00146 Matrix4 mat = convert_endpoints_to_matrix(a, b);
00147 load(mat);
00148
00149
00150 fprintf(outfile, "Cone { \n"
00151 "bottomRadius %f\n"
00152 "height %f}\n",
00153 r, distance(a,b));
00154
00155
00156 pop();
00157 }
00158
00159
00160
00161 void VrmlDisplayDevice::triangle(const float *a, const float *b, const float *c,
00162 const float *n1, const float *n2, const float *n3) {
00163 fprintf(outfile,
00164 "Normal { vector [\n"
00165 " %f %f %f,\n %f %f %f,\n %f %f %f\n"
00166 " ] }\n",
00167 n1[0], n1[1], n1[2], n2[0], n2[1], n2[2],
00168 n3[0], n3[1], n3[2]);
00169 fprintf(outfile,
00170 "Coordinate3 {point [\n"
00171 " %f %f %f,\n"
00172 " %f %f %f,\n"
00173 " %f %f %f\n"
00174 " ] }\n",
00175 a[0], a[1], a[2], b[0], b[1], b[2], c[0], c[1], c[2]);
00176 fprintf(outfile, "IndexedFaceSet { coordIndex [0, 1, 2, -1] }\n");
00177 }
00178
00179 void VrmlDisplayDevice::push(void) {
00180 fprintf(outfile, "#push matrix\nSeparator {\n");
00181 }
00182
00183 void VrmlDisplayDevice::pop(void) {
00184 fprintf(outfile, "#pop matrix\n}\n");
00185 }
00186
00187 void VrmlDisplayDevice::multmatrix(const Matrix4 &mat) {
00188 fprintf(outfile, "# multmatrix\n");
00189 load(mat);
00190 }
00191
00192 void VrmlDisplayDevice::load(const Matrix4 &mat) {
00193 fprintf(outfile,
00194 "MatrixTransform {\n"
00195 " matrix %g %g %g %g\n"
00196 " %g %g %g %g\n"
00197 " %g %g %g %g\n"
00198 " %g %g %g %g\n"
00199 "}\n",
00200 mat.mat[0], mat.mat[1], mat.mat[2], mat.mat[3],
00201 mat.mat[4], mat.mat[5], mat.mat[6], mat.mat[7],
00202 mat.mat[8], mat.mat[9], mat.mat[10], mat.mat[11],
00203 mat.mat[12], mat.mat[13], mat.mat[14], mat.mat[15]
00204 );
00205 }
00206
00207 void VrmlDisplayDevice::comment(const char *s) {
00208 fprintf (outfile, "# %s\n", s);
00209 }
00210
00212
00213
00214 void VrmlDisplayDevice::write_header(void) {
00215 fprintf(outfile, "#VRML V1.0 ascii\n");
00216 fprintf(outfile, "# Created with VMD: "
00217 "http://www.ks.uiuc.edu/Research/vmd/\n");
00218 fprintf(outfile, "Separator {\n");
00219 }
00220
00221 void VrmlDisplayDevice::write_trailer(void) {
00222 fprintf(outfile, "# That's all, folks\n}\n");
00223 }
00224
00225 void VrmlDisplayDevice::write_cindexmaterial(int cindex, int material) {
00226 write_colormaterial((float *) &matData[cindex], material);
00227 }
00228
00229 void VrmlDisplayDevice::write_colormaterial(float *rgb, int) {
00230
00231 fprintf(outfile, "Material { \n");
00232 fprintf(outfile, "diffuseColor %f %f %f\n",
00233 mat_diffuse * rgb[0],
00234 mat_diffuse * rgb[1],
00235 mat_diffuse * rgb[2]);
00236 fprintf(outfile, "ambientColor %f %f %f\n",
00237 mat_ambient * rgb[0],
00238 mat_ambient * rgb[1],
00239 mat_ambient * rgb[2]);
00240 fprintf(outfile, "specularColor %f %f %f\n",
00241 mat_specular * rgb[0],
00242 mat_specular * rgb[1],
00243 mat_specular * rgb[2]);
00244 fprintf(outfile, "shininess %f\n",
00245 mat_shininess);
00246 fprintf(outfile, "transparency %f\n",
00247 1.0 - mat_opacity);
00248 fprintf(outfile, "}\n");
00249 }
00250