/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLGeom/src/ICLGeom/RayCastOctreeObject.cpp ** ** Module : ICLGeom ** ** Authors: Christof Elbrechter ** ** ** ** ** ** GNU LESSER GENERAL PUBLIC LICENSE ** ** This file may be used under the terms of the GNU Lesser General ** ** Public License version 3.0 as published by the ** ** ** ** Free Software Foundation and appearing in the file LICENSE.LGPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the license requirements will ** ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** ********************************************************************/ #include #include namespace icl{ using namespace utils; namespace geom{ inline float sqr_ray_point_dist(const ViewRay &ray, const Vec &p){ const Vec x = p-ray.offset; return sqrnorm3(x)-sqr(sprod3(x,ray.direction)); } inline bool cmp_2nd(const std::pair &a, const std::pair &b){ return a.second < b.second; } static std::vector > compute_idx_dists(const Vec &o, const std::vector &rays){ std::vector > sv(rays.size()); for(size_t i=0;i &result){ for(const Vec *p=n->points; pnext;++p){ if(sqr_ray_point_dist(ray,*p) < maxSqrDist){ result.push_back(*p); } } if(n->children){ for(int i=0;i<8;++i){ const Super::AABB &aabb = n->children[i].boundary; if(sqr_ray_point_dist(ray,aabb.center) <= sqr(n->children[i].radius+maxDist)){ ray_cast_sqr_rec(n->children+i,ray,maxSqrDist, maxDist, result); } } } } void RayCastOctreeObject::ray_cast_sqr_rec_debug(const RayCastOctreeObject::Super::Node *n, const ViewRay &ray, float maxSqrDist, float maxDist, std::vector &result, std::vector &boxes, std::vector &points){ boxes.push_back(n->boundary); for(const Vec *p=n->points; pnext;++p){ points.push_back(*p); if(sqr_ray_point_dist(ray,*p) < maxSqrDist){ result.push_back(*p); } } if(n->children){ for(int i=0;i<8;++i){ const Super::AABB &aabb = n->children[i].boundary; if(sqr_ray_point_dist(ray,aabb.center) <= sqr(n->children[i].radius+maxDist)){ ray_cast_sqr_rec_debug(n->children+i,ray,maxSqrDist, maxDist, result, boxes, points); } } } } std::vector RayCastOctreeObject::rayCast(const ViewRay &ray, float maxDist) const{ const float maxSqrDist = sqr(maxDist); std::vector result; result.reserve(4); ray_cast_sqr_rec(Super::root, ray, maxSqrDist, maxDist, result); return result; } std::vector RayCastOctreeObject::rayCastDebug(const ViewRay &ray, float maxDist, std::vector &boxes, std::vector &points) const{ const float maxSqrDist = sqr(maxDist); std::vector result; result.reserve(4); ray_cast_sqr_rec_debug(Super::root, ray, maxSqrDist, maxDist, result, boxes, points); return result; } std::vector RayCastOctreeObject::rayCastSort(const ViewRay &ray, float maxDist) const{ std::vector rays = rayCast(ray,maxDist); std::vector > sv = compute_idx_dists(ray.offset, rays); std::sort(sv.begin(),sv.end(),cmp_2nd); std::vector raysSorted(rays.size()); for(size_t i=0;i rays = rayCast(ray,maxDist); if(!rays.size()) throw ICLException("RayCastOctreeObject::rayCastClosest:" " no point found in radius" ); std::vector > sv = compute_idx_dists(ray.offset, rays); return rays[std::min_element(sv.begin(),sv.end(), cmp_2nd)->first]; } } }