1 #ifndef MSP_GEOMETRY_HYPERBOX_H_
2 #define MSP_GEOMETRY_HYPERBOX_H_
6 #include <msp/linal/vector.h>
9 #include "surfacepoint.h"
14 template<typename T, unsigned D>
15 class HyperBox: public Shape<T, D>
18 LinAl::Vector<T, D> dimensions;
22 explicit HyperBox(const LinAl::Vector<T, D> &);
24 virtual HyperBox *clone() const;
26 const LinAl::Vector<T, D> &get_dimensions() const { return dimensions; }
27 T get_dimension(unsigned) const;
29 virtual HyperBox<T, D> get_axis_aligned_bounding_box() const { return *this; }
30 virtual bool contains(const LinAl::Vector<T, D> &) const;
31 virtual bool check_intersection(const Ray<T, D> &) const;
32 virtual unsigned get_max_ray_intersections() const { return 2; }
33 virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
36 template<typename T, unsigned D>
37 inline HyperBox<T, D>::HyperBox()
39 for(unsigned i=0; i<D; ++i)
43 template<typename T, unsigned D>
44 inline HyperBox<T, D>::HyperBox(const LinAl::Vector<T, D> &d):
48 template<typename T, unsigned D>
49 inline HyperBox<T, D> *HyperBox<T, D>::clone() const
51 return new HyperBox<T, D>(dimensions);
54 template<typename T, unsigned D>
55 inline T HyperBox<T, D>::get_dimension(unsigned i) const
60 template<typename T, unsigned D>
61 inline bool HyperBox<T, D>::contains(const LinAl::Vector<T, D> &point) const
63 for(unsigned i=0; i<D; ++i)
64 if(abs(point[i])>dimensions[i]/2)
69 template<typename T, unsigned D>
70 inline bool HyperBox<T, D>::check_intersection(const Ray<T, D> &ray) const
72 return get_intersections(ray, 0, 1);
75 template<typename T, unsigned D>
76 inline unsigned HyperBox<T, D>::get_intersections(const Ray<T, D> &ray, SurfacePoint<T, D> *points, unsigned size) const
80 LinAl::Vector<T, D> half_dim = dimensions/T(2);
83 for(unsigned i=0; i<D; ++i)
85 if(!ray.get_direction()[i])
88 for(int j=-1; j<=1; j+=2)
90 T x = (T(j)*half_dim[i]-ray.get_start()[i])/ray.get_direction()[i];
94 LinAl::Vector<T, D> p = ray.get_start()+ray.get_direction()*x;
97 for(unsigned k=0; (inside && k<D); ++k)
98 inside = (k==i || abs(p[k])<=half_dim[k]);
104 points[n].position = p;
105 points[n].normal = LinAl::Vector<T, D>();
106 points[n].normal[i] = j;
109 else if(n==1 && x<first_depth)
110 std::swap(points[0], points[1]);
123 } // namespace Geometry