home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / msdos / utils / graphtal.lzh / Graphtal.Amiga / RayshadeDevice.C < prev    next >
C/C++ Source or Header  |  1992-11-17  |  8KB  |  282 lines

  1. /*
  2.  * RayshadeDevice.C - rayshade device driver.
  3.  *
  4.  * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
  5.  *                     University of Berne, Switzerland
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified, and redistributed
  9.  * provided that this copyright notice is preserved on all copies.
  10.  *
  11.  * You may not distribute this software, in whole or in part, as part of
  12.  * any commercial product without the express consent of the authors.
  13.  *
  14.  * There is no warranty or other guarantee of fitness of this software
  15.  * for any purpose.  It is provided solely "as is".
  16.  *
  17.  */
  18.  
  19. #include <stdlib.h>
  20. #include "RayshadeDevice.h"
  21. #include "ViewTransform.h"
  22. #include "Polygon.h"
  23.  
  24. static const char* colorFile = "colors.ray.def";
  25.  
  26. //___________________________________________________________ RayshadeDevice
  27.  
  28. RayshadeDevice::RayshadeDevice(Options* options)
  29. : DeviceDriver(options), currentColor("Noname"), applyTexture(0),
  30.   savePrimitives(0), saveDefFile(NULL)
  31. {
  32.   if (theOptions->oname == "cout") {
  33.     Error(ERR_ADVISE, 
  34.       "No file name specified: using default.ray and default.ray.def");
  35.     theOptions->oname = "default.ray";
  36.   }
  37.   
  38.   rayFile = fopen(theOptions->oname, "w");
  39.   if (rayFile == NULL)
  40.     Error(ERR_PANIC, "can't open file " + theOptions->oname);
  41.   
  42.   defFile = fopen(theOptions->oname + ".def", "w");
  43.   if (defFile == NULL) 
  44.     Error(ERR_PANIC, "can't open file " + theOptions->oname + ".def\n");
  45. }
  46.  
  47. RayshadeDevice::~RayshadeDevice()
  48. {
  49.   StringTable_Iterator macroItr(macroNames);
  50.   while(macroItr.more()){
  51.     delete  macroItr.cur_value();
  52.     macroItr.next();
  53.   } 
  54. }
  55.  
  56. void RayshadeDevice::begin()
  57. {
  58.   fprintf(defFile, "#ifndef %s_DEF\n", LSystemName.chars());
  59.   fprintf(defFile, "# define %s_DEF\n\n", LSystemName.chars());
  60.   fprintf(defFile, "name %s\n", LSystemName.chars());
  61.   fprintf(defFile, "/* primitives:             \n");
  62.   fprintf(defFile, "grid                                        \n");
  63. }
  64.  
  65. void RayshadeDevice::end(const BoundingBox& b)
  66. {
  67.   long gridsize = (long)pow(primitives, 1./3.);
  68.  
  69.   fprintf(defFile, "end\n\n");
  70.   fprintf(defFile, "#endif\n");
  71.  
  72.   /*
  73.    * Number of primitives in this object.
  74.    */
  75.   fseek(defFile, 3*LSystemName.length()+49, 0); 
  76.   fprintf(defFile, "%ld */", primitives);
  77.  
  78.   /*
  79.    * Resulting grid size.
  80.    */
  81.   fseek(defFile, 3*LSystemName.length()+67, 0);
  82.   fprintf(defFile, "%ld %ld %ld", gridsize, gridsize, gridsize);
  83.  
  84.   fclose(defFile);
  85.   defFile = NULL;
  86.  
  87.   Vector eye, lookat, up;
  88.  
  89.   if (theOptions->autoscale) {
  90.     ViewTransform* view 
  91.       = new ViewTransform(b, theOptions->up, theOptions->fov,
  92.               theOptions->resX, theOptions->resY);    
  93.     eye = view->getEye(); lookat = view->getLookat(); up = view->getUp();
  94.     delete view;
  95.   }
  96.   else {
  97.     eye = theOptions->eye; lookat = theOptions->lookat; up = theOptions->up;
  98.   }
  99.  
  100.   if (theOptions->verbose) 
  101.     cerr << "primitives: "<< primitives << '\n';
  102.  
  103.   fprintf(rayFile, "/* This file was produced by graphtal ... so don't wonder.\n");
  104.   fprintf(rayFile, "   -------------------------------------------------------\n\n");
  105.   fprintf(rayFile, "   bounding volume:\n");
  106.   fprintf(rayFile, "     X: %.4g to %.4g\n", b.xmin(), b.xmax());
  107.   fprintf(rayFile, "     Y: %.4g to %.4g\n", b.ymin(), b.ymax());
  108.   fprintf(rayFile, "     Z: %.4g to %.4g\n", b.zmin(), b.zmax());
  109.   fprintf(rayFile, "     %ld primitives\n", primitives);
  110.   fprintf(rayFile, "*/\n\n");
  111.  
  112.   fprintf(rayFile, "screen %d %d\n", theOptions->resX, theOptions->resY);
  113.   fprintf(rayFile, "maxdepth 1\n");
  114.   fprintf(rayFile, "sample 1\n\n");
  115.  
  116.   fprintf(rayFile, "eyep  %.4g %.4g %.4g\n", eye[0], eye[1], eye[2]);
  117.   fprintf(rayFile, "lookp %.4g %.4g %.4g\n", lookat[0], lookat[1], lookat[2]);
  118.   fprintf(rayFile, "up    %.4g %.4g %.4g\n", up[0], up[1], up[2]);
  119.   fprintf(rayFile, "fov   %.4g\n\n", theOptions->fov);
  120.  
  121.   fprintf(rayFile, "light 1.0 point %.4g %.4g %.4g\n\n", eye[0], eye[1], eye[2]);
  122.  
  123.   fprintf(rayFile, "#define s sphere\n");
  124.   fprintf(rayFile, "#define cl cylinder\n");
  125.   fprintf(rayFile, "#define c cone\n");
  126.   fprintf(rayFile, "#define p poly\n");
  127.   fprintf(rayFile, "#define o object\n");
  128.   fprintf(rayFile, "#define t transform\n");
  129.   fprintf(rayFile, "#define a applysurf\n\n");
  130.  
  131.   fprintf(rayFile, "#include \"%s\"\n\n", colorFile);
  132.  
  133.   StringTable_Iterator macroItr(macroNames);
  134.   StringTable_Iterator libraryItr(libraryNames);
  135.  
  136.   while(libraryItr.more()){
  137.     fprintf(rayFile, "#include \"%s.ray.lib\"\n\n", libraryItr.cur_key().chars());
  138.     libraryItr.next();
  139.   }
  140.  
  141.   while(macroItr.more()){
  142.     fprintf(rayFile, "#include \"%s.ray.def\"\n\n", macroItr.cur_key().chars());
  143.     macroItr.next();
  144.   }
  145.  
  146.   fprintf(rayFile, "#include \"%s\"\n\n", 
  147.       (theOptions->oname + rcString(".def")).chars());
  148.   fprintf(rayFile, "o %s\n\n", LSystemName.chars());
  149.  
  150.   fclose(rayFile);
  151. }
  152.  
  153. void RayshadeDevice::cylinder(const Vector& p1, const Vector& p2, real r)
  154. {
  155.   primitives++;
  156.   fprintf(defFile, "cl %.4g %.4g %.4g %.4g %.4g %.4g %.4g\n",  
  157.       r, p1[0], p1[1], p1[2], p2[0], p2[1], p2[2]);
  158.   if (applyTexture)
  159.     fprintf(defFile, "%s\n", currentTexture.chars());
  160. }
  161.  
  162. void RayshadeDevice::cone(const Vector& p1, real r1, const Vector& p2, real r2)
  163. {
  164.   primitives++;
  165.   fprintf(defFile, "c %.4g %.4g %.4g %.4g %.4g %.4g %.4g %.4g\n",  
  166.       r1, p1[0], p1[1], p1[2], r2, p2[0], p2[1], p2[2]);
  167.   if (applyTexture)
  168.     fprintf(defFile, "%s\n", currentTexture.chars());
  169. }
  170.  
  171. void RayshadeDevice::polygon(Polygon* p)
  172. {
  173.   primitives++;
  174.   fprintf(defFile, "p\n"); 
  175.   for (register int i=0; i<p->numVertices(); i++) {
  176.     const Vector& P = p->vertex(i);
  177.     fprintf(defFile, "\t%.4g %.4g %.4g\n", P[0], P[1], P[2]);
  178.   }
  179.   delete p;
  180.   if (applyTexture)
  181.     fprintf(defFile, "%s\n", currentTexture.chars());
  182. }
  183.  
  184. void RayshadeDevice::sphere(const Vector& p, real r)
  185. {
  186.   primitives++;
  187.   fprintf(defFile, "s %.4g %.4g %.4g %.4g\n", r, p[0], p[1], p[2]);
  188.   if (applyTexture)
  189.     fprintf(defFile, "%s\n", currentTexture.chars());
  190. }
  191.  
  192. void RayshadeDevice::color(const Color& c)
  193. {
  194.   if (c.colorName() != currentColor) {
  195.     currentColor = c.colorName();
  196.     fprintf(defFile, "a %s\n", currentColor.chars());
  197.   }
  198. }
  199.  
  200. void RayshadeDevice::texture(const rcString& t)
  201. {
  202.   currentTexture = t;
  203.   applyTexture = !currentTexture.empty();
  204. }
  205.  
  206. void RayshadeDevice::beginMacro(const rcString& macroName)
  207. {
  208.   currentMacroName = macroName;
  209.   savePrimitives = primitives;
  210.   primitives = 0;
  211.   currentColor = "Noname";
  212.  
  213.   saveDefFile = defFile;
  214.   defFile = fopen(macroName + ".ray.def", "w");
  215.   if (defFile == NULL) 
  216.     Error(ERR_PANIC, "can't open file " + macroName + ".ray.def\n");
  217.  
  218.   fprintf(defFile, "#ifndef %s_DEF\n", macroName.chars());
  219.   fprintf(defFile, "# define %s_DEF\n\n", macroName.chars());
  220.   fprintf(defFile, "name %s\n", macroName.chars());
  221.   fprintf(defFile, "/* primitives:             \n");
  222.   fprintf(defFile, "grid                                        \n");
  223. }
  224.  
  225. void RayshadeDevice::endMacro()
  226. {
  227.   long gridsize = (long)pow(primitives, 1./3.);
  228.  
  229.   fprintf(defFile, "end\n\n");
  230.   fprintf(defFile, "#endif\n");
  231.  
  232.   /*
  233.    * Number of primitives in this object.
  234.    */
  235.   fseek(defFile, 3*currentMacroName.length()+49, 0); 
  236.   fprintf(defFile, "%ld */", primitives);
  237.  
  238.   /*
  239.    * Resulting grid size.
  240.    */
  241.   fseek(defFile, 3*currentMacroName.length()+67, 0);
  242.   fprintf(defFile, "%ld %ld %ld", gridsize, gridsize, gridsize);
  243.  
  244.   fclose(defFile);
  245.   defFile = saveDefFile;
  246.   saveDefFile = NULL;
  247.  
  248.   long* num = new long;
  249.   *num = primitives;
  250.   macroNames.find_and_replace(currentMacroName, num);
  251.   primitives = savePrimitives;
  252. }
  253.  
  254. void RayshadeDevice::executeMacro(const rcString& macroName, const TransMatrix& tmat)
  255. {
  256.   void* numPrimitives;
  257.   if (!macroNames.lookup(macroName, numPrimitives))
  258.     Error(ERR_PANIC, "RayshadeDevice::executeMacro: macro " 
  259.                  + macroName + " does not exist");
  260.  
  261.   primitives += *((long*)numPrimitives);
  262.  
  263.   object(macroName, tmat);
  264. }
  265.  
  266. void RayshadeDevice::libraryObject(const rcString& objectName, const TransMatrix& tmat)
  267. {
  268.   object(objectName, tmat);
  269. }
  270.  
  271. void RayshadeDevice::object(const rcString& name, const TransMatrix& tmat)
  272. {
  273.   fprintf(defFile, "o %s\n", name.chars());
  274.   fprintf(defFile, "\tt\t%.4g %.4g %.4g\n\t\t%.4g %.4g %.4g\n",
  275.       tmat(0,0), tmat(0,1), tmat(0,2), 
  276.       tmat(1,0), tmat(1,1), tmat(1,2));
  277.  
  278.   fprintf(defFile, "\t\t%.4g %.4g %.4g\n\t\t%.4g %.4g %.4g\n",
  279.       tmat(2,0), tmat(2,1), tmat(2,2),
  280.       tmat(3,0), tmat(3,1), tmat(3,2));
  281. }
  282.