From 20017370f00340d86c5c21a02ee2d8cbe30a18fb Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 28 Sep 2010 20:39:42 +0000 Subject: [PATCH 02/27] added expression production to grammar, changed grammar refs from number to expression, added BinOpNode class, currently segfaulting :( git-svn-id: svn://anubis/fart/branches/scene-file-scripting@315 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.cc | 27 +++++++++++++++++++++- parser/nodes.h | 38 ++++++++++++++++++++++++------ parser/parser.lex | 2 +- parser/parser.yy | 59 ++++++++++++++++++++++++++++++++--------------- 4 files changed, 98 insertions(+), 28 deletions(-) diff --git a/parser/nodes.cc b/parser/nodes.cc index f98008a..7af3eca 100644 --- a/parser/nodes.cc +++ b/parser/nodes.cc @@ -1,6 +1,11 @@ +#include + +#include +#include + #include "nodes.h" -#include + using namespace std; void Node::addChildren(refptr other) @@ -19,3 +24,23 @@ void Node::addChildren(refptr other) Node::~Node() { } + +double BinOpNode::getNumber() +{ + double o = one->getNumber(); + double t = two->getNumber(); + switch (m_op) + { + case '*': + return o * t; + case '/': + return o / t; + case '+': + return o + t; + case '-': + return o - t; + default: + cerr << "Error: BinOpNode created with op '" << m_op << "'" << endl; + exit(-3); + } +} diff --git a/parser/nodes.h b/parser/nodes.h index 275b871..edca3b4 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -15,16 +15,17 @@ class Node void addChildren(refptr other); std::vector< refptr > & getChildren() { return m_children; } - virtual int getInteger() { return 0; } - virtual double getNumber() { return 0.0; } - virtual refptr getVector() + virtual int getInteger() const { return 0; } + virtual double getNumber() const { return 0.0; } + virtual refptr getVector() const { return refptr(NULL); } - virtual bool isShape() { return false; } - virtual bool isMaterial() { return false; } - virtual bool isTransformBlock() { return false; } - virtual std::string getString() { return ""; } + virtual bool isShape() const { return false; } + virtual bool isMaterial() const { return false; } + virtual bool isTransformBlock() const { return false; } + virtual std::string getString() const { return ""; } + virtual bool isExpression() const { return false; } protected: std::vector< refptr > m_children; @@ -375,5 +376,28 @@ class WidthNode : public IntegerNode WidthNode(int i) : IntegerNode(i) {} }; +/******** scripting nodes ********/ + +class ExpressionNode : public Node +{ + public: + bool isExpression() const { return true; } + virtual double getInteger() { return getNumber(); } +}; + +class BinOpNode : public ExpressionNode +{ + public: + BinOpNode(char op, refptr one, refptr two) + : m_op(op), one(one), two(two) + { + } + virtual double getNumber(); + protected: + char m_op; + refptr one; + refptr two; +}; + #endif diff --git a/parser/parser.lex b/parser/parser.lex index 6b1ffc5..79cc0c7 100644 --- a/parser/parser.lex +++ b/parser/parser.lex @@ -14,7 +14,7 @@ \+ return PLUS; - return MINUS; -\* return STAR; +\* return TIMES; \/ return DIVIDE; % return MOD; diff --git a/parser/parser.yy b/parser/parser.yy index ebcb092..9be6450 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -33,7 +33,7 @@ static refptr parsed_scene_node; %token PLUS; %token MINUS; -%token STAR; +%token TIMES; %token DIVIDE; %token MOD; @@ -102,6 +102,10 @@ static refptr parsed_scene_node; %token IDENTIFIER; +%left PLUS MINUS +%left TIMES DIVIDE +%left UMINUS + %% scene: SCENE LCURLY scene_items RCURLY { @@ -168,7 +172,7 @@ camera_item: POSITION vector3 { | UP vector3 { $$ = new UpNode($2->getVector()); } - | VFOV number { + | VFOV expression { $$ = new VFOVNode($2->getNumber()); } ; @@ -219,7 +223,7 @@ intersect: INTERSECT LCURLY bool_items RCURLY { } ; -jitter: JITTER number { +jitter: JITTER expression { $$ = new JitterNode($2->getInteger()); } ; @@ -284,13 +288,13 @@ material_item: COLOR vector3 { | SPECULAR vector3 { $$ = new SpecularNode($2->getVector()); } - | REFLECTANCE number { + | REFLECTANCE expression { $$ = new ReflectanceNode($2->getNumber()); } - | SHININESS number { + | SHININESS expression { $$ = new ShininessNode($2->getNumber()); } - | TRANSPARENCY number { + | TRANSPARENCY expression { $$ = new TransparencyNode($2->getNumber()); } ; @@ -310,16 +314,16 @@ number: DEC_NUMBER { $$ = $1; } | REAL_NUMBER { $$ = $1; } ; -ngon: NGON DEC_NUMBER COMMA number { +ngon: NGON DEC_NUMBER COMMA expression { $$ = new NGonNode($2->getInteger()); $$->addChild(new RadiusNode($4->getNumber())); } ; -offset: OFFSET number { +offset: OFFSET expression { $$ = new OffsetNode($2->getNumber()); } - | OFFSET number LCURLY offset_items RCURLY { + | OFFSET expression LCURLY offset_items RCURLY { $$ = new OffsetNode($2->getNumber()); $$->addChildren($4); } @@ -333,7 +337,7 @@ offset_items: /* empty */ } ; -offset_item: SCALE number { +offset_item: SCALE expression { $$ = new ScaleNode(new Vector($2->getNumber(), $2->getNumber(), $2->getNumber())); } @@ -371,7 +375,7 @@ options_item: WIDTH DEC_NUMBER { | MAXDEPTH DEC_NUMBER { $$ = new MaxDepthNode($2->getInteger()); } - | EXPOSURE number { + | EXPOSURE expression { $$ = new ExposureNode($2->getNumber()); } | AMBIENT vector3 { @@ -396,7 +400,7 @@ plane_items: /* empty */ } ; -plane_item: POSITION vector3 COMMA number { +plane_item: POSITION vector3 COMMA expression { $$ = new PlanePositionNode($2->getVector(), $4->getNumber()); } | shape_item { $$ = $1; } @@ -419,7 +423,7 @@ polygon_items: /* empty */ polygon_item: vector2 { $$ = $1; } ; -radius: RADIUS number { +radius: RADIUS expression { $$ = new RadiusNode($2->getNumber()); } ; @@ -508,13 +512,13 @@ subtract: SUBTRACT LCURLY bool_items RCURLY { transform: TRANSLATE vector3 { $$ = new TranslateNode($2->getVector()); } - | ROTATE number COMMA vector3 { + | ROTATE expression COMMA vector3 { $$ = new RotateNode($2->getNumber(), $4->getVector()); } | SCALE vector3 { $$ = new ScaleNode($2->getVector()); } - | SCALE number { + | SCALE expression { $$ = new ScaleNode(new Vector($2->getNumber(), $2->getNumber(), $2->getNumber())); } @@ -524,7 +528,7 @@ transform_block: TRANSLATE vector3 LCURLY transform_block_items RCURLY { $$ = new TranslateBlockNode($2->getVector()); $$->addChildren($4); } - | ROTATE number COMMA vector3 LCURLY transform_block_items RCURLY { + | ROTATE expression COMMA vector3 LCURLY transform_block_items RCURLY { $$ = new RotateBlockNode($2->getNumber(), $4->getVector()); $$->addChildren($6); } @@ -532,7 +536,7 @@ transform_block: TRANSLATE vector3 LCURLY transform_block_items RCURLY { $$ = new ScaleBlockNode($2->getVector()); $$->addChildren($4); } - | SCALE number LCURLY transform_block_items RCURLY { + | SCALE expression LCURLY transform_block_items RCURLY { $$ = new ScaleBlockNode( new Vector($2->getNumber(), $2->getNumber(), $2->getNumber())); @@ -559,20 +563,37 @@ union: UNION LCURLY bool_items RCURLY { } ; -vector2: LESS number COMMA number GREATER { +vector2: LESS expression COMMA expression GREATER { refptr vec = 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 vec = 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); + } + ; + +term: factor { $$ = $1; } + | term PLUS factor { $$ = new BinOpNode('+', $1, $3); } + | term MINUS factor { $$ = new BinOpNode('-', $1, $3); } + ; + +factor: number { $$ = $1; } + | LPAREN expression RPAREN { $$ = $2; } + ; + %% refptr parse(const char * fileName) From 2f825f29f911750d7aaf038657c9bf407a6bbd3a Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 29 Sep 2010 19:30:14 +0000 Subject: [PATCH 03/27] moved computation of numbers and vectors from parser.yy to Scene-load.cc git-svn-id: svn://anubis/fart/branches/scene-file-scripting@318 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.h | 118 +++++++++++++++++++++++++++++------------------ parser/parser.yy | 86 ++++++++++++++++------------------ 2 files changed, 113 insertions(+), 91 deletions(-) diff --git a/parser/nodes.h b/parser/nodes.h index edca3b4..cd1662a 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -46,28 +46,60 @@ class IntegerNode : public Node class NumberNode : public Node { public: - NumberNode(double number) { m_number = number; } - double getNumber() { return m_number; } + NumberNode(double number) + { + m_number = number; + m_direct = true; + } + NumberNode(refptr expr) + { + addChild(expr); + m_direct = false; + } + double getNumber() + { + return m_direct ? m_number : m_children[0]->getNumber(); + } protected: double m_number; + bool m_direct; }; class VectorNode : public Node { public: - VectorNode(refptr vector) { m_vector = vector; } - refptr getVector() { return m_vector; } - - protected: - refptr m_vector; + VectorNode(refptr a, refptr b, refptr c) + { + addChild(a); + addChild(b); + addChild(c); + } + VectorNode(refptr node) + { + addChild(node); + } + refptr getVector() + { + if (m_children.size() == 1) + { + return m_children[0]->getVector(); + } + else if (m_children.size() == 3) + { + return new Vector( + m_children[0]->getNumber(), + m_children[1]->getNumber(), + m_children[2]->getNumber()); + } + return NULL; + } }; - class AmbientNode : public VectorNode { public: - AmbientNode(refptr vector) : VectorNode(vector) {} + AmbientNode(refptr vector) : VectorNode(vector) {} }; class AmbientOcclusionNode : public IntegerNode @@ -89,7 +121,7 @@ class CameraNode : public Node class ColorNode : public VectorNode { public: - ColorNode(refptr vector) : VectorNode(vector) {} + ColorNode(refptr vector) : VectorNode(vector) {} }; class CylNode : public Node @@ -101,13 +133,13 @@ class CylNode : public Node class DiffuseNode : public VectorNode { public: - DiffuseNode(refptr vector) : VectorNode(vector) {} + DiffuseNode(refptr vector) : VectorNode(vector) {} }; class ExposureNode : public NumberNode { public: - ExposureNode(double d) : NumberNode(d) {} + ExposureNode(refptr e) : NumberNode(e) {} }; class ExtrudeNode : public Node @@ -144,10 +176,10 @@ class ItemsNode : public Node { }; -class JitterNode : public IntegerNode +class JitterNode : public NumberNode { public: - JitterNode(int i) : IntegerNode(i) {} + JitterNode(refptr e) : NumberNode(e) {} }; class LightNode : public Node @@ -157,7 +189,7 @@ class LightNode : public Node class LookAtNode : public VectorNode { public: - LookAtNode(refptr vector) : VectorNode(vector) {} + LookAtNode(refptr vector) : VectorNode(vector) {} }; class MaterialNode : public Node @@ -191,16 +223,16 @@ class MultisampleNode : public IntegerNode MultisampleNode(int i) : IntegerNode(i) {} }; -class NGonNode : public IntegerNode +class NGonNode : public NumberNode { public: - NGonNode(int i) : IntegerNode(i) {} + NGonNode(refptr e) : NumberNode(e) {} }; class OffsetNode : public NumberNode { public: - OffsetNode(double d) : NumberNode(d) {} + OffsetNode(refptr e) : NumberNode(e) {} }; class OptionsNode : public Node @@ -213,20 +245,18 @@ class PlaneNode : public Node bool isShape() { return true; } }; -class PlanePositionNode : public Node +class PlanePositionNode : public VectorNode { public: - PlanePositionNode(refptr vec, double dist) + PlanePositionNode(refptr vec_node, refptr dist) + : VectorNode(vec_node) { - m_vector = vec; m_dist = dist; } - refptr getVector() { return m_vector; } - double getNumber() { return m_dist; } + double getNumber() { return m_dist->getNumber(); } protected: - refptr m_vector; - double m_dist; + refptr m_dist; }; class PolygonNode : public Node @@ -236,53 +266,53 @@ class PolygonNode : public Node class PositionNode : public VectorNode { public: - PositionNode(refptr vector) : VectorNode(vector) {} + PositionNode(refptr vector) : VectorNode(vector) {} }; class RadiusNode : public NumberNode { public: - RadiusNode(double d) : NumberNode(d) {} + RadiusNode(refptr e) : NumberNode(e) {} }; class ReflectanceNode : public NumberNode { public: - ReflectanceNode(double d) : NumberNode(d) {} + ReflectanceNode(refptr e) : NumberNode(e) {} }; class RotateNode : public VectorNode { public: - RotateNode(double angle, refptr vector) - : VectorNode(vector) + RotateNode(refptr angle, refptr vec_node) + : VectorNode(vec_node) { m_angle = angle; } - double getNumber() { return m_angle; } + double getNumber() { return m_angle->getNumber(); } protected: - double m_angle; + refptr m_angle; }; class RotateBlockNode : public RotateNode { public: - RotateBlockNode(double angle, refptr vector) - : RotateNode(angle, vector) {} + RotateBlockNode(refptr angle, refptr vec_node) + : RotateNode(angle, vec_node) {} bool isTransformBlock() { return true; } }; class ScaleNode : public VectorNode { public: - ScaleNode(refptr vector) : VectorNode(vector) {} + ScaleNode(refptr vector) : VectorNode(vector) {} }; class ScaleBlockNode : public ScaleNode { public: - ScaleBlockNode(refptr vector) : ScaleNode(vector) {} + ScaleBlockNode(refptr vector) : ScaleNode(vector) {} bool isTransformBlock() { return true; } }; @@ -306,19 +336,19 @@ class ShapeRefNode : public IdentifierNode class ShininessNode : public NumberNode { public: - ShininessNode(double d) : NumberNode(d) {} + ShininessNode(refptr e) : NumberNode(e) {} }; class SizeNode : public VectorNode { public: - SizeNode(refptr vector) : VectorNode(vector) {} + SizeNode(refptr vector) : VectorNode(vector) {} }; class SpecularNode : public VectorNode { public: - SpecularNode(refptr vector) : VectorNode(vector) {} + SpecularNode(refptr vector) : VectorNode(vector) {} }; class SphereNode : public Node @@ -336,20 +366,20 @@ class SubtractNode : public Node class TranslateNode : public VectorNode { public: - TranslateNode(refptr vector) : VectorNode(vector) {} + TranslateNode(refptr vector) : VectorNode(vector) {} }; class TranslateBlockNode : public TranslateNode { public: - TranslateBlockNode(refptr vector) : TranslateNode(vector) {} + TranslateBlockNode(refptr vector) : TranslateNode(vector) {} bool isTransformBlock() { return true; } }; class TransparencyNode : public NumberNode { public: - TransparencyNode(double d) : NumberNode(d) {} + TransparencyNode(refptr e) : NumberNode(e) {} }; class UnionNode : public Node @@ -361,13 +391,13 @@ class UnionNode : public Node class UpNode : public VectorNode { public: - UpNode(refptr vector) : VectorNode(vector) {} + UpNode(refptr vector) : VectorNode(vector) {} }; class VFOVNode : public NumberNode { public: - VFOVNode(double d) : NumberNode(d) {} + VFOVNode(refptr e) : NumberNode(e) {} }; class WidthNode : public IntegerNode diff --git a/parser/parser.yy b/parser/parser.yy index 9be6450..657ff98 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -144,7 +144,7 @@ box_items: /* empty */ ; box_item: SIZE vector3 { - $$ = new SizeNode($2->getVector()); + $$ = new SizeNode($2); } | shape_item { $$ = $1; } ; @@ -164,16 +164,16 @@ camera_items: /* empty */ ; camera_item: POSITION vector3 { - $$ = new PositionNode($2->getVector()); + $$ = new PositionNode($2); } | LOOKAT vector3 { - $$ = new LookAtNode($2->getVector()); + $$ = new LookAtNode($2); } | UP vector3 { - $$ = new UpNode($2->getVector()); + $$ = new UpNode($2); } | VFOV expression { - $$ = new VFOVNode($2->getNumber()); + $$ = new VFOVNode($2); } ; @@ -192,7 +192,7 @@ cyl_items: /* empty */ ; cyl_item: SIZE vector3 { - $$ = new SizeNode($2->getVector()); + $$ = new SizeNode($2); } | shape_item { $$ = $1; } ; @@ -224,7 +224,7 @@ intersect: INTERSECT LCURLY bool_items RCURLY { ; jitter: JITTER expression { - $$ = new JitterNode($2->getInteger()); + $$ = new JitterNode($2); } ; @@ -243,16 +243,16 @@ light_items: /* empty */ ; light_item: POSITION vector3 { - $$ = new PositionNode($2->getVector()); + $$ = new PositionNode($2); } | DIFFUSE vector3 { - $$ = new DiffuseNode($2->getVector()); + $$ = new DiffuseNode($2); } | SPECULAR vector3 { - $$ = new SpecularNode($2->getVector()); + $$ = new SpecularNode($2); } | COLOR vector3 { - $$ = new ColorNode($2->getVector()); + $$ = new ColorNode($2); } | radius { $$ = $1; @@ -277,25 +277,25 @@ material_items: /* empty */ ; material_item: COLOR vector3 { - $$ = new ColorNode($2->getVector()); + $$ = new ColorNode($2); } | AMBIENT vector3 { - $$ = new AmbientNode($2->getVector()); + $$ = new AmbientNode($2); } | DIFFUSE vector3 { - $$ = new DiffuseNode($2->getVector()); + $$ = new DiffuseNode($2); } | SPECULAR vector3 { - $$ = new SpecularNode($2->getVector()); + $$ = new SpecularNode($2); } | REFLECTANCE expression { - $$ = new ReflectanceNode($2->getNumber()); + $$ = new ReflectanceNode($2); } | SHININESS expression { - $$ = new ShininessNode($2->getNumber()); + $$ = new ShininessNode($2); } | TRANSPARENCY expression { - $$ = new TransparencyNode($2->getNumber()); + $$ = new TransparencyNode($2); } ; @@ -315,16 +315,16 @@ number: DEC_NUMBER { $$ = $1; } ; ngon: NGON DEC_NUMBER COMMA expression { - $$ = new NGonNode($2->getInteger()); - $$->addChild(new RadiusNode($4->getNumber())); + $$ = new NGonNode($2); + $$->addChild(new RadiusNode($4)); } ; offset: OFFSET expression { - $$ = new OffsetNode($2->getNumber()); + $$ = new OffsetNode($2); } | OFFSET expression LCURLY offset_items RCURLY { - $$ = new OffsetNode($2->getNumber()); + $$ = new OffsetNode($2); $$->addChildren($4); } ; @@ -338,14 +338,13 @@ offset_items: /* empty */ ; offset_item: SCALE expression { - $$ = new ScaleNode(new Vector($2->getNumber(), $2->getNumber(), - $2->getNumber())); + $$ = new ScaleNode(new VectorNode($2, $2, $2)); } | SCALE vector2 { - $$ = new ScaleNode($2->getVector()); + $$ = new ScaleNode($2); } | POSITION vector2 { - $$ = new PositionNode($2->getVector()); + $$ = new PositionNode($2); } ; @@ -376,10 +375,10 @@ options_item: WIDTH DEC_NUMBER { $$ = new MaxDepthNode($2->getInteger()); } | EXPOSURE expression { - $$ = new ExposureNode($2->getNumber()); + $$ = new ExposureNode($2); } | AMBIENT vector3 { - $$ = new AmbientNode($2->getVector()); + $$ = new AmbientNode($2); } | AMBIENT_OCCLUSION DEC_NUMBER { $$ = new AmbientOcclusionNode($2->getInteger()); @@ -401,7 +400,7 @@ plane_items: /* empty */ ; plane_item: POSITION vector3 COMMA expression { - $$ = new PlanePositionNode($2->getVector(), $4->getNumber()); + $$ = new PlanePositionNode($2, $4); } | shape_item { $$ = $1; } ; @@ -424,7 +423,7 @@ polygon_item: vector2 { $$ = $1; } ; radius: RADIUS expression { - $$ = new RadiusNode($2->getNumber()); + $$ = new RadiusNode($2); } ; @@ -510,36 +509,33 @@ subtract: SUBTRACT LCURLY bool_items RCURLY { ; transform: TRANSLATE vector3 { - $$ = new TranslateNode($2->getVector()); + $$ = new TranslateNode($2); } | ROTATE expression COMMA vector3 { - $$ = new RotateNode($2->getNumber(), $4->getVector()); + $$ = new RotateNode($2, $4); } | SCALE vector3 { - $$ = new ScaleNode($2->getVector()); + $$ = new ScaleNode($2); } | SCALE expression { - $$ = new ScaleNode(new Vector($2->getNumber(), - $2->getNumber(), $2->getNumber())); + $$ = new ScaleNode(new VectorNode($2, $2, $2)); } ; transform_block: TRANSLATE vector3 LCURLY transform_block_items RCURLY { - $$ = new TranslateBlockNode($2->getVector()); + $$ = new TranslateBlockNode($2); $$->addChildren($4); } | ROTATE expression COMMA vector3 LCURLY transform_block_items RCURLY { - $$ = new RotateBlockNode($2->getNumber(), $4->getVector()); + $$ = new RotateBlockNode($2, $4); $$->addChildren($6); } | SCALE vector3 LCURLY transform_block_items RCURLY { - $$ = new ScaleBlockNode($2->getVector()); + $$ = new ScaleBlockNode($2); $$->addChildren($4); } | SCALE expression LCURLY transform_block_items RCURLY { - $$ = new ScaleBlockNode( - new Vector($2->getNumber(), $2->getNumber(), - $2->getNumber())); + $$ = new ScaleBlockNode(new VectorNode($2, $2, $2)); $$->addChildren($4); } ; @@ -564,16 +560,12 @@ union: UNION LCURLY bool_items RCURLY { ; vector2: LESS expression COMMA expression GREATER { - refptr vec = - new Vector($2->getNumber(), $4->getNumber(), 0.0); - $$ = new VectorNode(vec); + $$ = new VectorNode($2, $4, new NumberNode(0.0)); } ; vector3: LESS expression COMMA expression COMMA expression GREATER { - refptr vec = - new Vector($2->getNumber(), $4->getNumber(), $6->getNumber()); - $$ = new VectorNode(vec); + $$ = new VectorNode($2, $4, $6); } ; From 1afa2b6510660eba4d25651dd42c68cd0140aea1 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 29 Sep 2010 19:47:38 +0000 Subject: [PATCH 04/27] fixed parser/nodes.h node classes not specifying "const" when overriding methods git-svn-id: svn://anubis/fart/branches/scene-file-scripting@319 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.h | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/parser/nodes.h b/parser/nodes.h index cd1662a..52fb5c9 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -15,16 +15,30 @@ class Node void addChildren(refptr other); std::vector< refptr > & getChildren() { return m_children; } - virtual int getInteger() const { return 0; } - virtual double getNumber() const { return 0.0; } + virtual int getInteger() const + { + std::cerr << "Warning: Node::getInteger() called!" << std::endl; + return 0; + } + virtual double getNumber() const + { + std::cerr << "Warning: Node::getNumber() called!" << std::endl; + return 0.0; + } virtual refptr getVector() const { + std::cerr << "Warning: Node::getVector() called!" << std::endl; return refptr(NULL); } + virtual std::string getString() const + { + std::cerr << "Warning: Node::getString() called!" << std::endl; + return ""; + } + virtual bool isShape() const { return false; } virtual bool isMaterial() const { return false; } virtual bool isTransformBlock() const { return false; } - virtual std::string getString() const { return ""; } virtual bool isExpression() const { return false; } protected: @@ -36,8 +50,8 @@ class IntegerNode : public Node { public: IntegerNode(int number) { m_number = number; } - int getInteger() { return m_number; } - double getNumber() { return m_number; } + int getInteger() const { return m_number; } + double getNumber() const { return m_number; } protected: int m_number; @@ -56,7 +70,7 @@ class NumberNode : public Node addChild(expr); m_direct = false; } - double getNumber() + double getNumber() const { return m_direct ? m_number : m_children[0]->getNumber(); } @@ -79,7 +93,7 @@ class VectorNode : public Node { addChild(node); } - refptr getVector() + refptr getVector() const { if (m_children.size() == 1) { @@ -92,7 +106,12 @@ class VectorNode : public Node m_children[1]->getNumber(), m_children[2]->getNumber()); } - return NULL; + else + { + std::cerr << "Warning: VectorNode::getVector() returning NULL!" + << std::endl; + return NULL; + } } }; @@ -158,7 +177,7 @@ class IdentifierNode : public Node { public: IdentifierNode(const std::string & str) { m_string = str; } - std::string getString() + std::string getString() const { return m_string; } @@ -253,7 +272,7 @@ class PlanePositionNode : public VectorNode { m_dist = dist; } - double getNumber() { return m_dist->getNumber(); } + double getNumber() const { return m_dist->getNumber(); } protected: refptr m_dist; @@ -412,7 +431,7 @@ class ExpressionNode : public Node { public: bool isExpression() const { return true; } - virtual double getInteger() { return getNumber(); } + virtual int getInteger() const { return getNumber(); } }; class BinOpNode : public ExpressionNode From 83fd083af8b163a01593a723b9c356f2af24e730 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 29 Sep 2010 19:58:21 +0000 Subject: [PATCH 05/27] removed annoying consts git-svn-id: svn://anubis/fart/branches/scene-file-scripting@320 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.h | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/parser/nodes.h b/parser/nodes.h index 52fb5c9..0abcfce 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -15,31 +15,31 @@ class Node void addChildren(refptr other); std::vector< refptr > & getChildren() { return m_children; } - virtual int getInteger() const + virtual int getInteger() { std::cerr << "Warning: Node::getInteger() called!" << std::endl; return 0; } - virtual double getNumber() const + virtual double getNumber() { std::cerr << "Warning: Node::getNumber() called!" << std::endl; return 0.0; } - virtual refptr getVector() const + virtual refptr getVector() { std::cerr << "Warning: Node::getVector() called!" << std::endl; return refptr(NULL); } - virtual std::string getString() const + virtual std::string getString() { std::cerr << "Warning: Node::getString() called!" << std::endl; return ""; } - virtual bool isShape() const { return false; } - virtual bool isMaterial() const { return false; } - virtual bool isTransformBlock() const { return false; } - virtual bool isExpression() const { return false; } + virtual bool isShape() { return false; } + virtual bool isMaterial() { return false; } + virtual bool isTransformBlock() { return false; } + virtual bool isExpression() { return false; } protected: std::vector< refptr > m_children; @@ -50,8 +50,8 @@ class IntegerNode : public Node { public: IntegerNode(int number) { m_number = number; } - int getInteger() const { return m_number; } - double getNumber() const { return m_number; } + virtual int getInteger() { return m_number; } + virtual double getNumber() { return m_number; } protected: int m_number; @@ -70,7 +70,7 @@ class NumberNode : public Node addChild(expr); m_direct = false; } - double getNumber() const + virtual double getNumber() { return m_direct ? m_number : m_children[0]->getNumber(); } @@ -93,7 +93,7 @@ class VectorNode : public Node { addChild(node); } - refptr getVector() const + refptr getVector() { if (m_children.size() == 1) { @@ -177,7 +177,7 @@ class IdentifierNode : public Node { public: IdentifierNode(const std::string & str) { m_string = str; } - std::string getString() const + std::string getString() { return m_string; } @@ -272,7 +272,7 @@ class PlanePositionNode : public VectorNode { m_dist = dist; } - double getNumber() const { return m_dist->getNumber(); } + double getNumber() { return m_dist->getNumber(); } protected: refptr m_dist; @@ -430,8 +430,9 @@ class WidthNode : public IntegerNode class ExpressionNode : public Node { public: - bool isExpression() const { return true; } - virtual int getInteger() const { return getNumber(); } + bool isExpression() { return true; } + virtual double getNumber() = 0; + virtual int getInteger() { return getNumber(); } }; class BinOpNode : public ExpressionNode From bd60471dfacdde88902482395640a5e6654a54df Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 29 Sep 2010 20:09:36 +0000 Subject: [PATCH 06/27] fixed VectorNode storing expression nodes as children instead of class members; fixed JitterNode not implementing getInteger() git-svn-id: svn://anubis/fart/branches/scene-file-scripting@321 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.h | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/parser/nodes.h b/parser/nodes.h index 0abcfce..fe3b634 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -84,35 +84,24 @@ class VectorNode : public Node { public: VectorNode(refptr a, refptr b, refptr c) + : m_a(a), m_b(b), m_c(c), m_direct(true) { - addChild(a); - addChild(b); - addChild(c); } VectorNode(refptr node) + : m_a(node), m_direct(false) { - addChild(node); } refptr getVector() { - if (m_children.size() == 1) - { - return m_children[0]->getVector(); - } - else if (m_children.size() == 3) - { - return new Vector( - m_children[0]->getNumber(), - m_children[1]->getNumber(), - m_children[2]->getNumber()); - } - else - { - std::cerr << "Warning: VectorNode::getVector() returning NULL!" - << std::endl; - return NULL; - } + return m_direct + ? new Vector(m_a->getNumber(), + m_b->getNumber(), + m_c->getNumber()) + : m_a->getVector(); } + protected: + refptr m_a, m_b, m_c; + bool m_direct; }; class AmbientNode : public VectorNode @@ -199,6 +188,7 @@ class JitterNode : public NumberNode { public: JitterNode(refptr e) : NumberNode(e) {} + int getInteger() { return getNumber(); } }; class LightNode : public Node From f54446bd6af40b0050321ebb165e758242322e42 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 29 Sep 2010 20:16:33 +0000 Subject: [PATCH 07/27] fixed Ngon using an expression for n_sides and implementing getInteger() git-svn-id: svn://anubis/fart/branches/scene-file-scripting@322 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.h | 1 + parser/parser.yy | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/parser/nodes.h b/parser/nodes.h index fe3b634..cae46da 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -236,6 +236,7 @@ class NGonNode : public NumberNode { public: NGonNode(refptr e) : NumberNode(e) {} + int getInteger() { return getNumber(); } }; class OffsetNode : public NumberNode diff --git a/parser/parser.yy b/parser/parser.yy index 657ff98..f029932 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -314,7 +314,7 @@ number: DEC_NUMBER { $$ = $1; } | REAL_NUMBER { $$ = $1; } ; -ngon: NGON DEC_NUMBER COMMA expression { +ngon: NGON expression COMMA expression { $$ = new NGonNode($2); $$->addChild(new RadiusNode($4)); } From 26d8d1a081cd08a73335abf9779a27efaeae8b03 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 29 Sep 2010 20:33:11 +0000 Subject: [PATCH 08/27] fixed NumberNode storing the expression as a child node git-svn-id: svn://anubis/fart/branches/scene-file-scripting@323 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/parser/nodes.h b/parser/nodes.h index cae46da..978bfd0 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -67,16 +67,17 @@ class NumberNode : public Node } NumberNode(refptr expr) { - addChild(expr); + m_expr = expr; m_direct = false; } virtual double getNumber() { - return m_direct ? m_number : m_children[0]->getNumber(); + return m_direct ? m_number : m_expr->getNumber(); } protected: double m_number; + refptr m_expr; bool m_direct; }; From 35d6e536aee56f4bd8ed9256d4996f0118905882 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 29 Sep 2010 20:55:02 +0000 Subject: [PATCH 09/27] removed optional negative sign preceding number literals in lexer since it was interfering with minus operator with no whitespace git-svn-id: svn://anubis/fart/branches/scene-file-scripting@324 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.h | 1 + parser/parser.lex | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/parser/nodes.h b/parser/nodes.h index 978bfd0..6b55bf2 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -105,6 +105,7 @@ class VectorNode : public Node bool m_direct; }; + class AmbientNode : public VectorNode { public: diff --git a/parser/parser.lex b/parser/parser.lex index 79cc0c7..d1a3707 100644 --- a/parser/parser.lex +++ b/parser/parser.lex @@ -36,8 +36,8 @@ \< return LESS; \> return GREATER; --?[0-9]+ *yylval = new IntegerNode(atoi(yytext)); return DEC_NUMBER; --?[0-9]*\.[0-9]+ *yylval = new NumberNode(atof(yytext)); return REAL_NUMBER; +[0-9]+ *yylval = new IntegerNode(atoi(yytext)); return DEC_NUMBER; +[0-9]*\.[0-9]+ *yylval = new NumberNode(atof(yytext)); return REAL_NUMBER; ambient return AMBIENT; ambient_occlusion return AMBIENT_OCCLUSION; From 442a7bdeda42a4f08bf313a4bddb092532b95232 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 29 Sep 2010 20:59:26 +0000 Subject: [PATCH 10/27] added VARREF in lexer matching $[a-zA-Z_][a-zA-Z_0-9]*, added VarRefNode class git-svn-id: svn://anubis/fart/branches/scene-file-scripting@325 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.h | 14 ++++++++++---- parser/parser.lex | 4 ++++ parser/parser.yy | 2 ++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/parser/nodes.h b/parser/nodes.h index 6b55bf2..5d63aa2 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -168,10 +168,7 @@ class IdentifierNode : public Node { public: IdentifierNode(const std::string & str) { m_string = str; } - std::string getString() - { - return m_string; - } + std::string getString() { return m_string; } protected: std::string m_string; }; @@ -442,5 +439,14 @@ class BinOpNode : public ExpressionNode refptr two; }; +class VarRefNode : public Node +{ + public: + VarRefNode(const std::string & str) { m_string = str; } + std::string getString() { return m_string; } + protected: + std::string m_string; +}; + #endif diff --git a/parser/parser.lex b/parser/parser.lex index d1a3707..ba08110 100644 --- a/parser/parser.lex +++ b/parser/parser.lex @@ -85,6 +85,10 @@ width return WIDTH; *yylval = new IdentifierNode(yytext); 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++; diff --git a/parser/parser.yy b/parser/parser.yy index f029932..64a38ef 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -101,6 +101,7 @@ static refptr parsed_scene_node; %token WIDTH; %token IDENTIFIER; +%token VARREF; %left PLUS MINUS %left TIMES DIVIDE @@ -583,6 +584,7 @@ term: factor { $$ = $1; } ; factor: number { $$ = $1; } + | VARREF { $$ = $1; } | LPAREN expression RPAREN { $$ = $2; } ; From 741ca57e11357ad664f2fd5d1cada05c6535a3f2 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 29 Sep 2010 21:33:22 +0000 Subject: [PATCH 11/27] added assignment expressions, for loop nodes, boolean expressions, ForNode class, BoolExpressionNode class, AssignmentNode class git-svn-id: svn://anubis/fart/branches/scene-file-scripting@326 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.cc | 26 +++++++++++++++ parser/nodes.h | 39 ++++++++++++++++++++++ parser/parser.lex | 10 ++++++ parser/parser.yy | 83 ++++++++++++++++++++++++++++++++++------------- 4 files changed, 136 insertions(+), 22 deletions(-) diff --git a/parser/nodes.cc b/parser/nodes.cc index 7af3eca..e073c05 100644 --- a/parser/nodes.cc +++ b/parser/nodes.cc @@ -44,3 +44,29 @@ double BinOpNode::getNumber() exit(-3); } } + +int BoolExpressionNode::getInteger() +{ + double o, t; + if (m_op != '!') + { + o = one->getNumber(); + t = two->getNumber(); + } + switch (m_op) + { + case '<': + return o < t; + case '>': + return o > t; + case '=': + return o == t; + case 'n': + return o != t; + case '!': + return ! one->getInteger(); + case 'T': + return 1; + } + return 0; +} diff --git a/parser/nodes.h b/parser/nodes.h index 5d63aa2..7e76233 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -425,6 +425,20 @@ class ExpressionNode : public Node virtual int getInteger() { return getNumber(); } }; +class AssignmentNode : public ExpressionNode +{ + public: + AssignmentNode(refptr varref, refptr expr) + : m_varref(varref), m_expr(expr) + { + } + std::string getString() { return m_varref->getString(); } + double getNumber() { return m_expr->getNumber(); } + protected: + refptr m_varref; + refptr m_expr; +}; + class BinOpNode : public ExpressionNode { public: @@ -439,6 +453,20 @@ class BinOpNode : public ExpressionNode refptr two; }; +class BoolExpressionNode : public Node +{ + public: + BoolExpressionNode(char op, refptr one, refptr two) + : m_op(op), one(one), two(two) + { + } + int getInteger(); + protected: + char m_op; + refptr one; + refptr two; +}; + class VarRefNode : public Node { public: @@ -448,5 +476,16 @@ class VarRefNode : public Node std::string m_string; }; +class ForNode : public Node +{ + public: + ForNode(refptr e1, refptr e2, refptr e3) + : m_e1(e1), m_e2(e2), m_e3(e3) + { + } + protected: + refptr m_e1, m_e2, m_e3; +}; + #endif diff --git a/parser/parser.lex b/parser/parser.lex index ba08110..a52d888 100644 --- a/parser/parser.lex +++ b/parser/parser.lex @@ -17,6 +17,10 @@ \* return TIMES; \/ return DIVIDE; % return MOD; +:= return ASSIGN; += return EQUALS; +!= return NOTEQUALS; +! return NOT; ; return SEMICOLON; : return COLON; @@ -81,6 +85,12 @@ up return UP; vfov return VFOV; width return WIDTH; +else return ELSE; +elsif return ELSIF; +for return FOR; +if return IF; +while return WHILE; + [a-zA-Z_][a-zA-Z_0-9]* { *yylval = new IdentifierNode(yytext); return IDENTIFIER; diff --git a/parser/parser.yy b/parser/parser.yy index 64a38ef..2372e9a 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -36,6 +36,10 @@ static refptr parsed_scene_node; %token TIMES; %token DIVIDE; %token MOD; +%token ASSIGN; +%token EQUALS; +%token NOTEQUALS; +%token NOT; %token SEMICOLON; %token COLON; @@ -103,6 +107,13 @@ static refptr parsed_scene_node; %token IDENTIFIER; %token VARREF; +%token ELSE; +%token ELSIF; +%token FOR; +%token IF; +%token WHILE; + +%right ASSIGN %left PLUS MINUS %left TIMES DIVIDE %left UMINUS @@ -218,6 +229,21 @@ extrude_item: polygon { $$ = $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; } + ; + intersect: INTERSECT LCURLY bool_items RCURLY { $$ = new IntersectNode(); $$->addChildren($3); @@ -437,12 +463,9 @@ scene_items: /* empty */ ; scene_item: camera { $$ = $1; } - | shape { $$ = $1; } - | options { $$ = $1; } | light { $$ = $1; } - | transform_block { $$ = $1; } - | material_definition { $$ = $1; } - | shape_definition { $$ = $1; } + | options { $$ = $1; } + | general_item { $$ = $1; } ; shape: plane { $$ = $1; } @@ -523,37 +546,24 @@ transform: TRANSLATE vector3 { } ; -transform_block: TRANSLATE vector3 LCURLY transform_block_items RCURLY { +transform_block: TRANSLATE vector3 LCURLY general_items RCURLY { $$ = new TranslateBlockNode($2); $$->addChildren($4); } - | ROTATE expression COMMA vector3 LCURLY transform_block_items RCURLY { + | ROTATE expression COMMA vector3 LCURLY general_items RCURLY { $$ = new RotateBlockNode($2, $4); $$->addChildren($6); } - | SCALE vector3 LCURLY transform_block_items RCURLY { + | SCALE vector3 LCURLY general_items RCURLY { $$ = new ScaleBlockNode($2); $$->addChildren($4); } - | SCALE expression LCURLY transform_block_items RCURLY { + | SCALE expression LCURLY general_items RCURLY { $$ = new ScaleBlockNode(new VectorNode($2, $2, $2)); $$->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 { $$ = new UnionNode(); $$->addChildren($3); @@ -576,8 +586,26 @@ expression: term { $$ = $1; } | MINUS expression %prec UMINUS { $$ = new BinOpNode('-', new NumberNode(0.0), $2); } + | assignment { $$ = $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); } @@ -588,6 +616,17 @@ factor: number { $$ = $1; } | LPAREN expression RPAREN { $$ = $2; } ; +assignment: VARREF ASSIGN expression { + $$ = new AssignmentNode($1, $3); + } + ; + +for: FOR LPAREN expression SEMICOLON bool_expression SEMICOLON expression RPAREN LCURLY general_items RCURLY { + $$ = new ForNode($3, $5, $7); + $$->addChildren($10); + } + ; + %% refptr parse(const char * fileName) From cd2f565df30a06a9f40a5095e581c2680d6c5012 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Fri, 1 Oct 2010 15:01:51 +0000 Subject: [PATCH 12/27] introduced ScaleScalarNode() node type to avoid evaluating expression multiple times git-svn-id: svn://anubis/fart/branches/scene-file-scripting@327 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.h | 16 ++++++++++++++++ parser/parser.yy | 6 +++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/parser/nodes.h b/parser/nodes.h index 7e76233..e8ebe75 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -325,6 +325,22 @@ class ScaleBlockNode : public ScaleNode bool isTransformBlock() { return true; } }; +class ScaleScalarNode : public Node +{ + public: + ScaleScalarNode(refptr expr) + : m_expr(expr) + { + } + refptr getVector() + { + double x = m_expr->getNumber(); + return new Vector(x, x, x); + } + protected: + refptr m_expr; +}; + class SceneNode : public Node { }; diff --git a/parser/parser.yy b/parser/parser.yy index 2372e9a..0ab8b37 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -365,7 +365,7 @@ offset_items: /* empty */ ; offset_item: SCALE expression { - $$ = new ScaleNode(new VectorNode($2, $2, $2)); + $$ = new ScaleNode(new ScaleScalarNode($2)); } | SCALE vector2 { $$ = new ScaleNode($2); @@ -542,7 +542,7 @@ transform: TRANSLATE vector3 { $$ = new ScaleNode($2); } | SCALE expression { - $$ = new ScaleNode(new VectorNode($2, $2, $2)); + $$ = new ScaleNode(new ScaleScalarNode($2)); } ; @@ -559,7 +559,7 @@ transform_block: TRANSLATE vector3 LCURLY general_items RCURLY { $$->addChildren($4); } | SCALE expression LCURLY general_items RCURLY { - $$ = new ScaleBlockNode(new VectorNode($2, $2, $2)); + $$ = new ScaleBlockNode(new ScaleScalarNode($2)); $$->addChildren($4); } ; From e2569c0a5450f9c2a9a39e61e3f30ca335e76204 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Fri, 1 Oct 2010 15:49:40 +0000 Subject: [PATCH 13/27] added util/Scope.h git-svn-id: svn://anubis/fart/branches/scene-file-scripting@328 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- main/Scene-load.cc | 1 + util/Scope.h | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 util/Scope.h diff --git a/main/Scene-load.cc b/main/Scene-load.cc index 9a4c75a..e4b982c 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -9,6 +9,7 @@ #include "parser/parser.h" #include "parser/nodes.h" #include "util/Polygon.h" +#include "util/Scope.h" using namespace std; diff --git a/util/Scope.h b/util/Scope.h new file mode 100644 index 0000000..9089053 --- /dev/null +++ b/util/Scope.h @@ -0,0 +1,55 @@ + +#ifndef SCOPE_H +#define SCOPE_H + +#include +#include +#include + +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 & operator[](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 (*m_list.rbegin())[key]; + } + 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 From 7014605fe321af0de5acca1db1f793bf2ddf54c8 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 4 Oct 2010 19:54:43 +0000 Subject: [PATCH 14/27] added parser_scope global, added local assignments and local declarations to parser, reworked Scope class to use get(), putLocal(), and putGlobal() methods git-svn-id: svn://anubis/fart/branches/scene-file-scripting@329 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- main/Scene-load.cc | 3 ++- parser/nodes.h | 60 +++++++++++++++++++++++++++++++++++++++++++--- parser/parser.h | 3 ++- parser/parser.lex | 1 + parser/parser.yy | 19 ++++++++++++++- util/Scope.h | 22 +++++++++++++++-- 6 files changed, 100 insertions(+), 8 deletions(-) diff --git a/main/Scene-load.cc b/main/Scene-load.cc index e4b982c..1130928 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -17,7 +17,8 @@ typedef vector< refptr >::const_iterator Node_Iterator; void Scene::load(const char * filename) { - refptr node = parse(filename); + refptr scope = new Scope(); + refptr node = parse(filename, scope); processNode(node); } diff --git a/parser/nodes.h b/parser/nodes.h index e8ebe75..87e072f 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -2,10 +2,17 @@ #ifndef NODES_H #define NODES_H NODES_H -#include "util/refptr.h" -#include "util/Vector.h" +#include /* exit() */ + #include #include +#include + +#include "util/refptr.h" +#include "util/Vector.h" +#include "util/Scope.h" + +extern refptr parser_scope; class Node { @@ -449,12 +456,49 @@ class AssignmentNode : public ExpressionNode { } std::string getString() { return m_varref->getString(); } - double getNumber() { return m_expr->getNumber(); } + double getNumber() + { + double n = m_expr->getNumber(); + parser_scope->putGlobal(getString(), n); + return n; + } protected: refptr m_varref; refptr m_expr; }; +class LocalAssignmentNode : public ExpressionNode +{ + public: + LocalAssignmentNode(refptr varref, refptr expr) + : m_varref(varref), m_expr(expr) + { + } + std::string getString() { return m_varref->getString(); } + double getNumber() + { + double n = m_expr->getNumber(); + parser_scope->putLocal(getString(), n); + return n; + } + protected: + refptr m_varref; + refptr m_expr; +}; + +class LocalDeclNode : public ExpressionNode +{ + public: + LocalDeclNode(refptr varref) : m_varref(varref) { } + double getNumber() + { + parser_scope->putLocal(m_varref->getString(), 0.0); + return 0.0; + } + protected: + refptr m_varref; +}; + class BinOpNode : public ExpressionNode { public: @@ -488,6 +532,16 @@ class VarRefNode : public Node public: VarRefNode(const std::string & str) { m_string = str; } std::string getString() { return m_string; } + double getNumber() + { + if (parser_scope->contains(m_string)) + { + return parser_scope->get(m_string); + } + std::cerr << "Error: No identifier '" << m_string << "' in scope" + << std::endl; + exit(4); + } protected: std::string m_string; }; diff --git a/parser/parser.h b/parser/parser.h index 158c90c..a231518 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -4,9 +4,10 @@ #include "nodes.h" #include "util/refptr.h" +#include "util/Scope.h" #define YYSTYPE refptr -refptr parse(const char * fileName); +refptr parse(const char * fileName, refptr scope); #endif diff --git a/parser/parser.lex b/parser/parser.lex index a52d888..97ce09a 100644 --- a/parser/parser.lex +++ b/parser/parser.lex @@ -90,6 +90,7 @@ elsif return ELSIF; for return FOR; if return IF; while return WHILE; +local return LOCAL; [a-zA-Z_][a-zA-Z_0-9]* { *yylval = new IdentifierNode(yytext); diff --git a/parser/parser.yy b/parser/parser.yy index 0ab8b37..3994319 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -5,6 +5,7 @@ #include #include "util/Vector.h" #include "util/refptr.h" +#include "util/Scope.h" #include "nodes.h" #include "parser.h" #include "parser.tab.hh" /* bison-generated header with YY[SL]TYPE */ @@ -24,6 +25,7 @@ int yywrap() } static refptr parsed_scene_node; +refptr parser_scope; %} @@ -112,6 +114,7 @@ static refptr parsed_scene_node; %token FOR; %token IF; %token WHILE; +%token LOCAL; %right ASSIGN %left PLUS MINUS @@ -587,6 +590,8 @@ expression: term { $$ = $1; } $$ = new BinOpNode('-', new NumberNode(0.0), $2); } | assignment { $$ = $1; } + | local_assignment { $$ = $1; } + | local_decl { $$ = $1; } ; bool_expression: expression LESS expression { @@ -621,6 +626,16 @@ assignment: VARREF ASSIGN expression { } ; +local_assignment: LOCAL VARREF ASSIGN expression { + $$ = new LocalAssignmentNode($2, $4); + } + ; + +local_decl: LOCAL VARREF { + $$ = new LocalDeclNode($2); + } + ; + for: FOR LPAREN expression SEMICOLON bool_expression SEMICOLON expression RPAREN LCURLY general_items RCURLY { $$ = new ForNode($3, $5, $7); $$->addChildren($10); @@ -629,8 +644,10 @@ for: FOR LPAREN expression SEMICOLON bool_expression SEMICOLON expression RPAREN %% -refptr parse(const char * fileName) +refptr parse(const char * fileName, refptr scope) { + parser_scope = scope; + yyin = fopen(fileName, "r"); if (yyin == NULL) { diff --git a/util/Scope.h b/util/Scope.h index 9089053..1c58051 100644 --- a/util/Scope.h +++ b/util/Scope.h @@ -23,7 +23,7 @@ class Scope } return false; } - double & operator[](const std::string & key) + double get(const std::string & key) { for (m_list_type::reverse_iterator it = m_list.rbegin(); it != m_list.rend(); @@ -34,7 +34,25 @@ class Scope return (*it)[key]; } } - return (*m_list.rbegin())[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() { From 91ea5a20e0441ff847286607a3d4067c85b6452a Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 4 Oct 2010 20:47:39 +0000 Subject: [PATCH 15/27] added ShapeRef typedef, added Scene::processGeneralItems() git-svn-id: svn://anubis/fart/branches/scene-file-scripting@330 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- main/Scene-load.cc | 72 ++++++++++++++++++++++++++-------------------- main/Scene.h | 23 ++++++++------- shapes/Shape.h | 1 + 3 files changed, 54 insertions(+), 42 deletions(-) diff --git a/main/Scene-load.cc b/main/Scene-load.cc index 1130928..1117884 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -33,7 +33,7 @@ void Scene::processNode(refptr node) } else if ( node->isShape() ) { - refptr shape = processShape(node); + ShapeRef shape = processShape(node); if ( ! shape.isNull() ) m_shapes.push_back(shape); } @@ -49,7 +49,7 @@ void Scene::processNode(refptr node) } else if (node->isTransformBlock()) { - vector< refptr > shapes = processTransformBlock(node); + vector shapes = processTransformBlock(node); for (int i = 0, sz = shapes.size(); i < sz; i++) { m_shapes.push_back(shapes[i]); @@ -111,7 +111,7 @@ void Scene::processScene(refptr node) } } -refptr Scene::processShape(refptr node) +ShapeRef Scene::processShape(refptr node) { if ( typeid(*node) == typeid(BoxNode) ) { @@ -149,7 +149,7 @@ refptr Scene::processShape(refptr node) exit(3); } - return refptr(NULL); + return ShapeRef(NULL); } void Scene::processCamera(refptr node) @@ -222,7 +222,7 @@ void Scene::processOptions(refptr node) } } -vector< refptr > Scene::processTransformBlock(refptr node) +vector Scene::processTransformBlock(refptr node) { if ( typeid(*node) == typeid(TranslateBlockNode) ) { @@ -240,8 +240,22 @@ vector< refptr > Scene::processTransformBlock(refptr node) m_transforms.push(m_transforms.top()); m_transforms.top().scale(node->getVector()); } + else + { + cerr << "Unknown transformation block node type!" << endl; + exit(4); + } - vector< refptr > shapes; + vector shapes = processGeneralItems(node); + + m_transforms.pop(); + + return shapes; +} + +vector Scene::processGeneralItems(refptr node) +{ + vector shapes; for (Node_Iterator it = node->getChildren().begin(); it != node->getChildren().end(); @@ -249,30 +263,26 @@ vector< refptr > Scene::processTransformBlock(refptr node) { if ((*it)->isTransformBlock()) { - vector< refptr > in = processTransformBlock(*it); + vector in = processTransformBlock(*it); for (int i = 0, sz = in.size(); i < sz; i++) { shapes.push_back(in[i]); } } - else if ( (*it)->isShape() ) + else if ( typeid(*node) == typeid(MaterialDefinitionNode) ) { - shapes.push_back(processShape(*it)); + processMaterialDefinition(node); } else if ( typeid(**it) == typeid(ShapeDefinitionNode) ) { processShapeDefinition(*it); } - else + else if ( (*it)->isShape() ) { - cerr << "Unknown transform block item: " << typeid(**it).name() - << endl; - exit(3); + shapes.push_back(processShape(*it)); } } - m_transforms.pop(); - return shapes; } @@ -348,7 +358,7 @@ refptr Scene::processMaterial(refptr node) return material; } -refptr Scene::processBox(refptr node) +ShapeRef Scene::processBox(refptr node) { refptr size = new Vector(1, 1, 1); refptr material; @@ -369,7 +379,7 @@ refptr Scene::processBox(refptr node) } } - refptr box = new Box(size); + ShapeRef box = new Box(size); if ( ! material.isNull() ) box->setMaterial(material); box->setTransform(m_transforms.top()); @@ -380,7 +390,7 @@ refptr Scene::processBox(refptr node) return box; } -refptr Scene::processCyl(refptr node) +ShapeRef Scene::processCyl(refptr node) { double radius1 = 1.0; double radius2 = 1.0; @@ -406,7 +416,7 @@ refptr Scene::processCyl(refptr node) } } - refptr cyl = new Cyl(radius1, radius2, height); + ShapeRef cyl = new Cyl(radius1, radius2, height); if ( ! material.isNull() ) cyl->setMaterial(material); cyl->setTransform(m_transforms.top()); @@ -459,7 +469,7 @@ refptr Scene::processLight(refptr node) return light; } -refptr Scene::processPlane(refptr node) +ShapeRef Scene::processPlane(refptr node) { Vector normal(0, 0, 1); double dist = 0; @@ -482,7 +492,7 @@ refptr Scene::processPlane(refptr node) } } - refptr plane = new Plane(normal[0], + ShapeRef plane = new Plane(normal[0], normal[1], normal[2], dist); @@ -496,7 +506,7 @@ refptr Scene::processPlane(refptr node) return plane; } -refptr Scene::processSphere(refptr node) +ShapeRef Scene::processSphere(refptr node) { double radius = 1.0; refptr material; @@ -517,7 +527,7 @@ refptr Scene::processSphere(refptr node) } } - refptr sphere = new Sphere(radius); + ShapeRef sphere = new Sphere(radius); if ( ! material.isNull() ) sphere->setMaterial(material); sphere->setTransform(m_transforms.top()); @@ -528,9 +538,9 @@ refptr Scene::processSphere(refptr node) return sphere; } -refptr Scene::processBool(refptr node) +ShapeRef Scene::processBool(refptr node) { - vector< refptr > shapes; + vector shapes; refptr material; bool restore_transform = processTransforms(node); @@ -542,7 +552,7 @@ refptr Scene::processBool(refptr node) { if ( (*it)->isShape() ) { - refptr shape = processShape(*it); + ShapeRef shape = processShape(*it); if ( ! shape.isNull() ) shapes.push_back(shape); } @@ -552,7 +562,7 @@ refptr Scene::processBool(refptr node) } else if ( (*it)->isTransformBlock() ) { - vector< refptr > in = processTransformBlock(*it); + vector in = processTransformBlock(*it); for (int i = 0, sz = in.size(); i < sz; i++) { shapes.push_back(in[i]); @@ -571,7 +581,7 @@ refptr Scene::processBool(refptr node) exit(3); } - refptr shape; + ShapeRef shape; if ( typeid(*node) == typeid(IntersectNode) ) shape = new Intersect(shapes); else if ( typeid(*node) == typeid(UnionNode) ) @@ -596,7 +606,7 @@ refptr Scene::processBool(refptr node) return shape; } -refptr Scene::processExtrude(refptr node) +ShapeRef Scene::processExtrude(refptr node) { refptr material; Extrude * extrude = new Extrude(); @@ -708,7 +718,7 @@ refptr Scene::processNGon(refptr node) return p; } -refptr Scene::processShapeRef(refptr node) +ShapeRef Scene::processShapeRef(refptr node) { if (m_shape_definitions.find(node->getString()) == m_shape_definitions.end()) @@ -719,7 +729,7 @@ refptr Scene::processShapeRef(refptr node) } refptr material; - refptr shape = m_shape_definitions[node->getString()]->clone(); + ShapeRef shape = m_shape_definitions[node->getString()]->clone(); bool restore_transform = processTransforms(node); diff --git a/main/Scene.h b/main/Scene.h index ed3ff37..d5214d5 100644 --- a/main/Scene.h +++ b/main/Scene.h @@ -62,21 +62,22 @@ class Scene void processChildren(refptr node); void processScene(refptr node); refptr processMaterial(refptr node); - refptr processBox(refptr node); - refptr processCyl(refptr node); + ShapeRef processBox(refptr node); + ShapeRef processCyl(refptr node); refptr processLight(refptr node); - refptr processPlane(refptr node); - refptr processSphere(refptr node); - refptr processShape(refptr node); - refptr processBool(refptr node); - refptr processExtrude(refptr node); - refptr processShapeRef(refptr node); + ShapeRef processPlane(refptr node); + ShapeRef processSphere(refptr node); + ShapeRef processShape(refptr node); + ShapeRef processBool(refptr node); + ShapeRef processExtrude(refptr node); + ShapeRef processShapeRef(refptr node); refptr processPolygon(refptr node); refptr processNGon(refptr node); bool processTransforms(refptr node); void processCamera(refptr node); void processOptions(refptr node); - std::vector< refptr > processTransformBlock(refptr node); + std::vector processTransformBlock(refptr node); + std::vector processGeneralItems(refptr node); void processMaterialDefinition(refptr node); void processShapeDefinition(refptr node); @@ -91,8 +92,8 @@ class Scene int m_ambient_occlusion_level; /* private data */ - std::vector< refptr > m_shapes; - std::map< std::string, refptr > m_shape_definitions; + std::vector m_shapes; + std::map m_shape_definitions; std::vector< refptr > m_lights; std::stack m_transforms; double m_view_plane_dist; diff --git a/shapes/Shape.h b/shapes/Shape.h index 5e78d41..df6d083 100644 --- a/shapes/Shape.h +++ b/shapes/Shape.h @@ -125,6 +125,7 @@ class Shape refptr m_material; }; +typedef refptr ShapeRef; #endif From 71e40b0277444864997e5f076483f9292ee04c98 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 4 Oct 2010 20:54:47 +0000 Subject: [PATCH 16/27] added stmt_expression rule to parser, added to general_items git-svn-id: svn://anubis/fart/branches/scene-file-scripting@331 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/parser.yy | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/parser/parser.yy b/parser/parser.yy index 3994319..0f3a794 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -245,6 +245,7 @@ general_item: transform_block { $$ = $1; } | shape_definition { $$ = $1; } | shape { $$ = $1; } | for { $$ = $1; } + | stmt_expression { $$ = $1; } ; intersect: INTERSECT LCURLY bool_items RCURLY { @@ -589,11 +590,14 @@ expression: term { $$ = $1; } | MINUS expression %prec UMINUS { $$ = new BinOpNode('-', new NumberNode(0.0), $2); } - | assignment { $$ = $1; } - | local_assignment { $$ = $1; } - | local_decl { $$ = $1; } + | stmt_expression { $$ = $1; } ; +stmt_expression: assignment { $$ = $1; } + | local_assignment { $$ = $1; } + | local_decl { $$ = $1; } + ; + bool_expression: expression LESS expression { $$ = new BoolExpressionNode('<', $1, $3); } From 01a713af98dfef59ad87f6f988333e2d7257a89c Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 4 Oct 2010 21:26:12 +0000 Subject: [PATCH 17/27] added Scene::processForNode() to process for nodes git-svn-id: svn://anubis/fart/branches/scene-file-scripting@332 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- main/Scene-load.cc | 47 ++++++++++++++++++++++++++++++++++++++-------- main/Scene.h | 1 + parser/nodes.h | 19 +++++++++++++++++-- parser/parser.yy | 6 +++++- 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/main/Scene-load.cc b/main/Scene-load.cc index 1117884..b712e1b 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -255,7 +255,7 @@ vector Scene::processTransformBlock(refptr node) vector Scene::processGeneralItems(refptr node) { - vector shapes; + vector shapes, incoming; for (Node_Iterator it = node->getChildren().begin(); it != node->getChildren().end(); @@ -263,15 +263,11 @@ vector Scene::processGeneralItems(refptr node) { if ((*it)->isTransformBlock()) { - vector in = processTransformBlock(*it); - for (int i = 0, sz = in.size(); i < sz; i++) - { - shapes.push_back(in[i]); - } + incoming = processTransformBlock(*it); } - else if ( typeid(*node) == typeid(MaterialDefinitionNode) ) + else if ( typeid(**it) == typeid(MaterialDefinitionNode) ) { - processMaterialDefinition(node); + processMaterialDefinition(*it); } else if ( typeid(**it) == typeid(ShapeDefinitionNode) ) { @@ -281,6 +277,41 @@ vector Scene::processGeneralItems(refptr node) { shapes.push_back(processShape(*it)); } + else if ( typeid(**it) == typeid(ForNode) ) + { + incoming = processForNode(*it); + } + while (incoming.size() > 0) + { + shapes.push_back(incoming[0]); + incoming.erase(incoming.begin()); + } + } + + return shapes; +} + +vector Scene::processForNode(refptr node) +{ + if (!node->getNode(0).isNull()) + { + node->getNode(0)->getNumber(); + } + + vector shapes, incoming; + + while (node->getNode(1)->getInteger() != 0) + { + incoming = processGeneralItems(node); + while (incoming.size() > 0) + { + shapes.push_back(incoming[0]); + incoming.erase(incoming.begin()); + } + if (!node->getNode(2).isNull()) + { + node->getNode(2)->getNumber(); + } } return shapes; diff --git a/main/Scene.h b/main/Scene.h index d5214d5..21be396 100644 --- a/main/Scene.h +++ b/main/Scene.h @@ -78,6 +78,7 @@ class Scene void processOptions(refptr node); std::vector processTransformBlock(refptr node); std::vector processGeneralItems(refptr node); + std::vector processForNode(refptr node); void processMaterialDefinition(refptr node); void processShapeDefinition(refptr node); diff --git a/parser/nodes.h b/parser/nodes.h index 87e072f..62fe405 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -42,6 +42,11 @@ class Node std::cerr << "Warning: Node::getString() called!" << std::endl; return ""; } + virtual refptr getNode(int idx) + { + std::cerr << "Warning: Node::getNode() called!" << std::endl; + return NULL; + } virtual bool isShape() { return false; } virtual bool isMaterial() { return false; } @@ -550,11 +555,21 @@ class ForNode : public Node { public: ForNode(refptr e1, refptr e2, refptr e3) - : m_e1(e1), m_e2(e2), m_e3(e3) { + m_nodes[0] = e1; + m_nodes[1] = e2; + m_nodes[2] = e3; + } + refptr getNode(int idx) + { + if (0 <= idx && idx <= 2) + { + return m_nodes[idx]; + } + return NULL; } protected: - refptr m_e1, m_e2, m_e3; + refptr m_nodes[3]; }; #endif diff --git a/parser/parser.yy b/parser/parser.yy index 0f3a794..c8ccf46 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -593,6 +593,10 @@ expression: term { $$ = $1; } | stmt_expression { $$ = $1; } ; +maybe_expression: /* empty */ + | expression { $$ = $1; } + ; + stmt_expression: assignment { $$ = $1; } | local_assignment { $$ = $1; } | local_decl { $$ = $1; } @@ -640,7 +644,7 @@ local_decl: LOCAL VARREF { } ; -for: FOR LPAREN expression SEMICOLON bool_expression SEMICOLON expression RPAREN LCURLY general_items RCURLY { +for: FOR LPAREN maybe_expression SEMICOLON bool_expression SEMICOLON maybe_expression RPAREN LCURLY general_items RCURLY { $$ = new ForNode($3, $5, $7); $$->addChildren($10); } From e23b762a014d15e819bd497e0d15bbf1e8602fef Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 4 Oct 2010 21:27:47 +0000 Subject: [PATCH 18/27] evaluating stmt_expression's in processGeneralItems() git-svn-id: svn://anubis/fart/branches/scene-file-scripting@333 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- main/Scene-load.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main/Scene-load.cc b/main/Scene-load.cc index b712e1b..dd5228b 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -281,6 +281,10 @@ vector Scene::processGeneralItems(refptr node) { incoming = processForNode(*it); } + else if ( (*it)->isExpression() ) + { + (*it)->getNumber(); /* evaluate the expression */ + } while (incoming.size() > 0) { shapes.push_back(incoming[0]); From 74f27c20769edcc4c6adb9f0ede9511322c2b36f Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 4 Oct 2010 21:47:07 +0000 Subject: [PATCH 19/27] removed processNode() and processChildren() git-svn-id: svn://anubis/fart/branches/scene-file-scripting@334 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- main/Scene-load.cc | 70 +++++++++------------------------------------- main/Scene.h | 2 -- 2 files changed, 13 insertions(+), 59 deletions(-) diff --git a/main/Scene-load.cc b/main/Scene-load.cc index dd5228b..b85dd12 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -19,64 +19,10 @@ void Scene::load(const char * filename) { refptr scope = new Scope(); refptr node = parse(filename, scope); - processNode(node); -} - -void Scene::processNode(refptr node) -{ - if (node.isNull()) - return; - - if ( typeid(*node) == typeid(SceneNode) ) + if ( ! node.isNull() ) { processScene(node); } - else if ( node->isShape() ) - { - ShapeRef shape = processShape(node); - if ( ! shape.isNull() ) - m_shapes.push_back(shape); - } - else if ( typeid(*node) == typeid(LightNode) ) - { - refptr light = processLight(node); - if ( ! light.isNull() ) - m_lights.push_back(light); - } - else if ( typeid(*node) == typeid(OptionsNode) ) - { - processOptions(node); - } - else if (node->isTransformBlock()) - { - vector 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) -{ - std::vector< refptr > & children = node->getChildren(); - for (int i = 0, sz = children.size(); i < sz; i++) - { - processNode(children[i]); - } } void Scene::processScene(refptr node) @@ -100,15 +46,25 @@ void Scene::processScene(refptr node) } } + /* then any other scene-specific items */ for (Node_Iterator it = node->getChildren().begin(); it != node->getChildren().end(); it++) { - if ( typeid(**it) != typeid(CameraNode) ) + if ( typeid(**it) == typeid(LightNode) ) { - processNode(*it); + refptr light = processLight(*it); + if ( ! light.isNull() ) + m_lights.push_back(light); + } + else if ( typeid(**it) == typeid(OptionsNode) ) + { + processOptions(*it); } } + + /* then any general items */ + processGeneralItems(node); } ShapeRef Scene::processShape(refptr node) diff --git a/main/Scene.h b/main/Scene.h index 21be396..eb789d2 100644 --- a/main/Scene.h +++ b/main/Scene.h @@ -58,8 +58,6 @@ class Scene /* In Scene-load.cc */ void load(const char * filename); - void processNode(refptr node); - void processChildren(refptr node); void processScene(refptr node); refptr processMaterial(refptr node); ShapeRef processBox(refptr node); From b851c3be98d88f8d8a1526c40add2182be120a64 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 6 Oct 2010 15:38:25 +0000 Subject: [PATCH 20/27] added Node::evaluate(parent) git-svn-id: svn://anubis/fart/branches/scene-file-scripting@335 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- main/Scene-load.cc | 15 ++++++--------- parser/nodes.h | 13 +++++++++++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/main/Scene-load.cc b/main/Scene-load.cc index b85dd12..53e2584 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -21,7 +21,12 @@ void Scene::load(const char * filename) refptr node = parse(filename, scope); if ( ! node.isNull() ) { - processScene(node); + refptr dummy = new Node(); + /* evaluate any scripting nodes in the node tree */ + node->evaluate(dummy); + + /* now we have a new node tree under 'dummy' with no scripting nodes */ + processScene(dummy->getChildren()[0]); } } @@ -233,14 +238,6 @@ vector Scene::processGeneralItems(refptr node) { shapes.push_back(processShape(*it)); } - else if ( typeid(**it) == typeid(ForNode) ) - { - incoming = processForNode(*it); - } - else if ( (*it)->isExpression() ) - { - (*it)->getNumber(); /* evaluate the expression */ - } while (incoming.size() > 0) { shapes.push_back(incoming[0]); diff --git a/parser/nodes.h b/parser/nodes.h index 62fe405..4dffee1 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -47,6 +47,19 @@ class Node std::cerr << "Warning: Node::getNode() called!" << std::endl; return NULL; } + virtual void evaluate(refptr parent) + { + std::cerr << "Warning: Node::evaluate() called!" << std::endl; + } + virtual void evaluateChildren(refptr parent) + { + for (std::vector< refptr >::iterator it = m_children.begin(); + it != m_children.end(); + it++) + { + (*it)->evaluate(parent); + } + } virtual bool isShape() { return false; } virtual bool isMaterial() { return false; } From 04022756e5c4e883035606feafe822951f7e5127 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 6 Oct 2010 15:41:47 +0000 Subject: [PATCH 21/27] added NodeRef typedef git-svn-id: svn://anubis/fart/branches/scene-file-scripting@336 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.cc | 4 +- parser/nodes.h | 102 ++++++++++++++++++++++++------------------------ 2 files changed, 54 insertions(+), 52 deletions(-) diff --git a/parser/nodes.cc b/parser/nodes.cc index e073c05..f7c55de 100644 --- a/parser/nodes.cc +++ b/parser/nodes.cc @@ -8,12 +8,12 @@ using namespace std; -void Node::addChildren(refptr other) +void Node::addChildren(NodeRef other) { if (other.isNull()) return; - for (vector< refptr >::const_iterator it = other->m_children.begin(); + for (vector::const_iterator it = other->m_children.begin(); it != other->m_children.end(); it++) { diff --git a/parser/nodes.h b/parser/nodes.h index 4dffee1..b6ee582 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -70,6 +70,8 @@ class Node std::vector< refptr > m_children; }; +typedef refptr NodeRef; + class IntegerNode : public Node { @@ -90,7 +92,7 @@ class NumberNode : public Node m_number = number; m_direct = true; } - NumberNode(refptr expr) + NumberNode(NodeRef expr) { m_expr = expr; m_direct = false; @@ -102,18 +104,18 @@ class NumberNode : public Node protected: double m_number; - refptr m_expr; + NodeRef m_expr; bool m_direct; }; class VectorNode : public Node { public: - VectorNode(refptr a, refptr b, refptr c) + VectorNode(NodeRef a, NodeRef b, NodeRef c) : m_a(a), m_b(b), m_c(c), m_direct(true) { } - VectorNode(refptr node) + VectorNode(NodeRef node) : m_a(node), m_direct(false) { } @@ -126,7 +128,7 @@ class VectorNode : public Node : m_a->getVector(); } protected: - refptr m_a, m_b, m_c; + NodeRef m_a, m_b, m_c; bool m_direct; }; @@ -134,7 +136,7 @@ class VectorNode : public Node class AmbientNode : public VectorNode { public: - AmbientNode(refptr vector) : VectorNode(vector) {} + AmbientNode(NodeRef vector) : VectorNode(vector) {} }; class AmbientOcclusionNode : public IntegerNode @@ -156,7 +158,7 @@ class CameraNode : public Node class ColorNode : public VectorNode { public: - ColorNode(refptr vector) : VectorNode(vector) {} + ColorNode(NodeRef vector) : VectorNode(vector) {} }; class CylNode : public Node @@ -168,13 +170,13 @@ class CylNode : public Node class DiffuseNode : public VectorNode { public: - DiffuseNode(refptr vector) : VectorNode(vector) {} + DiffuseNode(NodeRef vector) : VectorNode(vector) {} }; class ExposureNode : public NumberNode { public: - ExposureNode(refptr e) : NumberNode(e) {} + ExposureNode(NodeRef e) : NumberNode(e) {} }; class ExtrudeNode : public Node @@ -211,7 +213,7 @@ class ItemsNode : public Node class JitterNode : public NumberNode { public: - JitterNode(refptr e) : NumberNode(e) {} + JitterNode(NodeRef e) : NumberNode(e) {} int getInteger() { return getNumber(); } }; @@ -222,7 +224,7 @@ class LightNode : public Node class LookAtNode : public VectorNode { public: - LookAtNode(refptr vector) : VectorNode(vector) {} + LookAtNode(NodeRef vector) : VectorNode(vector) {} }; class MaterialNode : public Node @@ -259,14 +261,14 @@ class MultisampleNode : public IntegerNode class NGonNode : public NumberNode { public: - NGonNode(refptr e) : NumberNode(e) {} + NGonNode(NodeRef e) : NumberNode(e) {} int getInteger() { return getNumber(); } }; class OffsetNode : public NumberNode { public: - OffsetNode(refptr e) : NumberNode(e) {} + OffsetNode(NodeRef e) : NumberNode(e) {} }; class OptionsNode : public Node @@ -282,7 +284,7 @@ class PlaneNode : public Node class PlanePositionNode : public VectorNode { public: - PlanePositionNode(refptr vec_node, refptr dist) + PlanePositionNode(NodeRef vec_node, NodeRef dist) : VectorNode(vec_node) { m_dist = dist; @@ -290,7 +292,7 @@ class PlanePositionNode : public VectorNode double getNumber() { return m_dist->getNumber(); } protected: - refptr m_dist; + NodeRef m_dist; }; class PolygonNode : public Node @@ -300,25 +302,25 @@ class PolygonNode : public Node class PositionNode : public VectorNode { public: - PositionNode(refptr vector) : VectorNode(vector) {} + PositionNode(NodeRef vector) : VectorNode(vector) {} }; class RadiusNode : public NumberNode { public: - RadiusNode(refptr e) : NumberNode(e) {} + RadiusNode(NodeRef e) : NumberNode(e) {} }; class ReflectanceNode : public NumberNode { public: - ReflectanceNode(refptr e) : NumberNode(e) {} + ReflectanceNode(NodeRef e) : NumberNode(e) {} }; class RotateNode : public VectorNode { public: - RotateNode(refptr angle, refptr vec_node) + RotateNode(NodeRef angle, NodeRef vec_node) : VectorNode(vec_node) { m_angle = angle; @@ -326,13 +328,13 @@ class RotateNode : public VectorNode double getNumber() { return m_angle->getNumber(); } protected: - refptr m_angle; + NodeRef m_angle; }; class RotateBlockNode : public RotateNode { public: - RotateBlockNode(refptr angle, refptr vec_node) + RotateBlockNode(NodeRef angle, NodeRef vec_node) : RotateNode(angle, vec_node) {} bool isTransformBlock() { return true; } }; @@ -340,20 +342,20 @@ class RotateBlockNode : public RotateNode class ScaleNode : public VectorNode { public: - ScaleNode(refptr vector) : VectorNode(vector) {} + ScaleNode(NodeRef vector) : VectorNode(vector) {} }; class ScaleBlockNode : public ScaleNode { public: - ScaleBlockNode(refptr vector) : ScaleNode(vector) {} + ScaleBlockNode(NodeRef vector) : ScaleNode(vector) {} bool isTransformBlock() { return true; } }; class ScaleScalarNode : public Node { public: - ScaleScalarNode(refptr expr) + ScaleScalarNode(NodeRef expr) : m_expr(expr) { } @@ -363,7 +365,7 @@ class ScaleScalarNode : public Node return new Vector(x, x, x); } protected: - refptr m_expr; + NodeRef m_expr; }; class SceneNode : public Node @@ -386,19 +388,19 @@ class ShapeRefNode : public IdentifierNode class ShininessNode : public NumberNode { public: - ShininessNode(refptr e) : NumberNode(e) {} + ShininessNode(NodeRef e) : NumberNode(e) {} }; class SizeNode : public VectorNode { public: - SizeNode(refptr vector) : VectorNode(vector) {} + SizeNode(NodeRef vector) : VectorNode(vector) {} }; class SpecularNode : public VectorNode { public: - SpecularNode(refptr vector) : VectorNode(vector) {} + SpecularNode(NodeRef vector) : VectorNode(vector) {} }; class SphereNode : public Node @@ -416,20 +418,20 @@ class SubtractNode : public Node class TranslateNode : public VectorNode { public: - TranslateNode(refptr vector) : VectorNode(vector) {} + TranslateNode(NodeRef vector) : VectorNode(vector) {} }; class TranslateBlockNode : public TranslateNode { public: - TranslateBlockNode(refptr vector) : TranslateNode(vector) {} + TranslateBlockNode(NodeRef vector) : TranslateNode(vector) {} bool isTransformBlock() { return true; } }; class TransparencyNode : public NumberNode { public: - TransparencyNode(refptr e) : NumberNode(e) {} + TransparencyNode(NodeRef e) : NumberNode(e) {} }; class UnionNode : public Node @@ -441,13 +443,13 @@ class UnionNode : public Node class UpNode : public VectorNode { public: - UpNode(refptr vector) : VectorNode(vector) {} + UpNode(NodeRef vector) : VectorNode(vector) {} }; class VFOVNode : public NumberNode { public: - VFOVNode(refptr e) : NumberNode(e) {} + VFOVNode(NodeRef e) : NumberNode(e) {} }; class WidthNode : public IntegerNode @@ -469,7 +471,7 @@ class ExpressionNode : public Node class AssignmentNode : public ExpressionNode { public: - AssignmentNode(refptr varref, refptr expr) + AssignmentNode(NodeRef varref, NodeRef expr) : m_varref(varref), m_expr(expr) { } @@ -481,14 +483,14 @@ class AssignmentNode : public ExpressionNode return n; } protected: - refptr m_varref; - refptr m_expr; + NodeRef m_varref; + NodeRef m_expr; }; class LocalAssignmentNode : public ExpressionNode { public: - LocalAssignmentNode(refptr varref, refptr expr) + LocalAssignmentNode(NodeRef varref, NodeRef expr) : m_varref(varref), m_expr(expr) { } @@ -500,49 +502,49 @@ class LocalAssignmentNode : public ExpressionNode return n; } protected: - refptr m_varref; - refptr m_expr; + NodeRef m_varref; + NodeRef m_expr; }; class LocalDeclNode : public ExpressionNode { public: - LocalDeclNode(refptr varref) : m_varref(varref) { } + LocalDeclNode(NodeRef varref) : m_varref(varref) { } double getNumber() { parser_scope->putLocal(m_varref->getString(), 0.0); return 0.0; } protected: - refptr m_varref; + NodeRef m_varref; }; class BinOpNode : public ExpressionNode { public: - BinOpNode(char op, refptr one, refptr two) + BinOpNode(char op, NodeRef one, NodeRef two) : m_op(op), one(one), two(two) { } virtual double getNumber(); protected: char m_op; - refptr one; - refptr two; + NodeRef one; + NodeRef two; }; class BoolExpressionNode : public Node { public: - BoolExpressionNode(char op, refptr one, refptr two) + BoolExpressionNode(char op, NodeRef one, NodeRef two) : m_op(op), one(one), two(two) { } int getInteger(); protected: char m_op; - refptr one; - refptr two; + NodeRef one; + NodeRef two; }; class VarRefNode : public Node @@ -567,13 +569,13 @@ class VarRefNode : public Node class ForNode : public Node { public: - ForNode(refptr e1, refptr e2, refptr e3) + ForNode(NodeRef e1, NodeRef e2, NodeRef e3) { m_nodes[0] = e1; m_nodes[1] = e2; m_nodes[2] = e3; } - refptr getNode(int idx) + NodeRef getNode(int idx) { if (0 <= idx && idx <= 2) { @@ -582,7 +584,7 @@ class ForNode : public Node return NULL; } protected: - refptr m_nodes[3]; + NodeRef m_nodes[3]; }; #endif From 793c7afb2d2b74e20db141fdd09dacf602d28d35 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 6 Oct 2010 15:48:33 +0000 Subject: [PATCH 22/27] removed DEC_NUMBER parsing token and IntegerNode node, replaced with NumberNode git-svn-id: svn://anubis/fart/branches/scene-file-scripting@337 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.h | 38 ++++++++++++-------------------------- parser/parser.lex | 2 +- parser/parser.yy | 24 +++++++++++------------- 3 files changed, 24 insertions(+), 40 deletions(-) diff --git a/parser/nodes.h b/parser/nodes.h index b6ee582..68254e1 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -22,11 +22,8 @@ class Node void addChildren(refptr other); std::vector< refptr > & getChildren() { return m_children; } - virtual int getInteger() - { - std::cerr << "Warning: Node::getInteger() called!" << std::endl; - return 0; - } + virtual int getInteger() { return getNumber(); } + virtual double getNumber() { std::cerr << "Warning: Node::getNumber() called!" << std::endl; @@ -73,17 +70,6 @@ class Node typedef refptr NodeRef; -class IntegerNode : public Node -{ - public: - IntegerNode(int number) { m_number = number; } - virtual int getInteger() { return m_number; } - virtual double getNumber() { return m_number; } - - protected: - int m_number; -}; - class NumberNode : public Node { public: @@ -139,10 +125,10 @@ class AmbientNode : public VectorNode AmbientNode(NodeRef vector) : VectorNode(vector) {} }; -class AmbientOcclusionNode : public IntegerNode +class AmbientOcclusionNode : public NumberNode { public: - AmbientOcclusionNode(int i) : IntegerNode(i) {} + AmbientOcclusionNode(NodeRef e) : NumberNode(e) {} }; class BoxNode : public Node @@ -185,10 +171,10 @@ class ExtrudeNode : public Node bool isShape() { return true; } }; -class HeightNode : public IntegerNode +class HeightNode : public NumberNode { public: - HeightNode(int i) : IntegerNode(i) {} + HeightNode(NodeRef e) : NumberNode(e) {} }; class IdentifierNode : public Node @@ -246,16 +232,16 @@ class MaterialRefNode : public IdentifierNode bool isMaterial() { return true; } }; -class MaxDepthNode : public IntegerNode +class MaxDepthNode : public NumberNode { public: - MaxDepthNode(int i) : IntegerNode(i) {} + MaxDepthNode(NodeRef e) : NumberNode(e) {} }; -class MultisampleNode : public IntegerNode +class MultisampleNode : public NumberNode { public: - MultisampleNode(int i) : IntegerNode(i) {} + MultisampleNode(NodeRef e) : NumberNode(e) {} }; class NGonNode : public NumberNode @@ -452,10 +438,10 @@ class VFOVNode : public NumberNode VFOVNode(NodeRef e) : NumberNode(e) {} }; -class WidthNode : public IntegerNode +class WidthNode : public NumberNode { public: - WidthNode(int i) : IntegerNode(i) {} + WidthNode(NodeRef e) : NumberNode(e) {} }; /******** scripting nodes ********/ diff --git a/parser/parser.lex b/parser/parser.lex index 97ce09a..112fd89 100644 --- a/parser/parser.lex +++ b/parser/parser.lex @@ -40,7 +40,7 @@ \< return LESS; \> 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; ambient return AMBIENT; diff --git a/parser/parser.yy b/parser/parser.yy index c8ccf46..16f4cd6 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -61,7 +61,6 @@ refptr parser_scope; %token LESS; %token GREATER; -%token DEC_NUMBER; %token REAL_NUMBER; %token AMBIENT; @@ -341,8 +340,7 @@ material_ref: MATERIAL IDENTIFIER { } ; -number: DEC_NUMBER { $$ = $1; } - | REAL_NUMBER { $$ = $1; } +number: REAL_NUMBER { $$ = $1; } ; ngon: NGON expression COMMA expression { @@ -393,17 +391,17 @@ options_items: /* empty */ } ; -options_item: WIDTH DEC_NUMBER { - $$ = new WidthNode($2->getInteger()); +options_item: WIDTH expression { + $$ = new WidthNode($2); } - | HEIGHT DEC_NUMBER { - $$ = new HeightNode($2->getInteger()); + | HEIGHT expression { + $$ = new HeightNode($2); } - | MULTISAMPLE DEC_NUMBER { - $$ = new MultisampleNode($2->getInteger()); + | MULTISAMPLE expression { + $$ = new MultisampleNode($2); } - | MAXDEPTH DEC_NUMBER { - $$ = new MaxDepthNode($2->getInteger()); + | MAXDEPTH expression { + $$ = new MaxDepthNode($2); } | EXPOSURE expression { $$ = new ExposureNode($2); @@ -411,8 +409,8 @@ options_item: WIDTH DEC_NUMBER { | AMBIENT vector3 { $$ = new AmbientNode($2); } - | AMBIENT_OCCLUSION DEC_NUMBER { - $$ = new AmbientOcclusionNode($2->getInteger()); + | AMBIENT_OCCLUSION expression { + $$ = new AmbientOcclusionNode($2); } ; From f36c1fa60f271d35666b99a60faf84195f2b380e Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 6 Oct 2010 16:32:27 +0000 Subject: [PATCH 23/27] added evaluate() method for all non-scripting nodes, made evaluateChildren() recursive git-svn-id: svn://anubis/fart/branches/scene-file-scripting@338 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- main/Scene-load.cc | 6 +- parser/nodes.h | 208 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 197 insertions(+), 17 deletions(-) diff --git a/main/Scene-load.cc b/main/Scene-load.cc index 53e2584..cbb8103 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -21,12 +21,12 @@ void Scene::load(const char * filename) refptr node = parse(filename, scope); if ( ! node.isNull() ) { - refptr dummy = new Node(); /* evaluate any scripting nodes in the node tree */ - node->evaluate(dummy); + refptr processed_scene = node->evaluate(); + node->evaluateChildren(processed_scene); /* now we have a new node tree under 'dummy' with no scripting nodes */ - processScene(dummy->getChildren()[0]); + processScene(processed_scene); } } diff --git a/parser/nodes.h b/parser/nodes.h index 68254e1..c417e0e 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -44,17 +44,24 @@ class Node std::cerr << "Warning: Node::getNode() called!" << std::endl; return NULL; } - virtual void evaluate(refptr parent) + virtual refptr evaluate() { std::cerr << "Warning: Node::evaluate() called!" << std::endl; + return NULL; } virtual void evaluateChildren(refptr parent) { + /* recursively evaluate all children nodes */ for (std::vector< refptr >::iterator it = m_children.begin(); it != m_children.end(); it++) { - (*it)->evaluate(parent); + refptr evaluated = (*it)->evaluate(); + if ( ! evaluated.isNull() ) + { + (*it)->evaluateChildren(evaluated); + parent->addChild(evaluated); + } } } @@ -76,22 +83,23 @@ class NumberNode : public Node NumberNode(double number) { m_number = number; - m_direct = true; } NumberNode(NodeRef expr) { m_expr = expr; - m_direct = false; } virtual double getNumber() { - return m_direct ? m_number : m_expr->getNumber(); + return m_number; + } + virtual refptr evaluate() + { + return new NumberNode(m_number); } protected: double m_number; NodeRef m_expr; - bool m_direct; }; class VectorNode : public Node @@ -102,7 +110,7 @@ class VectorNode : public Node { } VectorNode(NodeRef node) - : m_a(node), m_direct(false) + : m_vector(node), m_direct(false) { } refptr getVector() @@ -113,8 +121,16 @@ class VectorNode : public Node m_c->getNumber()) : m_a->getVector(); } + virtual NodeRef evaluate() + { + return m_direct + ? new VectorNode(m_a->evaluate(), + m_b->evaluate(), + m_c->evaluate()) + : m_a->evaluate(); + } protected: - NodeRef m_a, m_b, m_c; + NodeRef m_a, m_b, m_c, m_vector; bool m_direct; }; @@ -123,58 +139,99 @@ class AmbientNode : public VectorNode { public: AmbientNode(NodeRef vector) : VectorNode(vector) {} + virtual NodeRef evaluate() + { + return new AmbientNode(m_vector->evaluate()); + } }; class AmbientOcclusionNode : public NumberNode { public: AmbientOcclusionNode(NodeRef e) : NumberNode(e) {} + virtual NodeRef evaluate() + { + return new AmbientOcclusionNode(m_expr->evaluate()); + } }; class BoxNode : public Node { public: bool isShape() { return true; } + virtual NodeRef evaluate() + { + return new BoxNode(); + } }; class CameraNode : public Node { + public: + virtual NodeRef evaluate() + { + return new CameraNode(); + } }; class ColorNode : public VectorNode { public: ColorNode(NodeRef vector) : VectorNode(vector) {} + virtual NodeRef evaluate() + { + return new ColorNode(m_vector->evaluate()); + } }; class CylNode : public Node { public: bool isShape() { return true; } + virtual NodeRef evaluate() + { + return new CylNode(); + } }; class DiffuseNode : public VectorNode { public: DiffuseNode(NodeRef vector) : VectorNode(vector) {} + virtual NodeRef evaluate() + { + return new DiffuseNode(m_vector->evaluate()); + } }; class ExposureNode : public NumberNode { public: ExposureNode(NodeRef e) : NumberNode(e) {} + virtual NodeRef evaluate() + { + return new ExposureNode(m_expr->evaluate()); + } }; class ExtrudeNode : public Node { public: bool isShape() { return true; } + virtual NodeRef evaluate() + { + return new ExtrudeNode(); + } }; class HeightNode : public NumberNode { public: HeightNode(NodeRef e) : NumberNode(e) {} + virtual NodeRef evaluate() + { + return new HeightNode(m_expr->evaluate()); + } }; class IdentifierNode : public Node @@ -182,6 +239,10 @@ class IdentifierNode : public Node public: IdentifierNode(const std::string & str) { m_string = str; } std::string getString() { return m_string; } + virtual NodeRef evaluate() + { + return new IdentifierNode(m_string); + } protected: std::string m_string; }; @@ -190,39 +251,62 @@ class IntersectNode : public Node { public: bool isShape() { return true; } + virtual NodeRef evaluate() + { + return new IntersectNode(); + } }; class ItemsNode : public Node { + public: + virtual NodeRef evaluate() + { + return new ItemsNode(); + } }; class JitterNode : public NumberNode { public: JitterNode(NodeRef e) : NumberNode(e) {} - int getInteger() { return getNumber(); } + virtual NodeRef evaluate() + { + return new JitterNode(m_expr->evaluate()); + } }; class LightNode : public Node { + public: + virtual NodeRef evaluate() { return new LightNode(); } }; class LookAtNode : public VectorNode { public: LookAtNode(NodeRef vector) : VectorNode(vector) {} + virtual NodeRef evaluate() + { + return new LookAtNode(m_vector->evaluate()); + } }; class MaterialNode : public Node { public: bool isMaterial() { return true; } + virtual NodeRef evaluate() { return new MaterialNode(); } }; class MaterialDefinitionNode : public IdentifierNode { public: MaterialDefinitionNode(const std::string & str) : IdentifierNode(str) {} + virtual NodeRef evaluate() + { + return new MaterialDefinitionNode(m_string); + } }; class MaterialRefNode : public IdentifierNode @@ -230,41 +314,60 @@ class MaterialRefNode : public IdentifierNode public: MaterialRefNode(const std::string & str) : IdentifierNode(str) {} bool isMaterial() { return true; } + virtual NodeRef evaluate() { return new MaterialRefNode(m_string); } }; class MaxDepthNode : public NumberNode { public: MaxDepthNode(NodeRef e) : NumberNode(e) {} + virtual NodeRef evaluate() + { + return new MaxDepthNode(m_expr->evaluate()); + } }; class MultisampleNode : public NumberNode { public: MultisampleNode(NodeRef e) : NumberNode(e) {} + virtual NodeRef evaluate() + { + return new MultisampleNode(m_expr->evaluate()); + } }; class NGonNode : public NumberNode { public: NGonNode(NodeRef e) : NumberNode(e) {} - int getInteger() { return getNumber(); } + virtual NodeRef evaluate() + { + return new NGonNode(m_expr->evaluate()); + } }; class OffsetNode : public NumberNode { public: OffsetNode(NodeRef e) : NumberNode(e) {} + virtual NodeRef evaluate() + { + return new OffsetNode(m_expr->evaluate()); + } }; class OptionsNode : public Node { + public: + virtual NodeRef evaluate() { return new OptionsNode(); } }; class PlaneNode : public Node { public: bool isShape() { return true; } + virtual NodeRef evaluate() { return new PlaneNode(); } }; class PlanePositionNode : public VectorNode @@ -276,6 +379,11 @@ class PlanePositionNode : public VectorNode m_dist = dist; } double getNumber() { return m_dist->getNumber(); } + virtual NodeRef evaluate() + { + return new PlanePositionNode(m_vector->evaluate(), + m_dist->evaluate()); + } protected: NodeRef m_dist; @@ -283,24 +391,38 @@ class PlanePositionNode : public VectorNode class PolygonNode : public Node { + public: + virtual NodeRef evaluate() { return new PolygonNode(); } }; class PositionNode : public VectorNode { public: PositionNode(NodeRef vector) : VectorNode(vector) {} + virtual NodeRef evaluate() + { + return new PositionNode(m_vector->evaluate()); + } }; class RadiusNode : public NumberNode { public: RadiusNode(NodeRef e) : NumberNode(e) {} + virtual NodeRef evaluate() + { + return new RadiusNode(m_expr->evaluate()); + } }; class ReflectanceNode : public NumberNode { public: ReflectanceNode(NodeRef e) : NumberNode(e) {} + virtual NodeRef evaluate() + { + return new ReflectanceNode(m_expr->evaluate()); + } }; class RotateNode : public VectorNode @@ -312,6 +434,10 @@ class RotateNode : public VectorNode m_angle = angle; } double getNumber() { return m_angle->getNumber(); } + virtual NodeRef evaluate() + { + return new RotateNode(m_angle->evaluate(), m_vector->evaluate()); + } protected: NodeRef m_angle; @@ -323,12 +449,20 @@ class RotateBlockNode : public RotateNode RotateBlockNode(NodeRef angle, NodeRef vec_node) : RotateNode(angle, vec_node) {} bool isTransformBlock() { return true; } + virtual NodeRef evaluate() + { + return new RotateBlockNode(m_angle->evaluate(), m_vector->evaluate()); + } }; class ScaleNode : public VectorNode { public: ScaleNode(NodeRef vector) : VectorNode(vector) {} + virtual NodeRef evaluate() + { + return new ScaleNode(m_vector->evaluate()); + } }; class ScaleBlockNode : public ScaleNode @@ -336,6 +470,10 @@ class ScaleBlockNode : public ScaleNode public: ScaleBlockNode(NodeRef vector) : ScaleNode(vector) {} bool isTransformBlock() { return true; } + virtual NodeRef evaluate() + { + return new ScaleBlockNode(m_vector->evaluate()); + } }; class ScaleScalarNode : public Node @@ -345,10 +483,10 @@ class ScaleScalarNode : public Node : m_expr(expr) { } - refptr getVector() + virtual NodeRef evaluate() { - double x = m_expr->getNumber(); - return new Vector(x, x, x); + NodeRef n = m_expr->evaluate(); + return new VectorNode(n, n, n); } protected: NodeRef m_expr; @@ -356,12 +494,15 @@ class ScaleScalarNode : public Node class SceneNode : public Node { + public: + virtual NodeRef evaluate() { return new SceneNode(); } }; class ShapeDefinitionNode : public IdentifierNode { public: ShapeDefinitionNode(const std::string & str) : IdentifierNode(str) {} + virtual NodeRef evaluate() { return new ShapeDefinitionNode(m_string); } }; class ShapeRefNode : public IdentifierNode @@ -369,42 +510,61 @@ class ShapeRefNode : public IdentifierNode public: ShapeRefNode(const std::string & str) : IdentifierNode(str) {} bool isShape() { return true; } + virtual NodeRef evaluate() { return new ShapeRefNode(m_string); } }; class ShininessNode : public NumberNode { public: ShininessNode(NodeRef e) : NumberNode(e) {} + virtual NodeRef evaluate() + { + return new ShininessNode(m_expr->evaluate()); + } }; class SizeNode : public VectorNode { public: SizeNode(NodeRef vector) : VectorNode(vector) {} + virtual NodeRef evaluate() + { + return new SizeNode(m_vector->evaluate()); + } }; class SpecularNode : public VectorNode { public: SpecularNode(NodeRef vector) : VectorNode(vector) {} + virtual NodeRef evaluate() + { + return new SpecularNode(m_vector->evaluate()); + } }; class SphereNode : public Node { public: bool isShape() { return true; } + virtual NodeRef evaluate() { return new SphereNode(); } }; class SubtractNode : public Node { public: bool isShape() { return true; } + virtual NodeRef evaluate() { return new SubtractNode(); } }; class TranslateNode : public VectorNode { public: TranslateNode(NodeRef vector) : VectorNode(vector) {} + virtual NodeRef evaluate() + { + return new TranslateNode(m_vector->evaluate()); + } }; class TranslateBlockNode : public TranslateNode @@ -412,36 +572,57 @@ class TranslateBlockNode : public TranslateNode public: TranslateBlockNode(NodeRef vector) : TranslateNode(vector) {} bool isTransformBlock() { return true; } + virtual NodeRef evaluate() + { + return new TranslateBlockNode(m_vector->evaluate()); + } }; class TransparencyNode : public NumberNode { public: TransparencyNode(NodeRef e) : NumberNode(e) {} + virtual NodeRef evaluate() + { + return new TransparencyNode(m_expr->evaluate()); + } }; class UnionNode : public Node { public: bool isShape() { return true; } + virtual NodeRef evaluate() { return new UnionNode(); } }; class UpNode : public VectorNode { public: UpNode(NodeRef vector) : VectorNode(vector) {} + virtual NodeRef evaluate() + { + return new UpNode(m_vector->evaluate()); + } }; class VFOVNode : public NumberNode { public: VFOVNode(NodeRef e) : NumberNode(e) {} + virtual NodeRef evaluate() + { + return new VFOVNode(m_expr->evaluate()); + } }; class WidthNode : public NumberNode { public: WidthNode(NodeRef e) : NumberNode(e) {} + virtual NodeRef evaluate() + { + return new WidthNode(m_expr->evaluate()); + } }; /******** scripting nodes ********/ @@ -451,7 +632,6 @@ class ExpressionNode : public Node public: bool isExpression() { return true; } virtual double getNumber() = 0; - virtual int getInteger() { return getNumber(); } }; class AssignmentNode : public ExpressionNode From 18886ef7679b73929765c5fbccdfbaa43eb9c69c Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 6 Oct 2010 17:42:37 +0000 Subject: [PATCH 24/27] reworked ForNode evaluation() git-svn-id: svn://anubis/fart/branches/scene-file-scripting@339 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- main/Scene-load.cc | 26 ------------- parser/nodes.cc | 96 ++++++++++++++++++++++++++++++++++++++-------- parser/nodes.h | 47 ++++++++++------------- 3 files changed, 100 insertions(+), 69 deletions(-) diff --git a/main/Scene-load.cc b/main/Scene-load.cc index cbb8103..a97394f 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -248,32 +248,6 @@ vector Scene::processGeneralItems(refptr node) return shapes; } -vector Scene::processForNode(refptr node) -{ - if (!node->getNode(0).isNull()) - { - node->getNode(0)->getNumber(); - } - - vector shapes, incoming; - - while (node->getNode(1)->getInteger() != 0) - { - incoming = processGeneralItems(node); - while (incoming.size() > 0) - { - shapes.push_back(incoming[0]); - incoming.erase(incoming.begin()); - } - if (!node->getNode(2).isNull()) - { - node->getNode(2)->getNumber(); - } - } - - return shapes; -} - void Scene::processMaterialDefinition(refptr node) { map< string, refptr >::iterator it = diff --git a/parser/nodes.cc b/parser/nodes.cc index f7c55de..e940673 100644 --- a/parser/nodes.cc +++ b/parser/nodes.cc @@ -3,6 +3,7 @@ #include #include +#include #include "nodes.h" @@ -25,48 +26,109 @@ Node::~Node() { } -double BinOpNode::getNumber() +NodeRef BinOpNode::evaluate() { - double o = one->getNumber(); - double t = two->getNumber(); + double o = one->evaluate()->getNumber(); + double t = two->evaluate()->getNumber(); + double r = 0.0; switch (m_op) { case '*': - return o * t; + r = o * t; + break; case '/': - return o / t; + r = o / t; + break; case '+': - return o + t; + r = o + t; + break; case '-': - return o - t; + r = o - t; + break; default: cerr << "Error: BinOpNode created with op '" << m_op << "'" << endl; exit(-3); } + return new NumberNode(r); } -int BoolExpressionNode::getInteger() +NodeRef BoolExpressionNode::evaluate() { double o, t; + double r = 0; if (m_op != '!') { - o = one->getNumber(); - t = two->getNumber(); + o = one->evaluate()->getNumber(); + t = two->evaluate()->getNumber(); } switch (m_op) { case '<': - return o < t; + r = o < t ? 0 : 1; + break; case '>': - return o > t; + r = o > t ? 0 : 1; + break; case '=': - return o == t; + r = o == t ? 0 : 1; + break; case 'n': - return o != t; + r = o != t ? 0 : 1; + break; case '!': - return ! one->getInteger(); + r = ! one->evaluate()->getInteger(); + break; case 'T': - return 1; + r = 1; + break; } - return 0; + 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::iterator it = m_children.begin(); + it != m_children.end(); + it++) + { + NodeRef n = (*it)->evaluate(); + if ( ! n.isNull() ) + { + if (typeid(*n) == typeid(EvaluatePropagateNode)) + { + for (vector::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; +} + diff --git a/parser/nodes.h b/parser/nodes.h index c417e0e..fa2716c 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -39,11 +39,6 @@ class Node std::cerr << "Warning: Node::getString() called!" << std::endl; return ""; } - virtual refptr getNode(int idx) - { - std::cerr << "Warning: Node::getNode() called!" << std::endl; - return NULL; - } virtual refptr evaluate() { std::cerr << "Warning: Node::evaluate() called!" << std::endl; @@ -631,7 +626,7 @@ class ExpressionNode : public Node { public: bool isExpression() { return true; } - virtual double getNumber() = 0; + virtual NodeRef evaluate() = 0; }; class AssignmentNode : public ExpressionNode @@ -642,11 +637,11 @@ class AssignmentNode : public ExpressionNode { } std::string getString() { return m_varref->getString(); } - double getNumber() + virtual NodeRef evaluate() { - double n = m_expr->getNumber(); + double n = m_expr->evaluate()->getNumber(); parser_scope->putGlobal(getString(), n); - return n; + return new NumberNode(n); } protected: NodeRef m_varref; @@ -661,11 +656,11 @@ class LocalAssignmentNode : public ExpressionNode { } std::string getString() { return m_varref->getString(); } - double getNumber() + virtual NodeRef evaluate() { - double n = m_expr->getNumber(); + double n = m_expr->evaluate()->getNumber(); parser_scope->putLocal(getString(), n); - return n; + return new NumberNode(n); } protected: NodeRef m_varref; @@ -676,10 +671,10 @@ class LocalDeclNode : public ExpressionNode { public: LocalDeclNode(NodeRef varref) : m_varref(varref) { } - double getNumber() + virtual NodeRef evaluate() { parser_scope->putLocal(m_varref->getString(), 0.0); - return 0.0; + return NULL; } protected: NodeRef m_varref; @@ -692,7 +687,7 @@ class BinOpNode : public ExpressionNode : m_op(op), one(one), two(two) { } - virtual double getNumber(); + virtual NodeRef evaluate(); protected: char m_op; NodeRef one; @@ -706,7 +701,7 @@ class BoolExpressionNode : public Node : m_op(op), one(one), two(two) { } - int getInteger(); + virtual NodeRef evaluate(); protected: char m_op; NodeRef one; @@ -718,11 +713,11 @@ class VarRefNode : public Node public: VarRefNode(const std::string & str) { m_string = str; } std::string getString() { return m_string; } - double getNumber() + virtual NodeRef evaluate() { if (parser_scope->contains(m_string)) { - return parser_scope->get(m_string); + return new NumberNode(parser_scope->get(m_string)); } std::cerr << "Error: No identifier '" << m_string << "' in scope" << std::endl; @@ -741,17 +736,17 @@ class ForNode : public Node m_nodes[1] = e2; m_nodes[2] = e3; } - NodeRef getNode(int idx) - { - if (0 <= idx && idx <= 2) - { - return m_nodes[idx]; - } - return NULL; - } + 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 From 4d488b9e555c91d31a3c7f2db220b9d5c847e6a8 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 6 Oct 2010 17:54:54 +0000 Subject: [PATCH 25/27] moved Node::evaluateChildren() to nodes.cc, added EvaluatePropagateNode support git-svn-id: svn://anubis/fart/branches/scene-file-scripting@340 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.cc | 29 +++++++++++++++++++++++++++++ parser/nodes.h | 16 +--------------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/parser/nodes.cc b/parser/nodes.cc index e940673..ba934b9 100644 --- a/parser/nodes.cc +++ b/parser/nodes.cc @@ -9,6 +9,35 @@ using namespace std; +void Node::evaluateChildren(refptr parent) +{ + /* recursively evaluate all children nodes */ + for (std::vector< refptr >::iterator it = m_children.begin(); + it != m_children.end(); + it++) + { + refptr evaluated = (*it)->evaluate(); + if ( ! evaluated.isNull() ) + { + if (typeid(*evaluated) == typeid(EvaluatePropagateNode)) + { + for (vector::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()) diff --git a/parser/nodes.h b/parser/nodes.h index fa2716c..aed4e41 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -44,21 +44,7 @@ class Node std::cerr << "Warning: Node::evaluate() called!" << std::endl; return NULL; } - virtual void evaluateChildren(refptr parent) - { - /* recursively evaluate all children nodes */ - for (std::vector< refptr >::iterator it = m_children.begin(); - it != m_children.end(); - it++) - { - refptr evaluated = (*it)->evaluate(); - if ( ! evaluated.isNull() ) - { - (*it)->evaluateChildren(evaluated); - parent->addChild(evaluated); - } - } - } + virtual void evaluateChildren(refptr parent); virtual bool isShape() { return false; } virtual bool isMaterial() { return false; } From 1dc370c99fe78d3876f52eae3643c343a88057b2 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 6 Oct 2010 19:27:54 +0000 Subject: [PATCH 26/27] fixed NumberNode and VectorNode "direct" bugs git-svn-id: svn://anubis/fart/branches/scene-file-scripting@341 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- parser/nodes.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/parser/nodes.h b/parser/nodes.h index aed4e41..2171053 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -62,24 +62,28 @@ class NumberNode : public Node { public: NumberNode(double number) + : m_number(number), m_direct(true) { - m_number = number; } NumberNode(NodeRef expr) + : m_direct(false) { m_expr = expr; } virtual double getNumber() { - return m_number; + return m_direct ? m_number : m_expr->getNumber(); } virtual refptr evaluate() { - return new NumberNode(m_number); + return m_direct + ? new NumberNode(m_number) + : new NumberNode(m_expr->evaluate()); } protected: double m_number; + bool m_direct; NodeRef m_expr; }; @@ -100,7 +104,7 @@ class VectorNode : public Node ? new Vector(m_a->getNumber(), m_b->getNumber(), m_c->getNumber()) - : m_a->getVector(); + : m_vector->getVector(); } virtual NodeRef evaluate() { @@ -108,7 +112,7 @@ class VectorNode : public Node ? new VectorNode(m_a->evaluate(), m_b->evaluate(), m_c->evaluate()) - : m_a->evaluate(); + : m_vector->evaluate(); } protected: NodeRef m_a, m_b, m_c, m_vector; From d84fc2a96f0d6b4b9ee710f7b773594a1188cb18 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 6 Oct 2010 20:17:40 +0000 Subject: [PATCH 27/27] actually saving off the parsed shapes helps a lot git-svn-id: svn://anubis/fart/branches/scene-file-scripting@342 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- main/Scene-load.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/main/Scene-load.cc b/main/Scene-load.cc index a97394f..0dec38c 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -69,7 +69,13 @@ void Scene::processScene(refptr node) } /* then any general items */ - processGeneralItems(node); + vector shapes = processGeneralItems(node); + for (vector::iterator it = shapes.begin(); + it != shapes.end(); + it++) + { + m_shapes.push_back(*it); + } } ShapeRef Scene::processShape(refptr node)