1 #ifndef MSP_GEOMETRY_COMPOSITESHAPE_H_
2 #define MSP_GEOMETRY_COMPOSITESHAPE_H_
12 Common operations for shapes composed of other shapes.
14 template<typename T, unsigned D, typename O>
15 class CompositeShape: public Shape<T, D>
19 typedef std::vector<Shape<T, D> *> ShapeArray;
24 CompositeShape(const Shape<T, D> &, const Shape<T, D> &);
25 template<typename Iter>
26 void init_from_iter_range(const Iter &, const Iter &);
27 CompositeShape(const CompositeShape &);
28 CompositeShape &operator=(const CompositeShape &);
30 virtual ~CompositeShape();
32 virtual BoundingBox<T, D> get_axis_aligned_bounding_box() const;
33 virtual bool contains(const LinAl::Vector<T, D> &) const;
34 virtual unsigned get_max_ray_intersections() const;
35 virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
38 template<typename T, unsigned D, typename O>
39 inline CompositeShape<T, D, O>::CompositeShape(const Shape<T, D> &s1, const Shape<T, D> &s2)
42 shapes.push_back(s1.clone());
43 shapes.push_back(s2.clone());
46 template<typename T, unsigned D, typename O>
47 template<typename Iter>
48 inline void CompositeShape<T, D, O>::init_from_iter_range(const Iter &begin, const Iter &end)
51 throw std::invalid_argument("CompositeShape::init_from_iter_range");
53 for(Iter i=begin; i!=end; ++i)
54 shapes.push_back((*i)->clone());
57 template<typename T, unsigned D, typename O>
58 inline CompositeShape<T, D, O>::CompositeShape(const CompositeShape<T, D, O> &other):
61 for(typename ShapeArray::iterator i=shapes.begin(); i!=shapes.end(); ++i)
65 template<typename T, unsigned D, typename O>
66 inline CompositeShape<T, D, O> &CompositeShape<T, D, O>::operator=(const CompositeShape<T, D, O> &other)
68 for(typename ShapeArray::iterator i=shapes.begin(); i!=shapes.end(); ++i)
71 shapes = other.shapes;
72 for(typename ShapeArray::iterator i=shapes.begin(); i!=shapes.end(); ++i)
76 template<typename T, unsigned D, typename O>
77 inline CompositeShape<T, D, O>::~CompositeShape()
79 for(typename ShapeArray::iterator i=shapes.begin(); i!=shapes.end(); ++i)
83 template<typename T, unsigned D, typename O>
84 inline BoundingBox<T, D> CompositeShape<T, D, O>::get_axis_aligned_bounding_box() const
86 BoundingBox<T, D> aabb;
87 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
90 aabb = (*i)->get_axis_aligned_bounding_box();
92 aabb = Ops::combine_aabb(aabb, (*i)->get_axis_aligned_bounding_box());
97 template<typename T, unsigned D, typename O>
98 inline bool CompositeShape<T, D, O>::contains(const LinAl::Vector<T, D> &point) const
100 bool inside = Ops::init_inside();
101 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
103 inside = Ops::combine_inside(inside, (*i)->contains(point));
104 if(Ops::is_inside_decided(inside))
110 template<typename T, unsigned D, typename O>
111 inline unsigned CompositeShape<T, D, O>::get_max_ray_intersections() const
113 unsigned max_isect = 0;
114 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
115 max_isect += (*i)->get_max_ray_intersections();
119 template<typename T, unsigned D, typename O>
120 inline unsigned CompositeShape<T, D, O>::get_intersections(const Ray<T, D> &ray, SurfacePoint<T, D> *points, unsigned size) const
123 for(typename ShapeArray::const_iterator i=shapes.begin(); (n<size && i!=shapes.end()); ++i)
126 unsigned count = (*i)->get_intersections(ray, points+base, size-base);
127 for(unsigned j=0; (n<size && j<count); ++j)
129 SurfacePoint<T, D> &pt = points[base+j];
131 bool surface = Ops::init_surface();
132 for(typename ShapeArray::const_iterator k=shapes.begin(); k!=shapes.end(); ++k)
134 surface = Ops::combine_surface(surface, (*k)->contains(pt.position));
138 if(points && base+j!=n)
146 sort_points(points, n);
151 } // namespace Geometry