From 0462a2e7bc2b0885e9ac1e2423ffd27200b49f40 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sat, 28 Feb 2009 19:59:22 +0000 Subject: [PATCH] working on Scene::process*() functions to load the scene from a file git-svn-id: svn://anubis/fart/trunk@164 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- main/Scene-load.cc | 188 +++++++++++++++++++++++++++++++++------------ main/Scene.cc | 1 + main/Scene.h | 5 +- util/Color.cc | 7 ++ util/Color.h | 2 + util/Transform.h | 13 ++++ 6 files changed, 167 insertions(+), 49 deletions(-) diff --git a/main/Scene-load.cc b/main/Scene-load.cc index 8e55fe1..f7b92a7 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -8,102 +8,105 @@ 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(m_transform); + shape->setTransform(transform); shape->setMaterial(m); m_shapes.push_back(shape); - m_transform.translate(1.0, 5.0, 0.5); + 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(m_transform); + shape->setTransform(transform); shape->setMaterial(m); m_shapes.push_back(shape); - m_transform.translate(-1.0, -5.0, -0.5); + transform.translate(-1.0, -5.0, -0.5); - m_transform.translate(-1, 3, -0.5); + transform.translate(-1, 3, -0.5); refptr shape1 = new Sphere(0.8); shape1->setMaterial(m); - shape1->setTransform(m_transform); + 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); - m_transform.rotate(20, 0, 1, 0); - shape2->setTransform(m_transform); + transform.rotate(20, 0, 1, 0); + shape2->setTransform(transform); shape = new Intersect(shape1, shape2); m_shapes.push_back(shape); - m_transform.rotate(-20, 0, 1, 0); - m_transform.translate(1, -3, 0.5); + transform.rotate(-20, 0, 1, 0); + transform.translate(1, -3, 0.5); - m_transform.translate(1.5, 3.2, -0.7); - m_transform.rotate(15, 0, 0, 1); + 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(m_transform); + shape1->setTransform(transform); m = new Material(); m->setDiffuseColor(Color::yellow); m->setAmbientColor(Color::yellow); shape2 = new Sphere(0.6); - m_transform.translate(-0.5, -0.5, 0.5); - shape2->setTransform(m_transform); + transform.translate(-0.5, -0.5, 0.5); + shape2->setTransform(transform); shape2->setMaterial(m); shape = new Subtract(shape1, shape2); m_shapes.push_back(shape); - m_transform.rotate(-15, 0, 0, 1); - m_transform.translate(-1.0, -2.7, 0.2); + transform.rotate(-15, 0, 0, 1); + transform.translate(-1.0, -2.7, 0.2); - m_transform.translate(1, 5, -1.5); + 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(m_transform); + shape->setTransform(transform); shape->setMaterial(m); m_shapes.push_back(shape); - m_transform.translate(-1, -5, 1.5); + transform.translate(-1, -5, 1.5); - m_transform.translate(-0.5, 6.5, 1.5); - m_transform.rotate(45, 1, 0, 0); + 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(m_transform); + shape->setTransform(transform); shape->setMaterial(m); m_shapes.push_back(shape); - m_transform.rotate(-45, 1, 0, 0); - m_transform.translate(0.5, -6.5, -1.5); + transform.rotate(-45, 1, 0, 0); + transform.translate(0.5, -6.5, -1.5); - m_transform.translate(-2.0, 5.0, 1.5); - m_transform.rotate(45, 0, 0, 1); - m_transform.rotate(45, 1, 0, 0); + 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(m_transform); + shape->setTransform(transform); shape->setMaterial(m); m_shapes.push_back(shape); - m_transform.rotate(-45, 1, 0, 0); - m_transform.rotate(-45, 0, 0, 1); - m_transform.translate(2.0, -5.0, -1.5); + 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)); @@ -123,6 +126,10 @@ void Scene::processNode(refptr node) { 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; @@ -143,45 +150,132 @@ void Scene::processChildren(refptr node) } } -refptr processMaterial(refptr node) +refptr Scene::processMaterial(refptr node) { - if (typeid(*node) != typeid(MaterialNode)) - return refptr(NULL); - refptr material = new Material(); - /* TODO: finish */ + 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 processBox(refptr node) +refptr Scene::processBox(refptr node) +{ + Vector size(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); + } + } + + if (restore_transform) + m_transforms.pop(); + + return refptr(NULL); +} + +refptr Scene::processCyl(refptr node) { /* TODO: finish */ return refptr(NULL); } -refptr processCyl(refptr node) -{ - /* TODO: finish */ - return refptr(NULL); -} - -refptr processLight(refptr node) +refptr Scene::processLight(refptr node) { /* TODO: finish */ return refptr(NULL); } -refptr processPlane(refptr node) +refptr Scene::processPlane(refptr node) { /* TODO: finish */ return refptr(NULL); } -refptr processSphere(refptr node) +refptr Scene::processSphere(refptr node) { /* TODO: finish */ return refptr(NULL); } +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; +} diff --git a/main/Scene.cc b/main/Scene.cc index 929bacb..5157215 100644 --- a/main/Scene.cc +++ b/main/Scene.cc @@ -29,6 +29,7 @@ Scene::Scene(const map & options, m_data = NULL; m_ambient_light = Color(0.1, 0.1, 0.1); m_max_depth = 10; + m_transforms.push(Transform()); load(filename); diff --git a/main/Scene.h b/main/Scene.h index d311680..be3ae77 100644 --- a/main/Scene.h +++ b/main/Scene.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "util/refptr.h" #include "util/Ray.h" #include "util/Color.h" @@ -45,7 +46,6 @@ class Scene void setMultisampleLevel(int level) { m_multisample_level = level; } void setVFOV(double vfov) { m_vfov = vfov; } void setAmbientLight(const Color & al) { m_ambient_light = al; } - Transform & getTransform() { return m_transform; } protected: /* private methods */ @@ -64,6 +64,7 @@ class Scene refptr processLight(refptr node); refptr processPlane(refptr node); refptr processSphere(refptr node); + bool processTransforms(refptr node); /* rendering parameters */ int m_width; @@ -78,7 +79,7 @@ class Scene /* private data */ std::vector< refptr > m_shapes; std::vector< refptr > m_lights; - Transform m_transform; + std::stack m_transforms; double m_view_plane_dist; int m_multisample_level_squared; double m_sample_span; diff --git a/util/Color.cc b/util/Color.cc index f719ec3..a4f155b 100644 --- a/util/Color.cc +++ b/util/Color.cc @@ -29,6 +29,13 @@ Color::Color(const Vector & v) b = v[2]; } +Color::Color(refptr v) +{ + r = (*v)[0]; + g = (*v)[1]; + b = (*v)[2]; +} + Color Color::operator*(const Color & other) const { Color result; diff --git a/util/Color.h b/util/Color.h index 4f28d9f..a3abaf8 100644 --- a/util/Color.h +++ b/util/Color.h @@ -2,6 +2,7 @@ #ifndef COLOR_H #define COLOR_H COLOR_H +#include "refptr.h" #include #include "util/Vector.h" @@ -13,6 +14,7 @@ class Color Color(); Color(double r, double g, double b); Color(const Vector & v); + Color(refptr v); Color operator*(const Color & other) const; Color operator*(double scale) const; diff --git a/util/Transform.h b/util/Transform.h index 39cdc23..eeaef69 100644 --- a/util/Transform.h +++ b/util/Transform.h @@ -2,6 +2,7 @@ #ifndef TRANSFORM_H #define TRANSFORM_H TRANSFORM_H +#include "refptr.h" #include "Matrix.h" #include "Ray.h" #include "Vector.h" @@ -16,8 +17,20 @@ class Transform const Vector & focus, const Vector & up); void translate(double x, double y, double z); + void translate(refptr vec) + { + translate((*vec)[0], (*vec)[1], (*vec)[2]); + } void rotate(double angle, double xv, double yv, double zv); + void rotate(double angle, refptr vec) + { + rotate(angle, (*vec)[0], (*vec)[1], (*vec)[2]); + } void scale(double xs, double ys, double zs); + void scale(refptr vec) + { + scale((*vec)[0], (*vec)[1], (*vec)[2]); + } Matrix & getMatrix() { return m_matrix; } Vector transform_point(const Vector & v); Vector transform_direction(const Vector & v);