Permalink
Browse files

Started implementing the object type box.

  • Loading branch information...
mlundblad committed May 8, 2012
1 parent 1934d16 commit 696291685e3c546ae3d48c9df2279b5dd3683b0a
Showing with 171 additions and 0 deletions.
  1. +2 −0 src/Makefile.am
  2. +105 −0 src/box.cc
  3. +64 −0 src/box.h
View
@@ -4,6 +4,8 @@ protracer_SOURCES=bitmap.cc \
bitmap.h \
bitmap_pigment.cc \
bitmap_pigment.h \
+ box.cc \
+ box.h \
camera.cc \
camera.h \
color.h \
View
@@ -0,0 +1,105 @@
+/* -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * This file is part of Protracer
+ *
+ * Protracer is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Protracer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Protracer. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "box.h"
+
+namespace Protracer {
+
+ Box::Box(const Vector& c1, const Vector& c2, Pigment* pigment,
+ const Finish& finish) :
+ Object(pigment, finish),
+ front_plane(Plane(Vector::unit_z(), c1, pigment->copy(), finish)),
+ back_plane(Plane(Vector::unit_z(), c2, pigment->copy(), finish)),
+ bottom_plane(Plane(Vector::unit_y(), c1, pigment->copy(), finish)),
+ top_plane(Plane(Vector::unit_y(), c2, pigment->copy(), finish)),
+ left_plane(Plane(Vector::unit_x(), c1, pigment->copy(), finish)),
+ right_plane(Plane(Vector::unit_x(), c2, pigment->copy(), finish))
+ {
+ bottom_front_left = c1;
+ bottom_back_left = c1 + Vector(0, 0, (c2 - c1).get_z());
+ bottom_front_right = c1 + Vector((c2 - c1).get_x(), 0, 0);
+ top_front_left = c1 + Vector(0, (c2 - c1).get_y(), 0);
+
+ // the side vectors are initially aligned to the coordinate axis
+ up = Vector(0, (c2 - c1).get_y(), 0);
+ right = Vector((c2 - c1).get_x(), 0, 0);
+ in = Vector(0, 0, (c2 - c1).get_z());
+ }
+
+ HitCalculation
+ Box::calculate_hit(const Ray& ray) const
+ {
+ HitCalculation hc1 = calculate_hit(ray, front_plane, bottom_front_left,
+ up, right);
+ HitCalculation hc2 = calculate_hit(ray, back_plane, bottom_back_left,
+ up, right);
+ HitCalculation hc3 = calculate_hit(ray, top_plane, top_front_left,
+ in, right);
+ HitCalculation hc4 = calculate_hit(ray, bottom_plane, bottom_front_left,
+ in, right);
+ HitCalculation hc5 = calculate_hit(ray, left_plane, bottom_front_left,
+ in, up);
+ HitCalculation hc6 = calculate_hit(ray, right_plane, bottom_front_right,
+ in, up);
+
+ HitCalculation hc = hc1;
+
+ if (hc2.is_hit() && hc2.get_distance() < hc.get_distance())
+ hc = hc2;
+ if (hc3.is_hit() && hc3.get_distance() < hc.get_distance())
+ hc = hc3;
+ if (hc4.is_hit() && hc4.get_distance() < hc.get_distance())
+ hc = hc4;
+ if (hc5.is_hit() && hc5.get_distance() < hc.get_distance())
+ hc = hc5;
+ if (hc6.is_hit() && hc6.get_distance() < hc.get_distance())
+ hc = hc6;
+
+ return hc;
+ }
+
+ HitCalculation
+ Box::calculate_hit(const Ray& ray, const Plane& span_plane,
+ const Vector& point,
+ const Vector& va, const Vector& vb) const
+ {
+ HitCalculation hc = span_plane.calculate_hit(ray);
+
+ if (hc.is_hit()) {
+ // we might want to precalculate these scalar products (see Triangle)
+ float aa = va.dot(va);
+ float bb = vb.dot(vb);
+ float ab = va.dot(vb);
+ Vector ri = ray.get_origin() + hc.get_distance() * ray.get_direction();
+ Vector q = ri - point;
+
+ float u = (bb * q.dot(va) - ab * q.dot(vb)) / (aa * bb - ab * ab);
+
+ if (0 < u && u < 1) {
+ float v = (q.dot(vb) - u * ab) / bb;
+
+ if (0 < v && v < 1) {
+ return hc;
+ }
+ }
+ }
+
+ return HitCalculation(false);
+ }
+}
View
@@ -0,0 +1,64 @@
+/* -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * This file is part of Protracer
+ *
+ * Protracer is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Protracer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Protracer. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef BOX_H
+#define BOX_H
+
+#include "object.h"
+#include "plane.h"
+
+namespace Protracer {
+
+ class Box : public Object {
+ public:
+ Box(const Vector& c1, const Vector& c2, Pigment* pigment,
+ const Finish& finish);
+
+ virtual HitCalculation calculate_hit(const Ray& ray) const;
+
+ private:
+ // define enough points and side vectors to be able to efficiantly
+ // calculate hits on all four side areas
+ Vector bottom_front_left;
+ Vector bottom_back_left;
+ Vector bottom_front_right;
+ Vector top_front_left;
+
+ // sides
+ Vector up;
+ Vector right;
+ Vector in;
+
+ // spanning planes
+ Plane front_plane;
+ Plane back_plane;
+ Plane top_plane;
+ Plane bottom_plane;
+ Plane left_plane;
+ Plane right_plane;
+
+ // calculate hit against one "side pane"
+ HitCalculation calculate_hit(const Ray& ray, const Plane& span_plane,
+ const Vector& point,
+ const Vector& va, const Vector& vb) const;
+
+ };
+}
+
+#endif //BOX_H

0 comments on commit 6962916

Please sign in to comment.