merged branch scene-file-parsing into trunk
git-svn-id: svn://anubis/fart/trunk@343 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
commit
700e47901b
@ -9,6 +9,7 @@
|
|||||||
#include "parser/parser.h"
|
#include "parser/parser.h"
|
||||||
#include "parser/nodes.h"
|
#include "parser/nodes.h"
|
||||||
#include "util/Polygon.h"
|
#include "util/Polygon.h"
|
||||||
|
#include "util/Scope.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -16,64 +17,16 @@ typedef vector< refptr<Node> >::const_iterator Node_Iterator;
|
|||||||
|
|
||||||
void Scene::load(const char * filename)
|
void Scene::load(const char * filename)
|
||||||
{
|
{
|
||||||
refptr<Node> node = parse(filename);
|
refptr<Scope> scope = new Scope();
|
||||||
processNode(node);
|
refptr<Node> node = parse(filename, scope);
|
||||||
}
|
if ( ! node.isNull() )
|
||||||
|
{
|
||||||
|
/* evaluate any scripting nodes in the node tree */
|
||||||
|
refptr<Node> processed_scene = node->evaluate();
|
||||||
|
node->evaluateChildren(processed_scene);
|
||||||
|
|
||||||
void Scene::processNode(refptr<Node> node)
|
/* now we have a new node tree under 'dummy' with no scripting nodes */
|
||||||
{
|
processScene(processed_scene);
|
||||||
if (node.isNull())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( typeid(*node) == typeid(SceneNode) )
|
|
||||||
{
|
|
||||||
processScene(node);
|
|
||||||
}
|
|
||||||
else if ( node->isShape() )
|
|
||||||
{
|
|
||||||
refptr<Shape> shape = processShape(node);
|
|
||||||
if ( ! shape.isNull() )
|
|
||||||
m_shapes.push_back(shape);
|
|
||||||
}
|
|
||||||
else if ( typeid(*node) == typeid(LightNode) )
|
|
||||||
{
|
|
||||||
refptr<Light> light = processLight(node);
|
|
||||||
if ( ! light.isNull() )
|
|
||||||
m_lights.push_back(light);
|
|
||||||
}
|
|
||||||
else if ( typeid(*node) == typeid(OptionsNode) )
|
|
||||||
{
|
|
||||||
processOptions(node);
|
|
||||||
}
|
|
||||||
else if (node->isTransformBlock())
|
|
||||||
{
|
|
||||||
vector< refptr<Shape> > shapes = processTransformBlock(node);
|
|
||||||
for (int i = 0, sz = shapes.size(); i < sz; i++)
|
|
||||||
{
|
|
||||||
m_shapes.push_back(shapes[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( typeid(*node) == typeid(MaterialDefinitionNode) )
|
|
||||||
{
|
|
||||||
processMaterialDefinition(node);
|
|
||||||
}
|
|
||||||
else if ( typeid(*node) == typeid(ShapeDefinitionNode) )
|
|
||||||
{
|
|
||||||
processShapeDefinition(node);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cerr << __FILE__ << ": " << __LINE__
|
|
||||||
<< ": error: unrecognized node!" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scene::processChildren(refptr<Node> node)
|
|
||||||
{
|
|
||||||
std::vector< refptr<Node> > & children = node->getChildren();
|
|
||||||
for (int i = 0, sz = children.size(); i < sz; i++)
|
|
||||||
{
|
|
||||||
processNode(children[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,18 +51,34 @@ void Scene::processScene(refptr<Node> node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* then any other scene-specific items */
|
||||||
for (Node_Iterator it = node->getChildren().begin();
|
for (Node_Iterator it = node->getChildren().begin();
|
||||||
it != node->getChildren().end();
|
it != node->getChildren().end();
|
||||||
it++)
|
it++)
|
||||||
{
|
{
|
||||||
if ( typeid(**it) != typeid(CameraNode) )
|
if ( typeid(**it) == typeid(LightNode) )
|
||||||
{
|
{
|
||||||
processNode(*it);
|
refptr<Light> light = processLight(*it);
|
||||||
|
if ( ! light.isNull() )
|
||||||
|
m_lights.push_back(light);
|
||||||
}
|
}
|
||||||
|
else if ( typeid(**it) == typeid(OptionsNode) )
|
||||||
|
{
|
||||||
|
processOptions(*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> Scene::processShape(refptr<Node> node)
|
/* then any general items */
|
||||||
|
vector<ShapeRef> shapes = processGeneralItems(node);
|
||||||
|
for (vector<ShapeRef>::iterator it = shapes.begin();
|
||||||
|
it != shapes.end();
|
||||||
|
it++)
|
||||||
|
{
|
||||||
|
m_shapes.push_back(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShapeRef Scene::processShape(refptr<Node> node)
|
||||||
{
|
{
|
||||||
if ( typeid(*node) == typeid(BoxNode) )
|
if ( typeid(*node) == typeid(BoxNode) )
|
||||||
{
|
{
|
||||||
@ -147,7 +116,7 @@ refptr<Shape> Scene::processShape(refptr<Node> node)
|
|||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
return refptr<Shape>(NULL);
|
return ShapeRef(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::processCamera(refptr<Node> node)
|
void Scene::processCamera(refptr<Node> node)
|
||||||
@ -220,7 +189,7 @@ void Scene::processOptions(refptr<Node> node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vector< refptr<Shape> > Scene::processTransformBlock(refptr<Node> node)
|
vector<ShapeRef> Scene::processTransformBlock(refptr<Node> node)
|
||||||
{
|
{
|
||||||
if ( typeid(*node) == typeid(TranslateBlockNode) )
|
if ( typeid(*node) == typeid(TranslateBlockNode) )
|
||||||
{
|
{
|
||||||
@ -238,8 +207,22 @@ vector< refptr<Shape> > Scene::processTransformBlock(refptr<Node> node)
|
|||||||
m_transforms.push(m_transforms.top());
|
m_transforms.push(m_transforms.top());
|
||||||
m_transforms.top().scale(node->getVector());
|
m_transforms.top().scale(node->getVector());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr << "Unknown transformation block node type!" << endl;
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
|
||||||
vector< refptr<Shape> > shapes;
|
vector<ShapeRef> shapes = processGeneralItems(node);
|
||||||
|
|
||||||
|
m_transforms.pop();
|
||||||
|
|
||||||
|
return shapes;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<ShapeRef> Scene::processGeneralItems(refptr<Node> node)
|
||||||
|
{
|
||||||
|
vector<ShapeRef> shapes, incoming;
|
||||||
|
|
||||||
for (Node_Iterator it = node->getChildren().begin();
|
for (Node_Iterator it = node->getChildren().begin();
|
||||||
it != node->getChildren().end();
|
it != node->getChildren().end();
|
||||||
@ -247,30 +230,27 @@ vector< refptr<Shape> > Scene::processTransformBlock(refptr<Node> node)
|
|||||||
{
|
{
|
||||||
if ((*it)->isTransformBlock())
|
if ((*it)->isTransformBlock())
|
||||||
{
|
{
|
||||||
vector< refptr<Shape> > in = processTransformBlock(*it);
|
incoming = processTransformBlock(*it);
|
||||||
for (int i = 0, sz = in.size(); i < sz; i++)
|
|
||||||
{
|
|
||||||
shapes.push_back(in[i]);
|
|
||||||
}
|
}
|
||||||
}
|
else if ( typeid(**it) == typeid(MaterialDefinitionNode) )
|
||||||
else if ( (*it)->isShape() )
|
|
||||||
{
|
{
|
||||||
shapes.push_back(processShape(*it));
|
processMaterialDefinition(*it);
|
||||||
}
|
}
|
||||||
else if ( typeid(**it) == typeid(ShapeDefinitionNode) )
|
else if ( typeid(**it) == typeid(ShapeDefinitionNode) )
|
||||||
{
|
{
|
||||||
processShapeDefinition(*it);
|
processShapeDefinition(*it);
|
||||||
}
|
}
|
||||||
else
|
else if ( (*it)->isShape() )
|
||||||
{
|
{
|
||||||
cerr << "Unknown transform block item: " << typeid(**it).name()
|
shapes.push_back(processShape(*it));
|
||||||
<< endl;
|
}
|
||||||
exit(3);
|
while (incoming.size() > 0)
|
||||||
|
{
|
||||||
|
shapes.push_back(incoming[0]);
|
||||||
|
incoming.erase(incoming.begin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_transforms.pop();
|
|
||||||
|
|
||||||
return shapes;
|
return shapes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,7 +326,7 @@ refptr<Material> Scene::processMaterial(refptr<Node> node)
|
|||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> Scene::processBox(refptr<Node> node)
|
ShapeRef Scene::processBox(refptr<Node> node)
|
||||||
{
|
{
|
||||||
refptr<Vector> size = new Vector(1, 1, 1);
|
refptr<Vector> size = new Vector(1, 1, 1);
|
||||||
refptr<Material> material;
|
refptr<Material> material;
|
||||||
@ -367,7 +347,7 @@ refptr<Shape> Scene::processBox(refptr<Node> node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> box = new Box(size);
|
ShapeRef box = new Box(size);
|
||||||
if ( ! material.isNull() )
|
if ( ! material.isNull() )
|
||||||
box->setMaterial(material);
|
box->setMaterial(material);
|
||||||
box->setTransform(m_transforms.top());
|
box->setTransform(m_transforms.top());
|
||||||
@ -378,7 +358,7 @@ refptr<Shape> Scene::processBox(refptr<Node> node)
|
|||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> Scene::processCyl(refptr<Node> node)
|
ShapeRef Scene::processCyl(refptr<Node> node)
|
||||||
{
|
{
|
||||||
double radius1 = 1.0;
|
double radius1 = 1.0;
|
||||||
double radius2 = 1.0;
|
double radius2 = 1.0;
|
||||||
@ -404,7 +384,7 @@ refptr<Shape> Scene::processCyl(refptr<Node> node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> cyl = new Cyl(radius1, radius2, height);
|
ShapeRef cyl = new Cyl(radius1, radius2, height);
|
||||||
if ( ! material.isNull() )
|
if ( ! material.isNull() )
|
||||||
cyl->setMaterial(material);
|
cyl->setMaterial(material);
|
||||||
cyl->setTransform(m_transforms.top());
|
cyl->setTransform(m_transforms.top());
|
||||||
@ -457,7 +437,7 @@ refptr<Light> Scene::processLight(refptr<Node> node)
|
|||||||
return light;
|
return light;
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> Scene::processPlane(refptr<Node> node)
|
ShapeRef Scene::processPlane(refptr<Node> node)
|
||||||
{
|
{
|
||||||
Vector normal(0, 0, 1);
|
Vector normal(0, 0, 1);
|
||||||
double dist = 0;
|
double dist = 0;
|
||||||
@ -480,7 +460,7 @@ refptr<Shape> Scene::processPlane(refptr<Node> node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> plane = new Plane(normal[0],
|
ShapeRef plane = new Plane(normal[0],
|
||||||
normal[1],
|
normal[1],
|
||||||
normal[2],
|
normal[2],
|
||||||
dist);
|
dist);
|
||||||
@ -494,7 +474,7 @@ refptr<Shape> Scene::processPlane(refptr<Node> node)
|
|||||||
return plane;
|
return plane;
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> Scene::processSphere(refptr<Node> node)
|
ShapeRef Scene::processSphere(refptr<Node> node)
|
||||||
{
|
{
|
||||||
double radius = 1.0;
|
double radius = 1.0;
|
||||||
refptr<Material> material;
|
refptr<Material> material;
|
||||||
@ -515,7 +495,7 @@ refptr<Shape> Scene::processSphere(refptr<Node> node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> sphere = new Sphere(radius);
|
ShapeRef sphere = new Sphere(radius);
|
||||||
if ( ! material.isNull() )
|
if ( ! material.isNull() )
|
||||||
sphere->setMaterial(material);
|
sphere->setMaterial(material);
|
||||||
sphere->setTransform(m_transforms.top());
|
sphere->setTransform(m_transforms.top());
|
||||||
@ -526,9 +506,9 @@ refptr<Shape> Scene::processSphere(refptr<Node> node)
|
|||||||
return sphere;
|
return sphere;
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> Scene::processBool(refptr<Node> node)
|
ShapeRef Scene::processBool(refptr<Node> node)
|
||||||
{
|
{
|
||||||
vector< refptr<Shape> > shapes;
|
vector<ShapeRef> shapes;
|
||||||
refptr<Material> material;
|
refptr<Material> material;
|
||||||
|
|
||||||
bool restore_transform = processTransforms(node);
|
bool restore_transform = processTransforms(node);
|
||||||
@ -540,7 +520,7 @@ refptr<Shape> Scene::processBool(refptr<Node> node)
|
|||||||
{
|
{
|
||||||
if ( (*it)->isShape() )
|
if ( (*it)->isShape() )
|
||||||
{
|
{
|
||||||
refptr<Shape> shape = processShape(*it);
|
ShapeRef shape = processShape(*it);
|
||||||
if ( ! shape.isNull() )
|
if ( ! shape.isNull() )
|
||||||
shapes.push_back(shape);
|
shapes.push_back(shape);
|
||||||
}
|
}
|
||||||
@ -550,7 +530,7 @@ refptr<Shape> Scene::processBool(refptr<Node> node)
|
|||||||
}
|
}
|
||||||
else if ( (*it)->isTransformBlock() )
|
else if ( (*it)->isTransformBlock() )
|
||||||
{
|
{
|
||||||
vector< refptr<Shape> > in = processTransformBlock(*it);
|
vector<ShapeRef> in = processTransformBlock(*it);
|
||||||
for (int i = 0, sz = in.size(); i < sz; i++)
|
for (int i = 0, sz = in.size(); i < sz; i++)
|
||||||
{
|
{
|
||||||
shapes.push_back(in[i]);
|
shapes.push_back(in[i]);
|
||||||
@ -569,7 +549,7 @@ refptr<Shape> Scene::processBool(refptr<Node> node)
|
|||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> shape;
|
ShapeRef shape;
|
||||||
if ( typeid(*node) == typeid(IntersectNode) )
|
if ( typeid(*node) == typeid(IntersectNode) )
|
||||||
shape = new Intersect(shapes);
|
shape = new Intersect(shapes);
|
||||||
else if ( typeid(*node) == typeid(UnionNode) )
|
else if ( typeid(*node) == typeid(UnionNode) )
|
||||||
@ -594,7 +574,7 @@ refptr<Shape> Scene::processBool(refptr<Node> node)
|
|||||||
return shape;
|
return shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> Scene::processExtrude(refptr<Node> node)
|
ShapeRef Scene::processExtrude(refptr<Node> node)
|
||||||
{
|
{
|
||||||
refptr<Material> material;
|
refptr<Material> material;
|
||||||
Extrude * extrude = new Extrude();
|
Extrude * extrude = new Extrude();
|
||||||
@ -706,7 +686,7 @@ refptr<Polygon> Scene::processNGon(refptr<Node> node)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> Scene::processShapeRef(refptr<Node> node)
|
ShapeRef Scene::processShapeRef(refptr<Node> node)
|
||||||
{
|
{
|
||||||
if (m_shape_definitions.find(node->getString())
|
if (m_shape_definitions.find(node->getString())
|
||||||
== m_shape_definitions.end())
|
== m_shape_definitions.end())
|
||||||
@ -717,7 +697,7 @@ refptr<Shape> Scene::processShapeRef(refptr<Node> node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
refptr<Material> material;
|
refptr<Material> material;
|
||||||
refptr<Shape> shape = m_shape_definitions[node->getString()]->clone();
|
ShapeRef shape = m_shape_definitions[node->getString()]->clone();
|
||||||
|
|
||||||
bool restore_transform = processTransforms(node);
|
bool restore_transform = processTransforms(node);
|
||||||
|
|
||||||
|
26
main/Scene.h
26
main/Scene.h
@ -58,25 +58,25 @@ class Scene
|
|||||||
|
|
||||||
/* In Scene-load.cc */
|
/* In Scene-load.cc */
|
||||||
void load(const char * filename);
|
void load(const char * filename);
|
||||||
void processNode(refptr<Node> node);
|
|
||||||
void processChildren(refptr<Node> node);
|
|
||||||
void processScene(refptr<Node> node);
|
void processScene(refptr<Node> node);
|
||||||
refptr<Material> processMaterial(refptr<Node> node);
|
refptr<Material> processMaterial(refptr<Node> node);
|
||||||
refptr<Shape> processBox(refptr<Node> node);
|
ShapeRef processBox(refptr<Node> node);
|
||||||
refptr<Shape> processCyl(refptr<Node> node);
|
ShapeRef processCyl(refptr<Node> node);
|
||||||
refptr<Light> processLight(refptr<Node> node);
|
refptr<Light> processLight(refptr<Node> node);
|
||||||
refptr<Shape> processPlane(refptr<Node> node);
|
ShapeRef processPlane(refptr<Node> node);
|
||||||
refptr<Shape> processSphere(refptr<Node> node);
|
ShapeRef processSphere(refptr<Node> node);
|
||||||
refptr<Shape> processShape(refptr<Node> node);
|
ShapeRef processShape(refptr<Node> node);
|
||||||
refptr<Shape> processBool(refptr<Node> node);
|
ShapeRef processBool(refptr<Node> node);
|
||||||
refptr<Shape> processExtrude(refptr<Node> node);
|
ShapeRef processExtrude(refptr<Node> node);
|
||||||
refptr<Shape> processShapeRef(refptr<Node> node);
|
ShapeRef processShapeRef(refptr<Node> node);
|
||||||
refptr<Polygon> processPolygon(refptr<Node> node);
|
refptr<Polygon> processPolygon(refptr<Node> node);
|
||||||
refptr<Polygon> processNGon(refptr<Node> node);
|
refptr<Polygon> processNGon(refptr<Node> node);
|
||||||
bool processTransforms(refptr<Node> node);
|
bool processTransforms(refptr<Node> node);
|
||||||
void processCamera(refptr<Node> node);
|
void processCamera(refptr<Node> node);
|
||||||
void processOptions(refptr<Node> node);
|
void processOptions(refptr<Node> node);
|
||||||
std::vector< refptr<Shape> > processTransformBlock(refptr<Node> node);
|
std::vector<ShapeRef> processTransformBlock(refptr<Node> node);
|
||||||
|
std::vector<ShapeRef> processGeneralItems(refptr<Node> node);
|
||||||
|
std::vector<ShapeRef> processForNode(refptr<Node> node);
|
||||||
void processMaterialDefinition(refptr<Node> node);
|
void processMaterialDefinition(refptr<Node> node);
|
||||||
void processShapeDefinition(refptr<Node> node);
|
void processShapeDefinition(refptr<Node> node);
|
||||||
|
|
||||||
@ -91,8 +91,8 @@ class Scene
|
|||||||
int m_ambient_occlusion_level;
|
int m_ambient_occlusion_level;
|
||||||
|
|
||||||
/* private data */
|
/* private data */
|
||||||
std::vector< refptr<Shape> > m_shapes;
|
std::vector<ShapeRef> m_shapes;
|
||||||
std::map< std::string, refptr<Shape> > m_shape_definitions;
|
std::map<std::string, ShapeRef> m_shape_definitions;
|
||||||
std::vector< refptr<Light> > m_lights;
|
std::vector< refptr<Light> > m_lights;
|
||||||
std::stack<Transform> m_transforms;
|
std::stack<Transform> m_transforms;
|
||||||
double m_view_plane_dist;
|
double m_view_plane_dist;
|
||||||
|
148
parser/nodes.cc
148
parser/nodes.cc
@ -1,14 +1,49 @@
|
|||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
#include "nodes.h"
|
#include "nodes.h"
|
||||||
#include <vector>
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void Node::addChildren(refptr<Node> other)
|
void Node::evaluateChildren(refptr<Node> parent)
|
||||||
|
{
|
||||||
|
/* recursively evaluate all children nodes */
|
||||||
|
for (std::vector< refptr<Node> >::iterator it = m_children.begin();
|
||||||
|
it != m_children.end();
|
||||||
|
it++)
|
||||||
|
{
|
||||||
|
refptr<Node> evaluated = (*it)->evaluate();
|
||||||
|
if ( ! evaluated.isNull() )
|
||||||
|
{
|
||||||
|
if (typeid(*evaluated) == typeid(EvaluatePropagateNode))
|
||||||
|
{
|
||||||
|
for (vector<NodeRef>::iterator it2
|
||||||
|
= evaluated->getChildren().begin();
|
||||||
|
it2 != evaluated->getChildren().end();
|
||||||
|
it2++)
|
||||||
|
{
|
||||||
|
parent->addChild(*it2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*it)->evaluateChildren(evaluated);
|
||||||
|
parent->addChild(evaluated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::addChildren(NodeRef other)
|
||||||
{
|
{
|
||||||
if (other.isNull())
|
if (other.isNull())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (vector< refptr<Node> >::const_iterator it = other->m_children.begin();
|
for (vector<NodeRef>::const_iterator it = other->m_children.begin();
|
||||||
it != other->m_children.end();
|
it != other->m_children.end();
|
||||||
it++)
|
it++)
|
||||||
{
|
{
|
||||||
@ -19,3 +54,110 @@ void Node::addChildren(refptr<Node> other)
|
|||||||
Node::~Node()
|
Node::~Node()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeRef BinOpNode::evaluate()
|
||||||
|
{
|
||||||
|
double o = one->evaluate()->getNumber();
|
||||||
|
double t = two->evaluate()->getNumber();
|
||||||
|
double r = 0.0;
|
||||||
|
switch (m_op)
|
||||||
|
{
|
||||||
|
case '*':
|
||||||
|
r = o * t;
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
r = o / t;
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
r = o + t;
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
r = o - t;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cerr << "Error: BinOpNode created with op '" << m_op << "'" << endl;
|
||||||
|
exit(-3);
|
||||||
|
}
|
||||||
|
return new NumberNode(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeRef BoolExpressionNode::evaluate()
|
||||||
|
{
|
||||||
|
double o, t;
|
||||||
|
double r = 0;
|
||||||
|
if (m_op != '!')
|
||||||
|
{
|
||||||
|
o = one->evaluate()->getNumber();
|
||||||
|
t = two->evaluate()->getNumber();
|
||||||
|
}
|
||||||
|
switch (m_op)
|
||||||
|
{
|
||||||
|
case '<':
|
||||||
|
r = o < t ? 0 : 1;
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
r = o > t ? 0 : 1;
|
||||||
|
break;
|
||||||
|
case '=':
|
||||||
|
r = o == t ? 0 : 1;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
r = o != t ? 0 : 1;
|
||||||
|
break;
|
||||||
|
case '!':
|
||||||
|
r = ! one->evaluate()->getInteger();
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
r = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return new NumberNode(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeRef ForNode::evaluate()
|
||||||
|
{
|
||||||
|
NodeRef eval = new EvaluatePropagateNode();
|
||||||
|
|
||||||
|
if (!m_nodes[0].isNull())
|
||||||
|
{
|
||||||
|
m_nodes[0]->evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (m_nodes[1]->evaluate()->getInteger() != 0)
|
||||||
|
{
|
||||||
|
for (vector<NodeRef>::iterator it = m_children.begin();
|
||||||
|
it != m_children.end();
|
||||||
|
it++)
|
||||||
|
{
|
||||||
|
NodeRef n = (*it)->evaluate();
|
||||||
|
if ( ! n.isNull() )
|
||||||
|
{
|
||||||
|
if (typeid(*n) == typeid(EvaluatePropagateNode))
|
||||||
|
{
|
||||||
|
for (vector<NodeRef>::iterator it2 = n->getChildren().begin();
|
||||||
|
it2 != n->getChildren().end();
|
||||||
|
it2++)
|
||||||
|
{
|
||||||
|
eval->addChild(*it2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eval->addChild(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_nodes[2].isNull())
|
||||||
|
{
|
||||||
|
m_nodes[2]->evaluate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear out all child nodes so that evaluateChildren() doesn't
|
||||||
|
* attempt to evaluate them */
|
||||||
|
m_children.clear();
|
||||||
|
|
||||||
|
return eval;
|
||||||
|
}
|
||||||
|
|
||||||
|
501
parser/nodes.h
501
parser/nodes.h
@ -2,10 +2,17 @@
|
|||||||
#ifndef NODES_H
|
#ifndef NODES_H
|
||||||
#define NODES_H NODES_H
|
#define NODES_H NODES_H
|
||||||
|
|
||||||
#include "util/refptr.h"
|
#include <stdlib.h> /* exit() */
|
||||||
#include "util/Vector.h"
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "util/refptr.h"
|
||||||
|
#include "util/Vector.h"
|
||||||
|
#include "util/Scope.h"
|
||||||
|
|
||||||
|
extern refptr<Scope> parser_scope;
|
||||||
|
|
||||||
class Node
|
class Node
|
||||||
{
|
{
|
||||||
@ -15,119 +22,211 @@ class Node
|
|||||||
void addChildren(refptr<Node> other);
|
void addChildren(refptr<Node> other);
|
||||||
std::vector< refptr<Node> > & getChildren() { return m_children; }
|
std::vector< refptr<Node> > & getChildren() { return m_children; }
|
||||||
|
|
||||||
virtual int getInteger() { return 0; }
|
virtual int getInteger() { return getNumber(); }
|
||||||
virtual double getNumber() { return 0.0; }
|
|
||||||
|
virtual double getNumber()
|
||||||
|
{
|
||||||
|
std::cerr << "Warning: Node::getNumber() called!" << std::endl;
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
virtual refptr<Vector> getVector()
|
virtual refptr<Vector> getVector()
|
||||||
{
|
{
|
||||||
|
std::cerr << "Warning: Node::getVector() called!" << std::endl;
|
||||||
return refptr<Vector>(NULL);
|
return refptr<Vector>(NULL);
|
||||||
}
|
}
|
||||||
|
virtual std::string getString()
|
||||||
|
{
|
||||||
|
std::cerr << "Warning: Node::getString() called!" << std::endl;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
virtual refptr<Node> evaluate()
|
||||||
|
{
|
||||||
|
std::cerr << "Warning: Node::evaluate() called!" << std::endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
virtual void evaluateChildren(refptr<Node> parent);
|
||||||
|
|
||||||
virtual bool isShape() { return false; }
|
virtual bool isShape() { return false; }
|
||||||
virtual bool isMaterial() { return false; }
|
virtual bool isMaterial() { return false; }
|
||||||
virtual bool isTransformBlock() { return false; }
|
virtual bool isTransformBlock() { return false; }
|
||||||
virtual std::string getString() { return ""; }
|
virtual bool isExpression() { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector< refptr<Node> > m_children;
|
std::vector< refptr<Node> > m_children;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef refptr<Node> NodeRef;
|
||||||
|
|
||||||
class IntegerNode : public Node
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IntegerNode(int number) { m_number = number; }
|
|
||||||
int getInteger() { return m_number; }
|
|
||||||
double getNumber() { return m_number; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int m_number;
|
|
||||||
};
|
|
||||||
|
|
||||||
class NumberNode : public Node
|
class NumberNode : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NumberNode(double number) { m_number = number; }
|
NumberNode(double number)
|
||||||
double getNumber() { return m_number; }
|
: m_number(number), m_direct(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
NumberNode(NodeRef expr)
|
||||||
|
: m_direct(false)
|
||||||
|
{
|
||||||
|
m_expr = expr;
|
||||||
|
}
|
||||||
|
virtual double getNumber()
|
||||||
|
{
|
||||||
|
return m_direct ? m_number : m_expr->getNumber();
|
||||||
|
}
|
||||||
|
virtual refptr<Node> evaluate()
|
||||||
|
{
|
||||||
|
return m_direct
|
||||||
|
? new NumberNode(m_number)
|
||||||
|
: new NumberNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double m_number;
|
double m_number;
|
||||||
|
bool m_direct;
|
||||||
|
NodeRef m_expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VectorNode : public Node
|
class VectorNode : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VectorNode(refptr<Vector> vector) { m_vector = vector; }
|
VectorNode(NodeRef a, NodeRef b, NodeRef c)
|
||||||
refptr<Vector> getVector() { return m_vector; }
|
: m_a(a), m_b(b), m_c(c), m_direct(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
VectorNode(NodeRef node)
|
||||||
|
: m_vector(node), m_direct(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
refptr<Vector> getVector()
|
||||||
|
{
|
||||||
|
return m_direct
|
||||||
|
? new Vector(m_a->getNumber(),
|
||||||
|
m_b->getNumber(),
|
||||||
|
m_c->getNumber())
|
||||||
|
: m_vector->getVector();
|
||||||
|
}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return m_direct
|
||||||
|
? new VectorNode(m_a->evaluate(),
|
||||||
|
m_b->evaluate(),
|
||||||
|
m_c->evaluate())
|
||||||
|
: m_vector->evaluate();
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
refptr<Vector> m_vector;
|
NodeRef m_a, m_b, m_c, m_vector;
|
||||||
|
bool m_direct;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class AmbientNode : public VectorNode
|
class AmbientNode : public VectorNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AmbientNode(refptr<Vector> vector) : VectorNode(vector) {}
|
AmbientNode(NodeRef vector) : VectorNode(vector) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new AmbientNode(m_vector->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class AmbientOcclusionNode : public IntegerNode
|
class AmbientOcclusionNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AmbientOcclusionNode(int i) : IntegerNode(i) {}
|
AmbientOcclusionNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new AmbientOcclusionNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class BoxNode : public Node
|
class BoxNode : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isShape() { return true; }
|
bool isShape() { return true; }
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new BoxNode();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CameraNode : public Node
|
class CameraNode : public Node
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new CameraNode();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ColorNode : public VectorNode
|
class ColorNode : public VectorNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ColorNode(refptr<Vector> vector) : VectorNode(vector) {}
|
ColorNode(NodeRef vector) : VectorNode(vector) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new ColorNode(m_vector->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CylNode : public Node
|
class CylNode : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isShape() { return true; }
|
bool isShape() { return true; }
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new CylNode();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiffuseNode : public VectorNode
|
class DiffuseNode : public VectorNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DiffuseNode(refptr<Vector> vector) : VectorNode(vector) {}
|
DiffuseNode(NodeRef vector) : VectorNode(vector) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new DiffuseNode(m_vector->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExposureNode : public NumberNode
|
class ExposureNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ExposureNode(double d) : NumberNode(d) {}
|
ExposureNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new ExposureNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExtrudeNode : public Node
|
class ExtrudeNode : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isShape() { return true; }
|
bool isShape() { return true; }
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new ExtrudeNode();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class HeightNode : public IntegerNode
|
class HeightNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HeightNode(int i) : IntegerNode(i) {}
|
HeightNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new HeightNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class IdentifierNode : public Node
|
class IdentifierNode : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IdentifierNode(const std::string & str) { m_string = str; }
|
IdentifierNode(const std::string & str) { m_string = str; }
|
||||||
std::string getString()
|
std::string getString() { return m_string; }
|
||||||
|
virtual NodeRef evaluate()
|
||||||
{
|
{
|
||||||
return m_string;
|
return new IdentifierNode(m_string);
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
std::string m_string;
|
std::string m_string;
|
||||||
@ -137,38 +236,62 @@ class IntersectNode : public Node
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isShape() { return true; }
|
bool isShape() { return true; }
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new IntersectNode();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ItemsNode : public Node
|
class ItemsNode : public Node
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new ItemsNode();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class JitterNode : public IntegerNode
|
class JitterNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JitterNode(int i) : IntegerNode(i) {}
|
JitterNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new JitterNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class LightNode : public Node
|
class LightNode : public Node
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
virtual NodeRef evaluate() { return new LightNode(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class LookAtNode : public VectorNode
|
class LookAtNode : public VectorNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LookAtNode(refptr<Vector> vector) : VectorNode(vector) {}
|
LookAtNode(NodeRef vector) : VectorNode(vector) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new LookAtNode(m_vector->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class MaterialNode : public Node
|
class MaterialNode : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isMaterial() { return true; }
|
bool isMaterial() { return true; }
|
||||||
|
virtual NodeRef evaluate() { return new MaterialNode(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class MaterialDefinitionNode : public IdentifierNode
|
class MaterialDefinitionNode : public IdentifierNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MaterialDefinitionNode(const std::string & str) : IdentifierNode(str) {}
|
MaterialDefinitionNode(const std::string & str) : IdentifierNode(str) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new MaterialDefinitionNode(m_string);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class MaterialRefNode : public IdentifierNode
|
class MaterialRefNode : public IdentifierNode
|
||||||
@ -176,123 +299,195 @@ class MaterialRefNode : public IdentifierNode
|
|||||||
public:
|
public:
|
||||||
MaterialRefNode(const std::string & str) : IdentifierNode(str) {}
|
MaterialRefNode(const std::string & str) : IdentifierNode(str) {}
|
||||||
bool isMaterial() { return true; }
|
bool isMaterial() { return true; }
|
||||||
|
virtual NodeRef evaluate() { return new MaterialRefNode(m_string); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class MaxDepthNode : public IntegerNode
|
class MaxDepthNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MaxDepthNode(int i) : IntegerNode(i) {}
|
MaxDepthNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new MaxDepthNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class MultisampleNode : public IntegerNode
|
class MultisampleNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MultisampleNode(int i) : IntegerNode(i) {}
|
MultisampleNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new MultisampleNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NGonNode : public IntegerNode
|
class NGonNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NGonNode(int i) : IntegerNode(i) {}
|
NGonNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new NGonNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class OffsetNode : public NumberNode
|
class OffsetNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OffsetNode(double d) : NumberNode(d) {}
|
OffsetNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new OffsetNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class OptionsNode : public Node
|
class OptionsNode : public Node
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
virtual NodeRef evaluate() { return new OptionsNode(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlaneNode : public Node
|
class PlaneNode : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isShape() { return true; }
|
bool isShape() { return true; }
|
||||||
|
virtual NodeRef evaluate() { return new PlaneNode(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlanePositionNode : public Node
|
class PlanePositionNode : public VectorNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PlanePositionNode(refptr<Vector> vec, double dist)
|
PlanePositionNode(NodeRef vec_node, NodeRef dist)
|
||||||
|
: VectorNode(vec_node)
|
||||||
{
|
{
|
||||||
m_vector = vec;
|
|
||||||
m_dist = dist;
|
m_dist = dist;
|
||||||
}
|
}
|
||||||
refptr<Vector> getVector() { return m_vector; }
|
double getNumber() { return m_dist->getNumber(); }
|
||||||
double getNumber() { return m_dist; }
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new PlanePositionNode(m_vector->evaluate(),
|
||||||
|
m_dist->evaluate());
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
refptr<Vector> m_vector;
|
NodeRef m_dist;
|
||||||
double m_dist;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PolygonNode : public Node
|
class PolygonNode : public Node
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
virtual NodeRef evaluate() { return new PolygonNode(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class PositionNode : public VectorNode
|
class PositionNode : public VectorNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PositionNode(refptr<Vector> vector) : VectorNode(vector) {}
|
PositionNode(NodeRef vector) : VectorNode(vector) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new PositionNode(m_vector->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class RadiusNode : public NumberNode
|
class RadiusNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RadiusNode(double d) : NumberNode(d) {}
|
RadiusNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new RadiusNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ReflectanceNode : public NumberNode
|
class ReflectanceNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ReflectanceNode(double d) : NumberNode(d) {}
|
ReflectanceNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new ReflectanceNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class RotateNode : public VectorNode
|
class RotateNode : public VectorNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RotateNode(double angle, refptr<Vector> vector)
|
RotateNode(NodeRef angle, NodeRef vec_node)
|
||||||
: VectorNode(vector)
|
: VectorNode(vec_node)
|
||||||
{
|
{
|
||||||
m_angle = angle;
|
m_angle = angle;
|
||||||
}
|
}
|
||||||
double getNumber() { return m_angle; }
|
double getNumber() { return m_angle->getNumber(); }
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new RotateNode(m_angle->evaluate(), m_vector->evaluate());
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double m_angle;
|
NodeRef m_angle;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RotateBlockNode : public RotateNode
|
class RotateBlockNode : public RotateNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RotateBlockNode(double angle, refptr<Vector> vector)
|
RotateBlockNode(NodeRef angle, NodeRef vec_node)
|
||||||
: RotateNode(angle, vector) {}
|
: RotateNode(angle, vec_node) {}
|
||||||
bool isTransformBlock() { return true; }
|
bool isTransformBlock() { return true; }
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new RotateBlockNode(m_angle->evaluate(), m_vector->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScaleNode : public VectorNode
|
class ScaleNode : public VectorNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScaleNode(refptr<Vector> vector) : VectorNode(vector) {}
|
ScaleNode(NodeRef vector) : VectorNode(vector) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new ScaleNode(m_vector->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScaleBlockNode : public ScaleNode
|
class ScaleBlockNode : public ScaleNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScaleBlockNode(refptr<Vector> vector) : ScaleNode(vector) {}
|
ScaleBlockNode(NodeRef vector) : ScaleNode(vector) {}
|
||||||
bool isTransformBlock() { return true; }
|
bool isTransformBlock() { return true; }
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new ScaleBlockNode(m_vector->evaluate());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScaleScalarNode : public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScaleScalarNode(NodeRef expr)
|
||||||
|
: m_expr(expr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
NodeRef n = m_expr->evaluate();
|
||||||
|
return new VectorNode(n, n, n);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
NodeRef m_expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SceneNode : public Node
|
class SceneNode : public Node
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
virtual NodeRef evaluate() { return new SceneNode(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShapeDefinitionNode : public IdentifierNode
|
class ShapeDefinitionNode : public IdentifierNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShapeDefinitionNode(const std::string & str) : IdentifierNode(str) {}
|
ShapeDefinitionNode(const std::string & str) : IdentifierNode(str) {}
|
||||||
|
virtual NodeRef evaluate() { return new ShapeDefinitionNode(m_string); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShapeRefNode : public IdentifierNode
|
class ShapeRefNode : public IdentifierNode
|
||||||
@ -300,79 +495,247 @@ class ShapeRefNode : public IdentifierNode
|
|||||||
public:
|
public:
|
||||||
ShapeRefNode(const std::string & str) : IdentifierNode(str) {}
|
ShapeRefNode(const std::string & str) : IdentifierNode(str) {}
|
||||||
bool isShape() { return true; }
|
bool isShape() { return true; }
|
||||||
|
virtual NodeRef evaluate() { return new ShapeRefNode(m_string); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShininessNode : public NumberNode
|
class ShininessNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShininessNode(double d) : NumberNode(d) {}
|
ShininessNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new ShininessNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SizeNode : public VectorNode
|
class SizeNode : public VectorNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SizeNode(refptr<Vector> vector) : VectorNode(vector) {}
|
SizeNode(NodeRef vector) : VectorNode(vector) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new SizeNode(m_vector->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpecularNode : public VectorNode
|
class SpecularNode : public VectorNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpecularNode(refptr<Vector> vector) : VectorNode(vector) {}
|
SpecularNode(NodeRef vector) : VectorNode(vector) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new SpecularNode(m_vector->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SphereNode : public Node
|
class SphereNode : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isShape() { return true; }
|
bool isShape() { return true; }
|
||||||
|
virtual NodeRef evaluate() { return new SphereNode(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class SubtractNode : public Node
|
class SubtractNode : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isShape() { return true; }
|
bool isShape() { return true; }
|
||||||
|
virtual NodeRef evaluate() { return new SubtractNode(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class TranslateNode : public VectorNode
|
class TranslateNode : public VectorNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TranslateNode(refptr<Vector> vector) : VectorNode(vector) {}
|
TranslateNode(NodeRef vector) : VectorNode(vector) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new TranslateNode(m_vector->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TranslateBlockNode : public TranslateNode
|
class TranslateBlockNode : public TranslateNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TranslateBlockNode(refptr<Vector> vector) : TranslateNode(vector) {}
|
TranslateBlockNode(NodeRef vector) : TranslateNode(vector) {}
|
||||||
bool isTransformBlock() { return true; }
|
bool isTransformBlock() { return true; }
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new TranslateBlockNode(m_vector->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TransparencyNode : public NumberNode
|
class TransparencyNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TransparencyNode(double d) : NumberNode(d) {}
|
TransparencyNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new TransparencyNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class UnionNode : public Node
|
class UnionNode : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isShape() { return true; }
|
bool isShape() { return true; }
|
||||||
|
virtual NodeRef evaluate() { return new UnionNode(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class UpNode : public VectorNode
|
class UpNode : public VectorNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UpNode(refptr<Vector> vector) : VectorNode(vector) {}
|
UpNode(NodeRef vector) : VectorNode(vector) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new UpNode(m_vector->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class VFOVNode : public NumberNode
|
class VFOVNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VFOVNode(double d) : NumberNode(d) {}
|
VFOVNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new VFOVNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class WidthNode : public IntegerNode
|
class WidthNode : public NumberNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WidthNode(int i) : IntegerNode(i) {}
|
WidthNode(NodeRef e) : NumberNode(e) {}
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
return new WidthNode(m_expr->evaluate());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******** scripting nodes ********/
|
||||||
|
|
||||||
|
class ExpressionNode : public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool isExpression() { return true; }
|
||||||
|
virtual NodeRef evaluate() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AssignmentNode : public ExpressionNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AssignmentNode(NodeRef varref, NodeRef expr)
|
||||||
|
: m_varref(varref), m_expr(expr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::string getString() { return m_varref->getString(); }
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
double n = m_expr->evaluate()->getNumber();
|
||||||
|
parser_scope->putGlobal(getString(), n);
|
||||||
|
return new NumberNode(n);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
NodeRef m_varref;
|
||||||
|
NodeRef m_expr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LocalAssignmentNode : public ExpressionNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LocalAssignmentNode(NodeRef varref, NodeRef expr)
|
||||||
|
: m_varref(varref), m_expr(expr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::string getString() { return m_varref->getString(); }
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
double n = m_expr->evaluate()->getNumber();
|
||||||
|
parser_scope->putLocal(getString(), n);
|
||||||
|
return new NumberNode(n);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
NodeRef m_varref;
|
||||||
|
NodeRef m_expr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LocalDeclNode : public ExpressionNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LocalDeclNode(NodeRef varref) : m_varref(varref) { }
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
parser_scope->putLocal(m_varref->getString(), 0.0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
NodeRef m_varref;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BinOpNode : public ExpressionNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BinOpNode(char op, NodeRef one, NodeRef two)
|
||||||
|
: m_op(op), one(one), two(two)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual NodeRef evaluate();
|
||||||
|
protected:
|
||||||
|
char m_op;
|
||||||
|
NodeRef one;
|
||||||
|
NodeRef two;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BoolExpressionNode : public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BoolExpressionNode(char op, NodeRef one, NodeRef two)
|
||||||
|
: m_op(op), one(one), two(two)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual NodeRef evaluate();
|
||||||
|
protected:
|
||||||
|
char m_op;
|
||||||
|
NodeRef one;
|
||||||
|
NodeRef two;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VarRefNode : public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VarRefNode(const std::string & str) { m_string = str; }
|
||||||
|
std::string getString() { return m_string; }
|
||||||
|
virtual NodeRef evaluate()
|
||||||
|
{
|
||||||
|
if (parser_scope->contains(m_string))
|
||||||
|
{
|
||||||
|
return new NumberNode(parser_scope->get(m_string));
|
||||||
|
}
|
||||||
|
std::cerr << "Error: No identifier '" << m_string << "' in scope"
|
||||||
|
<< std::endl;
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
std::string m_string;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ForNode : public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ForNode(NodeRef e1, NodeRef e2, NodeRef e3)
|
||||||
|
{
|
||||||
|
m_nodes[0] = e1;
|
||||||
|
m_nodes[1] = e2;
|
||||||
|
m_nodes[2] = e3;
|
||||||
|
}
|
||||||
|
virtual NodeRef evaluate();
|
||||||
|
protected:
|
||||||
|
NodeRef m_nodes[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* this class is only used to hold a set of items coming out of a class's
|
||||||
|
* evaluate() from above. the evaluateChildren() top-level method will
|
||||||
|
* propagate children of this class up to the level of their parent */
|
||||||
|
class EvaluatePropagateNode : public Node
|
||||||
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
|
|
||||||
#include "nodes.h"
|
#include "nodes.h"
|
||||||
#include "util/refptr.h"
|
#include "util/refptr.h"
|
||||||
|
#include "util/Scope.h"
|
||||||
|
|
||||||
#define YYSTYPE refptr<Node>
|
#define YYSTYPE refptr<Node>
|
||||||
|
|
||||||
refptr<Node> parse(const char * fileName);
|
refptr<Node> parse(const char * fileName, refptr<Scope> scope);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,9 +14,13 @@
|
|||||||
|
|
||||||
\+ return PLUS;
|
\+ return PLUS;
|
||||||
- return MINUS;
|
- return MINUS;
|
||||||
\* return STAR;
|
\* return TIMES;
|
||||||
\/ return DIVIDE;
|
\/ return DIVIDE;
|
||||||
% return MOD;
|
% return MOD;
|
||||||
|
:= return ASSIGN;
|
||||||
|
= return EQUALS;
|
||||||
|
!= return NOTEQUALS;
|
||||||
|
! return NOT;
|
||||||
|
|
||||||
; return SEMICOLON;
|
; return SEMICOLON;
|
||||||
: return COLON;
|
: return COLON;
|
||||||
@ -36,8 +40,8 @@
|
|||||||
\< return LESS;
|
\< return LESS;
|
||||||
\> return GREATER;
|
\> return GREATER;
|
||||||
|
|
||||||
-?[0-9]+ *yylval = new IntegerNode(atoi(yytext)); return DEC_NUMBER;
|
[0-9]+ *yylval = new NumberNode(atof(yytext)); return REAL_NUMBER;
|
||||||
-?[0-9]*\.[0-9]+ *yylval = new NumberNode(atof(yytext)); return REAL_NUMBER;
|
[0-9]*\.[0-9]+ *yylval = new NumberNode(atof(yytext)); return REAL_NUMBER;
|
||||||
|
|
||||||
ambient return AMBIENT;
|
ambient return AMBIENT;
|
||||||
ambient_occlusion return AMBIENT_OCCLUSION;
|
ambient_occlusion return AMBIENT_OCCLUSION;
|
||||||
@ -81,10 +85,21 @@ up return UP;
|
|||||||
vfov return VFOV;
|
vfov return VFOV;
|
||||||
width return WIDTH;
|
width return WIDTH;
|
||||||
|
|
||||||
|
else return ELSE;
|
||||||
|
elsif return ELSIF;
|
||||||
|
for return FOR;
|
||||||
|
if return IF;
|
||||||
|
while return WHILE;
|
||||||
|
local return LOCAL;
|
||||||
|
|
||||||
[a-zA-Z_][a-zA-Z_0-9]* {
|
[a-zA-Z_][a-zA-Z_0-9]* {
|
||||||
*yylval = new IdentifierNode(yytext);
|
*yylval = new IdentifierNode(yytext);
|
||||||
return IDENTIFIER;
|
return IDENTIFIER;
|
||||||
}
|
}
|
||||||
|
\$[a-zA-Z_][a-zA-Z_0-9]* {
|
||||||
|
*yylval = new VarRefNode(yytext+1);
|
||||||
|
return VARREF;
|
||||||
|
}
|
||||||
|
|
||||||
#.*\n yylloc->first_line++; yylloc->last_line++;
|
#.*\n yylloc->first_line++; yylloc->last_line++;
|
||||||
\n yylloc->first_line++; yylloc->last_line++;
|
\n yylloc->first_line++; yylloc->last_line++;
|
||||||
|
277
parser/parser.yy
277
parser/parser.yy
@ -5,6 +5,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "util/Vector.h"
|
#include "util/Vector.h"
|
||||||
#include "util/refptr.h"
|
#include "util/refptr.h"
|
||||||
|
#include "util/Scope.h"
|
||||||
#include "nodes.h"
|
#include "nodes.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "parser.tab.hh" /* bison-generated header with YY[SL]TYPE */
|
#include "parser.tab.hh" /* bison-generated header with YY[SL]TYPE */
|
||||||
@ -24,6 +25,7 @@ int yywrap()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static refptr<Node> parsed_scene_node;
|
static refptr<Node> parsed_scene_node;
|
||||||
|
refptr<Scope> parser_scope;
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -33,9 +35,13 @@ static refptr<Node> parsed_scene_node;
|
|||||||
|
|
||||||
%token PLUS;
|
%token PLUS;
|
||||||
%token MINUS;
|
%token MINUS;
|
||||||
%token STAR;
|
%token TIMES;
|
||||||
%token DIVIDE;
|
%token DIVIDE;
|
||||||
%token MOD;
|
%token MOD;
|
||||||
|
%token ASSIGN;
|
||||||
|
%token EQUALS;
|
||||||
|
%token NOTEQUALS;
|
||||||
|
%token NOT;
|
||||||
|
|
||||||
%token SEMICOLON;
|
%token SEMICOLON;
|
||||||
%token COLON;
|
%token COLON;
|
||||||
@ -55,7 +61,6 @@ static refptr<Node> parsed_scene_node;
|
|||||||
%token LESS;
|
%token LESS;
|
||||||
%token GREATER;
|
%token GREATER;
|
||||||
|
|
||||||
%token DEC_NUMBER;
|
|
||||||
%token REAL_NUMBER;
|
%token REAL_NUMBER;
|
||||||
|
|
||||||
%token AMBIENT;
|
%token AMBIENT;
|
||||||
@ -101,6 +106,19 @@ static refptr<Node> parsed_scene_node;
|
|||||||
%token WIDTH;
|
%token WIDTH;
|
||||||
|
|
||||||
%token IDENTIFIER;
|
%token IDENTIFIER;
|
||||||
|
%token VARREF;
|
||||||
|
|
||||||
|
%token ELSE;
|
||||||
|
%token ELSIF;
|
||||||
|
%token FOR;
|
||||||
|
%token IF;
|
||||||
|
%token WHILE;
|
||||||
|
%token LOCAL;
|
||||||
|
|
||||||
|
%right ASSIGN
|
||||||
|
%left PLUS MINUS
|
||||||
|
%left TIMES DIVIDE
|
||||||
|
%left UMINUS
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
@ -140,7 +158,7 @@ box_items: /* empty */
|
|||||||
;
|
;
|
||||||
|
|
||||||
box_item: SIZE vector3 {
|
box_item: SIZE vector3 {
|
||||||
$$ = new SizeNode($2->getVector());
|
$$ = new SizeNode($2);
|
||||||
}
|
}
|
||||||
| shape_item { $$ = $1; }
|
| shape_item { $$ = $1; }
|
||||||
;
|
;
|
||||||
@ -160,16 +178,16 @@ camera_items: /* empty */
|
|||||||
;
|
;
|
||||||
|
|
||||||
camera_item: POSITION vector3 {
|
camera_item: POSITION vector3 {
|
||||||
$$ = new PositionNode($2->getVector());
|
$$ = new PositionNode($2);
|
||||||
}
|
}
|
||||||
| LOOKAT vector3 {
|
| LOOKAT vector3 {
|
||||||
$$ = new LookAtNode($2->getVector());
|
$$ = new LookAtNode($2);
|
||||||
}
|
}
|
||||||
| UP vector3 {
|
| UP vector3 {
|
||||||
$$ = new UpNode($2->getVector());
|
$$ = new UpNode($2);
|
||||||
}
|
}
|
||||||
| VFOV number {
|
| VFOV expression {
|
||||||
$$ = new VFOVNode($2->getNumber());
|
$$ = new VFOVNode($2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -188,7 +206,7 @@ cyl_items: /* empty */
|
|||||||
;
|
;
|
||||||
|
|
||||||
cyl_item: SIZE vector3 {
|
cyl_item: SIZE vector3 {
|
||||||
$$ = new SizeNode($2->getVector());
|
$$ = new SizeNode($2);
|
||||||
}
|
}
|
||||||
| shape_item { $$ = $1; }
|
| shape_item { $$ = $1; }
|
||||||
;
|
;
|
||||||
@ -213,14 +231,30 @@ extrude_item: polygon { $$ = $1; }
|
|||||||
| shape_item { $$ = $1; }
|
| shape_item { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
general_items: /* empty */
|
||||||
|
| general_item general_items {
|
||||||
|
$$ = new ItemsNode();
|
||||||
|
$$->addChild($1);
|
||||||
|
$$->addChildren($2);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
general_item: transform_block { $$ = $1; }
|
||||||
|
| material_definition { $$ = $1; }
|
||||||
|
| shape_definition { $$ = $1; }
|
||||||
|
| shape { $$ = $1; }
|
||||||
|
| for { $$ = $1; }
|
||||||
|
| stmt_expression { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
intersect: INTERSECT LCURLY bool_items RCURLY {
|
intersect: INTERSECT LCURLY bool_items RCURLY {
|
||||||
$$ = new IntersectNode();
|
$$ = new IntersectNode();
|
||||||
$$->addChildren($3);
|
$$->addChildren($3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
jitter: JITTER number {
|
jitter: JITTER expression {
|
||||||
$$ = new JitterNode($2->getInteger());
|
$$ = new JitterNode($2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -239,16 +273,16 @@ light_items: /* empty */
|
|||||||
;
|
;
|
||||||
|
|
||||||
light_item: POSITION vector3 {
|
light_item: POSITION vector3 {
|
||||||
$$ = new PositionNode($2->getVector());
|
$$ = new PositionNode($2);
|
||||||
}
|
}
|
||||||
| DIFFUSE vector3 {
|
| DIFFUSE vector3 {
|
||||||
$$ = new DiffuseNode($2->getVector());
|
$$ = new DiffuseNode($2);
|
||||||
}
|
}
|
||||||
| SPECULAR vector3 {
|
| SPECULAR vector3 {
|
||||||
$$ = new SpecularNode($2->getVector());
|
$$ = new SpecularNode($2);
|
||||||
}
|
}
|
||||||
| COLOR vector3 {
|
| COLOR vector3 {
|
||||||
$$ = new ColorNode($2->getVector());
|
$$ = new ColorNode($2);
|
||||||
}
|
}
|
||||||
| radius {
|
| radius {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -273,25 +307,25 @@ material_items: /* empty */
|
|||||||
;
|
;
|
||||||
|
|
||||||
material_item: COLOR vector3 {
|
material_item: COLOR vector3 {
|
||||||
$$ = new ColorNode($2->getVector());
|
$$ = new ColorNode($2);
|
||||||
}
|
}
|
||||||
| AMBIENT vector3 {
|
| AMBIENT vector3 {
|
||||||
$$ = new AmbientNode($2->getVector());
|
$$ = new AmbientNode($2);
|
||||||
}
|
}
|
||||||
| DIFFUSE vector3 {
|
| DIFFUSE vector3 {
|
||||||
$$ = new DiffuseNode($2->getVector());
|
$$ = new DiffuseNode($2);
|
||||||
}
|
}
|
||||||
| SPECULAR vector3 {
|
| SPECULAR vector3 {
|
||||||
$$ = new SpecularNode($2->getVector());
|
$$ = new SpecularNode($2);
|
||||||
}
|
}
|
||||||
| REFLECTANCE number {
|
| REFLECTANCE expression {
|
||||||
$$ = new ReflectanceNode($2->getNumber());
|
$$ = new ReflectanceNode($2);
|
||||||
}
|
}
|
||||||
| SHININESS number {
|
| SHININESS expression {
|
||||||
$$ = new ShininessNode($2->getNumber());
|
$$ = new ShininessNode($2);
|
||||||
}
|
}
|
||||||
| TRANSPARENCY number {
|
| TRANSPARENCY expression {
|
||||||
$$ = new TransparencyNode($2->getNumber());
|
$$ = new TransparencyNode($2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -306,21 +340,20 @@ material_ref: MATERIAL IDENTIFIER {
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
number: DEC_NUMBER { $$ = $1; }
|
number: REAL_NUMBER { $$ = $1; }
|
||||||
| REAL_NUMBER { $$ = $1; }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
ngon: NGON DEC_NUMBER COMMA number {
|
ngon: NGON expression COMMA expression {
|
||||||
$$ = new NGonNode($2->getInteger());
|
$$ = new NGonNode($2);
|
||||||
$$->addChild(new RadiusNode($4->getNumber()));
|
$$->addChild(new RadiusNode($4));
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
offset: OFFSET number {
|
offset: OFFSET expression {
|
||||||
$$ = new OffsetNode($2->getNumber());
|
$$ = new OffsetNode($2);
|
||||||
}
|
}
|
||||||
| OFFSET number LCURLY offset_items RCURLY {
|
| OFFSET expression LCURLY offset_items RCURLY {
|
||||||
$$ = new OffsetNode($2->getNumber());
|
$$ = new OffsetNode($2);
|
||||||
$$->addChildren($4);
|
$$->addChildren($4);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -333,15 +366,14 @@ offset_items: /* empty */
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
offset_item: SCALE number {
|
offset_item: SCALE expression {
|
||||||
$$ = new ScaleNode(new Vector($2->getNumber(), $2->getNumber(),
|
$$ = new ScaleNode(new ScaleScalarNode($2));
|
||||||
$2->getNumber()));
|
|
||||||
}
|
}
|
||||||
| SCALE vector2 {
|
| SCALE vector2 {
|
||||||
$$ = new ScaleNode($2->getVector());
|
$$ = new ScaleNode($2);
|
||||||
}
|
}
|
||||||
| POSITION vector2 {
|
| POSITION vector2 {
|
||||||
$$ = new PositionNode($2->getVector());
|
$$ = new PositionNode($2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -359,26 +391,26 @@ options_items: /* empty */
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
options_item: WIDTH DEC_NUMBER {
|
options_item: WIDTH expression {
|
||||||
$$ = new WidthNode($2->getInteger());
|
$$ = new WidthNode($2);
|
||||||
}
|
}
|
||||||
| HEIGHT DEC_NUMBER {
|
| HEIGHT expression {
|
||||||
$$ = new HeightNode($2->getInteger());
|
$$ = new HeightNode($2);
|
||||||
}
|
}
|
||||||
| MULTISAMPLE DEC_NUMBER {
|
| MULTISAMPLE expression {
|
||||||
$$ = new MultisampleNode($2->getInteger());
|
$$ = new MultisampleNode($2);
|
||||||
}
|
}
|
||||||
| MAXDEPTH DEC_NUMBER {
|
| MAXDEPTH expression {
|
||||||
$$ = new MaxDepthNode($2->getInteger());
|
$$ = new MaxDepthNode($2);
|
||||||
}
|
}
|
||||||
| EXPOSURE number {
|
| EXPOSURE expression {
|
||||||
$$ = new ExposureNode($2->getNumber());
|
$$ = new ExposureNode($2);
|
||||||
}
|
}
|
||||||
| AMBIENT vector3 {
|
| AMBIENT vector3 {
|
||||||
$$ = new AmbientNode($2->getVector());
|
$$ = new AmbientNode($2);
|
||||||
}
|
}
|
||||||
| AMBIENT_OCCLUSION DEC_NUMBER {
|
| AMBIENT_OCCLUSION expression {
|
||||||
$$ = new AmbientOcclusionNode($2->getInteger());
|
$$ = new AmbientOcclusionNode($2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -396,8 +428,8 @@ plane_items: /* empty */
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
plane_item: POSITION vector3 COMMA number {
|
plane_item: POSITION vector3 COMMA expression {
|
||||||
$$ = new PlanePositionNode($2->getVector(), $4->getNumber());
|
$$ = new PlanePositionNode($2, $4);
|
||||||
}
|
}
|
||||||
| shape_item { $$ = $1; }
|
| shape_item { $$ = $1; }
|
||||||
;
|
;
|
||||||
@ -419,8 +451,8 @@ polygon_items: /* empty */
|
|||||||
polygon_item: vector2 { $$ = $1; }
|
polygon_item: vector2 { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
radius: RADIUS number {
|
radius: RADIUS expression {
|
||||||
$$ = new RadiusNode($2->getNumber());
|
$$ = new RadiusNode($2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -433,12 +465,9 @@ scene_items: /* empty */
|
|||||||
;
|
;
|
||||||
|
|
||||||
scene_item: camera { $$ = $1; }
|
scene_item: camera { $$ = $1; }
|
||||||
| shape { $$ = $1; }
|
|
||||||
| options { $$ = $1; }
|
|
||||||
| light { $$ = $1; }
|
| light { $$ = $1; }
|
||||||
| transform_block { $$ = $1; }
|
| options { $$ = $1; }
|
||||||
| material_definition { $$ = $1; }
|
| general_item { $$ = $1; }
|
||||||
| shape_definition { $$ = $1; }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
shape: plane { $$ = $1; }
|
shape: plane { $$ = $1; }
|
||||||
@ -506,77 +535,125 @@ subtract: SUBTRACT LCURLY bool_items RCURLY {
|
|||||||
;
|
;
|
||||||
|
|
||||||
transform: TRANSLATE vector3 {
|
transform: TRANSLATE vector3 {
|
||||||
$$ = new TranslateNode($2->getVector());
|
$$ = new TranslateNode($2);
|
||||||
}
|
}
|
||||||
| ROTATE number COMMA vector3 {
|
| ROTATE expression COMMA vector3 {
|
||||||
$$ = new RotateNode($2->getNumber(), $4->getVector());
|
$$ = new RotateNode($2, $4);
|
||||||
}
|
}
|
||||||
| SCALE vector3 {
|
| SCALE vector3 {
|
||||||
$$ = new ScaleNode($2->getVector());
|
$$ = new ScaleNode($2);
|
||||||
}
|
}
|
||||||
| SCALE number {
|
| SCALE expression {
|
||||||
$$ = new ScaleNode(new Vector($2->getNumber(),
|
$$ = new ScaleNode(new ScaleScalarNode($2));
|
||||||
$2->getNumber(), $2->getNumber()));
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
transform_block: TRANSLATE vector3 LCURLY transform_block_items RCURLY {
|
transform_block: TRANSLATE vector3 LCURLY general_items RCURLY {
|
||||||
$$ = new TranslateBlockNode($2->getVector());
|
$$ = new TranslateBlockNode($2);
|
||||||
$$->addChildren($4);
|
$$->addChildren($4);
|
||||||
}
|
}
|
||||||
| ROTATE number COMMA vector3 LCURLY transform_block_items RCURLY {
|
| ROTATE expression COMMA vector3 LCURLY general_items RCURLY {
|
||||||
$$ = new RotateBlockNode($2->getNumber(), $4->getVector());
|
$$ = new RotateBlockNode($2, $4);
|
||||||
$$->addChildren($6);
|
$$->addChildren($6);
|
||||||
}
|
}
|
||||||
| SCALE vector3 LCURLY transform_block_items RCURLY {
|
| SCALE vector3 LCURLY general_items RCURLY {
|
||||||
$$ = new ScaleBlockNode($2->getVector());
|
$$ = new ScaleBlockNode($2);
|
||||||
$$->addChildren($4);
|
$$->addChildren($4);
|
||||||
}
|
}
|
||||||
| SCALE number LCURLY transform_block_items RCURLY {
|
| SCALE expression LCURLY general_items RCURLY {
|
||||||
$$ = new ScaleBlockNode(
|
$$ = new ScaleBlockNode(new ScaleScalarNode($2));
|
||||||
new Vector($2->getNumber(), $2->getNumber(),
|
|
||||||
$2->getNumber()));
|
|
||||||
$$->addChildren($4);
|
$$->addChildren($4);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
transform_block_items: /* empty */
|
|
||||||
| transform_block_item transform_block_items {
|
|
||||||
$$ = new ItemsNode();
|
|
||||||
$$->addChild($1);
|
|
||||||
$$->addChildren($2);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
transform_block_item: transform_block { $$ = $1; }
|
|
||||||
| shape { $$ = $1; }
|
|
||||||
| shape_definition { $$ = $1; }
|
|
||||||
;
|
|
||||||
|
|
||||||
union: UNION LCURLY bool_items RCURLY {
|
union: UNION LCURLY bool_items RCURLY {
|
||||||
$$ = new UnionNode();
|
$$ = new UnionNode();
|
||||||
$$->addChildren($3);
|
$$->addChildren($3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
vector2: LESS number COMMA number GREATER {
|
vector2: LESS expression COMMA expression GREATER {
|
||||||
refptr<Vector> vec =
|
$$ = new VectorNode($2, $4, new NumberNode(0.0));
|
||||||
new Vector($2->getNumber(), $4->getNumber(), 0.0);
|
|
||||||
$$ = new VectorNode(vec);
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
vector3: LESS number COMMA number COMMA number GREATER {
|
vector3: LESS expression COMMA expression COMMA expression GREATER {
|
||||||
refptr<Vector> vec =
|
$$ = new VectorNode($2, $4, $6);
|
||||||
new Vector($2->getNumber(), $4->getNumber(), $6->getNumber());
|
}
|
||||||
$$ = new VectorNode(vec);
|
;
|
||||||
|
|
||||||
|
expression: term { $$ = $1; }
|
||||||
|
| expression TIMES term { $$ = new BinOpNode('*', $1, $3); }
|
||||||
|
| expression DIVIDE term { $$ = new BinOpNode('/', $1, $3); }
|
||||||
|
| MINUS expression %prec UMINUS {
|
||||||
|
$$ = new BinOpNode('-', new NumberNode(0.0), $2);
|
||||||
|
}
|
||||||
|
| stmt_expression { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
maybe_expression: /* empty */
|
||||||
|
| expression { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
stmt_expression: assignment { $$ = $1; }
|
||||||
|
| local_assignment { $$ = $1; }
|
||||||
|
| local_decl { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
bool_expression: expression LESS expression {
|
||||||
|
$$ = new BoolExpressionNode('<', $1, $3);
|
||||||
|
}
|
||||||
|
| expression GREATER expression {
|
||||||
|
$$ = new BoolExpressionNode('>', $1, $3);
|
||||||
|
}
|
||||||
|
| expression EQUALS expression {
|
||||||
|
$$ = new BoolExpressionNode('=', $1, $3);
|
||||||
|
}
|
||||||
|
| expression NOTEQUALS expression {
|
||||||
|
$$ = new BoolExpressionNode('n', $1, $3);
|
||||||
|
}
|
||||||
|
| NOT bool_expression {
|
||||||
|
$$ = new BoolExpressionNode('!', $2, NULL);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
term: factor { $$ = $1; }
|
||||||
|
| term PLUS factor { $$ = new BinOpNode('+', $1, $3); }
|
||||||
|
| term MINUS factor { $$ = new BinOpNode('-', $1, $3); }
|
||||||
|
;
|
||||||
|
|
||||||
|
factor: number { $$ = $1; }
|
||||||
|
| VARREF { $$ = $1; }
|
||||||
|
| LPAREN expression RPAREN { $$ = $2; }
|
||||||
|
;
|
||||||
|
|
||||||
|
assignment: VARREF ASSIGN expression {
|
||||||
|
$$ = new AssignmentNode($1, $3);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
local_assignment: LOCAL VARREF ASSIGN expression {
|
||||||
|
$$ = new LocalAssignmentNode($2, $4);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
local_decl: LOCAL VARREF {
|
||||||
|
$$ = new LocalDeclNode($2);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
for: FOR LPAREN maybe_expression SEMICOLON bool_expression SEMICOLON maybe_expression RPAREN LCURLY general_items RCURLY {
|
||||||
|
$$ = new ForNode($3, $5, $7);
|
||||||
|
$$->addChildren($10);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
refptr<Node> parse(const char * fileName)
|
refptr<Node> parse(const char * fileName, refptr<Scope> scope)
|
||||||
{
|
{
|
||||||
|
parser_scope = scope;
|
||||||
|
|
||||||
yyin = fopen(fileName, "r");
|
yyin = fopen(fileName, "r");
|
||||||
if (yyin == NULL)
|
if (yyin == NULL)
|
||||||
{
|
{
|
||||||
|
@ -125,6 +125,7 @@ class Shape
|
|||||||
refptr<Material> m_material;
|
refptr<Material> m_material;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef refptr<Shape> ShapeRef;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
73
util/Scope.h
Normal file
73
util/Scope.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
|
||||||
|
#ifndef SCOPE_H
|
||||||
|
#define SCOPE_H
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Scope
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Scope() { push(); }
|
||||||
|
bool contains(const std::string & key)
|
||||||
|
{
|
||||||
|
for (m_list_type::const_reverse_iterator it = m_list.rbegin();
|
||||||
|
it != m_list.rend();
|
||||||
|
it++)
|
||||||
|
{
|
||||||
|
if (it->find(key) != it->end())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
double get(const std::string & key)
|
||||||
|
{
|
||||||
|
for (m_list_type::reverse_iterator it = m_list.rbegin();
|
||||||
|
it != m_list.rend();
|
||||||
|
it++)
|
||||||
|
{
|
||||||
|
if (it->find(key) != it->end())
|
||||||
|
{
|
||||||
|
return (*it)[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
void putLocal(const std::string & key, double val)
|
||||||
|
{
|
||||||
|
(*m_list.rbegin())[key] = val;
|
||||||
|
}
|
||||||
|
void putGlobal(const std::string & key, double val)
|
||||||
|
{
|
||||||
|
for (m_list_type::reverse_iterator it = m_list.rbegin();
|
||||||
|
it != m_list.rend();
|
||||||
|
it++)
|
||||||
|
{
|
||||||
|
if (it->find(key) != it->end())
|
||||||
|
{
|
||||||
|
(*it)[key] = val;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
putLocal(key, val);
|
||||||
|
}
|
||||||
|
void push()
|
||||||
|
{
|
||||||
|
m_list.push_back(std::map< std::string, double >());
|
||||||
|
}
|
||||||
|
void pop()
|
||||||
|
{
|
||||||
|
if (m_list.size() > 1)
|
||||||
|
{
|
||||||
|
m_list.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
typedef std::list< std::map< std::string, double > > m_list_type;
|
||||||
|
m_list_type m_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user