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:
parent
b60e27824b
commit
79c951030d
12 changed files with 166 additions and 62 deletions
|
@ -28,6 +28,7 @@ files = [
|
||||||
'objectPlane.cc',
|
'objectPlane.cc',
|
||||||
'reader_yaml.cc',
|
'reader_yaml.cc',
|
||||||
'scene.cc',
|
'scene.cc',
|
||||||
|
'stats.cc',
|
||||||
'writer_png.cc',
|
'writer_png.cc',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include "basics.h"
|
#include "basics.h"
|
||||||
#include "material.h"
|
#include "material.h"
|
||||||
|
#include "stats.hh"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ struct Object
|
||||||
* @param [out] t A vector of all intersection t values
|
* @param [out] t A vector of all intersection t values
|
||||||
* @return `true` if the ray intersects with this object
|
* @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 bool point_is_on_surface(const Vector3 &p) const = 0;
|
||||||
virtual Vector3 compute_normal(const Vector3 &p) const = 0;
|
virtual Vector3 compute_normal(const Vector3 &p) const = 0;
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,12 @@ Box::SetFar(const Vector3& far)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Box::DoesIntersect(const Ray& ray,
|
Box::DoesIntersect(const Ray& ray,
|
||||||
TVector& t)
|
TVector& t,
|
||||||
|
Stats& stats)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
|
stats.boxIntersectionTests++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX: For now, I'm assuming that all boxes are parallel to the coordinate
|
* XXX: For now, I'm assuming that all boxes are parallel to the coordinate
|
||||||
* axes. This is the Kay-Kajiya box intersection algorithm.
|
* axes. This is the Kay-Kajiya box intersection algorithm.
|
||||||
|
@ -174,8 +177,10 @@ Box::DoesIntersect(const Ray& ray,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have an intersection! */
|
/* We have an intersection! */
|
||||||
|
stats.boxIntersections++;
|
||||||
t.push_back(tNear);
|
t.push_back(tNear);
|
||||||
t.push_back(tFar);
|
t.push_back(tFar);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ struct Box
|
||||||
Vector3& GetFar();
|
Vector3& GetFar();
|
||||||
void SetFar(const Vector3& far);
|
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;
|
bool point_is_on_surface(const Vector3 &p) const;
|
||||||
Vector3 compute_normal(const Vector3 &p) const;
|
Vector3 compute_normal(const Vector3 &p) const;
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,8 @@ Plane::SetDistance(Double distance)
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
Plane::DoesIntersect(const Ray &ray,
|
Plane::DoesIntersect(const Ray &ray,
|
||||||
TVector& t)
|
TVector& t,
|
||||||
|
Stats& stats)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -90,6 +91,8 @@ Plane::DoesIntersect(const Ray &ray,
|
||||||
* t = -(n . RO + D) / (n . RD)
|
* t = -(n . RO + D) / (n . RD)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
stats.planeIntersectionTests++;
|
||||||
|
|
||||||
/* The denominator for the t equation above. */
|
/* The denominator for the t equation above. */
|
||||||
Double vd = mNormal.dot(ray.direction);
|
Double vd = mNormal.dot(ray.direction);
|
||||||
if (NearZero(vd)) {
|
if (NearZero(vd)) {
|
||||||
|
@ -110,6 +113,7 @@ Plane::DoesIntersect(const Ray &ray,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stats.planeIntersections++;
|
||||||
t.push_back(t0);
|
t.push_back(t0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* @see charles::Object::DoesIntersect
|
* @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;
|
bool point_is_on_surface(const Vector3 &p) const;
|
||||||
Vector3 compute_normal(const Vector3 &p) const;
|
Vector3 compute_normal(const Vector3 &p) const;
|
||||||
|
|
||||||
|
|
|
@ -66,9 +66,12 @@ Sphere::set_radius(float r)
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
Sphere::DoesIntersect(const Ray& ray,
|
Sphere::DoesIntersect(const Ray& ray,
|
||||||
TVector& t)
|
TVector& t,
|
||||||
|
Stats& stats)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
|
stats.sphereIntersectionTests++;
|
||||||
|
|
||||||
/* Origin of the vector in object space. */
|
/* Origin of the vector in object space. */
|
||||||
Vector3 rayOriginObj = ray.origin - GetOrigin();
|
Vector3 rayOriginObj = ray.origin - GetOrigin();
|
||||||
|
|
||||||
|
@ -119,6 +122,7 @@ Sphere::DoesIntersect(const Ray& ray,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stats.sphereIntersections++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
float get_radius();
|
float get_radius();
|
||||||
void set_radius(float r);
|
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;
|
bool point_is_on_surface(const Vector3 &p) const;
|
||||||
Vector3 compute_normal(const Vector3 &p) const;
|
Vector3 compute_normal(const Vector3 &p) const;
|
||||||
private:
|
private:
|
||||||
|
|
41
src/scene.cc
41
src/scene.cc
|
@ -174,6 +174,8 @@ Scene::render()
|
||||||
printf("Rendering completed in %f seconds.\n\n", seconds.count());
|
printf("Rendering completed in %f seconds.\n\n", seconds.count());
|
||||||
LOG_INFO << "Rendering completed in " << seconds.count() << " seconds.";
|
LOG_INFO << "Rendering completed in " << seconds.count() << " seconds.";
|
||||||
mStats.PrintRayTable();
|
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.
|
// Find intersections of this ray with objects in the scene.
|
||||||
for (Object::Ptr s : shapes) {
|
for (Object::Ptr s : shapes) {
|
||||||
ts.clear();
|
ts.clear();
|
||||||
if (s->DoesIntersect(ray, ts)) {
|
if (s->DoesIntersect(ray, ts, mStats)) {
|
||||||
for (Double t : ts) {
|
for (Double t : ts) {
|
||||||
if (t < 1e-2) {
|
if (t < 1e-2) {
|
||||||
break;
|
break;
|
||||||
|
@ -279,7 +281,7 @@ Scene::trace_ray(const Ray &ray,
|
||||||
|
|
||||||
/* Figure out if we're in shadow. */
|
/* Figure out if we're in shadow. */
|
||||||
ts.clear();
|
ts.clear();
|
||||||
if (s->DoesIntersect(shadowRay, ts)) {
|
if (s->DoesIntersect(shadowRay, ts, mStats)) {
|
||||||
diffuse_level = 0.0;
|
diffuse_level = 0.0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -323,38 +325,3 @@ Scene::trace_ray(const Ray &ray,
|
||||||
|
|
||||||
return out_color;
|
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);
|
|
||||||
}
|
|
||||||
|
|
18
src/scene.h
18
src/scene.h
|
@ -16,6 +16,7 @@
|
||||||
#include "basics.h"
|
#include "basics.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
#include "stats.hh"
|
||||||
|
|
||||||
|
|
||||||
class AmbientLight;
|
class AmbientLight;
|
||||||
|
@ -70,22 +71,7 @@ private:
|
||||||
std::list<PointLight *> lights;
|
std::list<PointLight *> lights;
|
||||||
|
|
||||||
// Rendering stats
|
// Rendering stats
|
||||||
struct Stats
|
charles::Stats mStats;
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
// Rendering output.
|
// Rendering output.
|
||||||
bool _is_rendered;
|
bool _is_rendered;
|
||||||
|
|
92
src/stats.cc
Normal file
92
src/stats.cc
Normal 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
44
src/stats.hh
Normal 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__ */
|
Loading…
Add table
Add a link
Reference in a new issue