Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the sphere class to allow movement #1128

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ set ( SOURCE_NEXT_WEEK
src/TheNextWeek/hittable.h
src/TheNextWeek/hittable_list.h
src/TheNextWeek/material.h
src/TheNextWeek/moving_sphere.h
src/TheNextWeek/quad.h
src/TheNextWeek/scene.h
src/TheNextWeek/sphere.h
Expand Down
8 changes: 3 additions & 5 deletions src/TheNextWeek/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "constant_medium.h"
#include "hittable_list.h"
#include "material.h"
#include "moving_sphere.h"
#include "quad.h"
#include "scene.h"
#include "sphere.h"
Expand Down Expand Up @@ -54,8 +53,7 @@ void random_spheres(scene& scene_desc) {
auto albedo = color::random() * color::random();
sphere_material = make_shared<lambertian>(albedo);
auto center2 = center + vec3(0, random_double(0,.5), 0);
world.add(make_shared<moving_sphere>(
center, center2, 0.2, sphere_material));
world.add(make_shared<sphere>(center, center2, 0.2, sphere_material));
} else if (choose_mat < 0.95) {
// metal
auto albedo = color::random(0.5, 1);
Expand Down Expand Up @@ -303,8 +301,8 @@ void final_scene(scene& scene_desc) {

auto center1 = point3(400, 400, 200);
auto center2 = center1 + vec3(30,0,0);
auto moving_sphere_material = make_shared<lambertian>(color(0.7, 0.3, 0.1));
world.add(make_shared<moving_sphere>(center1, center2, 50, moving_sphere_material));
auto sphere_material = make_shared<lambertian>(color(0.7, 0.3, 0.1));
world.add(make_shared<sphere>(center1, center2, 50, sphere_material));

world.add(make_shared<sphere>(point3(260, 150, 45), 50, make_shared<dielectric>(1.5)));
world.add(make_shared<sphere>(
Expand Down
75 changes: 0 additions & 75 deletions src/TheNextWeek/moving_sphere.h

This file was deleted.

33 changes: 28 additions & 5 deletions src/TheNextWeek/sphere.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,28 @@ class sphere : public hittable {
public:
sphere() {}

sphere(point3 ctr, double r, shared_ptr<material> m) : center(ctr), radius(r), mat(m) {
// Static Sphere
sphere(point3 _center, double _radius, shared_ptr<material> _material)
: center1(_center), radius(_radius), mat(_material), is_moving(false)
{
const auto rvec = vec3(radius, radius, radius);
bbox = aabb(center - rvec, center + rvec);
bbox = aabb(center1 - rvec, center1 + rvec);
}

// Moving Sphere
sphere(point3 _center1, point3 _center2, double _radius, shared_ptr<material> _material)
: center1(_center1), radius(_radius), mat(_material), is_moving(true)
{
const auto rvec = vec3(radius, radius, radius);
const aabb box0(_center1 - rvec, _center1 + rvec);
const aabb box1(_center2 - rvec, _center2 + rvec);
bbox = aabb(box0, box1);

center_vec = _center2 - _center1;
}

bool hit(const ray& r, interval ray_t, hit_record& rec) const override {
point3 center = is_moving ? sphere_center(r.time()) : center1;
vec3 oc = r.origin() - center;
auto a = r.direction().length_squared();
auto half_b = dot(oc, r.direction());
Expand Down Expand Up @@ -55,13 +71,20 @@ class sphere : public hittable {

aabb bounding_box() const override { return bbox; }

public:
point3 center;
private:
point3 center1;
double radius;
shared_ptr<material> mat;
bool is_moving;
vec3 center_vec;
aabb bbox;

private:
point3 sphere_center(double time) const {
// Linearly interpolate from center1 to center2 according to time, where t=0 yields
// center1, and t=1 yields center2.
return center1 + time * center_vec;
}

static void get_sphere_uv(const point3& p, double& u, double& v) {
// p: a given point on the sphere of radius one, centered at the origin.
// u: returned value [0,1] of angle around the Y axis from X=-1.
Expand Down
37 changes: 30 additions & 7 deletions src/TheRestOfYourLife/sphere.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,28 @@ class sphere : public hittable {
public:
sphere() {}

sphere(point3 ctr, double r, shared_ptr<material> m) : center(ctr), radius(r), mat(m) {
// Static Sphere
sphere(point3 _center, double _radius, shared_ptr<material> _material)
: center1(_center), radius(_radius), mat(_material), is_moving(false)
{
const auto rvec = vec3(radius, radius, radius);
bbox = aabb(center - rvec, center + rvec);
bbox = aabb(center1 - rvec, center1 + rvec);
}

// Moving Sphere
sphere(point3 _center1, point3 _center2, double _radius, shared_ptr<material> _material)
: center1(_center1), radius(_radius), mat(_material), is_moving(true)
{
const auto rvec = vec3(radius, radius, radius);
const aabb box0(_center1 - rvec, _center1 + rvec);
const aabb box1(_center2 - rvec, _center2 + rvec);
bbox = aabb(box0, box1);

center_vec = _center2 - _center1;
}

bool hit(const ray& r, interval ray_t, hit_record& rec) const override {
point3 center = is_moving ? sphere_center(r.time()) : center1;
vec3 oc = r.origin() - center;
auto a = r.direction().length_squared();
auto half_b = dot(oc, r.direction());
Expand Down Expand Up @@ -61,27 +77,34 @@ class sphere : public hittable {
if (!this->hit(ray(o, v), interval(0.001, infinity), rec))
return 0;

auto cos_theta_max = sqrt(1 - radius*radius/(center-o).length_squared());
auto cos_theta_max = sqrt(1 - radius*radius/(center1 - o).length_squared());
auto solid_angle = 2*pi*(1-cos_theta_max);

return 1 / solid_angle;
}

vec3 random(const point3& o) const override {
vec3 direction = center - o;
vec3 direction = center1 - o;
auto distance_squared = direction.length_squared();
onb uvw;
uvw.build_from_w(direction);
return uvw.local(random_to_sphere(radius, distance_squared));
}

public:
point3 center;
private:
point3 center1;
double radius;
shared_ptr<material> mat;
bool is_moving;
vec3 center_vec;
aabb bbox;

private:
point3 sphere_center(double time) const {
// Linearly interpolate from center1 to center2 according to time, where t=0 yields
// center1, and t=1 yields center2.
return center1 + time * center_vec;
}

static void get_sphere_uv(const point3& p, double& u, double& v) {
// p: a given point on the sphere of radius one, centered at the origin.
// u: returned value [0,1] of angle around the Y axis from X=-1.
Expand Down