diff --git a/smallpt.cpp b/smallpt.cpp
index cd78b4c..fdc9e21 100644
--- a/smallpt.cpp
+++ b/smallpt.cpp
@@ -115,55 +115,74 @@ struct Sphere {
}
};
-//Scene: radius, position, emission, color, material
-Sphere g_spheres[] = {
- Sphere(1e5, // Left
- Vec(1e5 + 1, 40.8, 81.6),
- Vec(),
- Vec(1, 1, 1) * 0.8,
- SPECULAR),
- Sphere(1e5, // Right
- Vec(-1e5 + 99, 40.8, 81.6),
- Vec(),
- Vec(1, 1, 1) * 0.8,
- SPECULAR),
- Sphere(1e5, // Back
- Vec(50, 40.8, 1e5),
- Vec(),
- Vec(1, 1, 1) * 0.8,
- SPECULAR),
- Sphere(1e5, // Front
- Vec(50, 40.8, -1e5 + 170),
- Vec(),
- Vec(1, 1, 1) * 0.8,
- SPECULAR),
- Sphere(1e5, // Bottom
- Vec(50, 1e5, 81.6),
- Vec(),
- Vec(1, 1, 1) * 0.999,
- SPECULAR),
- Sphere(1e5, // Top
- Vec(50, -1e5 + 81.6, 81.6),
- Vec(),
- Vec(1, 1, 1) * 0.5,
- DIFFUSE),
- Sphere(16.5, // Mirror ball
- Vec(27, 16.5, 47),
- Vec(),
- Vec(1, 1, 1) * 0.999,
- SPECULAR),
- Sphere(16.5, // Glass
- Vec(73, 16.5, 78),
- Vec(),
- Vec(1, 1, 1) * 0.999,
- REFRACTION),
- Sphere(600, // Light
- Vec(50, 681.6 - 0.27, 81.6),
- Vec(12, 12, 12),
- Vec(),
- DIFFUSE)
+#define SPHERES_COUNT 9
+#define SPHERES_ROT_RADIUS 20.0
+#define SPHERES_ROT_SPEED 0.25
+
+struct Scene {
+ Sphere spheres[SPHERES_COUNT] = {
+ Sphere(16.5, // Mirror ball
+ Vec(50.0, 16.5, 50.0),
+ Vec(),
+ Vec(1, 1, 1) * 0.999,
+ SPECULAR),
+ Sphere(16.5, // Glass
+ Vec(50, 16.5, 50.0),
+ Vec(),
+ Vec(1, 1, 1) * 0.999,
+ REFRACTION),
+ Sphere(1e5, // Left
+ Vec(1e5 + 1, 40.8, 81.6),
+ Vec(),
+ Vec(1, 1, 1) * 0.7,
+ SPECULAR),
+ Sphere(1e5, // Right
+ Vec(-1e5 + 99, 40.8, 81.6),
+ Vec(),
+ Vec(1, 1, 1) * 0.7,
+ SPECULAR),
+ Sphere(1e5, // Back
+ Vec(50, 40.8, 1e5),
+ Vec(),
+ Vec(1, 1, 1) * 0.7,
+ SPECULAR),
+ Sphere(1e5, // Front
+ Vec(50, 40.8, -1e5 + 170),
+ Vec(),
+ Vec(1, 1, 1) * 0.7,
+ SPECULAR),
+ Sphere(1e5, // Bottom
+ Vec(50, 1e5, 81.6),
+ Vec(),
+ Vec(1, 0.9, 0.7) * 0.9,
+ SPECULAR),
+ Sphere(1e5, // Top
+ Vec(50, -1e5 + 81.6, 81.6),
+ Vec(),
+ Vec(1, 0.9, 0.9) * 0.8,
+ DIFFUSE),
+ Sphere(600, // Light
+ Vec(50, 681.6 - 0.27, 81.6),
+ Vec(12, 12, 12),
+ Vec(),
+ DIFFUSE)
+ };
+
+ void update_time (F time)
+ {
+ F theta = time * SPHERES_ROT_SPEED * M_PI * 2.0;
+ spheres[0].position = Vec(50.0, 16.5, 50.0) +
+ Vec(cos(theta) * SPHERES_ROT_RADIUS, 0.0,
+ sin(theta) * SPHERES_ROT_RADIUS);
+ theta += M_PI;
+ spheres[1].position = Vec(50.0, 16.5, 50.0) +
+ Vec(cos(theta) * SPHERES_ROT_RADIUS, 0.0,
+ sin(theta) * SPHERES_ROT_RADIUS);
+ }
};
+Scene g_scene;
+
inline F clamp (F x)
{
return x < 0 ? 0 : x > 1 ? 1 : x;
@@ -176,12 +195,12 @@ inline int toInt (F x)
inline bool intersect (const Ray &r, F &t, int &id)
{
- int i = sizeof(g_spheres) / sizeof(Sphere);
+ int i = SPHERES_COUNT;
F d;
F inf = 1e20;
t = inf;
while (i--) {
- if ((d = g_spheres[i].intersect(r)) && d < t) {
+ if ((d = g_scene.spheres[i].intersect(r)) && d < t) {
t = d;
id = i;
}
@@ -195,7 +214,7 @@ Vec radiance (const Ray &r, int depth, unsigned short *Xi)
int id = 0; // Id of intersected object
if (! intersect(r, t, id)) // If miss, return black
return Vec();
- const Sphere &obj = g_spheres[id]; // The hit object
+ const Sphere &obj = g_scene.spheres[id]; // The hit object
Vec x = r.origin + r.direction * t;
Vec n = (x - obj.position).normalize();
Vec nl = n.dot(r.direction) < 0 ? n : n * -1;
@@ -260,14 +279,16 @@ Vec radiance (const Ray &r, int depth, unsigned short *Xi)
int main (int argc, char *argv[])
{
- int w = 1024;
- int h = 768;
- int samples = argc == 2 ? atoi(argv[1]) / 4 : 1;
+ int w = 800;
+ int h = 600;
+ int samples = argc >= 2 ? atoi(argv[1]) / 4 : 1;
+ F time = argc >= 3 ? atof(argv[2]) : 0.0;
Ray camera(Vec(50,52,295.6), Vec(0,-0.042612,-1).normalize());
Vec cx = Vec(w * .5135 / h);
Vec cy = (cx % camera.direction).normalize() * .5135;
Vec r;
Vec *c = new Vec[w * h];
+ g_scene.update_time(time);
#pragma omp parallel for schedule(dynamic, 1) private(r) // OpenMP
for (int y = 0; y < h; y++) { // Loop over image rows
fprintf(stderr, "\rRendering (%d spp) %5.2f%%",
@@ -299,9 +320,13 @@ int main (int argc, char *argv[])
}
}
}
- FILE *f = fopen("image.ppm", "w"); // Write image to PPM file.
+ char a[1024] = {0};
+ snprintf(a, sizeof(a) - 1, "image_%09.9f.ppm", time);
+ FILE *f = fopen(a, "wb");
fprintf(f, "P3\n%d %d\n%d\n", w, h, 255);
for (int i = 0; i < w * h; i++)
fprintf(f, "%d %d %d ", toInt(c[i].x), toInt(c[i].y),
toInt(c[i].z));
+ delete[] c;
+ delete g_scene;
}