home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / graphtal / ryshddvc.c < prev    next >
C/C++ Source or Header  |  1992-11-02  |  8KB  |  287 lines

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