1 #ifndef MSP_GEOMETRY_COMPOSITESHAPE_H_
2 #define MSP_GEOMETRY_COMPOSITESHAPE_H_
6 #include "boundingbox.h"
13 Common operations for shapes composed of other shapes.
15 template<typename T, unsigned D, typename O>
16 class CompositeShape: public Shape<T, D>
20 typedef std::vector<Shape<T, D> *> ShapeArray;
25 CompositeShape(const Shape<T, D> &, const Shape<T, D> &);
26 CompositeShape(const CompositeShape &);
27 CompositeShape &operator=(const CompositeShape &);
28 template<typename Iter>
29 void init_from_iter_range(const Iter &, const Iter &);
31 virtual ~CompositeShape();
33 virtual BoundingBox<T, D> get_axis_aligned_bounding_box() const;
34 virtual bool contains(const LinAl::Vector<T, D> &) const;
35 virtual unsigned get_max_ray_intersections() const;
36 virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
39 template<typename T, unsigned D, typename O>
40 inline CompositeShape<T, D, O>::CompositeShape(const Shape<T, D> &s1, const Shape<T, D> &s2)
43 shapes.push_back(s1.clone());
44 shapes.push_back(s2.clone());
47 template<typename T, unsigned D, typename O>
48 template<typename Iter>
49 inline void CompositeShape<T, D, O>::init_from_iter_range(const Iter &begin, const Iter &end)
52 throw std::invalid_argument("CompositeShape::init_from_iter_range");
54 for(Iter i=begin; i!=end; ++i)
55 shapes.push_back((*i)->clone());
58 template<typename T, unsigned D, typename O>
59 inline CompositeShape<T, D, O>::CompositeShape(const CompositeShape<T, D, O> &other)
61 shapes.reserve(other.shapes.size());
62 for(typename ShapeArray::const_iterator i=other.shapes.begin(); i!=other.shapes.end(); ++i)
63 shapes.push_back((*i)->clone());
66 template<typename T, unsigned D, typename O>
67 inline CompositeShape<T, D, O>::~CompositeShape()
69 for(typename ShapeArray::iterator i=shapes.begin(); i!=shapes.end(); ++i)
73 template<typename T, unsigned D, typename O>
74 inline BoundingBox<T, D> CompositeShape<T, D, O>::get_axis_aligned_bounding_box() const
76 BoundingBox<T, D> aabb;
77 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
80 aabb = (*i)->get_axis_aligned_bounding_box();
82 aabb = Ops::combine_aabb(aabb, (*i)->get_axis_aligned_bounding_box());
87 template<typename T, unsigned D, typename O>
88 inline bool CompositeShape<T, D, O>::contains(const LinAl::Vector<T, D> &point) const
90 bool inside = Ops::init_inside();
91 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
93 inside = Ops::combine_inside(inside, (*i)->contains(point));
94 if(Ops::is_inside_decided(inside))
100 template<typename T, unsigned D, typename O>
101 inline unsigned CompositeShape<T, D, O>::get_max_ray_intersections() const
103 unsigned max_isect = 0;
104 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
105 max_isect += (*i)->get_max_ray_intersections();
109 template<typename T, unsigned D, typename O>
110 inline unsigned CompositeShape<T, D, O>::get_intersections(const Ray<T, D> &ray, SurfacePoint<T, D> *points, unsigned size) const
113 for(typename ShapeArray::const_iterator i=shapes.begin(); (n<size && i!=shapes.end()); ++i)
116 unsigned count = (*i)->get_intersections(ray, points+base, size-base);
117 for(unsigned j=0; (n<size && j<count); ++j)
119 SurfacePoint<T, D> &pt = points[base+j];
121 bool surface = Ops::init_surface();
122 for(typename ShapeArray::const_iterator k=shapes.begin(); k!=shapes.end(); ++k)
124 surface = Ops::combine_surface(surface, (*k)->contains(pt.position));
128 if(points && base+j!=n)
136 sort_points(points, n);
141 } // namespace Geometry