From 47b72b8baeebb71ff8e5781b0b38b5b1b88c6ce0 Mon Sep 17 00:00:00 2001 From: CJSatnarine Date: Thu, 11 Jul 2024 09:43:23 -0400 Subject: [PATCH] Implement instance rotation --- hittable.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/hittable.h b/hittable.h index fd39a52..a7b84a2 100644 --- a/hittable.h +++ b/hittable.h @@ -64,4 +64,78 @@ class translate : public hittable { aabb bBox; }; +class rotateY : public hittable { + public: + rotateY(shared_ptr object, double angle) : object(object) { + auto radians = degreesToRadians(angle); + sinTheta = sin(radians); + cosTheta = cos(radians); + bBox = object->boundingBox(); + + point3 min(infinity, infinity, infinity); + point3 max(-infinity, -infinity, -infinity); + + for (int i = 0; i < 2; i ++) { + for (int j = 0; j < 2; j++) { + for (int k = 0; k < 2; k++) { + auto x = i * bBox.x.max + (1 - i) * bBox.x.min; + auto y = j * bBox.y.max + (1 - j) * bBox.y.min; + auto z = k * bBox.z.max + (1 - k) * bBox.z.min; + + auto newX = cosTheta * x + sinTheta * z; + auto newZ = -sinTheta * x + cosTheta * z; + + vec3 tester(newX, y, newZ); + + for (int c = 0; c < 3; c++) { + min[c] = fmin(min[c], tester[c]); + max[c] = fmax(max[c], tester[c]); + } + } + } + } + + bBox = aabb(min, max); + } + + bool hit(const ray& r, interval rayT, hitRecord& rec) const override { + // Change the ray from world space to object space. + auto origin = r.origin(); + auto direction = r.direction(); + + origin[0] = cosTheta * r.origin()[0] - sinTheta * r.origin()[2]; + origin[2] = sinTheta * r.origin()[0] + cosTheta * r.origin()[2]; + + + direction[0] = cosTheta * r.direction()[0] - sinTheta * r.direction()[2]; + direction[2] = sinTheta * r.direction()[0] + cosTheta * r.direction()[2]; + + ray rotatedR(origin, direction, r.time()); + + // Determine whether an intersection exists in object space (and if so, where). + if (!object->hit(rotatedR, rayT, rec)) return false; + + // Change the intersection point from object space to world space. + auto p = rec.p; + p[0] = cosTheta * rec.p[0] + sinTheta * rec.p[2]; + p[2] = -sinTheta * rec.p[0] + cosTheta * rec.normal[2]; + + // Change the normal from object space to world space. + auto normal = rec.normal; + normal[0] = cosTheta * rec.normal[0] + sinTheta * rec.normal[2]; + normal[2] = -sinTheta * rec.normal[0] + cosTheta * rec.normal[2]; + + rec.p = p; + rec.normal = normal; + + return true; + } + + private: + shared_ptr object; + double sinTheta; + double cosTheta; + aabb bBox; +}; + #endif \ No newline at end of file