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.
This commit is contained in:
Eryn Wells 2014-08-02 15:21:14 -07:00
parent b60e27824b
commit 79c951030d
12 changed files with 166 additions and 62 deletions

View file

@ -28,6 +28,7 @@ files = [
'objectPlane.cc',
'reader_yaml.cc',
'scene.cc',
'stats.cc',
'writer_png.cc',
]

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -60,7 +60,8 @@ Plane::SetDistance(Double distance)
*/
bool
Plane::DoesIntersect(const Ray &ray,
TVector& t)
TVector& t,
Stats& stats)
const
{
/*
@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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:

View file

@ -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);
}

View file

@ -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<PointLight *> 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;

92
src/stats.cc Normal file
View file

@ -0,0 +1,92 @@
/* stats.cc
* vim: set tw=80:
* Eryn Wells <eryn@erynwells.me>
*/
#include <cstdio>
#include <string>
#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 */

44
src/stats.hh Normal file
View file

@ -0,0 +1,44 @@
/* stats.hh
* vim: set tw=80:
* Eryn Wells <eryn@erynwells.me>
*/
#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__ */