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 CompositeShape(const CompositeShape &);
26 CompositeShape &operator=(const CompositeShape &);
27 template<typename Iter>
28 void init_from_iter_range(const Iter &, const Iter &);
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)
60 shapes.reserve(other.shapes.size());
61 for(typename ShapeArray::const_iterator i=other.shapes.begin(); i!=other.shapes.end(); ++i)
62 shapes.push_back((*i)->clone());
65 template<typename T, unsigned D, typename O>
66 inline CompositeShape<T, D, O>::~CompositeShape()
68 for(typename ShapeArray::iterator i=shapes.begin(); i!=shapes.end(); ++i)
72 template<typename T, unsigned D, typename O>
73 inline BoundingBox<T, D> CompositeShape<T, D, O>::get_axis_aligned_bounding_box() const
75 BoundingBox<T, D> aabb;
76 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
79 aabb = (*i)->get_axis_aligned_bounding_box();
81 aabb = Ops::combine_aabb(aabb, (*i)->get_axis_aligned_bounding_box());
86 template<typename T, unsigned D, typename O>
87 inline bool CompositeShape<T, D, O>::contains(const LinAl::Vector<T, D> &point) const
89 bool inside = Ops::init_inside();
90 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
92 inside = Ops::combine_inside(inside, (*i)->contains(point));
93 if(Ops::is_inside_decided(inside))
99 template<typename T, unsigned D, typename O>
100 inline unsigned CompositeShape<T, D, O>::get_max_ray_intersections() const
102 unsigned max_isect = 0;
103 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
104 max_isect += (*i)->get_max_ray_intersections();
108 template<typename T, unsigned D, typename O>
109 inline unsigned CompositeShape<T, D, O>::get_intersections(const Ray<T, D> &ray, SurfacePoint<T, D> *points, unsigned size) const
112 for(typename ShapeArray::const_iterator i=shapes.begin(); (n<size && i!=shapes.end()); ++i)
115 unsigned count = (*i)->get_intersections(ray, points+base, size-base);
116 for(unsigned j=0; (n<size && j<count); ++j)
118 SurfacePoint<T, D> &pt = points[base+j];
120 bool surface = Ops::init_surface();
121 for(typename ShapeArray::const_iterator k=shapes.begin(); k!=shapes.end(); ++k)
123 surface = Ops::combine_surface(surface, (*k)->contains(pt.position));
127 if(points && base+j!=n)
135 sort_points(points, n);
140 } // namespace Geometry