diff --git a/examples/osgspheresegment/osgspheresegment.cpp b/examples/osgspheresegment/osgspheresegment.cpp index 6c9312a88..99c79ab1c 100644 --- a/examples/osgspheresegment/osgspheresegment.cpp +++ b/examples/osgspheresegment/osgspheresegment.cpp @@ -8,6 +8,8 @@ #include #include +#include + #include #include @@ -233,24 +235,84 @@ void build_world(osg::Group *root) terrainGeode->setStateSet( stateset ); - float size = 1000; // 10km; - float scale = size/39.0f; // 10km; - float z_scale = scale*3.0f; - - osg::HeightField* grid = new osg::HeightField; - grid->allocate(38,39); - grid->setXInterval(scale); - grid->setYInterval(scale); - - for(unsigned int r=0;r<39;++r) - { - for(unsigned int c=0;c<38;++c) - { - grid->setHeight(c,r,z_scale*vertex[r+c*39][2]); - } - } - terrainGeode->addDrawable(new osg::ShapeDrawable(grid)); + { + unsigned int numColumns = 38; + unsigned int numRows = 39; + unsigned int r, c; + + osg::Vec3 origin(0.0f,0.0f,0.0f); + osg::Vec3 size(1000.0f,1000.0f,250.0f); + + osg::Geometry* geometry = new osg::Geometry; + + osg::Vec3Array& v = *(new osg::Vec3Array(numColumns*numRows)); + osg::Vec2Array& tc = *(new osg::Vec2Array(numColumns*numRows)); + osg::Vec4ubArray& color = *(new osg::Vec4ubArray(1)); + + color[0].set(255,255,255,255); + + float rowCoordDelta = size.y()/(float)(numRows-1); + float columnCoordDelta = size.x()/(float)(numColumns-1); + + float rowTexDelta = 1.0f/(float)(numRows-1); + float columnTexDelta = 1.0f/(float)(numColumns-1); + + // compute z range of z values of grid data so we can scale it. + float min_z = FLT_MAX; + float max_z = -FLT_MAX; + for(r=0;rsetVertexArray(&v); + geometry->setTexCoordArray(0, &tc); + geometry->setColorArray(&color); + geometry->setColorBinding(osg::Geometry::BIND_OVERALL); + + for(r=0;raddPrimitiveSet(&drawElements); + int ei=0; + for(c=0;caddDrawable(geometry); + } } @@ -272,7 +334,7 @@ void build_world(osg::Group *root) root->addChild(ss.get()); } - osgSim::SphereSegment::LineList lines = ss->computeIntersection(terrainGeode.get(), osg::Matrixd::identity()); + osgSim::SphereSegment::LineList lines = ss->computeIntersection(osg::Matrixd::identity(), terrainGeode.get()); if (!lines.empty()) { osg::notify(osg::NOTICE)<<"We've found intersections!!!!"< > LineList; - /** Compute the interesection lines between specified geometry and this sphere segment.*/ - LineList computeIntersection(osg::Node* subgraph, const osg::Matrixd& transform); + /** Compute the interesection lines between subgraph and this sphere segment.*/ + LineList computeIntersection(const osg::Matrixd& matrix, osg::Node* subgraph); + + /** Compute the interesection lines between specified drawable and this sphere segment.*/ + LineList computeIntersection(const osg::Matrixd& matrix, osg::Drawable* drawable); private: diff --git a/src/osgSim/SphereSegment.cpp b/src/osgSim/SphereSegment.cpp index 6ab8f33cc..d51ab5714 100644 --- a/src/osgSim/SphereSegment.cpp +++ b/src/osgSim/SphereSegment.cpp @@ -1,8 +1,24 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + #include + #include #include #include #include +#include +#include #include #include @@ -1057,10 +1073,9 @@ class PolytopeVisitor : public osg::NodeVisitor }; -SphereSegment::LineList SphereSegment::computeIntersection(osg::Node* subgraph, const osg::Matrixd& transform) +SphereSegment::LineList SphereSegment::computeIntersection(const osg::Matrixd& transform, osg::Node* subgraph) { osg::notify(osg::NOTICE)<<"Creating line intersection between sphere segment and subgraph."<_matrix, itr->_drawable.get()); + all_lines.insert(all_lines.end(), lines.begin(), lines.end()); + } + + // join all the lines that have ends that are close together.. + + return all_lines; +} + +struct TriangleIntersectOperator +{ + + TriangleIntersectOperator(): + _radius(-1.0f), + _azMin(0.0f), + _azMax(0.0f), + _elevMin(0.0f), + _elevMax(0.0f), + _numOutside(0), + _numInside(0), + _numIntersecting(0) {} + + typedef osg::ref_ptr PositionArray; + typedef std::vector RegionArray; + + PositionArray _positions; + RegionArray _regions; + float _radius; + float _azMin, _azMax, _elevMin, _elevMax; + + unsigned int _numOutside; + unsigned int _numInside; + unsigned int _numIntersecting; + + inline void operator()(unsigned int p1, unsigned int p2, unsigned int p3) + { + // reject if outside. + if (_regions[p1]==1 && _regions[p2]==1 && _regions[p3]==1) + { + ++_numOutside; + return; + } + + if (_regions[p1]==-1 && _regions[p2]==-1 && _regions[p3]==-1) + { + ++_numInside; + return; + } + + ++_numIntersecting; + + } + +}; + + +SphereSegment::LineList SphereSegment::computeIntersection(const osg::Matrixd& transform, osg::Drawable* drawable) +{ + // cast to Geometry, return empty handed if Drawable not a Geometry. + osg::Geometry* geometry = dynamic_cast(drawable); + if (!geometry) return LineList(); + + // get vertices from geometry, return empty handed if a Vec3Array not present. + osg::Vec3Array* vertices = dynamic_cast(geometry->getVertexArray()); + if (!vertices) return LineList(); + + typedef osg::TriangleIndexFunctor TriangleIntersectFunctor; + TriangleIntersectFunctor tif; + + tif._radius = _radius; + tif._azMin = _azMin; + tif._azMax = _azMax; + tif._elevMin = _elevMin; + tif._elevMax = _elevMax; + + tif._positions = vertices; + tif._regions.resize(vertices->size(), 1); + + // traverse the triangles in the Geometry dedicating intersections + geometry->accept(tif); + + osg::notify(osg::NOTICE)<<"_numOutside = "<