|
894 | 894 | sphere() {} |
895 | 895 | sphere(point3 ctr, double r) : center(ctr), radius(r) {}; |
896 | 896 |
|
897 | | - bool hit(const ray& r, double ray_tmin, double ray_tmax, hit_record& rec) const override; |
| 897 | + bool hit(const ray& r, double ray_tmin, double ray_tmax, hit_record& rec) const override { |
| 898 | + vec3 oc = r.origin() - center; |
| 899 | + auto a = r.direction().length_squared(); |
| 900 | + auto half_b = dot(oc, r.direction()); |
| 901 | + auto c = oc.length_squared() - radius*radius; |
| 902 | + |
| 903 | + auto discriminant = half_b*half_b - a*c; |
| 904 | + if (discriminant < 0) return false; |
| 905 | + auto sqrtd = sqrt(discriminant); |
| 906 | + |
| 907 | + // Find the nearest root that lies in the acceptable range. |
| 908 | + auto root = (-half_b - sqrtd) / a; |
| 909 | + if (root < ray_tmin || ray_tmax < root) { |
| 910 | + root = (-half_b + sqrtd) / a; |
| 911 | + if (root < ray_tmin || ray_tmax < root) |
| 912 | + return false; |
| 913 | + } |
| 914 | + |
| 915 | + rec.t = root; |
| 916 | + rec.p = r.at(rec.t); |
| 917 | + rec.normal = (rec.p - center) / radius; |
| 918 | + |
| 919 | + return true; |
| 920 | + } |
898 | 921 |
|
899 | 922 | public: |
900 | 923 | point3 center; |
901 | 924 | double radius; |
902 | 925 | }; |
903 | 926 |
|
904 | | - bool sphere::hit(const ray& r, double ray_tmin, double ray_tmax, hit_record& rec) const { |
905 | | - vec3 oc = r.origin() - center; |
906 | | - auto a = r.direction().length_squared(); |
907 | | - auto half_b = dot(oc, r.direction()); |
908 | | - auto c = oc.length_squared() - radius*radius; |
909 | | - |
910 | | - auto discriminant = half_b*half_b - a*c; |
911 | | - if (discriminant < 0) return false; |
912 | | - auto sqrtd = sqrt(discriminant); |
913 | | - |
914 | | - // Find the nearest root that lies in the acceptable range. |
915 | | - auto root = (-half_b - sqrtd) / a; |
916 | | - if (root < ray_tmin || ray_tmax < root) { |
917 | | - root = (-half_b + sqrtd) / a; |
918 | | - if (root < ray_tmin || ray_tmax < root) |
919 | | - return false; |
920 | | - } |
921 | | - |
922 | | - rec.t = root; |
923 | | - rec.p = r.at(rec.t); |
924 | | - rec.normal = (rec.p - center) / radius; |
925 | | - |
926 | | - return true; |
927 | | - } |
928 | | - |
929 | 927 | #endif |
930 | 928 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
931 | 929 | [Listing [sphere-initial]: <kbd>[sphere.h]</kbd> The sphere class] |
|
1024 | 1022 | And then we add the surface side determination to the class: |
1025 | 1023 |
|
1026 | 1024 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1027 | | - bool sphere::hit(const ray& r, double ray_tmin, double ray_tmax, hit_record& rec) const { |
| 1025 | + class sphere : public hittable { |
| 1026 | + public: |
1028 | 1027 | ... |
| 1028 | + bool here::hit(const ray& r, double ray_tmin, double ray_tmax, hit_record& rec) const { |
| 1029 | + ... |
1029 | 1030 |
|
1030 | | - rec.t = root; |
1031 | | - rec.p = r.at(rec.t); |
| 1031 | + rec.t = root; |
| 1032 | + rec.p = r.at(rec.t); |
1032 | 1033 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1033 | | - vec3 outward_normal = (rec.p - center) / radius; |
1034 | | - rec.set_face_normal(r, outward_normal); |
| 1034 | + vec3 outward_normal = (rec.p - center) / radius; |
| 1035 | + rec.set_face_normal(r, outward_normal); |
1035 | 1036 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1036 | 1037 |
|
1037 | | - return true; |
1038 | | - } |
| 1038 | + return true; |
| 1039 | + } |
| 1040 | + ... |
| 1041 | + }; |
1039 | 1042 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1040 | 1043 | [Listing [sphere-final]: <kbd>[sphere.h]</kbd> The sphere class with normal determination] |
1041 | 1044 |
|
|
1068 | 1071 | void clear() { objects.clear(); } |
1069 | 1072 | void add(shared_ptr<hittable> object) { objects.push_back(object); } |
1070 | 1073 |
|
1071 | | - bool hit(const ray& r, double ray_tmin, double ray_tmax, hit_record& rec) const override; |
1072 | | - |
1073 | | - public: |
1074 | | - std::vector<shared_ptr<hittable>> objects; |
1075 | | - }; |
| 1074 | + bool hit(const ray& r, double ray_tmin, double ray_tmax, hit_record& rec) const override { |
| 1075 | + hit_record temp_rec; |
| 1076 | + bool hit_anything = false; |
| 1077 | + auto closest_so_far = ray_tmax; |
1076 | 1078 |
|
1077 | | - bool hittable_list::hit(const ray& r, double ray_tmin, double ray_tmax, hit_record& rec) const { |
1078 | | - hit_record temp_rec; |
1079 | | - bool hit_anything = false; |
1080 | | - auto closest_so_far = ray_tmax; |
1081 | | - |
1082 | | - for (const auto& object : objects) { |
1083 | | - if (object->hit(r, ray_tmin, closest_so_far, temp_rec)) { |
1084 | | - hit_anything = true; |
1085 | | - closest_so_far = temp_rec.t; |
1086 | | - rec = temp_rec; |
| 1079 | + for (const auto& object : objects) { |
| 1080 | + if (object->hit(r, ray_tmin, closest_so_far, temp_rec)) { |
| 1081 | + hit_anything = true; |
| 1082 | + closest_so_far = temp_rec.t; |
| 1083 | + rec = temp_rec; |
| 1084 | + } |
1087 | 1085 | } |
| 1086 | + |
| 1087 | + return hit_anything; |
1088 | 1088 | } |
1089 | 1089 |
|
1090 | | - return hit_anything; |
1091 | | - } |
| 1090 | + public: |
| 1091 | + std::vector<shared_ptr<hittable>> objects; |
| 1092 | + }; |
1092 | 1093 |
|
1093 | 1094 | #endif |
1094 | 1095 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
1310 | 1311 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1311 | 1312 | [Listing [interval-initial]: <kbd>[interval.h]</kbd> Introducing the new interval class] |
1312 | 1313 |
|
| 1314 | + |
1313 | 1315 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1314 | 1316 | class hittable { |
1315 | | - public: |
| 1317 | + public: |
| 1318 | + ... |
1316 | 1319 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1317 | | - virtual bool hit(const ray& r, interval ray_t, hit_record& rec) const = 0; |
| 1320 | + virtual bool hit(const ray& r, interval ray_t, hit_record& rec) const = 0; |
1318 | 1321 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1319 | 1322 | }; |
1320 | 1323 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1321 | 1324 | [Listing [hittable-with-interval]: <kbd>[hittable.h]</kbd> hittable::hit() using interval] |
1322 | 1325 |
|
1323 | 1326 |
|
1324 | | - |
1325 | 1327 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1326 | 1328 | class hittable_list : public hittable { |
| 1329 | + public: |
1327 | 1330 | ... |
1328 | 1331 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1329 | | - bool hit(const ray& r, interval ray_t, hit_record& rec) const override; |
1330 | | - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1331 | | - ... |
1332 | | - }; |
1333 | | - |
1334 | | - |
1335 | | - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1336 | | - bool hittable_list::hit(const ray& r, interval ray_t, hit_record& rec) const { |
| 1332 | + bool hit(const ray& r, interval ray_t, hit_record& rec) const override { |
1337 | 1333 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1338 | | - hit_record temp_rec; |
1339 | | - bool hit_anything = false; |
| 1334 | + hit_record temp_rec; |
| 1335 | + bool hit_anything = false; |
1340 | 1336 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1341 | | - auto closest_so_far = ray_t.max; |
| 1337 | + auto closest_so_far = ray_t.max; |
1342 | 1338 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1343 | 1339 |
|
1344 | | - for (const auto& object : objects) { |
| 1340 | + for (const auto& object : objects) { |
1345 | 1341 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1346 | | - if (object->hit(r, interval(ray_t.min, closest_so_far), temp_rec)) { |
| 1342 | + if (object->hit(r, interval(ray_t.min, closest_so_far), temp_rec)) { |
1347 | 1343 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1348 | | - hit_anything = true; |
1349 | | - closest_so_far = temp_rec.t; |
1350 | | - rec = temp_rec; |
| 1344 | + hit_anything = true; |
| 1345 | + closest_so_far = temp_rec.t; |
| 1346 | + rec = temp_rec; |
| 1347 | + } |
1351 | 1348 | } |
1352 | | - } |
1353 | 1349 |
|
1354 | | - return hit_anything; |
1355 | | - } |
| 1350 | + return hit_anything; |
| 1351 | + } |
1356 | 1352 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1357 | 1353 | [Listing [hittable-list-with-interval]: <kbd>[hittable.h]</kbd> |
1358 | | - hittable_list::hit() using interval] |
1359 | | - |
| 1354 | + hittable_list::hit() using interval] |
1360 | 1355 |
|
1361 | 1356 |
|
1362 | 1357 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1363 | 1358 | class sphere : public hittable { |
1364 | | - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1365 | | - bool hit(const ray& r, interval ray_t, hit_record& rec) const override; |
1366 | | - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1359 | + public: |
1367 | 1360 | ... |
1368 | | - }; |
1369 | | - |
1370 | | - |
1371 | 1361 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1372 | | - bool sphere::hit(const ray& r, interval ray_t, hit_record& rec) const { |
| 1362 | + bool hit(const ray& r, interval ray_t, hit_record& rec) const override { |
1373 | 1363 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1374 | | - ... |
| 1364 | + ... |
1375 | 1365 |
|
1376 | | - // Find the nearest root that lies in the acceptable range. |
1377 | | - auto root = (-half_b - sqrtd) / a; |
| 1366 | + // Find the nearest root that lies in the acceptable range. |
| 1367 | + auto root = (-half_b - sqrtd) / a; |
1378 | 1368 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1379 | | - if (!ray_t.contains(root)) { |
| 1369 | + if (!ray_t.contains(root)) { |
1380 | 1370 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1381 | | - root = (-half_b + sqrtd) / a; |
| 1371 | + root = (-half_b + sqrtd) / a; |
1382 | 1372 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1383 | | - if (!ray_t.contains(root)) |
| 1373 | + if (!ray_t.contains(root)) |
1384 | 1374 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1385 | | - return false; |
| 1375 | + return false; |
| 1376 | + } |
| 1377 | + ... |
1386 | 1378 | } |
1387 | 1379 | ... |
1388 | | - } |
| 1380 | + }; |
1389 | 1381 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1390 | 1382 | [Listing [sphere-with-interval]: <kbd>[sphere.h]</kbd> sphere using interval] |
1391 | 1383 |
|
|
2107 | 2099 | : center(ctr), radius(r), mat_ptr(m) {}; |
2108 | 2100 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2109 | 2101 |
|
2110 | | - bool hit(const ray& r, interval ray_t, hit_record& rec) const override; |
| 2102 | + bool hit(const ray& r, interval ray_t, hit_record& rec) const override { |
| 2103 | + ... |
| 2104 | + |
| 2105 | + rec.t = root; |
| 2106 | + rec.p = r.at(rec.t); |
| 2107 | + vec3 outward_normal = (rec.p - center) / radius; |
| 2108 | + rec.set_face_normal(r, outward_normal); |
| 2109 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 2110 | + rec.mat_ptr = mat_ptr; |
| 2111 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 2112 | + |
| 2113 | + return true; |
| 2114 | + } |
2111 | 2115 |
|
2112 | 2116 | public: |
2113 | 2117 | point3 center; |
|
2116 | 2120 | shared_ptr<material> mat_ptr; |
2117 | 2121 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2118 | 2122 | }; |
2119 | | - |
2120 | | - bool sphere::hit(const ray& r, interval ray_t, hit_record& rec) const { |
2121 | | - ... |
2122 | | - |
2123 | | - rec.t = root; |
2124 | | - rec.p = r.at(rec.t); |
2125 | | - vec3 outward_normal = (rec.p - center) / radius; |
2126 | | - rec.set_face_normal(r, outward_normal); |
2127 | | - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
2128 | | - rec.mat_ptr = mat_ptr; |
2129 | | - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2130 | | - |
2131 | | - return true; |
2132 | | - } |
2133 | 2123 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2134 | 2124 | [Listing [sphere-material]: <kbd>[sphere.h]</kbd> Ray-sphere intersection with added material information] |
2135 | 2125 | </div> |
|
0 commit comments