From a510ecf5bdfbdca6748951bc4e8cb145254b3b15 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 30 May 2007 14:18:33 +0000 Subject: [PATCH] Added trapezodial fitting code --- src/osgSim/OverlayNode.cpp | 278 +++++++++++++++++++++++++++++++++---- 1 file changed, 254 insertions(+), 24 deletions(-) diff --git a/src/osgSim/OverlayNode.cpp b/src/osgSim/OverlayNode.cpp index f5739536d..589d7919e 100644 --- a/src/osgSim/OverlayNode.cpp +++ b/src/osgSim/OverlayNode.cpp @@ -38,6 +38,7 @@ public: struct Face { + std::string name; osg::Plane plane; Vertices vertices; }; @@ -61,6 +62,7 @@ public: { // left plane. Face& face = createFace(); + face.name = "left"; face.plane.set(1.0,0.0,0.0,1.0); face.vertices.push_back(v000); face.vertices.push_back(v001); @@ -70,6 +72,7 @@ public: { // right plane. Face& face = createFace(); + face.name = "right"; face.plane.set(-1.0,0.0,0.0,1.0); face.vertices.push_back(v100); face.vertices.push_back(v110); @@ -79,6 +82,7 @@ public: { // bottom plane. Face& face = createFace(); + face.name = "bottom"; face.plane.set(0.0,1.0,0.0,1.0); face.vertices.push_back(v000); face.vertices.push_back(v100); @@ -88,6 +92,7 @@ public: { // top plane. Face& face = createFace(); + face.name = "top"; face.plane.set(0.0,-1.0,0.0,1.0); face.vertices.push_back(v111); face.vertices.push_back(v011); @@ -98,6 +103,7 @@ public: if (withNear) { // near plane Face& face = createFace(); + face.name = "near"; face.plane.set(0.0,0.0,-1.0,1.0); face.vertices.push_back(v000); face.vertices.push_back(v010); @@ -108,6 +114,7 @@ public: if (withFar) { // far plane Face& face = createFace(); + face.name = "far"; face.plane.set(0.0,0.0,1.0,1.0); face.vertices.push_back(v001); face.vertices.push_back(v101); @@ -137,6 +144,7 @@ public: { // x min plane Face& face = createFace(); + face.name = "xMin"; face.plane.set(1.0,0.0,0.0,-bb.xMin()); face.vertices.push_back(v000); face.vertices.push_back(v001); @@ -146,6 +154,7 @@ public: { // x max plane. Face& face = createFace(); + face.name = "xMax"; face.plane.set(-1.0,0.0,0.0,bb.xMax()); face.vertices.push_back(v100); face.vertices.push_back(v110); @@ -155,6 +164,7 @@ public: { // y min plane. Face& face = createFace(); + face.name = "yMin"; face.plane.set(0.0,1.0,0.0,-bb.yMin()); face.vertices.push_back(v000); face.vertices.push_back(v100); @@ -164,6 +174,7 @@ public: { // y max plane. Face& face = createFace(); + face.name = "yMax"; face.plane.set(0.0,-1.0,0.0,bb.yMax()); face.vertices.push_back(v111); face.vertices.push_back(v011); @@ -172,6 +183,7 @@ public: } { // z min plane Face& face = createFace(); + face.name = "zMin"; face.plane.set(0.0,0.0,1.0,-bb.zMin()); face.vertices.push_back(v000); face.vertices.push_back(v010); @@ -181,6 +193,7 @@ public: { // z max plane Face& face = createFace(); + face.name = "zMax"; face.plane.set(0.0,0.0,-1.0,bb.zMax()); face.vertices.push_back(v001); face.vertices.push_back(v101); @@ -272,6 +285,7 @@ public: // osg::notify(osg::NOTICE)<<" edge Ok"<first; Face face; + face.name = "baseSide"; face.plane.set(vertex, edge.first, edge.second); face.vertices.push_back(vertex); face.vertices.push_back(edge.first); @@ -320,7 +334,7 @@ public: osg::Plane basePlane(normal, center); - cut(basePlane); + cut(basePlane,"basePlane"); } @@ -399,6 +413,7 @@ public: osg::Vec3d projected_second = edge.second - normal * h_second; Face face; + face.name = "baseSide"; face.plane.set(projected_first, edge.first, edge.second); face.vertices.push_back(projected_first); face.vertices.push_back(projected_second); @@ -414,6 +429,7 @@ public: } Face newFace; + newFace.name = "basePlane"; newFace.plane.set(normal,control); osg::Vec3d side = ( fabs(normal.x()) < fabs(normal.y()) ) ? @@ -448,6 +464,113 @@ public: _faces.push_back(newFace); + } + + void computeSilhoette(const osg::Vec3d& normal, Vertices& vertices) + { + + typedef std::pair EdgePair; + typedef std::vector EdgeFaces; + typedef std::map EdgeMap; + + EdgeMap edgeMap; + + + for(Faces::iterator itr = _faces.begin(); + itr != _faces.end(); + ++itr) + { + Face& face = *itr; + for(unsigned int i=0; i VertexSet; + VertexSet uniqueVertices; + + for(EdgeMap::iterator eitr = edgeMap.begin(); + eitr != edgeMap.end(); + ++eitr) + { + const EdgePair& edge = eitr->first; + const EdgeFaces& edgeFaces = eitr->second; + if (edgeFaces.size()==1) + { + // osg::notify(osg::NOTICE)<<"Open edge found "<name<plane.getNormal() * normal; + double dotProduct1 = edgeFaces[1]->plane.getNormal() * normal; + if (dotProduct0 * dotProduct1 <0.0) + { + // osg::notify(osg::NOTICE)<<" Silhoette edge found "<name<<" "<name<name<<" "<name< AnglePositions; + AnglePositions anglePositions; + for(vitr = uniqueVertices.begin(); + vitr != uniqueVertices.end(); + ++vitr) + { + osg::Vec3d delta = *vitr - center; + double angle = atan2(delta * u, delta * v); + if (angle<0.0) angle += 2.0*osg::PI; + anglePositions[angle] = *vitr; + } + + for(AnglePositions::iterator aitr = anglePositions.begin(); + aitr != anglePositions.end(); + ++aitr) + { + vertices.push_back(aitr->second); + } + + } @@ -469,11 +592,11 @@ public: itr != polytope._faces.end(); ++itr) { - cut(itr->plane); + cut(itr->plane, itr->name); } } - void cut(const osg::Plane& plane) + void cut(const osg::Plane& plane, const std::string& name=std::string()) { // osg::notify(osg::NOTICE)<<" Cutting plane "<addDrawable(frustum.createDrawable(osg::Vec4d(0.0f,0.0f,1.0f,1.0f))); } - CustomPolytope::Vertices corners; - overlayPolytope.cut(frustum); - overlayPolytope.getPoints(corners); - - if (overlayData._geode.valid()) - { - overlayData._geode->addDrawable(overlayPolytope.createDrawable(osg::Vec4d(1.0f,1.0f,1.0f,1.0f))); - } // osg::notify(osg::NOTICE)<<"AFTER CUT corners = "<getBound().center(); osg::Vec3d frustum_axis = cv->getLookVectorLocal(); @@ -1207,36 +1322,151 @@ void OverlayNode::traverse_VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY(osg::NodeVis osg::Vec3d overlayLookVector = upVector ^ sideVector; overlayLookVector.normalize(); + + overlayPolytope.cut(frustum); + + CustomPolytope::Vertices corners; +#if 0 + overlayPolytope.getPoints(corners); +#else + overlayPolytope.computeSilhoette(lookVector, corners); +#endif + if (corners.empty()) return; + + if (overlayData._geode.valid()) + { + overlayData._geode->addDrawable(overlayPolytope.createDrawable(osg::Vec4d(1.0f,1.0f,1.0f,1.0f))); + } + + // osg::notify(osg::NOTICE)<<" lookVector ="< ProjectedVertices; + ProjectedVertices projectedVertices; + + unsigned int i; + for(i=0; i< corners.size(); ++i) { - osg::Vec3d delta = *itr - center; + osg::Vec3d delta = corners[i] - center; double distance_side = delta * sideVector; double distance_up = delta * upVector; + projectedVertices.push_back(osg::Vec2d(distance_side, distance_up)); - if (distance_sidemax_side) max_side = distance_side; + if (distance_sidemax_side) + { + max_side = distance_side; + rightPointIndex = i; + } if (distance_upmax_up) max_up = distance_up; } - //osg::notify(osg::NOTICE)<<" upVector ="<= mid_side && vb.x() >= mid_side) + { + // osg::notify(osg::NOTICE)<<"Both on right va="<