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',
|
||||
'reader_yaml.cc',
|
||||
'scene.cc',
|
||||
'stats.cc',
|
||||
'writer_png.cc',
|
||||
]
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
41
src/scene.cc
41
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);
|
||||
}
|
||||
|
|
18
src/scene.h
18
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<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
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