From b4a2c8ef8e2b8ba1376026c972cc983aa90ca379 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Fri, 9 Jul 2010 18:33:26 +0000 Subject: [PATCH] allowing transform blocks inside boolean shapes, but using a shape reference to a boolean shape does not propagate transform properly git-svn-id: svn://anubis/fart/trunk@286 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- main/Scene-load.cc | 84 +++++++++++++++++++++++++++++++++------------ main/Scene.h | 2 +- parser/nodes.h | 9 +++-- parser/parser.yy | 3 +- shapes/BoolShape.cc | 8 ----- shapes/BoolShape.h | 1 - shapes/Shape.h | 2 +- 7 files changed, 73 insertions(+), 36 deletions(-) diff --git a/main/Scene-load.cc b/main/Scene-load.cc index 41a1765..ee34cd9 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -45,17 +45,13 @@ void Scene::processNode(refptr node) { processOptions(node); } - else if ( typeid(*node) == typeid(TranslateBlockNode) ) + else if (node->isTransformBlock()) { - processTransformBlock(node); - } - else if ( typeid(*node) == typeid(RotateBlockNode) ) - { - processTransformBlock(node); - } - else if ( typeid(*node) == typeid(ScaleBlockNode) ) - { - processTransformBlock(node); + vector< refptr > 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) ) { @@ -131,15 +127,9 @@ refptr Scene::processShape(refptr node) { return processCyl(node); } - else if ( typeid(*node) == typeid(IntersectNode) ) - { - return processBool(node); - } - else if ( typeid(*node) == typeid(UnionNode) ) - { - return processBool(node); - } - else if ( typeid(*node) == typeid(SubtractNode) ) + else if ( typeid(*node) == typeid(IntersectNode) + || typeid(*node) == typeid(UnionNode) + || typeid(*node) == typeid(SubtractNode) ) { return processBool(node); } @@ -151,6 +141,11 @@ refptr Scene::processShape(refptr node) { return processShapeRef(node); } + else + { + cerr << "Error: Unknown shape!" << endl; + exit(3); + } return refptr(NULL); } @@ -225,7 +220,7 @@ void Scene::processOptions(refptr node) } } -void Scene::processTransformBlock(refptr node) +vector< refptr > Scene::processTransformBlock(refptr node) { if ( typeid(*node) == typeid(TranslateBlockNode) ) { @@ -244,9 +239,39 @@ void Scene::processTransformBlock(refptr node) m_transforms.top().scale(node->getVector()); } - processChildren(node); + vector< refptr > shapes; + + for (Node_Iterator it = node->getChildren().begin(); + it != node->getChildren().end(); + it++) + { + if ((*it)->isTransformBlock()) + { + vector< refptr > in = processTransformBlock(*it); + for (int i = 0, sz = in.size(); i < sz; i++) + { + shapes.push_back(in[i]); + } + } + else if ( (*it)->isShape() ) + { + shapes.push_back(processShape(*it)); + } + else if ( typeid(**it) == typeid(ShapeDefinitionNode) ) + { + processShapeDefinition(*it); + } + else + { + cerr << "Unknown transform block item: " << typeid(**it).name() + << endl; + exit(3); + } + } m_transforms.pop(); + + return shapes; } void Scene::processMaterialDefinition(refptr node) @@ -522,6 +547,23 @@ refptr Scene::processBool(refptr node) { material = processMaterial(*it); } + else if ( (*it)->isTransformBlock() ) + { + vector< refptr > in = processTransformBlock(*it); + for (int i = 0, sz = in.size(); i < sz; i++) + { + shapes.push_back(in[i]); + } + } + else if ( typeid(**it) == typeid(ShapeDefinitionNode) ) + { + processShapeDefinition(*it); + } + else + { + cerr << "Error: unknown boolean object item" << endl; + exit(3); + } } if (shapes.size() < 2) diff --git a/main/Scene.h b/main/Scene.h index e7f4d03..ed3ff37 100644 --- a/main/Scene.h +++ b/main/Scene.h @@ -76,7 +76,7 @@ class Scene bool processTransforms(refptr node); void processCamera(refptr node); void processOptions(refptr node); - void processTransformBlock(refptr node); + std::vector< refptr > processTransformBlock(refptr node); void processMaterialDefinition(refptr node); void processShapeDefinition(refptr node); diff --git a/parser/nodes.h b/parser/nodes.h index eb61491..275b871 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -23,6 +23,7 @@ class Node } virtual bool isShape() { return false; } virtual bool isMaterial() { return false; } + virtual bool isTransformBlock() { return false; } virtual std::string getString() { return ""; } protected: @@ -267,9 +268,8 @@ class RotateBlockNode : public RotateNode { public: RotateBlockNode(double angle, refptr vector) - : RotateNode(angle, vector) - { - } + : RotateNode(angle, vector) {} + bool isTransformBlock() { return true; } }; class ScaleNode : public VectorNode @@ -282,6 +282,7 @@ class ScaleBlockNode : public ScaleNode { public: ScaleBlockNode(refptr vector) : ScaleNode(vector) {} + bool isTransformBlock() { return true; } }; class SceneNode : public Node @@ -298,6 +299,7 @@ class ShapeRefNode : public IdentifierNode { public: ShapeRefNode(const std::string & str) : IdentifierNode(str) {} + bool isShape() { return true; } }; class ShininessNode : public NumberNode @@ -340,6 +342,7 @@ class TranslateBlockNode : public TranslateNode { public: TranslateBlockNode(refptr vector) : TranslateNode(vector) {} + bool isTransformBlock() { return true; } }; class TransparencyNode : public NumberNode diff --git a/parser/parser.yy b/parser/parser.yy index 4eefaba..4b3c3b5 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -121,6 +121,8 @@ bool_items: /* empty */ bool_item: shape | shape_item + | shape_definition + | transform_block ; box: BOX LCURLY box_items RCURLY { @@ -532,7 +534,6 @@ transform_block_items: /* empty */ ; transform_block_item: transform_block { $$ = $1; } - | light { $$ = $1; } | shape { $$ = $1; } | shape_definition { $$ = $1; } ; diff --git a/shapes/BoolShape.cc b/shapes/BoolShape.cc index a8e27b0..3695963 100644 --- a/shapes/BoolShape.cc +++ b/shapes/BoolShape.cc @@ -7,11 +7,3 @@ void BoolShape::setMaterial(refptr material) m_shape1->setMaterial(material); m_shape2->setMaterial(material); } - -void BoolShape::setTransform(Transform & t) -{ - m_transform = t; - m_inverse = t.getInverse(); - m_shape1->setTransform(t); - m_shape2->setTransform(t); -} diff --git a/shapes/BoolShape.h b/shapes/BoolShape.h index e2a66df..f95f176 100644 --- a/shapes/BoolShape.h +++ b/shapes/BoolShape.h @@ -9,7 +9,6 @@ class BoolShape : public Shape public: virtual IntersectionList intersect(refptr _this, const Ray & ray) = 0; virtual void setMaterial(refptr material); - virtual void setTransform(Transform & t); virtual refptr clone() = 0; protected: diff --git a/shapes/Shape.h b/shapes/Shape.h index 72025af..b5ad9c6 100644 --- a/shapes/Shape.h +++ b/shapes/Shape.h @@ -103,7 +103,7 @@ class Shape const Ray & ray) = 0; virtual refptr clone() = 0; - virtual void setTransform(Transform & t) + void setTransform(Transform & t) { m_transform = t; m_inverse = t.getInverse();