diff --git a/src/osgSim/SphereSegment.cpp b/src/osgSim/SphereSegment.cpp index 09c99dcaf..27c33bf01 100644 --- a/src/osgSim/SphereSegment.cpp +++ b/src/osgSim/SphereSegment.cpp @@ -1276,9 +1276,158 @@ struct TriangleIntersectOperator Edge* _e2; Edge* _e3; }; + + struct Region + { + enum Classification + { + INSIDE = -1, + INTERSECTS = 0, + OUTSIDE = 1 + }; + + Region(): + _radiusSurface(OUTSIDE), + _leftSurface(OUTSIDE), + _rightSurface(OUTSIDE), + _bottomSurface(OUTSIDE), + _topSurface(OUTSIDE) {} + + + + void classify(const osg::Vec3& vertex, double radius2, double azimMin, double azimMax, double elevMin, double elevMax) + { + + double rad2 = vertex.length2(); + double length_xy = sqrtf(vertex.x()*vertex.x() + vertex.y()*vertex.y()); + double elevation = atan2(vertex.z(),length_xy); + double azim = atan2(vertex.x(),vertex.y()); + if (azim<0.0) azim += 2.0*osg::PI; + + // radius surface + if (rad2 > radius2) _radiusSurface = OUTSIDE; + else if (rad2 < radius2) _radiusSurface = INSIDE; + else _radiusSurface = INTERSECTS; + + // bottom surface + if (elevationelevMin) _bottomSurface = INSIDE; + else _bottomSurface = INTERSECTS; + + // top surface + if (elevation>elevMax) _topSurface = OUTSIDE; + else if (elevationazimMin) _leftSurface = INSIDE; + else _leftSurface = INTERSECTS; + + // right surface + if (azim>azimMax) _rightSurface = OUTSIDE; + else if (azim VertexArray; - typedef std::vector< int > RegionArray; + typedef std::vector< Region > RegionArray; typedef std::vector< bool > BoolArray; typedef std::vector< unsigned int > IndexArray; typedef std::vector< osg::ref_ptr > TriangleArray; @@ -1306,7 +1455,7 @@ struct TriangleIntersectOperator void computePositionAndRegions(const osg::Matrixd& matrix, osg::Vec3Array& array) { _originalVertices.resize(array.size()); - _regions.resize(array.size(), 1); + _regions.resize(array.size()); _vertexInIntersectionSet.resize(array.size(), false); _candidateVertexIndices.clear(); @@ -1316,56 +1465,28 @@ struct TriangleIntersectOperator { osg::Vec3 vertex = array[i]*matrix - _centre; _originalVertices[i] = vertex; - double rad2 = vertex.length2(); - if (rad2 > radius2) - { - _regions[i] = 1; - } - else - { - double length_xy = sqrtf(vertex.x()*vertex.x() + vertex.y()*vertex.y()); - double elevation = atan2(vertex.z(),length_xy); - if (elevation<_elevMin || elevation>_elevMax) - { - _regions[i] = 1; - } - else - { - double azim = atan2(vertex.x(),vertex.y()); - if (azim<0.0) azim += 2.0*osg::PI; - if (azim<_azMin || azim>_azMax) - { - _regions[i] = 1; - } - else - { - if (rad2==radius2 || elevation==_elevMin || elevation==_elevMax || azim==_azMin || azim==_azMax) - { - _regions[i] = 0; - } - else - { - _regions[i] = -1; - } - - } - } - - } + _regions[i].classify(vertex, radius2, _azMin, _azMax, _elevMin, _elevMax); } } inline void operator()(unsigned int p1, unsigned int p2, unsigned int p3) { + RegionCounter rc; + rc.add(_regions[p1]); + rc.add(_regions[p2]); + rc.add(_regions[p3]); + + Region::Classification classification = rc.overallClassification(); + // reject if outside. - if (_regions[p1]==1 && _regions[p2]==1 && _regions[p3]==1) + if (classification==Region::OUTSIDE) { ++_numOutside; return; } - if (_regions[p1]==-1 && _regions[p2]==-1 && _regions[p3]==-1) + if (classification==Region::INSIDE) { ++_numInside; return; @@ -1516,8 +1637,15 @@ struct TriangleIntersectOperator Edge* addEdge(unsigned int p1, unsigned int p2, Triangle* tri) { - if ((_regions[p1]==_regions[p2]) && _regions[p1]!=0) return 0; - + RegionCounter rc; + rc.add(_regions[p1]); + rc.add(_regions[p2]); + +#if 0 +// the fact I have to comment this check out suggest that there is a problem elsewhere... + Region::Classification classification = rc.overallClassification(); + if (classification==Region::OUTSIDE || classification==Region::INSIDE) return 0; +#endif osg::ref_ptr edge = new Edge(p1, p2); EdgeSet::iterator itr = _edges.find(edge); if (itr==_edges.end()) @@ -1534,21 +1662,8 @@ struct TriangleIntersectOperator } } - template - void computeIntersections(I intersector) + void connectIntersections(EdgeList& hitEdges) { - // collect all the intersecting edges - EdgeList hitEdges; - for(EdgeSet::iterator itr = _edges.begin(); - itr != _edges.end(); - ++itr) - { - Edge* edge = const_cast(itr->get()); - if (intersector(edge)) - { - hitEdges.push_back(edge); - } - } osg::notify(osg::NOTICE)<<"Number of edge intersections "< + void computeIntersections(I intersector) + { + // collect all the intersecting edges + EdgeList hitEdges; + for(EdgeSet::iterator itr = _edges.begin(); + itr != _edges.end(); + ++itr) + { + Edge* edge = const_cast(itr->get()); + if (intersector(edge)) + { + hitEdges.push_back(edge); + } + } + + connectIntersections(hitEdges); + } }; bool computeQuadraticSolution(double a, double b, double c, double& s1, double& s2) @@ -1750,6 +1884,13 @@ struct AzimIntersector } double r = (t*v1.y()-v1.x()) / div; + if (r<0.0 || r>1.0) + { + edge->_intersectionType = TriangleIntersectOperator::Edge::NO_INTERSECTION; + return false; + } + + double one_minus_r = 1.0f-r; edge->_intersectionType = TriangleIntersectOperator::Edge::MID_POINT;