1 #ifndef MSP_GEOMETRY_COMPOSITESHAPE_H_
2 #define MSP_GEOMETRY_COMPOSITESHAPE_H_
11 Common operations for shapes composed of other shapes.
13 template<typename T, unsigned D, typename O>
14 class CompositeShape: public Shape<T, D>
18 typedef std::vector<Shape<T, D> *> ShapeArray;
22 CompositeShape(const Shape<T, D> &, const Shape<T, D> &);
23 CompositeShape(const ShapeArray &);
24 CompositeShape(const CompositeShape &);
25 CompositeShape &operator=(const CompositeShape &);
27 virtual ~CompositeShape();
29 virtual HyperBox<T, D> get_axis_aligned_bounding_box() const;
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;
33 virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
36 template<typename T, unsigned D, typename O>
37 inline CompositeShape<T, D, O>::CompositeShape(const Shape<T, D> &s1, const Shape<T, D> &s2)
40 shapes.push_back(s1.clone());
41 shapes.push_back(s2.clone());
44 template<typename T, unsigned D, typename O>
45 inline CompositeShape<T, D, O>::CompositeShape(const ShapeArray &s)
48 throw std::invalid_argument("CompositeShape::CompositeShape");
50 shapes.reserve(s.size());
51 for(typename ShapeArray::const_iterator i=s.begin(); i!=s.end(); ++i)
52 shapes.push_back((*i)->clone());
55 template<typename T, unsigned D, typename O>
56 inline CompositeShape<T, D, O>::~CompositeShape()
58 for(typename ShapeArray::iterator i=shapes.begin(); i!=shapes.end(); ++i)
62 template<typename T, unsigned D, typename O>
63 inline HyperBox<T, D> CompositeShape<T, D, O>::get_axis_aligned_bounding_box() const
66 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
69 aabb = (*i)->get_axis_aligned_bounding_box();
71 aabb = Ops::combine_aabb(aabb, (*i)->get_axis_aligned_bounding_box());
76 template<typename T, unsigned D, typename O>
77 inline bool CompositeShape<T, D, O>::contains(const LinAl::Vector<T, D> &point) const
79 bool inside = Ops::init_inside();
80 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
82 inside = Ops::combine_inside(inside, (*i)->contains(point));
83 if(Ops::is_inside_decided(inside))
89 template<typename T, unsigned D, typename O>
90 inline bool CompositeShape<T, D, O>::check_intersection(const Ray<T, D> &ray) const
92 return get_intersections(ray, 0, 1);
95 template<typename T, unsigned D, typename O>
96 inline unsigned CompositeShape<T, D, O>::get_max_ray_intersections() const
98 unsigned max_isect = 0;
99 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
100 max_isect += (*i)->get_max_ray_intersections();
104 template<typename T, unsigned D, typename O>
105 inline unsigned CompositeShape<T, D, O>::get_intersections(const Ray<T, D> &ray, SurfacePoint<T, D> *points, unsigned size) const
108 for(typename ShapeArray::const_iterator i=shapes.begin(); (n<size && i!=shapes.end()); ++i)
111 unsigned count = (*i)->get_intersections(ray, points+base, size-base);
112 for(unsigned j=0; (n<size && j<count); ++j)
114 SurfacePoint<T, D> &pt = points[base+j];
116 bool surface = Ops::init_surface();
117 for(typename ShapeArray::const_iterator k=shapes.begin(); k!=shapes.end(); ++k)
119 surface = Ops::combine_surface(surface, (*k)->contains(pt.position));
123 if(points && base+j!=n)
131 sort_points(points, n);
136 } // namespace Geometry