void TerrainProfileCalculator::recompute()
{
    if (_start.isValid() && _end.isValid())
    {
        //computeTerrainProfile( _mapNode.get(), _start, _end, _numSamples, _profile);
        osg::Vec3d start, end;
        _start.toWorld( start );
        _end.toWorld( end );
        osgSim::ElevationSlice slice;
        slice.setStartPoint( start );
        slice.setEndPoint( end );
        slice.setDatabaseCacheReadCallback( 0 );
        slice.computeIntersections( _mapNode->getTerrainEngine());
        _profile.clear();
        for (unsigned int i = 0; i < slice.getDistanceHeightIntersections().size(); i++)
        {
            _profile.addElevation( slice.getDistanceHeightIntersections()[i].first, slice.getDistanceHeightIntersections()[i].second);
        }

        for( ChangedCallbackList::iterator i = _changedCallbacks.begin(); i != _changedCallbacks.end(); i++ )
        {
            if ( i->get() )
                i->get()->onChanged(this);
        }
    }
}
示例#2
0
void TerrainProfileCalculator::recompute()
{
    if (_start.isValid() && _end.isValid())
    {
        computeTerrainProfile( _mapNode.get(), _start, _end, _profile);

        for( ChangedCallbackList::iterator i = _changedCallbacks.begin(); i != _changedCallbacks.end(); i++ )
        {
            if ( i->get() )
                i->get()->onChanged(this);
        }
    }
    else
    {
        _profile.clear();
    }
}
示例#3
0
void
LineOfSightNode::compute(osg::Node* node, bool backgroundThread)
{
    if (_start != _end)
    {
      const SpatialReference* mapSRS = _mapNode->getMapSRS();

      //Computes the LOS and redraws the scene
      if (_startAltitudeMode == AltitudeMode::ABSOLUTE)
          _mapNode->getMap()->toWorldPoint( GeoPoint(mapSRS,_start), _startWorld );
      else
          getRelativeWorld(_start.x(), _start.y(), _start.z(), _mapNode.get(), _startWorld);

      if (_endAltitudeMode == AltitudeMode::ABSOLUTE)
          _mapNode->getMap()->toWorldPoint( GeoPoint(mapSRS,_end), _endWorld );
      else
          getRelativeWorld(_end.x(), _end.y(), _end.z(), _mapNode.get(), _endWorld);
      
      osgSim::LineOfSight los;
      los.setDatabaseCacheReadCallback(0);
      unsigned int index = los.addLOS(_startWorld, _endWorld);
      los.computeIntersections(node);
      osgSim::LineOfSight::Intersections hits = los.getIntersections(0);    
      if (hits.size() > 0)
      {
          _hasLOS = false;
          _hitWorld = *hits.begin();
          GeoPoint mapHit;
          _mapNode->getMap()->worldPointToMapPoint( _hitWorld, mapHit);
          _hit = mapHit.vec3d();
      }
      else
      {
          _hasLOS = true;
      }
    }

    draw(backgroundThread);

    for( ChangedCallbackList::iterator i = _changedCallbacks.begin(); i != _changedCallbacks.end(); i++ )
    {
        i->get()->onChanged();
    }	
}
示例#4
0
void
RadialLineOfSightNode::compute_fill(osg::Node* node, bool backgroundThread)
{    
    //Get the center point in geocentric    
    if (_altitudeMode == AltitudeMode::ABSOLUTE)
    {
        GeoPoint centerMap(_mapNode->getMapSRS(), _center);
        _mapNode->getMap()->toWorldPoint( centerMap, _centerWorld );
    }
    else
    {
        getRelativeWorld(_center.x(), _center.y(), _center.z(), _mapNode.get(), _centerWorld );
    }

    osg::Vec3d up = osg::Vec3d(_centerWorld);
    up.normalize();

    //Get the "side" vector
    osg::Vec3d side = up ^ osg::Vec3d(0,0,1);

    //Get the number of spokes
    double delta = osg::PI * 2.0 / (double)_numSpokes;
    
    osg::Geometry* geometry = new osg::Geometry;
    osg::Vec3Array* verts = new osg::Vec3Array();
    verts->reserve(_numSpokes * 2);
    geometry->setVertexArray( verts );

    osg::Vec4Array* colors = new osg::Vec4Array();
    colors->reserve( _numSpokes * 2 );

    geometry->setColorArray( colors );
    geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

    osgSim::LineOfSight los;
    los.setDatabaseCacheReadCallback(0);

    for (unsigned int i = 0; i < _numSpokes; i++)
    {
        double angle = delta * (double)i;
        osg::Quat quat(angle, up );
        osg::Vec3d spoke = quat * (side * _radius);
        osg::Vec3d end = _centerWorld + spoke;        
        los.addLOS( _centerWorld, end);      
    }

    los.computeIntersections(node);

    for (unsigned int i = 0; i < _numSpokes; i++)
    {
        //Get the current hit
        osg::Vec3d currEnd = los.getEndPoint(i);
        bool currHasLOS = los.getIntersections(i).empty();
        osg::Vec3d currHit = currHasLOS ? osg::Vec3d() : *los.getIntersections(i).begin();

        unsigned int nextIndex = i + 1;
        if (nextIndex == _numSpokes) nextIndex = 0;
        //Get the current hit
        osg::Vec3d nextEnd = los.getEndPoint(nextIndex);
        bool nextHasLOS = los.getIntersections(nextIndex).empty();
        osg::Vec3d nextHit = nextHasLOS ? osg::Vec3d() : *los.getIntersections(nextIndex).begin();
        
        if (currHasLOS && nextHasLOS)
        {
            //Both rays have LOS            
            verts->push_back( _centerWorld - _centerWorld );
            colors->push_back( _goodColor );
            
            verts->push_back( nextEnd - _centerWorld );
            colors->push_back( _goodColor );
            
            verts->push_back( currEnd - _centerWorld );                       
            colors->push_back( _goodColor );
        }        
        else if (!currHasLOS && !nextHasLOS)
        {
            //Both rays do NOT have LOS

            //Draw the "good triangle"            
            verts->push_back( _centerWorld - _centerWorld );
            colors->push_back( _goodColor );
            
            verts->push_back( nextHit - _centerWorld );
            colors->push_back( _goodColor );
            
            verts->push_back( currHit - _centerWorld );                       
            colors->push_back( _goodColor );

            //Draw the two bad triangles
            verts->push_back( currHit - _centerWorld );
            colors->push_back( _badColor );
            
            verts->push_back( nextHit - _centerWorld );
            colors->push_back( _badColor );
            
            verts->push_back( nextEnd - _centerWorld );                       
            colors->push_back( _badColor );

            verts->push_back( currHit - _centerWorld );
            colors->push_back( _badColor );
            
            verts->push_back( nextEnd - _centerWorld );
            colors->push_back( _badColor );
            
            verts->push_back( currEnd - _centerWorld );                       
            colors->push_back( _badColor );
        }
        else if (!currHasLOS && nextHasLOS)
        {
            //Current does not have LOS but next does

            //Draw the good portion
            verts->push_back( _centerWorld - _centerWorld );
            colors->push_back( _goodColor );
            
            verts->push_back( nextEnd - _centerWorld );
            colors->push_back( _goodColor );
            
            verts->push_back( currHit - _centerWorld );                       
            colors->push_back( _goodColor );

            //Draw the bad portion
            verts->push_back( currHit - _centerWorld );
            colors->push_back( _badColor );
            
            verts->push_back( nextEnd - _centerWorld );
            colors->push_back( _badColor );
            
            verts->push_back( currEnd - _centerWorld );                       
            colors->push_back( _badColor );
        }
        else if (currHasLOS && !nextHasLOS)
        {
            //Current does not have LOS but next does
            //Draw the good portion
            verts->push_back( _centerWorld - _centerWorld );
            colors->push_back( _goodColor );
            
            verts->push_back( nextHit - _centerWorld );
            colors->push_back( _goodColor );
            
            verts->push_back( currEnd - _centerWorld );                       
            colors->push_back( _goodColor );

            //Draw the bad portion
            verts->push_back( nextHit - _centerWorld );
            colors->push_back( _badColor );
            
            verts->push_back( nextEnd - _centerWorld );
            colors->push_back( _badColor );
            
            verts->push_back( currEnd - _centerWorld );                       
            colors->push_back( _badColor );
        }               
    }
    

    geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, verts->size()));

    osg::Geode* geode = new osg::Geode();
    geode->addDrawable( geometry );

    getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
    getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);

    osg::MatrixTransform* mt = new osg::MatrixTransform;
    mt->setMatrix(osg::Matrixd::translate(_centerWorld));
    mt->addChild(geode);
    
    if (!backgroundThread)
    {
        //Remove all the children
        removeChildren(0, getNumChildren());
        addChild( mt );  
    }
    else
    {
        _pendingNode = mt;
    }

    for( ChangedCallbackList::iterator i = _changedCallbacks.begin(); i != _changedCallbacks.end(); i++ )
    {
        i->get()->onChanged();
    }	
}
示例#5
0
void
RadialLineOfSightNode::compute_line(osg::Node* node, bool backgroundThread)
{    
    //Get the center point in geocentric    
    if (_altitudeMode == AltitudeMode::ABSOLUTE)
    {
        GeoPoint center(_mapNode->getMapSRS(),_center);
        _mapNode->getMap()->toWorldPoint( center, _centerWorld );
    }
    else
    {
        getRelativeWorld(_center.x(), _center.y(), _center.z(), _mapNode.get(), _centerWorld );
    }

    osg::Vec3d up = osg::Vec3d(_centerWorld);
    up.normalize();

    //Get the "side" vector
    osg::Vec3d side = up ^ osg::Vec3d(0,0,1);

    //Get the number of spokes
    double delta = osg::PI * 2.0 / (double)_numSpokes;
    
    osg::Geometry* geometry = new osg::Geometry;
    osg::Vec3Array* verts = new osg::Vec3Array();
    verts->reserve(_numSpokes * 5);
    geometry->setVertexArray( verts );

    osg::Vec4Array* colors = new osg::Vec4Array();
    colors->reserve( _numSpokes * 5 );

    geometry->setColorArray( colors );
    geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

    osg::Vec3d previousEnd;
    osg::Vec3d firstEnd;

    osgSim::LineOfSight los;
    los.setDatabaseCacheReadCallback(0);

    for (unsigned int i = 0; i < _numSpokes; i++)
    {
        double angle = delta * (double)i;
        osg::Quat quat(angle, up );
        osg::Vec3d spoke = quat * (side * _radius);
        osg::Vec3d end = _centerWorld + spoke;        
        los.addLOS( _centerWorld, end);      
    }

    los.computeIntersections(node);

    for (unsigned int i = 0; i < _numSpokes; i++)
    {
        osg::Vec3d start = los.getStartPoint(i);
        osg::Vec3d end = los.getEndPoint(i);

        osgSim::LineOfSight::Intersections hits = los.getIntersections(i);
        osg::Vec3d hit;
        bool hasLOS = hits.empty();
        if (!hasLOS)
        {
            hit = *hits.begin();
        }

        if (hasLOS)
        {
            verts->push_back( start - _centerWorld );
            verts->push_back( end - _centerWorld );
            colors->push_back( _goodColor );
            colors->push_back( _goodColor );
        }
        else
        {
            if (_displayMode == MODE_SPLIT)
            {
                verts->push_back( start - _centerWorld );
                verts->push_back( hit - _centerWorld  );
                colors->push_back( _goodColor );
                colors->push_back( _goodColor );

                verts->push_back( hit - _centerWorld );
                verts->push_back( end - _centerWorld );
                colors->push_back( _badColor );
                colors->push_back( _badColor );
            }
            else if (_displayMode == MODE_SINGLE)
            {
                verts->push_back( start - _centerWorld );
                verts->push_back( end - _centerWorld );
                colors->push_back( _badColor );                                
                colors->push_back( _badColor );                
            }
        }


        if (i > 0)
        {
            verts->push_back( end - _centerWorld );
            verts->push_back( previousEnd - _centerWorld );
            colors->push_back( _outlineColor );
            colors->push_back( _outlineColor );
        }
        else
        {
            firstEnd = end;
        }

        previousEnd = end;
    }


    //Add the last outside of circle
    verts->push_back( firstEnd - _centerWorld );
    verts->push_back( previousEnd - _centerWorld );
    colors->push_back( osg::Vec4(1,1,1,1));
    colors->push_back( osg::Vec4(1,1,1,1));

    geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 0, verts->size()));

    osg::Geode* geode = new osg::Geode();
    geode->addDrawable( geometry );

    getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

    osg::MatrixTransform* mt = new osg::MatrixTransform;
    mt->setMatrix(osg::Matrixd::translate(_centerWorld));
    mt->addChild(geode);
    
    if (!backgroundThread)
    {
        //Remove all the children
        removeChildren(0, getNumChildren());
        addChild( mt );  
    }
    else
    {
        _pendingNode = mt;
    }

    for( ChangedCallbackList::iterator i = _changedCallbacks.begin(); i != _changedCallbacks.end(); i++ )
    {
        i->get()->onChanged();
    }	
}