diff --git a/src/osgSim/SphereSegment.cpp b/src/osgSim/SphereSegment.cpp index db1b22b77..422b0e7a8 100644 --- a/src/osgSim/SphereSegment.cpp +++ b/src/osgSim/SphereSegment.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -1119,6 +1120,49 @@ SphereSegment::LineList SphereSegment::computeIntersection(const osg::Matrixd& t return all_lines; } +osg::Node* SphereSegment::computeIntersectionSubgraph(const osg::Matrixd& transform, osg::Node* subgraph) +{ + osg::notify(osg::NOTICE)<<"Creating line intersection between sphere segment and subgraph."<accept(polytopeVisitor); + + if (polytopeVisitor.getHits().empty()) + { + osg::notify(osg::NOTICE)<<"No hits found."<addChild(computeIntersectionSubgraph(itr->_matrix, itr->_drawable.get())); + } + + // join all the lines that have ends that are close together.. + + return group; +} struct dereference_less { @@ -1158,6 +1202,16 @@ struct TriangleIntersectOperator _numInside(0), _numIntersecting(0) {} + enum SurfaceType + { + NO_SURFACE = 0, + RADIUS_SURFACE, + LEFT_SURFACE, + RIGHT_SURFACE, + BOTTOM_SURFACE, + TOP_SURFACE + }; + struct Triangle; struct Edge : public osg::Referenced @@ -1173,7 +1227,7 @@ struct TriangleIntersectOperator BOTH_ENDS }; - Edge(unsigned int p1, unsigned int p2, bool intersectionEdge=false): + Edge(unsigned int p1, unsigned int p2, SurfaceType intersectionEdge=NO_SURFACE): _intersectionType(NO_INTERSECTION), _intersectionVertexIndex(0), _p1Outside(false), @@ -1226,7 +1280,7 @@ struct TriangleIntersectOperator bool _p1Outside; bool _p2Outside; TriangleList _toTraverse; - bool _intersectionEdge; + SurfaceType _intersectionEdge; }; typedef std::list< osg::ref_ptr > EdgeList; @@ -1305,197 +1359,9 @@ struct TriangleIntersectOperator } template - unsigned int computeHitEdges(TriangleIntersectOperator& tio, I intersector) - { - // collect all the intersecting edges - EdgeList hitEdges; - for(EdgeList::iterator itr = _edges.begin(); - itr != _edges.end(); - ++itr) - { - Edge* edge = const_cast(itr->get()); - if (intersector(edge)) hitEdges.push_back(edge); - } - - if (hitEdges.empty()) return 0; - - - unsigned int numHitEdges = hitEdges.size(); - - EdgeList newEdgeList; - - osg::notify(osg::NOTICE)<<"Num Hit edges"<=2) - { - Edge* edge1 = hitEdges.front().get(); hitEdges.pop_front(); - int p1 = tio._originalVertices.size(); - edge1->_intersectionVertexIndex = p1; - tio._originalVertices.push_back(edge1->_intersectionVertex); - - Edge* edge2 = hitEdges.front().get(); hitEdges.pop_front(); - int p2 = tio._originalVertices.size(); - edge2->_intersectionVertexIndex = p2; - tio._originalVertices.push_back(edge2->_intersectionVertex); - - newEdgeList.push_back(new Edge(p1,p2,true)); - } - - for(EdgeList::iterator itr = _edges.begin(); - itr != _edges.end(); - ++itr) - { - Edge* edge = const_cast(itr->get()); - if (!(edge->completlyOutside())) - { - if (edge->_intersectionType==Edge::NO_INTERSECTION) - { - newEdgeList.push_back(edge); - } - else - { - if (!edge->_p1Outside) - { - newEdgeList.push_back(new Edge(edge->_intersectionVertexIndex, edge->_p1, edge->_intersectionEdge)); - } - else if (!edge->_p2Outside) - { - newEdgeList.push_back(new Edge(edge->_intersectionVertexIndex, edge->_p2, edge->_intersectionEdge)); - } - else - { - osg::notify(osg::NOTICE)<<"Problem"< > EdgeVector; - EdgeVector edges; - for(EdgeList::const_iterator itr = _edges.begin(); - itr != _edges.end(); - ++itr) - { - if ((*itr)->_intersectionEdge) - { - osg::notify(osg::NOTICE)<<" accepting edge "<<(*itr)->_p1<<" "<<(*itr)->_p2<_p1<<" "<<(*itr)->_p2<_p1 == edges[j]->_p1) || (edges[i]->_p1 == edges[j]->_p2)) - { - ++numMatchesFor_p1; - } - - if ((edges[i]->_p2 == edges[j]->_p1) || (edges[i]->_p2 == edges[j]->_p2)) - { - ++numMatchesFor_p2; - } - } - if (numMatchesFor_p1==0) break; - if (numMatchesFor_p2==0) break; - } - - // get first edge. - osg::ref_ptr edge = edges[i]; - edges.erase(edges.begin()+i); - - // start a new line, add it to the list of lines. - osg::Vec3Array* newLine = new osg::Vec3Array; - generatedLines.push_back(newLine); - - unsigned int activePoint = 0; - if (numMatchesFor_p1==0) - { - newLine->push_back(tio._originalVertices[edge->_p1]+tio._centre); - newLine->push_back(tio._originalVertices[edge->_p2]+tio._centre); - activePoint = edge->_p2; - } - else - { - newLine->push_back(tio._originalVertices[edge->_p2]+tio._centre); - newLine->push_back(tio._originalVertices[edge->_p1]+tio._centre); - activePoint = edge->_p1; - } - - osg::notify(osg::NOTICE)<<"Start with "<_p1<<" "<_p2<<" activePoint="<_p1 == activePoint) - { - - activePoint = (*itr)->_p2; - newLine->push_back(tio._originalVertices[activePoint]+tio._centre); - - osg::notify(osg::NOTICE)<<"A Found "<<(*itr)->_p1<<" "<<(*itr)->_p2<<" activePoint="<_p2 == activePoint) - { - activePoint = (*itr)->_p1; - newLine->push_back(tio._originalVertices[activePoint]+tio._centre); - osg::notify(osg::NOTICE)<<"B Found "<<(*itr)->_p1<<" "<<(*itr)->_p2<<" activePoint="< edge = edges.front(); - edges.erase(edges.begin()); - - newLine->push_back(tio._originalVertices[edge->_p1]+tio._centre); - newLine->push_back(tio._originalVertices[edge->_p2]+tio._centre); - activePoint = edge->_p2; - - osg::notify(osg::NOTICE)<<"*********** Problem 2 with "<_p1<<" "<_p2<<" activePoint="< radius2) _radiusSurface = OUTSIDE; else if (rad2 < radius2) _radiusSurface = INSIDE; @@ -1543,15 +1413,26 @@ struct TriangleIntersectOperator else if (elevationazimMin) _leftSurface = INSIDE; - else _leftSurface = INTERSECTS; - - // right surface - if (azim>azimMax) _rightSurface = OUTSIDE; - else if (azimazimRange) + { + _leftSurface = (azimDelta<-azimRange || azimDelta>(osg::PI-azimRange)) ? OUTSIDE : INSIDE; + _rightSurface = (azimDelta>azimRange || azimDelta<(azimRange-osg::PI)) ? OUTSIDE : INSIDE; + } + else if (azimDelta==-azimRange) + { + _leftSurface = INTERSECTS; + _rightSurface = INSIDE; + } + else if (azimDelta==azimRange) + { + _leftSurface = INSIDE; + _rightSurface = INTERSECTS; + } + else + { + _leftSurface = INSIDE; + _rightSurface = INSIDE; + } } Classification _radiusSurface; @@ -1626,6 +1507,44 @@ struct TriangleIntersectOperator return Region::INTERSECTS; } + Region::Classification overallClassification(SurfaceType surfaceType, SurfaceType assocatedSurfaceType) const + { + // if all vertices are outside any of the surfaces then we are completely outside + if ((assocatedSurfaceType!=RADIUS_SURFACE && surfaceType!=RADIUS_SURFACE && _outside_radiusSurface==_numVertices) || + (assocatedSurfaceType!=LEFT_SURFACE && surfaceType!=LEFT_SURFACE && _outside_leftSurface==_numVertices) || + (assocatedSurfaceType!=RIGHT_SURFACE && surfaceType!=RIGHT_SURFACE && _outside_rightSurface==_numVertices) || + (assocatedSurfaceType!=TOP_SURFACE && surfaceType!=TOP_SURFACE && _outside_topSurface==_numVertices) || + (assocatedSurfaceType!=BOTTOM_SURFACE && surfaceType!=BOTTOM_SURFACE && _outside_bottomSurface==_numVertices)) return Region::OUTSIDE; + + // if all the vertices on all the sides and inside then we are completely inside + if ((assocatedSurfaceType!=RADIUS_SURFACE && surfaceType!=RADIUS_SURFACE && _inside_radiusSurface==_numVertices) && + (assocatedSurfaceType!=LEFT_SURFACE && surfaceType!=LEFT_SURFACE && _inside_leftSurface==_numVertices) && + (assocatedSurfaceType!=RIGHT_SURFACE && surfaceType!=RIGHT_SURFACE && _inside_rightSurface==_numVertices) && + (assocatedSurfaceType!=TOP_SURFACE && surfaceType!=TOP_SURFACE && _inside_topSurface==_numVertices) && + (assocatedSurfaceType!=BOTTOM_SURFACE && surfaceType!=BOTTOM_SURFACE && _inside_bottomSurface==_numVertices)) return Region::INSIDE; + + return Region::INTERSECTS; + } + + bool intersecting(SurfaceType surfaceType) const + { + // if all vertices are outside any of the surfaces then we are completely outside + if ((surfaceType!=RADIUS_SURFACE && _outside_radiusSurface!=0) || + (surfaceType!=LEFT_SURFACE && _outside_leftSurface!=0) || + (surfaceType!=RIGHT_SURFACE && _outside_rightSurface!=0) || + (surfaceType!=TOP_SURFACE && _outside_topSurface!=0) || + (surfaceType!=BOTTOM_SURFACE && _outside_bottomSurface!=0)) return false; + + // if all the vertices on all the sides and inside then we are completely inside + if ((surfaceType!=RADIUS_SURFACE && _inside_radiusSurface!=0) && + (surfaceType!=LEFT_SURFACE && _inside_leftSurface!=0) && + (surfaceType!=RIGHT_SURFACE && _inside_rightSurface!=0) && + (surfaceType!=TOP_SURFACE && _inside_topSurface!=0) && + (surfaceType!=BOTTOM_SURFACE && _inside_bottomSurface!=0)) return false; + + return true; + } + int numberOfIntersectingSurfaces() const { int sidesThatIntersect = 0; @@ -2401,6 +2320,254 @@ struct RadiusIntersector }; +template +unsigned int TriangleIntersectOperator::Polygon::computeHitEdges(TriangleIntersectOperator& tio, I intersector, SurfaceType surfaceType) +{ + // collect all the intersecting edges + EdgeList hitEdges; + for(EdgeList::iterator itr = _edges.begin(); + itr != _edges.end(); + ++itr) + { + Edge* edge = const_cast(itr->get()); + if (intersector(edge)) hitEdges.push_back(edge); + } + + if (hitEdges.empty()) return 0; + + + unsigned int numHitEdges = hitEdges.size(); + + EdgeList newEdgeList; + + double radius2 = tio._radius*tio._radius; + + osg::notify(osg::NOTICE)<<"Num Hit edges"<=2) + { + Edge* edge1 = hitEdges.front().get(); hitEdges.pop_front(); + int p1 = tio._originalVertices.size(); + edge1->_intersectionVertexIndex = p1; + tio._originalVertices.push_back(edge1->_intersectionVertex); + tio._regions.push_back(Region()); + tio._regions[p1].classify(edge1->_intersectionVertex, radius2, tio._azMin, tio._azMax, tio._elevMin, tio._elevMax); + + Edge* edge2 = hitEdges.front().get(); hitEdges.pop_front(); + int p2 = tio._originalVertices.size(); + edge2->_intersectionVertexIndex = p2; + tio._originalVertices.push_back(edge2->_intersectionVertex); + tio._regions.push_back(Region()); + tio._regions[p2].classify(edge2->_intersectionVertex, radius2, tio._azMin, tio._azMax, tio._elevMin, tio._elevMax); + + newEdgeList.push_back(new Edge(p1,p2,surfaceType)); + } + + for(EdgeList::iterator itr = _edges.begin(); + itr != _edges.end(); + ++itr) + { + Edge* edge = const_cast(itr->get()); + if (!(edge->completlyOutside())) + { + if (edge->_intersectionType==Edge::NO_INTERSECTION) + { + newEdgeList.push_back(edge); + } + else + { + if (!edge->_p1Outside) + { + newEdgeList.push_back(new Edge(edge->_intersectionVertexIndex, edge->_p1, edge->_intersectionEdge)); + } + else if (!edge->_p2Outside) + { + newEdgeList.push_back(new Edge(edge->_intersectionVertexIndex, edge->_p2, edge->_intersectionEdge)); + } + else + { + osg::notify(osg::NOTICE)<<"Problem"< > EdgeVector; + EdgeVector edges; + for(EdgeList::const_iterator itr = _edges.begin(); + itr != _edges.end(); + ++itr) + { + +#if 0 +// if ((*itr)->_intersectionEdge) + { + edges.push_back(*itr); + } +#else + if ((*itr)->_intersectionEdge) + { + + RegionCounter rc; + rc.add(tio._regions[(*itr)->_p1]); + rc.add(tio._regions[(*itr)->_p2]); + +#if 1 + + Region::Classification classification = rc.overallClassification((*itr)->_intersectionEdge, adjacentEdge[(*itr)->_intersectionEdge]); + +// Region::Classification classification = rc.overallClassification(); + + // reject if outside. + if (classification==Region::OUTSIDE) + { + osg::notify(osg::NOTICE)<<" disgarding outside edge "<<(*itr)->_p1<<" "<<(*itr)->_p2<_p1<<" "<<(*itr)->_p2<_p1<<" "<<(*itr)->_p2<_intersectionEdge)) + { + osg::notify(osg::NOTICE)<<" accepting edge "<<(*itr)->_p1<<" "<<(*itr)->_p2<_p1<<" "<<(*itr)->_p2<_p1 == edges[j]->_p1) || (edges[i]->_p1 == edges[j]->_p2)) + { + ++numMatchesFor_p1; + } + + if ((edges[i]->_p2 == edges[j]->_p1) || (edges[i]->_p2 == edges[j]->_p2)) + { + ++numMatchesFor_p2; + } + } + if (numMatchesFor_p1==0) break; + if (numMatchesFor_p2==0) break; + } + + // get first edge. + osg::ref_ptr edge = edges[i]; + edges.erase(edges.begin()+i); + + // start a new line, add it to the list of lines. + osg::Vec3Array* newLine = new osg::Vec3Array; + generatedLines.push_back(newLine); + + unsigned int activePoint = 0; + if (numMatchesFor_p1==0) + { + newLine->push_back(tio._originalVertices[edge->_p1]+tio._centre); + newLine->push_back(tio._originalVertices[edge->_p2]+tio._centre); + activePoint = edge->_p2; + } + else + { + newLine->push_back(tio._originalVertices[edge->_p2]+tio._centre); + newLine->push_back(tio._originalVertices[edge->_p1]+tio._centre); + activePoint = edge->_p1; + } + + osg::notify(osg::NOTICE)<<"Start with "<_p1<<" "<_p2<<" activePoint="<_p1 == activePoint) + { + + activePoint = (*itr)->_p2; + newLine->push_back(tio._originalVertices[activePoint]+tio._centre); + + osg::notify(osg::NOTICE)<<"A Found "<<(*itr)->_p1<<" "<<(*itr)->_p2<<" activePoint="<_p2 == activePoint) + { + activePoint = (*itr)->_p1; + newLine->push_back(tio._originalVertices[activePoint]+tio._centre); + osg::notify(osg::NOTICE)<<"B Found "<<(*itr)->_p1<<" "<<(*itr)->_p2<<" activePoint="< edge = edges.front(); + edges.erase(edges.begin()); + + newLine->push_back(tio._originalVertices[edge->_p1]+tio._centre); + newLine->push_back(tio._originalVertices[edge->_p2]+tio._centre); + activePoint = edge->_p2; + + osg::notify(osg::NOTICE)<<"*********** Problem 2 with "<_p1<<" "<_p2<<" activePoint="<