From 79c951030d4845c1c0f5f334b7aba727e1297c6d Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 2 Aug 2014 15:21:14 -0700 Subject: [PATCH] Move Stats to its own module Move Stats to its own module and pass it around to the intersection methods to keep track of how many tests and successful intersections there are. --- src/SConscript | 1 + src/object.h | 3 +- src/objectBox.cc | 7 +++- src/objectBox.hh | 2 +- src/objectPlane.cc | 10 +++-- src/objectPlane.hh | 2 +- src/object_sphere.cc | 6 ++- src/object_sphere.h | 2 +- src/scene.cc | 41 ++------------------ src/scene.h | 18 +-------- src/stats.cc | 92 ++++++++++++++++++++++++++++++++++++++++++++ src/stats.hh | 44 +++++++++++++++++++++ 12 files changed, 166 insertions(+), 62 deletions(-) create mode 100644 src/stats.cc create mode 100644 src/stats.hh diff --git a/src/SConscript b/src/SConscript index e9fae8e..517ae22 100644 --- a/src/SConscript +++ b/src/SConscript @@ -28,6 +28,7 @@ files = [ 'objectPlane.cc', 'reader_yaml.cc', 'scene.cc', + 'stats.cc', 'writer_png.cc', ] diff --git a/src/object.h b/src/object.h index 67706ca..c621fc1 100644 --- a/src/object.h +++ b/src/object.h @@ -15,6 +15,7 @@ #include "basics.h" #include "material.h" +#include "stats.hh" #include "texture.h" #include "types.hh" @@ -42,7 +43,7 @@ struct Object * @param [out] t A vector of all intersection t values * @return `true` if the ray intersects with this object */ - virtual bool DoesIntersect(const Ray& ray, TVector& t) const = 0; + virtual bool DoesIntersect(const Ray& ray, TVector& t, Stats& stats) const = 0; virtual bool point_is_on_surface(const Vector3 &p) const = 0; virtual Vector3 compute_normal(const Vector3 &p) const = 0; diff --git a/src/objectBox.cc b/src/objectBox.cc index b2af53d..e467e4e 100644 --- a/src/objectBox.cc +++ b/src/objectBox.cc @@ -53,9 +53,12 @@ Box::SetFar(const Vector3& far) bool Box::DoesIntersect(const Ray& ray, - TVector& t) + TVector& t, + Stats& stats) const { + stats.boxIntersectionTests++; + /* * XXX: For now, I'm assuming that all boxes are parallel to the coordinate * axes. This is the Kay-Kajiya box intersection algorithm. @@ -174,8 +177,10 @@ Box::DoesIntersect(const Ray& ray, } /* We have an intersection! */ + stats.boxIntersections++; t.push_back(tNear); t.push_back(tFar); + return true; } diff --git a/src/objectBox.hh b/src/objectBox.hh index b0dd746..714b2fe 100644 --- a/src/objectBox.hh +++ b/src/objectBox.hh @@ -21,7 +21,7 @@ struct Box Vector3& GetFar(); void SetFar(const Vector3& far); - bool DoesIntersect(const Ray& ray, TVector& t) const; + bool DoesIntersect(const Ray& ray, TVector& t, Stats& stats) const; bool point_is_on_surface(const Vector3 &p) const; Vector3 compute_normal(const Vector3 &p) const; diff --git a/src/objectPlane.cc b/src/objectPlane.cc index 8c022e7..d80d813 100644 --- a/src/objectPlane.cc +++ b/src/objectPlane.cc @@ -60,7 +60,8 @@ Plane::SetDistance(Double distance) */ bool Plane::DoesIntersect(const Ray &ray, - TVector& t) + TVector& t, + Stats& stats) const { /* @@ -70,7 +71,7 @@ Plane::DoesIntersect(const Ray &ray, * * A * x + B * y + C * z + D = 0, where * A^2 + B^2 + C^2 = 1. - * + * * The sign of D determines which side of the origin the plane is on. * * We can figure out the distance from the ray's origin to the intersection @@ -80,7 +81,7 @@ Plane::DoesIntersect(const Ray &ray, * indicated with lowercase letters (ROx is the x component of RO). * * A(ROx + RDx * t) + B(ROy + RDy * t) + C(ROz + RDz * t) + D = 0 - * + * * We then solve for t. * * t = -(A * ROx + B * ROy + C * ROz + D) / (A * RDx + B * RDy + C * RDz) @@ -90,6 +91,8 @@ Plane::DoesIntersect(const Ray &ray, * t = -(n . RO + D) / (n . RD) */ + stats.planeIntersectionTests++; + /* The denominator for the t equation above. */ Double vd = mNormal.dot(ray.direction); if (NearZero(vd)) { @@ -110,6 +113,7 @@ Plane::DoesIntersect(const Ray &ray, return false; } + stats.planeIntersections++; t.push_back(t0); return true; } diff --git a/src/objectPlane.hh b/src/objectPlane.hh index 612798f..f3463f8 100644 --- a/src/objectPlane.hh +++ b/src/objectPlane.hh @@ -30,7 +30,7 @@ public: /** * @see charles::Object::DoesIntersect */ - bool DoesIntersect(const Ray &ray, TVector& t) const; + bool DoesIntersect(const Ray &ray, TVector& t, Stats& stats) const; bool point_is_on_surface(const Vector3 &p) const; Vector3 compute_normal(const Vector3 &p) const; diff --git a/src/object_sphere.cc b/src/object_sphere.cc index 6505921..4e83a4a 100644 --- a/src/object_sphere.cc +++ b/src/object_sphere.cc @@ -66,9 +66,12 @@ Sphere::set_radius(float r) */ bool Sphere::DoesIntersect(const Ray& ray, - TVector& t) + TVector& t, + Stats& stats) const { + stats.sphereIntersectionTests++; + /* Origin of the vector in object space. */ Vector3 rayOriginObj = ray.origin - GetOrigin(); @@ -119,6 +122,7 @@ Sphere::DoesIntersect(const Ray& ray, } } + stats.sphereIntersections++; return true; } diff --git a/src/object_sphere.h b/src/object_sphere.h index d703504..8a69552 100644 --- a/src/object_sphere.h +++ b/src/object_sphere.h @@ -26,7 +26,7 @@ public: float get_radius(); void set_radius(float r); - bool DoesIntersect(const Ray& ray, TVector& t) const; + bool DoesIntersect(const Ray& ray, TVector& t, Stats& stats) const; bool point_is_on_surface(const Vector3 &p) const; Vector3 compute_normal(const Vector3 &p) const; private: diff --git a/src/scene.cc b/src/scene.cc index 5f90c54..2b1046b 100644 --- a/src/scene.cc +++ b/src/scene.cc @@ -174,6 +174,8 @@ Scene::render() printf("Rendering completed in %f seconds.\n\n", seconds.count()); LOG_INFO << "Rendering completed in " << seconds.count() << " seconds."; mStats.PrintRayTable(); + printf("\n"); + mStats.PrintIntersectionsTable(); } @@ -225,7 +227,7 @@ Scene::trace_ray(const Ray &ray, // Find intersections of this ray with objects in the scene. for (Object::Ptr s : shapes) { ts.clear(); - if (s->DoesIntersect(ray, ts)) { + if (s->DoesIntersect(ray, ts, mStats)) { for (Double t : ts) { if (t < 1e-2) { break; @@ -279,7 +281,7 @@ Scene::trace_ray(const Ray &ray, /* Figure out if we're in shadow. */ ts.clear(); - if (s->DoesIntersect(shadowRay, ts)) { + if (s->DoesIntersect(shadowRay, ts, mStats)) { diffuse_level = 0.0; break; } @@ -323,38 +325,3 @@ Scene::trace_ray(const Ray &ray, return out_color; } - - -unsigned long -Scene::Stats::TotalRays() - const -{ - return primaryRays + shadowRays + reflectionRays + transmissionRays; -} - - -void -Scene::Stats::PrintRayTable() - const -{ - printf("RAY TYPE NUM %%\n"); - printf("-------------- ---------- ------\n"); - PrintRayRow("primary", primaryRays); - PrintRayRow("shadow", shadowRays); - PrintRayRow("reflection", reflectionRays); - PrintRayRow("transmission", transmissionRays); - PrintRayRow("total", TotalRays()); -} - - -void -Scene::Stats::PrintRayRow(const std::string& title, - const unsigned long& value) - const -{ - double totalRays = TotalRays(); - printf("%-14s %10ld %#5.1lf%%\n", - title.c_str(), - value, - double(value) / totalRays * 100.0); -} diff --git a/src/scene.h b/src/scene.h index bbdeffe..93ae813 100644 --- a/src/scene.h +++ b/src/scene.h @@ -16,6 +16,7 @@ #include "basics.h" #include "camera.h" #include "object.h" +#include "stats.hh" class AmbientLight; @@ -70,22 +71,7 @@ private: std::list lights; // Rendering stats - struct Stats - { - unsigned long TotalRays() const; - - void PrintRayTable() const; - - /* Ray counts */ - unsigned long primaryRays; - unsigned long shadowRays; - unsigned long reflectionRays; - unsigned long transmissionRays; - - private: - void PrintRayRow(const std::string& title, - const unsigned long& value) const; - } mStats; + charles::Stats mStats; // Rendering output. bool _is_rendered; diff --git a/src/stats.cc b/src/stats.cc new file mode 100644 index 0000000..345e5c1 --- /dev/null +++ b/src/stats.cc @@ -0,0 +1,92 @@ +/* stats.cc + * vim: set tw=80: + * Eryn Wells + */ + +#include +#include + +#include "stats.hh" + + +namespace charles{ + +Stats::Stats() + : primaryRays(), + shadowRays(), + reflectionRays(), + transmissionRays(), + boxIntersections(), + boxIntersectionTests(), + planeIntersections(), + planeIntersectionTests(), + sphereIntersections(), + sphereIntersectionTests() +{ } + + +unsigned long +Stats::TotalRays() + const +{ + return primaryRays + shadowRays + reflectionRays + transmissionRays; +} + + +void +Stats::PrintRayTable() + const +{ + printf("RAY TYPE NUM %%\n"); + printf("-------------- ---------- ------\n"); + PrintRayRow("primary", primaryRays); + PrintRayRow("shadow", shadowRays); + PrintRayRow("reflection", reflectionRays); + PrintRayRow("transmission", transmissionRays); + PrintRayRow("total", TotalRays()); +} + + +void +Stats::PrintIntersectionsTable() + const +{ + printf("SHAPE INTS TESTS SUCC %%\n"); + printf("-------------- ---------- ---------- -------\n"); + if (boxIntersectionTests > 0) { + PrintIntersectionsRow("boxes", boxIntersections, boxIntersectionTests); + } + if (planeIntersectionTests > 0) { + PrintIntersectionsRow("planes", planeIntersections, planeIntersectionTests); + } + if (sphereIntersectionTests > 0) { + PrintIntersectionsRow("spheres", sphereIntersections, sphereIntersectionTests); + } +} + + +void +Stats::PrintRayRow(const std::string& title, + const unsigned long& value) + const +{ + double totalRays = TotalRays(); + printf("%-14s %10ld %#6.1lf%%\n", + title.c_str(), + value, + double(value) / totalRays * 100.0); +} + + +void +Stats::PrintIntersectionsRow(const std::string& title, + const unsigned long& num, + const unsigned long& total) + const +{ + printf("%-14s %10ld %10ld %#5.1lf%%\n", + title.c_str(), + num, total, double(num) / double(total) * 100.0); +} + +} /* namespace charles */ diff --git a/src/stats.hh b/src/stats.hh new file mode 100644 index 0000000..0f535ca --- /dev/null +++ b/src/stats.hh @@ -0,0 +1,44 @@ +/* stats.hh + * vim: set tw=80: + * Eryn Wells + */ + +#ifndef __STATS_HH__ +#define __STATS_HH__ + +namespace charles { + +struct Stats +{ + Stats(); + + unsigned long TotalRays() const; + + void PrintRayTable() const; + void PrintIntersectionsTable() const; + + /* Ray counts */ + unsigned long primaryRays; + unsigned long shadowRays; + unsigned long reflectionRays; + unsigned long transmissionRays; + + /* Intersection counts */ + unsigned long boxIntersections; + unsigned long boxIntersectionTests; + unsigned long planeIntersections; + unsigned long planeIntersectionTests; + unsigned long sphereIntersections; + unsigned long sphereIntersectionTests; + +private: + void PrintRayRow(const std::string& title, + const unsigned long& value) const; + void PrintIntersectionsRow(const std::string& title, + const unsigned long& num, + const unsigned long& total) const; +}; + +} /* namespace charles */ + +#endif /* __STATS_HH__ */