X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgeometry%2Fcompositeshape.h;h=55467d762993add17cbc4fe74ae7bfda2f776c22;hb=5e5a34537e5f2efc71181f2bf6878c3e2e62b398;hp=fd55c8e6e090875cd147f57697a35190fa26206e;hpb=68389c29cf88d6522dcfa00b5e2a5166e3947210;p=libs%2Fmath.git diff --git a/source/geometry/compositeshape.h b/source/geometry/compositeshape.h index fd55c8e..55467d7 100644 --- a/source/geometry/compositeshape.h +++ b/source/geometry/compositeshape.h @@ -1,6 +1,7 @@ #ifndef MSP_GEOMETRY_COMPOSITESHAPE_H_ #define MSP_GEOMETRY_COMPOSITESHAPE_H_ +#include #include #include "shape.h" @@ -19,16 +20,17 @@ protected: ShapeArray shapes; + CompositeShape() { } CompositeShape(const Shape &, const Shape &); - CompositeShape(const ShapeArray &); + template + void init_from_iter_range(const Iter &, const Iter &); CompositeShape(const CompositeShape &); CompositeShape &operator=(const CompositeShape &); public: virtual ~CompositeShape(); - virtual HyperBox get_axis_aligned_bounding_box() const; + virtual BoundingBox get_axis_aligned_bounding_box() const; virtual bool contains(const LinAl::Vector &) const; - virtual bool check_intersection(const Ray &) const; virtual unsigned get_max_ray_intersections() const; virtual unsigned get_intersections(const Ray &, SurfacePoint *, unsigned) const; }; @@ -42,16 +44,35 @@ inline CompositeShape::CompositeShape(const Shape &s1, const Shap } template -inline CompositeShape::CompositeShape(const ShapeArray &s) +template +inline void CompositeShape::init_from_iter_range(const Iter &begin, const Iter &end) { - if(s.empty()) - throw std::invalid_argument("CompositeShape::CompositeShape"); + if(begin==end) + throw std::invalid_argument("CompositeShape::init_from_iter_range"); - shapes.reserve(s.size()); - for(typename ShapeArray::const_iterator i=s.begin(); i!=s.end(); ++i) + for(Iter i=begin; i!=end; ++i) shapes.push_back((*i)->clone()); } +template +inline CompositeShape::CompositeShape(const CompositeShape &other): + shapes(other.shapes) +{ + for(typename ShapeArray::iterator i=shapes.begin(); i!=shapes.end(); ++i) + *i = (*i)->clone(); +} + +template +inline CompositeShape &CompositeShape::operator=(const CompositeShape &other) +{ + for(typename ShapeArray::iterator i=shapes.begin(); i!=shapes.end(); ++i) + delete *i; + + shapes = other.shapes; + for(typename ShapeArray::iterator i=shapes.begin(); i!=shapes.end(); ++i) + *i = (*i)->clone(); +} + template inline CompositeShape::~CompositeShape() { @@ -60,9 +81,9 @@ inline CompositeShape::~CompositeShape() } template -inline HyperBox CompositeShape::get_axis_aligned_bounding_box() const +inline BoundingBox CompositeShape::get_axis_aligned_bounding_box() const { - HyperBox aabb; + BoundingBox aabb; for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i) { if(i==shapes.begin()) @@ -86,12 +107,6 @@ inline bool CompositeShape::contains(const LinAl::Vector &point) return inside; } -template -inline bool CompositeShape::check_intersection(const Ray &ray) const -{ - return get_intersections(ray, 0, 1); -} - template inline unsigned CompositeShape::get_max_ray_intersections() const { @@ -105,14 +120,13 @@ template inline unsigned CompositeShape::get_intersections(const Ray &ray, SurfacePoint *points, unsigned size) const { unsigned n = 0; - for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i) + for(typename ShapeArray::const_iterator i=shapes.begin(); (nget_intersections(ray, points+base, size-base); - for(unsigned j=0; j pt = points[base+j]; + SurfacePoint &pt = points[base+j]; bool surface = Ops::init_surface(); for(typename ShapeArray::const_iterator k=shapes.begin(); k!=shapes.end(); ++k) @@ -121,22 +135,16 @@ inline unsigned CompositeShape::get_intersections(const Ray &ray, if(surface) { - if(points) - { - unsigned k; - for(k=n; (k>0 && points[k-1].distance>pt.distance); --k) - points[k] = points[k-1]; - if(base+j!=k) - points[k] = pt; - } + if(points && base+j!=n) + points[n] = pt; ++n; - if(n==size) - return n; } } } + sort_points(points, n); + return n; }