diff --git a/main/Scene-load.cc b/main/Scene-load.cc index 10461d6..32741cb 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -13,8 +13,8 @@ typedef vector< refptr >::const_iterator Node_Iterator; void Scene::load(const char * filename) { /* TODO: parse file somehow */ -// refptr node = parse(filename); -// processNode(node); + refptr node = parse(filename); + processNode(node); Transform transform; @@ -122,23 +122,40 @@ void Scene::processNode(refptr node) { processChildren(node); } - else if ( typeid(*node) == typeid(BoxNode) ) +} + +refptr Scene::processShape(refptr node) +{ + if ( typeid(*node) == typeid(BoxNode) ) { - cout << "saw a box" << endl; - } - else if ( typeid(*node) == typeid(MaterialNode) ) - { - refptr mat = processMaterial(node); + return processBox(node); } else if ( typeid(*node) == typeid(PlaneNode) ) { - cout << "saw a plane" << endl; + return processPlane(node); } else if ( typeid(*node) == typeid(SphereNode) ) { - cout << "saw a sphere" << endl; + return processSphere(node); + } + else if ( typeid(*node) == typeid(CylNode) ) + { + 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) ) + { + return processBool(node); } + return refptr(NULL); } void Scene::processChildren(refptr node) @@ -332,6 +349,76 @@ refptr Scene::processSphere(refptr node) return sphere; } +refptr Scene::processBool(refptr node) +{ + refptr shape1, shape2; + refptr material; + int shapes_seen = 0; + + bool restore_transform = processTransforms(node); + + for (Node_Iterator it = node->getChildren().begin(); + it != node->getChildren().end(); + it++) + { + if ( node->isShape() ) + { + switch (shapes_seen) + { + case 0: shape1 = processShape(node); + break; + case 1: shape2 = processShape(node); + break; + } + shapes_seen++; + } + else if ( typeid(**it) == typeid(MaterialNode) ) + { + material = processMaterial(*it); + } + } + + if (shapes_seen < 2 || shape1.isNull() || shape2.isNull()) + { + if (shapes_seen < 2) + cerr << __FILE__ << ": " << __LINE__ + << ": error: only saw " + << shapes_seen + << " child shapes!" + << endl; + if (shape1.isNull()) + cerr << __FILE__ << ": " << __LINE__ + << ": error: shape1 is null!" << endl; + if (shape2.isNull()) + cerr << __FILE__ << ": " << __LINE__ + << ": error: shape2 is null!" << endl; + exit(3); + } + + refptr shape; + if ( typeid(*node) == typeid(IntersectNode) ) + shape = new Intersect(shape1, shape2); + else if ( typeid(*node) == typeid(UnionNode) ) + shape = new Union(shape1, shape2); + else if ( typeid(*node) == typeid(SubtractNode) ) + shape = new Subtract(shape1, shape2); + else + { + cerr << __FILE__ << ": " << __LINE__ + << ": error: bool object unrecognized" << endl; + exit(3); + } + + if ( ! material.isNull() ) + shape->setMaterial(material); + shape->setTransform(m_transforms.top()); + + if (restore_transform) + m_transforms.pop(); + + return shape; +} + bool Scene::processTransforms(refptr node) { bool did_any = false; diff --git a/main/Scene.h b/main/Scene.h index be3ae77..3b9c70c 100644 --- a/main/Scene.h +++ b/main/Scene.h @@ -64,6 +64,8 @@ class Scene refptr processLight(refptr node); refptr processPlane(refptr node); refptr processSphere(refptr node); + refptr processShape(refptr node); + refptr processBool(refptr node); bool processTransforms(refptr node); /* rendering parameters */ diff --git a/parser/nodes.h b/parser/nodes.h index 68bbf9b..df4a417 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -20,6 +20,7 @@ class Node { return refptr(NULL); } + virtual bool isShape() { return false; } protected: std::vector< refptr > m_children; @@ -66,6 +67,8 @@ class AmbientNode : public VectorNode class BoxNode : public Node { + public: + bool isShape() { return true; } }; class CameraNode : public Node @@ -80,6 +83,8 @@ class ColorNode : public VectorNode class CylNode : public Node { + public: + bool isShape() { return true; } }; class DiffuseNode : public VectorNode @@ -96,6 +101,8 @@ class HeightNode : public IntegerNode class IntersectNode : public Node { + public: + bool isShape() { return true; } }; class ItemsNode : public Node @@ -126,6 +133,8 @@ class OptionsNode : public Node class PlaneNode : public Node { + public: + bool isShape() { return true; } }; class PlanePositionNode : public Node @@ -199,10 +208,6 @@ class SceneNode : public Node { }; -class ShapeNode : public Node -{ -}; - class ShininessNode : public NumberNode { public: @@ -223,10 +228,14 @@ class SpecularNode : public VectorNode class SphereNode : public Node { + public: + bool isShape() { return true; } }; class SubtractNode : public Node { + public: + bool isShape() { return true; } }; class TranslateNode : public VectorNode @@ -243,6 +252,8 @@ class TranslateBlockNode : public TranslateNode class UnionNode : public Node { + public: + bool isShape() { return true; } }; class UpNode : public Node