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