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 unsigned get_max_ray_intersections() const;
32 virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
35 template<typename T, unsigned D, typename O>
36 inline CompositeShape<T, D, O>::CompositeShape(const Shape<T, D> &s1, const Shape<T, D> &s2)
39 shapes.push_back(s1.clone());
40 shapes.push_back(s2.clone());
43 template<typename T, unsigned D, typename O>
44 inline CompositeShape<T, D, O>::CompositeShape(const ShapeArray &s)
47 throw std::invalid_argument("CompositeShape::CompositeShape");
49 shapes.reserve(s.size());
50 for(typename ShapeArray::const_iterator i=s.begin(); i!=s.end(); ++i)
51 shapes.push_back((*i)->clone());
54 template<typename T, unsigned D, typename O>
55 inline CompositeShape<T, D, O>::~CompositeShape()
57 for(typename ShapeArray::iterator i=shapes.begin(); i!=shapes.end(); ++i)
61 template<typename T, unsigned D, typename O>
62 inline HyperBox<T, D> CompositeShape<T, D, O>::get_axis_aligned_bounding_box() const
65 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
68 aabb = (*i)->get_axis_aligned_bounding_box();
70 aabb = Ops::combine_aabb(aabb, (*i)->get_axis_aligned_bounding_box());
75 template<typename T, unsigned D, typename O>
76 inline bool CompositeShape<T, D, O>::contains(const LinAl::Vector<T, D> &point) const
78 bool inside = Ops::init_inside();
79 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
81 inside = Ops::combine_inside(inside, (*i)->contains(point));
82 if(Ops::is_inside_decided(inside))
88 template<typename T, unsigned D, typename O>
89 inline unsigned CompositeShape<T, D, O>::get_max_ray_intersections() const
91 unsigned max_isect = 0;
92 for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
93 max_isect += (*i)->get_max_ray_intersections();
97 template<typename T, unsigned D, typename O>
98 inline unsigned CompositeShape<T, D, O>::get_intersections(const Ray<T, D> &ray, SurfacePoint<T, D> *points, unsigned size) const
101 for(typename ShapeArray::const_iterator i=shapes.begin(); (n<size && i!=shapes.end()); ++i)
104 unsigned count = (*i)->get_intersections(ray, points+base, size-base);
105 for(unsigned j=0; (n<size && j<count); ++j)
107 SurfacePoint<T, D> &pt = points[base+j];
109 bool surface = Ops::init_surface();
110 for(typename ShapeArray::const_iterator k=shapes.begin(); k!=shapes.end(); ++k)
112 surface = Ops::combine_surface(surface, (*k)->contains(pt.position));
116 if(points && base+j!=n)
124 sort_points(points, n);
129 } // namespace Geometry