Drawing a Vertical Line from a TrackNode to Center of Earth.

classic Classic list List threaded Threaded
5 messages Options
Damian Dixon Damian Dixon
Reply | Threaded
Open this post in threaded view
|

Drawing a Vertical Line from a TrackNode to Center of Earth.

Hi,

I'm attempting to draw a vertical line from a TrackNode (I've derived my own class) to the center of the Earth.

I am using the following code in an attempt to calculate the line:

    GeoPoint centerMap;
    _center.transform(getMapNode()->getMapSRS(), centerMap);
    centerMap.toWorld(_centerWorld, getMapNode()->getTerrain());

    osg::Vec3d centerTrack;
    pos.toWorld(centerTrack, getMapNode()->getTerrain());

    vertices->push_back(centerTrack);
    vertices->push_back(_centerWorld);

Where pos is from getPosition(). getMapNode returns the MapNode used for the TrackNode's.

One end of the line is correctly anchored on the track symbol. The other is not correct.

I've been staring at this for a little bit too long and could do with some help.

Thanks
Damian


I am using the following code to draw the line:

    osg::Geometry* geometry = new osg::Geometry();
    geometry->setUseVertexBufferObjects(true);

    geometry->setVertexArray(vertices);
    if (vertices->getVertexBufferObject())
        vertices->getVertexBufferObject()->setUsage(GL_STATIC_DRAW_ARB);

    osg::Vec4Array* colors = new osg::Vec4Array();
    colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    geometry->setColorArray(colors);
    geometry->setColorBinding(osg::Geometry::BIND_OVERALL);

    geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, vertices->size()));

    addDrawable("line", geometry);



gwaldron gwaldron
Reply | Threaded
Open this post in threaded view
|

Re: Drawing a Vertical Line from a TrackNode to Center of Earth.

The center of the world is just (0,0,0). Try that.
Glenn Waldron / Pelican Mapping
Damian Dixon Damian Dixon
Reply | Threaded
Open this post in threaded view
|

Re: Drawing a Vertical Line from a TrackNode to Center of Earth.

Setting the center of the world to (0, 0, 0) does not work.

I think that (0,0,0) represents the center of the Symbol in this case.

Either way I need to sleep on this one.



The following is the code I am using for deriving my own TrackNode:


class MyTrackNode : public osgEarth::Annotation::TrackNode, public osgEarth::MapNodeObserver
{
public:
   // META_AnnotationNode(osgEarthAnnotation, MyTrackNode);

    void terrainChanged(const osgEarth::TileKey& tileKey, osg::Node* terrain);

    MyTrackNode(
        osgEarth::MapNode*                    mapNode,
        const osgEarth::GeoPoint&             position,
        osg::Image*                 image,
        const osgEarth::Annotation::TrackNodeFieldSchema& fieldSchema);

    MyTrackNode(
        osgEarth::MapNode*                    mapNode,
        const osgEarth::GeoPoint&             position,
        const osgEarth::Symbology::Style&                style,
        const osgEarth::Annotation::TrackNodeFieldSchema& fieldSchema);

    // MapNodeObserver
    void  setMapNode(osgEarth::MapNode* mapNode);
    osgEarth::MapNode* getMapNode() { return _mapNode.get(); }

    //
    virtual void setPosition(const osgEarth::GeoPoint& pos);

    osg::Node* getNode();

protected:

    virtual ~MyTrackNode();
    void compute(osg::Node* node, const osgEarth::GeoPoint& pos);
    void setup();

    osgEarth::GeoPoint   _center;
    osg::Vec3d _centerWorld;
    osg::observer_ptr< osgEarth::MapNode > _mapNode;
    osg::ref_ptr < osgEarth::TerrainCallback > _terrainChangedCallback;
};


class TerrainChangedCallback : public osgEarth::TerrainCallback
{
public:
    TerrainChangedCallback(MyTrackNode* track) :
        _track(track)
    {
    }

    virtual void onTileAdded(const osgEarth::TileKey& tileKey, osg::Node* terrain, TerrainCallbackContext&)
    {
        _track->terrainChanged(tileKey, terrain);
    }

private:
    MyTrackNode* _track;
};

