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); } } }
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(); } }
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(); } }
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(); } }
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(); } }