00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <string.h>
00024 #include <math.h>
00025 #include <time.h>
00026 #include "RayShadeDisplayDevice.h"
00027 #include "Matrix4.h"
00028 #include "DispCmds.h"
00029 #include "Inform.h"
00030 #include "utilities.h"
00031 #define DEFAULT_RADIUS 0.002f
00032 #define DASH_LENGTH 0.02f
00033 #define SCALE_FACTOR 1.3f
00034
00036
00037
00038 RayShadeDisplayDevice::RayShadeDisplayDevice()
00039 : FileRenderer("Rayshade", "Rayshade 4.0", "vmdscene.ray", "rayshade < %s > %s.rle") { }
00040
00041
00042 RayShadeDisplayDevice::~RayShadeDisplayDevice(void) { }
00043
00045
00046
00047 float RayShadeDisplayDevice::scale_fix(float x) {
00048 return ( x / SCALE_FACTOR );
00049 }
00050
00051
00052 void RayShadeDisplayDevice::point(float * spdata) {
00053 float vec[3];
00054
00055
00056 (transMat.top()).multpoint3d(spdata, vec);
00057
00058 write_cindexmaterial(colorIndex, materialIndex);
00059
00060 fprintf(outfile, "sphere %5f %5f %5f %5f\n",
00061 scale_fix(float(lineWidth)*DEFAULT_RADIUS),
00062 scale_fix(vec[0]), scale_fix(vec[1]), scale_fix(vec[2]));
00063 }
00064
00065
00066
00067 void RayShadeDisplayDevice::sphere(float * spdata) {
00068 float vec[3];
00069 float radius;
00070
00071
00072 (transMat.top()).multpoint3d(spdata, vec);
00073 radius = scale_radius(spdata[3]);
00074
00075 write_cindexmaterial(colorIndex, materialIndex);
00076
00077 fprintf(outfile, "sphere %5f %5f %5f %5f\n", scale_fix(radius),
00078 scale_fix(vec[0]), scale_fix(vec[1]), scale_fix(vec[2]));
00079 }
00080
00081
00082
00083
00084 void RayShadeDisplayDevice::line(float *a, float*b) {
00085 int i, j, test;
00086 float dirvec[3], unitdirvec[3];
00087 float from[3], to[3], tmp1[3], tmp2[3];
00088
00089 if (lineStyle == ::SOLIDLINE) {
00090
00091 (transMat.top()).multpoint3d(a, from);
00092 (transMat.top()).multpoint3d(b, to);
00093
00094 write_cindexmaterial(colorIndex, materialIndex);
00095 fprintf(outfile, "cylinder %5f %5f %5f %5f %5f %5f %5f\n",
00096 scale_fix(float(lineWidth)*DEFAULT_RADIUS),
00097 scale_fix(from[0]), scale_fix(from[1]), scale_fix(from[2]),
00098 scale_fix(to[0]), scale_fix(to[1]), scale_fix(to[2]));
00099
00100 } else if (lineStyle == ::DASHEDLINE) {
00101
00102 (transMat.top()).multpoint3d(a, tmp1);
00103 (transMat.top()).multpoint3d(b, tmp2);
00104
00105
00106 vec_sub(dirvec, tmp2, tmp1);
00107 vec_copy(unitdirvec, dirvec);
00108 vec_normalize(unitdirvec);
00109 test = 1;
00110 i = 0;
00111 while (test == 1) {
00112 for (j=0; j<3; j++) {
00113 from[j] = (float) (tmp1[j] + (2*i )*DASH_LENGTH*unitdirvec[j]);
00114 to[j] = (float) (tmp1[j] + (2*i + 1)*DASH_LENGTH*unitdirvec[j]);
00115 }
00116 if (fabsf(tmp1[0] - to[0]) >= fabsf(dirvec[0]) ) {
00117 vec_copy(to, tmp2);
00118 test = 0;
00119 }
00120
00121
00122 write_cindexmaterial(colorIndex, materialIndex);
00123 fprintf(outfile, "cylinder %5f %5f %5f %5f %5f %5f %5f\n",
00124 scale_fix(float(lineWidth)*DEFAULT_RADIUS),
00125 scale_fix(from[0]), scale_fix(from[1]), scale_fix(from[2]),
00126 scale_fix(to[0]), scale_fix(to[1]), scale_fix(to[2]));
00127 i++;
00128 }
00129 } else {
00130 msgErr << "RayShadeDisplayDevice: Unknown line style " << lineStyle << sendmsg;
00131 }
00132 }
00133
00134
00135
00136 void RayShadeDisplayDevice::cylinder(float *a, float *b, float r,int ) {
00137 float from[3], to[3];
00138 float radius;
00139
00140
00141 (transMat.top()).multpoint3d(a, from);
00142 (transMat.top()).multpoint3d(b, to);
00143 radius = scale_radius(r);
00144
00145 write_cindexmaterial(colorIndex, materialIndex);
00146 fprintf(outfile, "cylinder %5f %5f %5f %5f %5f %5f %5f\n",
00147 scale_fix(radius),
00148 scale_fix(from[0]), scale_fix(from[1]), scale_fix(from[2]),
00149 scale_fix(to[0]), scale_fix(to[1]), scale_fix(to[2]));
00150
00151
00152 fprintf(outfile, "disc %5f %5f %5f %5f %5f %5f %5f\n",
00153 scale_fix(radius),
00154 scale_fix(from[0]), scale_fix(from[1]), scale_fix(from[2]),
00155 scale_fix(from[0]-to[0]), scale_fix(from[1]-to[1]),
00156 scale_fix(from[2]-to[2]));
00157 fprintf(outfile, "disc %5f %5f %5f %5f %5f %5f %5f\n",
00158 scale_fix(radius),
00159 scale_fix(to[0]), scale_fix(to[1]), scale_fix(to[2]),
00160 scale_fix(to[0]-from[0]), scale_fix(to[1]-from[1]),
00161 scale_fix(to[2]-from[2]));
00162 }
00163
00164
00165 void RayShadeDisplayDevice::cone(float *a, float *b, float r) {
00166 float from[3], to[3];
00167 float radius;
00168
00169
00170 (transMat.top()).multpoint3d(a, from);
00171 (transMat.top()).multpoint3d(b, to);
00172 radius = scale_radius(r);
00173
00174 write_cindexmaterial(colorIndex, materialIndex);
00175 fprintf(outfile, "cone %5f %5f %5f %5f %5f %5f %5f %5f\n",
00176 scale_fix(radius),
00177 scale_fix(from[0]), scale_fix(from[1]), scale_fix(from[2]),
00178 scale_fix(float(lineWidth)*DEFAULT_RADIUS),
00179 scale_fix(to[0]), scale_fix(to[1]), scale_fix(to[2]));
00180 }
00181
00182
00183 void RayShadeDisplayDevice::triangle(const float *a, const float *b, const float *c, const float *n1, const float *n2, const float *n3) {
00184 float vec1[3], vec2[3], vec3[3];
00185 float norm1[3], norm2[3], norm3[3];
00186
00187
00188
00189 (transMat.top()).multpoint3d(a, vec1);
00190 (transMat.top()).multpoint3d(b, vec2);
00191 (transMat.top()).multpoint3d(c, vec3);
00192
00193
00194 (transMat.top()).multnorm3d(n1, norm1);
00195 (transMat.top()).multnorm3d(n2, norm2);
00196 (transMat.top()).multnorm3d(n3, norm3);
00197
00198 write_cindexmaterial(colorIndex, materialIndex);
00199 fprintf(outfile, "triangle %5f %5f %5f %5f %5f %5f ",
00200 scale_fix(vec1[0]), scale_fix(vec1[1]), scale_fix(vec1[2]),
00201 scale_fix(norm1[0]), scale_fix(norm1[1]), scale_fix(norm1[2]));
00202 fprintf(outfile, "%5f %5f %5f %5f %5f %5f ",
00203 scale_fix(vec2[0]), scale_fix(vec2[1]), scale_fix(vec2[2]),
00204 scale_fix(norm2[0]), scale_fix(norm2[1]), scale_fix(norm2[2]));
00205 fprintf(outfile, "%5f %5f %5f %5f %5f %5f\n",
00206 scale_fix(vec3[0]), scale_fix(vec3[1]), scale_fix(vec3[2]),
00207 scale_fix(norm3[0]), scale_fix(norm3[1]), scale_fix(norm3[2]));
00208 }
00209
00211
00212
00213 void RayShadeDisplayDevice::write_header() {
00214 time_t t;
00215
00216
00217 t = time(NULL);
00218 fprintf(outfile,"/* Rayshade input script: %s\n", my_filename);
00219 fprintf(outfile," Creation date: %s",asctime(localtime(&t)));
00220 fprintf(outfile," ---------------------------- */\n\n");
00221
00222
00223
00224 fprintf(outfile, "\n/* Define current view */\n");
00225 fprintf(outfile, "eyep %5f %5f %5f\n", eyePos[0], eyePos[1], eyePos[2]);
00226 fprintf(outfile, "lookp %5f %5f %5f\n", eyeDir[0], eyeDir[1], eyeDir[2]);
00227 fprintf(outfile, "up %5f %5f %5f\n", 0.0, 1.0, 0.0);
00228 fprintf(outfile, "fov %5f\n", 45.0);
00229 if (stereo_mode()) {
00230 fprintf(outfile, "eyesep %5f\n", eyesep() );
00231 }
00232 fprintf(outfile, "maxdepth 10\n");
00233
00234
00235 fprintf(outfile, "screen %d %d\n", (int) xSize, (int) ySize);
00236
00237
00238 fprintf(outfile, "\n/* Light Definitions */\n");
00239
00240 for (int i=0;i<DISP_LIGHTS;i++) {
00241 if (lightState[i].on) {
00242 fprintf(outfile, "light %3.2f %3.2f %3.2f ", lightState[i].color[0],
00243 lightState[i].color[1], lightState[i].color[2]);
00244 fprintf(outfile, "directional %5f %5f %5f\n", lightState[i].pos[0],
00245 lightState[i].pos[1], lightState[i].pos[2]);
00246 }
00247 }
00248
00249
00250 fprintf(outfile, "\n/* Set background color */\n");
00251 fprintf(outfile, "background %3.2f %3.2f %3.2f\n",
00252 backColor[0], backColor[1], backColor[2]);
00253
00254
00255 fprintf(outfile, "\n/* Start object descriptions */\n");
00256
00257 }
00258
00259 void RayShadeDisplayDevice::comment(const char *s) {
00260 fprintf (outfile, "\n/* %s */\n", s);
00261 }
00262
00263
00264
00265 void RayShadeDisplayDevice::write_trailer() {
00266 fprintf(outfile,"\n/* End of File */\n");
00267 msgInfo << "Rayshade file generation finished" << sendmsg;
00268 }
00269
00270 void RayShadeDisplayDevice::write_cindexmaterial(int cindex, int material) {
00271 write_colormaterial((float *) &matData[cindex], material);
00272 }
00273
00274 void RayShadeDisplayDevice::write_colormaterial(float *rgb, int) {
00275 fprintf(outfile, "applysurf diffuse %3.2f %3.2f %3.2f ",
00276 mat_diffuse * rgb[0],
00277 mat_diffuse * rgb[1],
00278 mat_diffuse * rgb[2]);
00279 fprintf(outfile, "specular %3.2f %3.2f %3.2f transp %3.2f",
00280 mat_specular * rgb[0],
00281 mat_specular * rgb[1],
00282 mat_specular * rgb[2],
00283 1.0 - mat_opacity);
00284 fprintf(outfile, "specpow %3.2f\n", mat_shininess);
00285 }
00286