MyTrackNode::MyTrackNode(
    osgEarth::MapNode*                    mapNode,
    const osgEarth::GeoPoint&             position,
    osg::Image*                 image,
    const osgEarth::Annotation::TrackNodeFieldSchema& fieldSchema)
    : TrackNode(mapNode, position, image, fieldSchema)
    , _mapNode(mapNode)
{
}

MyTrackNode::MyTrackNode(
    osgEarth::MapNode*                    mapNode,
        const osgEarth::GeoPoint&             position,
        const osgEarth::Symbology::Style&                style,
        const osgEarth::Annotation::TrackNodeFieldSchema& fieldSchema)
    : TrackNode(mapNode, position, style, fieldSchema)
    , _mapNode(mapNode)
{
    setup();
}

void MyTrackNode::terrainChanged(const osgEarth::TileKey& tileKey, osg::Node* terrain)
{
    compute(getNode(), getPosition());
}

MyTrackNode::~MyTrackNode()
{
    setMapNode(0L);
}

void MyTrackNode::setup()
{
    _terrainChangedCallback = new TerrainChangedCallback(this);
    _mapNode->getTerrain()->addTerrainCallback(_terrainChangedCallback.get());
}

void
MyTrackNode::setMapNode(MapNode* mapNode)
{
    MapNode* oldMapNode = getMapNode();

    if (oldMapNode != mapNode)
    {
        if (oldMapNode)
        {
            if (_terrainChangedCallback.valid())
            {
                oldMapNode->getTerrain()->removeTerrainCallback(_terrainChangedCallback.get());
            }
        }

        _mapNode = mapNode;

        if (_mapNode.valid() && _terrainChangedCallback.valid())
        {
            _mapNode->getTerrain()->addTerrainCallback(_terrainChangedCallback.get());
        }

        compute(getNode(), getPosition());
    }
}

osg::Node*
MyTrackNode::getNode()
{
    //if (getMapNode()) return getMapNode()->getTerrainEngine();
    return _mapNode.get();
}

void
MyTrackNode::compute(osg::Node* node, const GeoPoint& pos)
{
    NamedDrawables::iterator itr = _namedDrawables.find("line");
    if (itr != _namedDrawables.end())
    {
        _namedDrawables.erase(itr);
    }
    osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
    vertices->reserve(2);

#if 1
    //GeoPoint centerMap;
    //_center.transform(getMapNode()->getMapSRS(), centerMap);
    //centerMap.toWorld(_centerWorld, getMapNode()->getTerrain());

    auto mapSRS = getMapNode()->getMapSRS();

    osg::Vec3d centerTrack;
    pos.toWorld(centerTrack, getMapNode()->getTerrain());
    pos.transform(mapSRS).toWorld(centerTrack);

    vertices->push_back(centerTrack);
    vertices->push_back(_centerWorld);
#else
    vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
    vertices->push_back(osg::Vec3(0.f, -10000.0f, 0.0f));
#endif

    osg::Geometry* geometry = new osg::Geometry();
    geometry->setUseVertexBufferObjects(true);

    geometry->setVertexArray(vertices);
    if (vertices->getVertexBufferObject())
        vertices->getVertexBufferObject()->setUsage(GL_STATIC_DRAW_ARB);

    osg::Vec4Array* colors = new osg::Vec4Array();
    colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    geometry->setColorArray(colors);
    geometry->setColorBinding(osg::Geometry::BIND_OVERALL);

    geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, vertices->size()));

    addDrawable("line", geometry);
}

void MyTrackNode::setPosition(const GeoPoint& pos)
{
    compute(getNode(), pos);
    TrackNode::setPosition(pos);
}


I know that there is a problem with the way I am adding and removing drawables.

Damian Dixon Damian Dixon
Reply | Threaded
Open this post in threaded view
|

Re: Drawing a Vertical Line from a TrackNode to Center of Earth.

It appears that at the point of drawing my line the xyz axis are such that:

The center is the middle of the Icon.
z is out of the screen.
y is is up.
x is to the right.

It looks like I am picking up the billboard transformation for the Icon and Text.

Damian Dixon Damian Dixon
Reply | Threaded
Open this post in threaded view
|

Re: Drawing a Vertical Line from a TrackNode to Center of Earth.

I am taking a different approach and adding the line as an osg::Geode separately from my TrackNode.

I will probably create my own Track object as I need history points as well.