X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgeometry%2Fcompositeshape.h;h=f0b1f529544c12913202640c1e22604e5e5d5ded;hb=39626a640e3b6a1ff8894e0cf47db68540d669b2;hp=4c640be22f4c5045076b9659ce7734d517f1127c;hpb=09cc3a8648dd20e9a07d669b353c4a120b67c1c4;p=libs%2Fmath.git diff --git a/source/geometry/compositeshape.h b/source/geometry/compositeshape.h index 4c640be..f0b1f52 100644 --- a/source/geometry/compositeshape.h +++ b/source/geometry/compositeshape.h @@ -1,9 +1,9 @@ #ifndef MSP_GEOMETRY_COMPOSITESHAPE_H_ #define MSP_GEOMETRY_COMPOSITESHAPE_H_ +#include #include #include -#include "boundingbox.h" #include "shape.h" namespace Msp { @@ -20,19 +20,24 @@ protected: typedef std::vector *> ShapeArray; ShapeArray shapes; + unsigned max_isect; + unsigned min_scratch; CompositeShape() { } CompositeShape(const Shape &, const Shape &); - CompositeShape(const CompositeShape &); - CompositeShape &operator=(const CompositeShape &); template void init_from_iter_range(const Iter &, const Iter &); +private: + void init(); +protected: + CompositeShape(const CompositeShape &); + CompositeShape &operator=(const CompositeShape &); public: virtual ~CompositeShape(); virtual BoundingBox get_axis_aligned_bounding_box() const; virtual bool contains(const LinAl::Vector &) const; - virtual unsigned get_max_ray_intersections() const; + virtual unsigned get_max_ray_intersections() const { return max_isect; } virtual unsigned get_intersections(const Ray &, SurfacePoint *, unsigned) const; }; @@ -42,6 +47,7 @@ inline CompositeShape::CompositeShape(const Shape &s1, const Shap shapes.reserve(2); shapes.push_back(s1.clone()); shapes.push_back(s2.clone()); + init(); } template @@ -53,14 +59,44 @@ inline void CompositeShape::init_from_iter_range(const Iter &begin, con for(Iter i=begin; i!=end; ++i) shapes.push_back((*i)->clone()); + init(); } template -inline CompositeShape::CompositeShape(const CompositeShape &other) +inline void CompositeShape::init() { - shapes.reserve(other.shapes.size()); - for(typename ShapeArray::const_iterator i=other.shapes.begin(); i!=other.shapes.end(); ++i) - shapes.push_back((*i)->clone()); + max_isect = 0; + min_scratch = 0; + for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i) + { + unsigned mi = (*i)->get_max_ray_intersections(); + max_isect += mi; + min_scratch = std::max(min_scratch, mi); + } +} + +template +inline CompositeShape::CompositeShape(const CompositeShape &other): + shapes(other.shapes), + max_isect(other.max_isect), + min_scratch(other.min_scratch) +{ + 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(); + + max_isect = other.max_isect; + min_scratch = other.min_scratch; } template @@ -97,26 +133,25 @@ inline bool CompositeShape::contains(const LinAl::Vector &point) return inside; } -template -inline unsigned CompositeShape::get_max_ray_intersections() const -{ - unsigned max_isect = 0; - for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i) - max_isect += (*i)->get_max_ray_intersections(); - return max_isect; -} - template inline unsigned CompositeShape::get_intersections(const Ray &ray, SurfacePoint *points, unsigned size) const { + SurfacePoint *buffer = points; + unsigned buf_size = size; + if(!points) + { + buffer = new SurfacePoint[min_scratch]; + buf_size = min_scratch; + } + unsigned n = 0; for(typename ShapeArray::const_iterator i=shapes.begin(); (nget_intersections(ray, points+base, size-base); + unsigned base = (points ? n : 0); + unsigned count = (*i)->get_intersections(ray, buffer+base, buf_size-base); for(unsigned j=0; (n &pt = points[base+j]; + SurfacePoint &pt = buffer[base+j]; bool surface = Ops::init_surface(); for(typename ShapeArray::const_iterator k=shapes.begin(); k!=shapes.end(); ++k) @@ -133,7 +168,10 @@ inline unsigned CompositeShape::get_intersections(const Ray &ray, } } - sort_points(points, n); + if(points) + sort_points(points, n); + else + delete[] buffer; return n; }