From 47ae52ed051e6c438cfd952e1cb368ca96fd19c6 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 9 Aug 2014 12:25:59 -0700 Subject: [PATCH] Woo Scene updates... --- src/camera.hh | 1 - src/scene.cc | 311 ++++++++++++++++++++++++++++---------------------- src/scene.h | 84 -------------- src/scene.hh | 86 ++++++++++++++ 4 files changed, 258 insertions(+), 224 deletions(-) delete mode 100644 src/scene.h create mode 100644 src/scene.hh diff --git a/src/camera.hh b/src/camera.hh index 2b006da..b34e605 100644 --- a/src/camera.hh +++ b/src/camera.hh @@ -51,7 +51,6 @@ struct Camera virtual basics::Ray PrimaryRay(const int x, const int width, const int y, const int height) const = 0; -protected: virtual std::string GetTypeString() const; private: diff --git a/src/scene.cc b/src/scene.cc index 9aae326..d64a05a 100644 --- a/src/scene.cc +++ b/src/scene.cc @@ -5,84 +5,123 @@ * Eryn Wells */ -#include +#include #include #include +#include + +#include "scene.hh" #include "basics.h" #include "light.h" #include "log.hh" -#include "object.h" -#include "scene.h" +#include "object.hh" #include "writer.h" +#include "basics/basics.hh" #define LOG_NAME "scene" #include "logModule.hh" -using namespace charles; + +using charles::basics::Ray; +using charles::basics::Vector4; +namespace charles { + +/* + * charles::Scene::Scene -- + */ Scene::Scene() - : width(640), height(480), + : mWidth(640), + mHeight(480), mCamera(new PerspectiveCamera()), - max_depth(5), - min_weight(1e-4), - ambient(new AmbientLight()), - shapes(), - lights(), + mMaxDepth(5), + mMinWeight(1e-6), + mAmbient(), + mObjects(), + mLights(), mStats(), - pixels(NULL) + mPixels(NULL) { } +/* + * charles::Scene::~Scene -- + */ Scene::~Scene() { mCamera.reset(); - if (ambient != NULL) { - delete ambient; - } + mObjects.clear(); - shapes.clear(); - - for (PointLight *l : lights) { + for (PointLight *l : mLights) { delete l; } - lights.clear(); + mLights.clear(); - if (pixels != NULL) { - delete[] pixels; - _is_rendered = false; + if (mPixels != NULL) { + delete[] mPixels; + mIsRendered = false; } } -bool -Scene::is_rendered() - const -{ - return _is_rendered; -} - - -int -Scene::get_width() - const -{ - return width; -} - - -int -Scene::get_height() - const -{ - return height; -} - - /* - * Scene::GetCamera -- + * charles::Scene::IsRendered -- + */ +bool +Scene::IsRendered() + const +{ + return mIsRendered; +} + + +/* + * charles::Scene::GetWidth -- + */ +UInt +Scene::GetWidth() + const +{ + return mWidth; +} + + +/* + * charles::Scene::SetWidth -- + */ +void +Scene::SetWidth(UInt w) +{ + mWidth = w; +} + + +/* + * charles::Scene::GetHeight -- + */ +UInt +Scene::GetHeight() + const +{ + return mHeight; +} + + +/* + * charles::Scene::SetHeight -- + */ +void +Scene::SetHeight(UInt h) +{ + mHeight = h; +} + + +/* + * charles::Scene::GetCamera -- */ Camera::Ptr Scene::GetCamera() @@ -93,63 +132,55 @@ Scene::GetCamera() /* - * Scene::SetCamera -- + * charles::Scene::SetCamera -- */ void -Scene::SetCamera(Camera* camera) +Scene::SetCamera(Camera::Ptr camera) { - mCamera.reset(camera); -} - - -AmbientLight & -Scene::get_ambient() - const -{ - return *ambient; -} - - -const Color * -Scene::get_pixels() - const -{ - return pixels; + mCamera = camera; } /* - * scene_load -- - * - * Load scene objects into this Scene from the given file. + * charles::Scene::GetAmbient -- */ -void -Scene::read(const std::string &filename) -{ } +AmbientLight& +Scene::GetAmbient() +{ + return mAmbient; +} /* - * scene_save -- - * - * Write a rendered scene to the given file. + * charles::Scene::GetPixels -- + */ +const Color* +Scene::GetPixels() + const +{ + return mPixels; +} + + +/* + * charles::Scene::Write -- */ void -Scene::write(Writer &writer, const std::string &filename) +Scene::Write(Writer& writer, + const std::string& filename) { writer.write_scene(*this, filename); } /* - * Scene::render -- - * - * Render the given Scene. + * charles::Scene::Render -- */ void -Scene::render() +Scene::Render() { - LOG_INFO << "Rendering scene with " << shapes.size() << " objects."; - printf("Rendering scene with %lu objects.\n", shapes.size()); + LOG_INFO << "Rendering scene with " << mObjects.size() << " objects."; + printf("Rendering scene with %lu objects.\n", mObjects.size()); LogCamera(); LogObjects(); @@ -157,23 +188,23 @@ Scene::render() std::chrono::time_point start, end; start = std::chrono::system_clock::now(); - pixels = new Color[width * height]; + mPixels = new Color[mWidth * mHeight]; - Ray primary_ray; - Vector3 o, d; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - primary_ray = mCamera->compute_primary_ray(x, width, y, height); + Ray primaryRay; + Vector4 o, d; + for (UInt y = 0; y < mHeight; y++) { + for (UInt x = 0; x < mWidth; x++) { + primaryRay = mCamera->PrimaryRay(x, mWidth, y, mHeight); mStats.primaryRays++; - Color c = trace_ray(primary_ray); - pixels[y * width + x] = c; + Color c = TraceRay(primaryRay); + mPixels[y * mWidth + x] = c; } } end = std::chrono::system_clock::now(); - std::chrono::duration seconds = end - start; + std::chrono::duration seconds = end - start; - _is_rendered = true; + mIsRendered = true; printf("Rendering completed in %f seconds.\n\n", seconds.count()); LOG_INFO << "Rendering completed in " << seconds.count() << " seconds."; @@ -184,83 +215,77 @@ Scene::render() /* - * Scene::add_shape -- - * - * Add a shape to the scene. + * charles::Scene::AddObject -- */ void -Scene::add_shape(Object::Ptr shape) +Scene::AddObject(Object::Ptr obj) { - shapes.push_back(shape); + mObjects.push_back(obj); } /* - * Scene::add_light -- - * - * Add a light to the scene. + * charles::Scene::AddLight -- */ void -Scene::add_light(PointLight *light) +Scene::AddLight(PointLight* light) { - lights.push_back(light); + mLights.push_back(light); } /* - * Scene::trace_ray -- - * - * Trace the given ray through the scene, recursing until depth has been reached. + * charles::Scene::TraceRay -- */ Color -Scene::trace_ray(const Ray &ray, - const int depth, - const float weight) +Scene::TraceRay(const Ray &ray, + const int depth, + const Double weight) { - if (depth >= max_depth || weight <= min_weight) { + if (depth >= mMaxDepth || weight <= mMinWeight) { return Color::Black; } - Color out_color = Color::Black; - Object::Ptr intersected_shape; + Color outColor = Color::Black; + Object::Ptr intersectedObj; TVector ts; - Double nearest_t = INFINITY; + Double nearestT = INFINITY; ts.reserve(2); // Find intersections of this ray with objects in the scene. - for (Object::Ptr s : shapes) { + for (Object::Ptr obj : mObjects) { ts.clear(); - if (s->DoesIntersect(ray, ts, mStats)) { - if (ts[0] < nearest_t) { - intersected_shape = s; - nearest_t = ts[0]; + if (obj->Intersect(ray, ts, mStats)) { + if (ts[0] < nearestT) { + intersectedObj = obj; + nearestT = ts[0]; } } } // If there was no intersection, return black. - if (!intersected_shape) { - return out_color; + if (!intersectedObj) { + return outColor; } - Material& shape_material = intersected_shape->GetMaterial(); - const Color& shape_color = shape_material.GetDiffuseColor(); + Material& material = intersectedObj->GetMaterial(); + const Color& shapeColor = material.GetDiffuseColor(); - Vector3 intersection = ray.parameterize(nearest_t); - Vector3 normal = intersected_shape->compute_normal(intersection); + Vector4 intersection = ray.Parameterize(nearestT); + Vector4 normal = intersectedObj->Normal(intersection); /* * Diffuse lighting. (Shading, etc.) */ - Vector3 light_direction; - Double ldotn, diffuse_level, ambient_level; + Vector4 lightDirection; + Double ldotn, diffuseLevel, ambientLevel; Ray shadowRay; - for (PointLight *l : lights) { - light_direction = (l->GetOrigin() - intersection).normalize(); - ldotn = light_direction.dot(normal); + for (PointLight *l : mLights) { + lightDirection = (l->GetOrigin() - intersection).normalize(); + ldotn = lightDirection.Dot(normal); /* * TODO: What is this even for? Removing it makes the darker showers @@ -270,12 +295,12 @@ Scene::trace_ray(const Ray &ray, ldotn = 0.0; } - diffuse_level = shape_material.GetDiffuseIntensity(); - ambient_level = 1.0 - diffuse_level; + diffuseLevel = material.GetDiffuseIntensity(); + ambientLevel = 1.0 - diffuseLevel; - shadowRay = Ray(intersection, light_direction); - for (Object::Ptr s : shapes) { - if (s == intersected_shape) { + shadowRay = Ray(intersection, lightDirection); + for (Object::Ptr obj : mObjects) { + if (obj == intersectedObj) { /* Skip the intersected shape. */ continue; } @@ -284,8 +309,8 @@ Scene::trace_ray(const Ray &ray, /* Figure out if we're in shadow. */ ts.clear(); - if (s->DoesIntersect(shadowRay, ts, mStats)) { - diffuse_level = 0.0; + if (obj->Intersect(shadowRay, ts, mStats)) { + diffuseLevel = 0.0; break; } } @@ -293,8 +318,8 @@ Scene::trace_ray(const Ray &ray, /* * Compute basic Lambert diffuse shading for this object. */ - out_color += shape_color * ( ambient_level * ambient->compute_color_contribution() - + diffuse_level * ldotn); + outColor += shapeColor * ( ambientLevel * mAmbient.compute_color_contribution() + + diffuseLevel * ldotn); } /* @@ -328,10 +353,13 @@ Scene::trace_ray(const Ray &ray, out_color += specular_level * specular_color * reflection_color; #endif - return out_color; + return outColor; } +/* + * charles::Scene::LogCamera -- + */ void Scene::LogCamera() const @@ -341,7 +369,7 @@ Scene::LogCamera() LOG_DEBUG << "BEGIN CAMERA"; LOG_DEBUG << " type = " << c.GetTypeString(); LOG_DEBUG << " origin = " << c.GetOrigin(); - LOG_DEBUG << " direction = " << c.get_direction(); + LOG_DEBUG << " direction = " << c.GetDirection(); LOG_DEBUG << " right = " << c.GetRight(); LOG_DEBUG << " up = " << c.GetUp(); LOG_DEBUG << " coordinate system is " @@ -350,15 +378,20 @@ Scene::LogCamera() } +/* + * charles::Scene::LogObjects -- + */ void Scene::LogObjects() const { LOG_DEBUG << "BEGIN SCENE OBJECTS"; - for (Object::Ptr obj : shapes) { + for (Object::Ptr obj : mObjects) { LOG_DEBUG << " " << *obj; } LOG_DEBUG << "END SCENE OBJECTS"; } + +} /* namespace charles */ diff --git a/src/scene.h b/src/scene.h deleted file mode 100644 index d8a86ad..0000000 --- a/src/scene.h +++ /dev/null @@ -1,84 +0,0 @@ -/* scene.h - * - * Definition of the Scene class. - * - * Scenes are the top level object in charles. Scenes contain objects, lights, a camera, - * etc. and can be rendered to pixel data and written to a file. - * - * Eryn Wells - */ - -#ifndef __SCENE_H__ -#define __SCENE_H__ - -#include -#include -#include "basics.h" -#include "camera.h" -#include "object.h" -#include "stats.hh" - - -class AmbientLight; -class PointLight; -class Writer; - - -class Scene -{ -public: - Scene(); - ~Scene(); - - bool is_rendered() const; - - int get_width() const; - void set_width(int w) { width = w; } - int get_height() const; - void set_height(int h) { height = h; } - - Camera::Ptr GetCamera() const; - void SetCamera(Camera* camera); - - AmbientLight &get_ambient() const; - const Color *get_pixels() const; - - void read(const std::string &filename); - void write(Writer &writer, const std::string &filename); - void render(); - - void add_shape(charles::Object::Ptr obj); - void add_light(PointLight *light); - -private: - Color trace_ray(const Ray &ray, const int depth = 0, const float weight = 1.0); - - void LogCamera() const; - void LogObjects() const; - - // Pixel dimensions of the image. - int width, height; - - Camera::Ptr mCamera; - - /* - * Ray tracing parameters. max_depth indicates the maximum depth of the ray tree. min_weight indicates the minimum - * specular weight to apply before giving up. - */ - int max_depth; - float min_weight; - - // Scene objects. - AmbientLight *ambient; - std::list shapes; - std::list lights; - - // Rendering stats - charles::Stats mStats; - - // Rendering output. - bool _is_rendered; - Color *pixels; -}; - -#endif diff --git a/src/scene.hh b/src/scene.hh new file mode 100644 index 0000000..53b594c --- /dev/null +++ b/src/scene.hh @@ -0,0 +1,86 @@ +/* scene.h + * vim: tw=80: + * Eryn Wells + */ + +#ifndef __SCENE_H__ +#define __SCENE_H__ + +#include +#include + +#include "camera.hh" +#include "light.h" +#include "object.hh" +#include "stats.hh" +#include "basics/basics.hh" + + +class Writer; + + +namespace charles { + +/** + * Scenes are the top level object in charles. Scenes contain objects, lights, a + * camera, etc. and can be rendered to pixel data and written to a file. + */ +struct Scene +{ + Scene(); + ~Scene(); + + UInt GetWidth() const; + void SetWidth(UInt w); + UInt GetHeight() const; + void SetHeight(UInt h); + + Camera::Ptr GetCamera() const; + void SetCamera(Camera::Ptr camera); + + void Write(Writer& writer, const std::string& filename); + + void Render(); + bool IsRendered() const; + const Color* GetPixels() const; + + AmbientLight& GetAmbient(); + void AddObject(Object::Ptr obj); + void AddLight(PointLight* light); + +private: + Color TraceRay(const basics::Ray &ray, + const int depth = 0, + const Double weight = 1.0); + + void LogCamera() const; + void LogObjects() const; + + /** Pixel width */ + UInt mWidth; + /** Pixel height */ + UInt mHeight; + + Camera::Ptr mCamera; + + /** Maximum depth of the ray tree */ + int mMaxDepth; + /** Minimum specular weight to apply before giving up */ + float mMinWeight; + + // Scene objects. + AmbientLight mAmbient; + std::list mObjects; + std::list mLights; + + // Rendering stats + charles::Stats mStats; + + // Rendering output. + bool mIsRendered; + Color *mPixels; +}; + +} /* namespace charles */ + +#endif