#include #include #include "Scene.h" #include "Light.h" #include "parser/parser.h" #include "parser/nodes.h" using namespace std; typedef vector< refptr >::const_iterator Node_Iterator; void Scene::load(const char * filename) { /* TODO: parse file somehow */ // refptr node = parse(filename); // processNode(node); Transform transform; refptr m = new Material(); m->setDiffuseColor(Color::white); m->setAmbientColor(Color::white); refptr shape = new Plane(0, 0, 1, 2); shape->setTransform(transform); shape->setMaterial(m); m_shapes.push_back(shape); transform.translate(1.0, 5.0, 0.5); m = new Material(); m->setDiffuseColor(Color::red); m->setAmbientColor(Color::red); shape = new Sphere(1.0); shape->setTransform(transform); shape->setMaterial(m); m_shapes.push_back(shape); transform.translate(-1.0, -5.0, -0.5); transform.translate(-1, 3, -0.5); refptr shape1 = new Sphere(0.8); shape1->setMaterial(m); shape1->setTransform(transform); refptr shape2 = new Box(new Vector(2, 2, 0.6)); m = new Material(); m->setDiffuseColor(Color::magenta); m->setAmbientColor(Color::magenta); shape2->setMaterial(m); transform.rotate(20, 0, 1, 0); shape2->setTransform(transform); shape = new Intersect(shape1, shape2); m_shapes.push_back(shape); transform.rotate(-20, 0, 1, 0); transform.translate(1, -3, 0.5); transform.translate(1.5, 3.2, -0.7); transform.rotate(15, 0, 0, 1); m = new Material(); m->setDiffuseColor(Color::magenta); m->setAmbientColor(Color::magenta); shape1 = new Box(new Vector(1, 1, 1)); shape1->setMaterial(m); shape1->setTransform(transform); m = new Material(); m->setDiffuseColor(Color::yellow); m->setAmbientColor(Color::yellow); shape2 = new Sphere(0.6); transform.translate(-0.5, -0.5, 0.5); shape2->setTransform(transform); shape2->setMaterial(m); shape = new Subtract(shape1, shape2); m_shapes.push_back(shape); transform.rotate(-15, 0, 0, 1); transform.translate(-1.0, -2.7, 0.2); transform.translate(1, 5, -1.5); m = new Material(); m->setDiffuseColor(Color::blue); m->setAmbientColor(Color::blue); shape = new Box(new Vector(1.8, 1.8, 0.5)); shape->setTransform(transform); shape->setMaterial(m); m_shapes.push_back(shape); transform.translate(-1, -5, 1.5); transform.translate(-0.5, 6.5, 1.5); transform.rotate(45, 1, 0, 0); m = new Material(); m->setDiffuseColor(Color::cyan); m->setAmbientColor(Color::cyan); shape = new Cyl(1.0, 0.0, 2.0); shape->setTransform(transform); shape->setMaterial(m); m_shapes.push_back(shape); transform.rotate(-45, 1, 0, 0); transform.translate(0.5, -6.5, -1.5); transform.translate(-2.0, 5.0, 1.5); transform.rotate(45, 0, 0, 1); transform.rotate(45, 1, 0, 0); m = new Material(); m->setDiffuseColor(Color::yellow); m->setAmbientColor(Color::yellow); shape = new Box(new Vector(1, 1, 1)); shape->setTransform(transform); shape->setMaterial(m); m_shapes.push_back(shape); transform.rotate(-45, 1, 0, 0); transform.rotate(-45, 0, 0, 1); transform.translate(2.0, -5.0, -1.5); refptr light = new PointLight(); light->setPosition(Vector(2, -1, 2)); m_lights.push_back(light); } void Scene::processNode(refptr node) { if (node.isNull()) return; if ( typeid(*node) == typeid(SceneNode) ) { processChildren(node); } else if ( typeid(*node) == typeid(BoxNode) ) { cout << "saw a box" << endl; } else if ( typeid(*node) == typeid(MaterialNode) ) { refptr mat = processMaterial(node); } else if ( typeid(*node) == typeid(PlaneNode) ) { cout << "saw a plane" << endl; } else if ( typeid(*node) == typeid(SphereNode) ) { cout << "saw a sphere" << 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]); } } refptr Scene::processMaterial(refptr node) { refptr material = new Material(); for (Node_Iterator it = node->getChildren().begin(); it != node->getChildren().end(); it++) { if ( typeid(**it) == typeid(ColorNode) ) { material->setDiffuseColor(Color((*it)->getVector())); material->setAmbientColor(Color((*it)->getVector())); } else if ( typeid(**it) == typeid(AmbientNode) ) { material->setAmbientColor(Color((*it)->getVector())); } else if ( typeid(**it) == typeid(DiffuseNode) ) { material->setDiffuseColor(Color((*it)->getVector())); } else if ( typeid(**it) == typeid(SpecularNode) ) { material->setSpecularColor(Color((*it)->getVector())); } else if ( typeid(**it) == typeid(ReflectanceNode) ) { material->setReflectance((*it)->getNumber()); } else if ( typeid(**it) == typeid(ShininessNode) ) { material->setShininess((*it)->getNumber()); } } return material; } refptr Scene::processBox(refptr node) { refptr size = new Vector(1, 1, 1); refptr material; bool restore_transform = processTransforms(node); for (Node_Iterator it = node->getChildren().begin(); it != node->getChildren().end(); it++) { if ( typeid(**it) == typeid(SizeNode) ) { size = (*it)->getVector(); } else if ( typeid(**it) == typeid(MaterialNode) ) { material = processMaterial(*it); } } refptr box = new Box(size); if ( ! material.isNull() ) box->setMaterial(material); box->setTransform(m_transforms.top()); if (restore_transform) m_transforms.pop(); return box; } refptr Scene::processCyl(refptr node) { double radius1 = 1.0; double radius2 = 1.0; double height = 1.0; refptr material; bool restore_transform = processTransforms(node); for (Node_Iterator it = node->getChildren().begin(); it != node->getChildren().end(); it++) { if ( typeid(**it) == typeid(SizeNode) ) { const Vector & v = *(*it)->getVector(); radius1 = v[0]; radius2 = v[1]; height = v[2]; } else if ( typeid(**it) == typeid(MaterialNode) ) { material = processMaterial(*it); } } refptr cyl = new Cyl(radius1, radius2, height); if ( ! material.isNull() ) cyl->setMaterial(material); cyl->setTransform(m_transforms.top()); if (restore_transform) m_transforms.pop(); return cyl; } refptr Scene::processLight(refptr node) { /* TODO: finish */ return refptr(NULL); } refptr Scene::processPlane(refptr node) { /* TODO: finish */ return refptr(NULL); } refptr Scene::processSphere(refptr node) { double radius = 1.0; refptr material; bool restore_transform = processTransforms(node); for (Node_Iterator it = node->getChildren().begin(); it != node->getChildren().end(); it++) { if ( typeid(**it) == typeid(RadiusNode) ) { radius = (*it)->getNumber(); } else if ( typeid(**it) == typeid(MaterialNode) ) { material = processMaterial(*it); } } refptr sphere = new Sphere(radius); if ( ! material.isNull() ) sphere->setMaterial(material); sphere->setTransform(m_transforms.top()); if (restore_transform) m_transforms.pop(); return sphere; } bool Scene::processTransforms(refptr node) { bool did_any = false; for (Node_Iterator it = node->getChildren().begin(); it != node->getChildren().end(); it++) { if ( typeid(**it) == typeid(TranslateNode) ) { if (did_any == false) { m_transforms.push(m_transforms.top()); did_any = true; } m_transforms.top().translate((*it)->getVector()); } else if ( typeid(**it) == typeid(RotateNode) ) { if (did_any == false) { m_transforms.push(m_transforms.top()); did_any = true; } m_transforms.top().rotate((*it)->getNumber(), (*it)->getVector()); } else if ( typeid(**it) == typeid(ScaleNode) ) { if (did_any == false) { m_transforms.push(m_transforms.top()); did_any = true; } m_transforms.top().scale((*it)->getVector()); } } return did_any; }