1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 20017 Robert Osfield 2 * 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 5 * (at your option) any later version. The full license is in LICENSE file 6 * included with this distribution, and on the openscenegraph.org website. 7 * 8 * This library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * OpenSceneGraph Public License for more details. 12 */ 13 14 #include <osg/Polytope> 15 #include <osg/Notify> 16 17 using namespace osg; 18 contains(const osg::Vec3f & v0,const osg::Vec3f & v1,const osg::Vec3f & v2) const19bool Polytope::contains(const osg::Vec3f& v0, const osg::Vec3f& v1, const osg::Vec3f& v2) const 20 { 21 if (!_maskStack.back()) return true; 22 23 // initialize the set of vertices to test. 24 typedef std::vector<osg::Vec3d> Vertices; 25 26 Vertices src, dest; 27 src.reserve(4+_planeList.size()); 28 dest.reserve(4+_planeList.size()); 29 30 src.push_back(v0); 31 src.push_back(v1); 32 src.push_back(v2); 33 src.push_back(v0); 34 35 ClippingMask resultMask = _maskStack.back(); 36 ClippingMask selector_mask = 0x1; 37 38 for(PlaneList::const_iterator pitr = _planeList.begin(); 39 pitr != _planeList.end(); 40 ++pitr) 41 { 42 if (resultMask&selector_mask) 43 { 44 //OSG_NOTICE<<"Polytope::contains() Plane testing"<<std::endl; 45 46 dest.clear(); 47 48 const osg::Plane& plane = *pitr; 49 Vertices::iterator vitr = src.begin(); 50 51 osg::Vec3d* v_previous = &(*(vitr++)); 52 double d_previous = plane.distance(*v_previous); 53 54 for(; vitr != src.end(); ++vitr) 55 { 56 osg::Vec3d* v_current = &(*vitr); 57 double d_current = plane.distance(*v_current); 58 59 if (d_previous>=0.0) 60 { 61 dest.push_back(*v_previous); 62 } 63 64 if (d_previous*d_current<0.0) 65 { 66 // edge crosses plane so insert the vertex between them. 67 double distance = d_previous-d_current; 68 double r_current = d_previous/distance; 69 osg::Vec3d v_new = (*v_previous)*(1.0-r_current) + (*v_current)*r_current; 70 dest.push_back(v_new); 71 } 72 73 d_previous = d_current; 74 v_previous = v_current; 75 76 } 77 78 if (d_previous>=0.0) 79 { 80 dest.push_back(*v_previous); 81 } 82 83 if (dest.size()<=1) 84 { 85 // OSG_NOTICE<<"Polytope::contains() All points on triangle culled, dest.size()="<<dest.size()<<std::endl; 86 return false; 87 } 88 89 dest.swap(src); 90 } 91 else 92 { 93 // OSG_NOTICE<<"Polytope::contains() Plane disabled"<<std::endl; 94 } 95 96 selector_mask <<= 1; 97 } 98 99 //OSG_NOTICE<<"Polytope::contains() triangle within Polytope, src.size()="<<src.size()<<std::endl; 100 return true; 101 } 102