home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Photo CD Demo 1
/
Demo.bin
/
graphtal
/
ryshddvc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-02
|
8KB
|
287 lines
/*
* RayshadeDevice.C - rayshade device driver.
*
* Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
* All rights reserved.
*
* This software may be freely copied, modified, and redistributed
* provided that this copyright notice is preserved on all copies.
*
* You may not distribute this software, in whole or in part, as part of
* any commercial product without the express consent of the authors.
*
* There is no warranty or other guarantee of fitness of this software
* for any purpose. It is provided solely "as is".
*
*/
#include <stdlib.h>
#include "RayshadeDevice.h"
#include "ViewTransform.h"
#include "Polygon.h"
static const char* colorFile = "colors.ray.def";
//___________________________________________________________ RayshadeDevice
RayshadeDevice::RayshadeDevice(Options* options)
: DeviceDriver(options), currentColor("Noname"), applyTexture(0),
savePrimitives(0), saveDefFile(NULL)
{
if (theOptions->oname == "cout") {
Error(ERR_ADVISE,
"No file name specified: writing to files default.ray and default.ray.def");
theOptions->oname = "default.ray";
}
rayFile.open(theOptions->oname);
if (!rayFile)
Error(ERR_PANIC, "can't open file " + theOptions->oname);
defFile = new ofstream(theOptions->oname + ".def");
if (!*defFile)
Error(ERR_PANIC, "can't open file " + theOptions->oname + ".def\n");
defFile->precision(4);
}
RayshadeDevice::~RayshadeDevice()
{
StringTable_Iterator macroItr(macroNames);
while(macroItr.more()){
delete macroItr.cur_value();
macroItr.next();
}
delete defFile;
}
void RayshadeDevice::begin()
{
*defFile << "#ifndef " << LSystemName << "_DEF\n";
*defFile << "# define " << LSystemName << "_DEF\n\n";
*defFile << "name " << LSystemName << '\n';
*defFile << "/* primitives: \n";
*defFile << "grid \n";
}
void RayshadeDevice::end(const BoundingBox& b)
{
long gridsize = (long)pow(primitives, 1./3.);
*defFile << "end\n\n";
*defFile << "#endif\n";
/*
* Number of primitives in this object.
*/
defFile->seekp(3*LSystemName.length()+49, ios::beg);
*defFile << primitives << " */";
/*
* Resulting grid size.
*/
defFile->seekp(3*LSystemName.length()+67, ios::beg);
*defFile << gridsize << " " << gridsize << " " << gridsize;
defFile->close();
delete defFile;
defFile = NULL;
Vector eye, lookat, up;
if (theOptions->autoscale) {
ViewTransform* view = new ViewTransform(b, theOptions->up, theOptions->fov,
theOptions->resX, theOptions->resY);
eye = view->getEye(); lookat = view->getLookat(); up = view->getUp();
delete view;
}
else {
eye = theOptions->eye; lookat = theOptions->lookat; up = theOptions->up;
}
if (theOptions->verbose)
cerr << "primitives: "<< primitives << '\n';
rayFile << "/* This file was produced by graphtal ... so don't wonder.\n";
rayFile << " -------------------------------------------------------\n\n";
rayFile << " bounding volume:\n";
rayFile << " X: " << b.xmin() << " to " << b.xmax() << '\n';
rayFile << " Y: " << b.ymin() << " to " << b.ymax() << '\n';
rayFile << " Z: " << b.zmin() << " to " << b.zmax() << '\n';
rayFile << " " << primitives << " primitives\n";
rayFile << "*/\n\n";
rayFile << "screen " << theOptions->resX << ' ' << theOptions->resY << '\n';
rayFile << "maxdepth 1\n";
rayFile << "sample 1\n\n";
rayFile << "eyep " << eye[0] << ' ' << eye[1] << ' ' << eye[2] << '\n';
rayFile << "lookp " << lookat[0] << ' ' << lookat[1] << ' ' << lookat[2] << '\n';
rayFile << "up " << up[0] << ' ' << up[1] << ' ' << up[2] << '\n';
rayFile << "fov " << theOptions->fov << "\n\n";
rayFile << "light 1.0 point " << eye[0] << ' ' << eye[1] << ' ' << eye[2] << "\n\n";
rayFile << "#define s sphere\n";
rayFile << "#define cl cylinder\n";
rayFile << "#define c cone\n";
rayFile << "#define p poly\n";
rayFile << "#define o object\n";
rayFile << "#define t transform\n";
rayFile << "#define a applysurf\n\n";
rayFile << "#include \"" << colorFile << "\"\n\n";
StringTable_Iterator macroItr(macroNames);
StringTable_Iterator libraryItr(libraryNames);
while(libraryItr.more()){
rayFile << "#include \"" << libraryItr.cur_key() << ".ray.lib\"\n\n";
libraryItr.next();
}
while(macroItr.more()){
rayFile << "#include \"" << macroItr.cur_key() << ".ray.def\"\n\n";
macroItr.next();
}
rayFile << "#include \"" << theOptions->oname + rcString(".def") << "\"\n\n";
rayFile << "o " << LSystemName << "\n\n";
rayFile.close();
}
void RayshadeDevice::cylinder(const Vector& p1, const Vector& p2, real r)
{
primitives++;
*defFile << "cl "
<< r
<< ' ' << p1[0] << ' ' << p1[1] << ' ' << p1[2]
<< ' ' << p2[0] << ' ' << p2[1] << ' ' << p2[2] << '\n';
if (applyTexture)
*defFile << currentTexture << '\n';
}
void RayshadeDevice::cone(const Vector& p1, real r1, const Vector& p2, real r2)
{
primitives++;
*defFile << "c "
<< r1 << ' ' << p1[0] << ' ' << p1[1] << ' ' << p1[2] << ' '
<< r2 << ' ' << p2[0] << ' ' << p2[1] << ' ' << p2[2] << '\n';
if (applyTexture)
*defFile << currentTexture << '\n';
}
void RayshadeDevice::polygon(Polygon* p)
{
primitives++;
*defFile << "p\n";
for (register int i=0; i<p->numVertices(); i++) {
const Vector& P = p->vertex(i);
*defFile << '\t' << P[0] << ' ' << P[1] << ' ' << P[2] << '\n';
}
delete p;
if (applyTexture)
*defFile << currentTexture << '\n';
}
void RayshadeDevice::sphere(const Vector& p, real r)
{
primitives++;
*defFile << "s "
<< r << ' ' << p[0] << ' ' << p[1] << ' ' << p[2] << '\n';
if (applyTexture)
*defFile << currentTexture << '\n';
}
void RayshadeDevice::color(const Color& c)
{
if (c.colorName() != currentColor) {
currentColor = c.colorName();
*defFile << "a " << currentColor << '\n';
}
}
void RayshadeDevice::texture(const rcString& t)
{
currentTexture = t;
applyTexture = !currentTexture.empty();
}
void RayshadeDevice::beginMacro(const rcString& macroName)
{
currentMacroName = macroName;
savePrimitives = primitives;
primitives = 0;
currentColor = "Noname";
saveDefFile = defFile;
defFile = new ofstream(macroName + ".ray.def");
if (!*defFile)
Error(ERR_PANIC, "can't open file " + macroName + ".ray.def\n");
defFile->precision(4);
*defFile << "#ifndef " << macroName << "_DEF\n";
*defFile << "# define " << macroName << "_DEF\n\n";
*defFile << "name " << macroName << '\n';
*defFile << "/* primitives: \n";
*defFile << "grid \n";
}
void RayshadeDevice::endMacro()
{
long gridsize = (long)pow(primitives, 1./3.);
*defFile << "end\n\n";
*defFile << "#endif\n";
/*
* Number of primitives in this object.
*/
defFile->seekp(3*currentMacroName.length()+49, ios::beg);
*defFile << primitives << " */";
/*
* Resulting grid size.
*/
defFile->seekp(3*currentMacroName.length()+67, ios::beg);
*defFile << gridsize << " " << gridsize << " " << gridsize;
defFile->close(); delete defFile;
defFile = saveDefFile;
saveDefFile = NULL;
long* num = new long;
*num = primitives;
macroNames.find_and_replace(currentMacroName, num);
primitives = savePrimitives;
}
void RayshadeDevice::executeMacro(const rcString& macroName, const TransMatrix& tmat)
{
void* numPrimitives;
if (!macroNames.lookup(macroName, numPrimitives))
Error(ERR_PANIC, "RayshadeDevice::executeMacro: macro "
+ macroName + " does not exist");
primitives += *((long*)numPrimitives);
object(macroName, tmat);
}
void RayshadeDevice::libraryObject(const rcString& objectName, const TransMatrix& tmat)
{
object(objectName, tmat);
}
void RayshadeDevice::object(const rcString& name, const TransMatrix& tmat)
{
*defFile << "o " << name << '\n'
<< "\tt\t"
<< tmat(0,0) << ' ' << tmat(0,1) << ' ' << tmat(0,2) << "\n\t\t"
<< tmat(1,0) << ' ' << tmat(1,1) << ' ' << tmat(1,2) << "\n\t\t"
<< tmat(2,0) << ' ' << tmat(2,1) << ' ' << tmat(2,2) << "\n\t\t"
<< tmat(3,0) << ' ' << tmat(3,1) << ' ' << tmat(3,2) << "\n";
}