package tinyray.language;
import java.util.Iterator;
/** * Die Klasse PovRayCode implementiert einen Besucher (Visitor), * der aus einem Syntaxbaum, der mit Hilfe von LanguageKit erzeugt ist, * einen POV-Ray-Code erzeugt. */ public class PovRayCode implements Visitor<String, String> {
// Zeichenkette für eine neue Zeile. private final static String NEWLINE = "\r\n";
// Zeichenkette für das Einrücken vorgesehen, // um den Ausgabe-Code etwas lesbarer zu gestalten. private final static String INDENT = "\t";
// Globale Parameter. private Defaults defaults;
/** * Initialisiert den PovRayCode-Visitor mit der Voreinstellung der * globalen Parameter (Defaults). */ public PovRayCode() { this.defaults = new Defaults(); // color = [0.5, 0.5, 0.5] this.defaults.parameters.visitables.add(new Vector(0.5, 0.5, 0.5)); // ambient = [0.1, 0.1, 0.1] this.defaults.parameters.visitables.add(new Vector(0.1, 0.1, 0.1)); // specular = 0.5 this.defaults.parameters.visitables.add(new Real(0.5)); // shininess = 1000.0 this.defaults.parameters.visitables.add(new Real(1000.0)); // mirror = 0.4 this.defaults.parameters.visitables.add(new Real(0.4)); }
/** * Besucht einen besuchbaren Tinyray-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param tinyray Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Tinyray tinyray, String indent) { String result = ""; // Kommentar result += indent; result += "// Automatisch generierter POV-Ray-Code (POV-Ray 3.6.1)."; result += NEWLINE + indent; result += "// Herkunft: Tinyray (http://www.stefan-baur.de)"; result += NEWLINE; result += NEWLINE; // Ambience result += NEWLINE; result += tinyray.ambience.accept(this, indent); result += NEWLINE; // Camera result += NEWLINE; result += tinyray.camera.accept(this, indent); result += NEWLINE; // Background result += NEWLINE; result += tinyray.background.accept(this, indent); result += NEWLINE; // Fog if (tinyray.fog.density.value > 0.0) { result += NEWLINE; result += tinyray.fog.accept(this, indent); result += NEWLINE; } // Suns Iterator<Sun> suns = tinyray.suns.iterator(); while (suns.hasNext()) { result += NEWLINE; result += suns.next().accept(this, indent); result += NEWLINE; } // Geos Iterator<Visitable> visitables = tinyray.visitables.iterator(); while (visitables.hasNext()) { result += NEWLINE; result += visitables.next().accept(this, indent); result += NEWLINE; } // Sourcecode result += NEWLINE + indent; result += "// Quelle: Tinyray-Code"; result += NEWLINE + indent; result += "//"; result += NEWLINE; result += tinyray.accept(new PrettyPrint(), indent + "// "); result += NEWLINE; return result; }
/** * Besucht einen besuchbaren Camera-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param camera Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Camera camera, String indent) { String result = ""; result += indent; result += "camera {"; result += NEWLINE + indent + INDENT; result += "perspective"; result += NEWLINE + indent + INDENT; result += "location "; result += camera.location.accept(this, ""); result += NEWLINE + indent + INDENT; result += "look_at "; result += camera.lookAt.accept(this, ""); result += NEWLINE + indent + INDENT; result += "up -y"; result += NEWLINE + indent + INDENT; result += "sky "; result += camera.up.accept(this, ""); result += NEWLINE + indent + INDENT; result += "angle 40.0 // eigentlich 30.0, aber 40.0 passt besser!?"; result += NEWLINE + indent; result += "}"; return result; }
/** * Besucht einen besuchbaren Background-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param background Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Background background, String indent) { String result = ""; result += indent; result += "background {"; result += NEWLINE + indent + INDENT; result += "color rgb "; result += background.color.accept(this, ""); result += NEWLINE + indent; result += "}"; return result; }
/** * Besucht einen besuchbaren Ambience-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param ambience Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Ambience ambience, String indent) { String result = ""; result += indent; result += "global_settings {"; result += NEWLINE + indent + INDENT; result += "ambient_light rgb "; result += ambience.color.accept(this, ""); result += NEWLINE + indent; result += "}"; return result; }
/** * Besucht einen besuchbaren Fog-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param fog Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Fog fog, String indent) { String result = ""; result += indent; result += "fog {"; result += NEWLINE + indent + INDENT; result += "fog_type 1"; result += NEWLINE + indent + INDENT; Real distance = new Real(1.0 / fog.density.value); result += "distance "; result += distance.accept(this, ""); result += NEWLINE + indent + INDENT; result += "color rgb "; result += fog.color.accept(this, ""); result += NEWLINE + indent; result += "}"; return result; }
/** * Besucht einen besuchbaren Sun-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param sun Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Sun sun, String indent) { String result = ""; result += indent; result += "light_source {"; result += NEWLINE + indent + INDENT; Vector location = Vector.mult(10000.0, sun.direction); result += location.accept(this, ""); result += ", "; result += sun.color.accept(this, ""); result += NEWLINE + indent + INDENT; result += "parallel"; result += NEWLINE + indent + INDENT; result += "point_at "; result += (new Vector()).accept(this, ""); result += NEWLINE + indent; result += "}"; return result; }
/** * Besucht einen besuchbaren Bounding-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param bounding Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Bounding bounding, String indent) { String result = ""; Iterator<Visitable> visitables = bounding.visitables.iterator(); while (visitables.hasNext()) { result += NEWLINE; result += visitables.next().accept(this, indent); result += NEWLINE; } return result; }
/** * Besucht einen besuchbaren Triangle-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param triangle Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Triangle triangle, String indent) { String result = ""; result += indent; result += "triangle {"; result += NEWLINE; result += triangle.x.accept(this, indent + INDENT); result += ", "; result += triangle.y.accept(this, ""); result += ", "; result += triangle.z.accept(this, ""); result += NEWLINE; result += triangle.parameters.accept(this, indent + INDENT); result += NEWLINE + indent; result += "}"; return result; }
/** * Besucht einen besuchbaren Sphere-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param sphere Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Sphere sphere, String indent) { String result = ""; result += indent; result += "sphere {"; result += NEWLINE; result += sphere.center.accept(this, indent + INDENT); result += ", "; result += sphere.radius.accept(this, ""); result += NEWLINE; result += sphere.parameters.accept(this, indent + INDENT); result += NEWLINE + indent; result += "}"; return result; }
/** * Besucht einen besuchbaren Plane-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param plane Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Plane plane, String indent) { String result = ""; result += indent; result += "plane {"; result += NEWLINE; Vector normal0 = Vector.normal0(plane.x, plane.y, plane.z); result += normal0.accept(this, indent + INDENT); result += ", "; Real distance = new Real(-Vector.dot(normal0, Vector.anti(plane.x))); result += distance.accept(this, ""); result += NEWLINE; result += plane.parameters.accept(this, indent + INDENT); result += NEWLINE + indent; result += "}"; return result; }
/** * Besucht einen besuchbaren Defaults-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param defaults Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Defaults defaults, String indent) { String result = ""; int globalDefaultsSize = this.defaults.parameters.visitables.size(); int size = defaults.parameters.visitables.size();
for (int i = 0; i < Math.min(globalDefaultsSize, size); i++) { Visitable v = defaults.parameters.visitables.get(i); this.defaults.parameters.visitables.set(i, v); } return result; }
/** * Besucht einen besuchbaren Parameters-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param parameters Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Parameters parameters, String indent) { String result = "";
int globalDefaultsSize = this.defaults.parameters.visitables.size(); int parametersSize = parameters.visitables.size(); // params auf default setzen Parameters params = new Parameters(); for (int i = 0; i < globalDefaultsSize; i++) { Visitable v = this.defaults.parameters.visitables.get(i); params.visitables.add(v); } // params mit parameters überschreiben for (int i = 0; i < Math.min(globalDefaultsSize, parametersSize); i++) { Visitable v = parameters.visitables.get(i); params.visitables.set(i, v); } int size = params.visitables.size();
// texture einleiten result += indent; result += "texture {"; if (0 < size) { result += NEWLINE + indent + INDENT; result += "pigment {"; result += NEWLINE + indent + INDENT + INDENT; result += "color rgb "; result += params.visitables.get(0).accept(this, ""); result += NEWLINE + indent + INDENT; result += "}"; } if (1 < size) { // finish einleiten result += NEWLINE + indent + INDENT; result += "finish {"; result += NEWLINE + indent + INDENT + INDENT; result += "ambient rgb "; result += params.visitables.get(1).accept(this, ""); } if (2 < size) { result += NEWLINE + indent + INDENT + INDENT; result += "phong "; result += params.visitables.get(2).accept(this, ""); } if (3 < size) { result += NEWLINE + indent + INDENT + INDENT; result += "phong_size "; result += params.visitables.get(3).accept(this, ""); }
if (4 < size) { result += NEWLINE + indent + INDENT + INDENT; result += "reflection "; result += params.visitables.get(4).accept(this, ""); } if (1 < size) { // finish abschließen result += NEWLINE + indent + INDENT; result += "}"; // finish } // texture abschließen result += NEWLINE + indent; result += "}"; return result; }
/** * Besucht einen besuchbaren Vector-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param vector Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Vector vector, String indent) { String result = ""; result += indent; result += "<"; result += vector.x.accept(this, ""); result += ", "; result += vector.y.accept(this, ""); result += ", "; result += vector.z.accept(this, ""); result += ">"; return result; }
/** * Besucht einen besuchbaren Real-Knoten und generiert einen * entsprechenden POV-Ray-Code mit einer bestimmten Einrückung * und gibt diesen Code als Zeichenkette zurück. * @param real Der besuchbare Knoten. * @param indent Die Einrückung. * @return Der generierte POV-Ray-Code. */ public String visit(Real real, String indent) { String result = ""; result += indent; result += new Float(real.value).toString(); return result; } } | |