Skip to content

Instantly share code, notes, and snippets.

@gwaldron
Last active October 26, 2021 15:06
Show Gist options
  • Save gwaldron/27c8dfabb6bd6d4e7b37860ed5224074 to your computer and use it in GitHub Desktop.
Save gwaldron/27c8dfabb6bd6d4e7b37860ed5224074 to your computer and use it in GitHub Desktop.
ImageTimeline example
/*** PASTE ME OVER osgearth_imgui.cpp ***/
#include <osgEarth/ImGui/ImGui>
#include <osgEarth/EarthManipulator>
#include <osgEarth/ImageLayer>
#include <osg/ImageSequence>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
using namespace osgEarth;
using namespace osgEarth::Util;
struct App
{
DateTime _time;
};
class ImageTimeline : public osg::Image
{
public:
using Sequence = std::map<TimeStamp, osg::ref_ptr<const osg::Image>>;
Sequence _images;
Sequence::iterator _ptr;
void insert(const DateTime& dt, const osg::Image* image)
{
_images.insert(std::make_pair(dt.asTimeStamp(), image));
if (_images.size() == 1)
{
setDateTime(dt);
}
}
void insert(const DateTime& dt, osg::ref_ptr<osg::Image> image)
{
insert(dt, image.get());
}
bool requiresUpdateCall() const override
{
return true;
}
void update(osg::NodeVisitor* nv) override
{
DateTime dt(nv->getFrameStamp()->getSimulationTime());
setDateTime(dt);
}
void setDateTime(const DateTime& dt)
{
_ptr = _images.lower_bound(dt.asTimeStamp());
if (_ptr != _images.end())
{
const osg::Image* image = _ptr->second.get();
setImage(image->s(), image->t(), image->r(),
image->getInternalTextureFormat(),
image->getPixelFormat(), image->getDataType(),
const_cast<unsigned char*>(image->data()),
osg::Image::NO_DELETE,
image->getPacking());
setMipmapLevels(image->getMipmapLevels());
}
}
};
class TimelineLayer : public ImageLayer
{
public:
META_LayerNoOptions(osgEarth, TimelineLayer, ImageLayer, TimelineLayer);
void init() override
{
ImageLayer::init();
setProfile(Profile::create(Profile::GLOBAL_GEODETIC));
setAsyncLoading(false);
}
GeoImage createImageImplementation(const TileKey& key, ProgressCallback* c) const override
{
ImageTimeline* timeline = new ImageTimeline();
timeline->insert(DateTime(0), osgDB::readRefImageFile("../data/icon.png"));
timeline->insert(DateTime(1), osgDB::readRefImageFile("../data/placemark32.png"));
timeline->insert(DateTime(2), osgDB::readRefImageFile("../data/hospital.png"));
return GeoImage(timeline, key.getExtent());
}
};
struct TimeGUI : public GUI::BaseGUI
{
App& _app;
float _time;
TimeGUI(App& app) : BaseGUI("Time Control"), _app(app), _time(0.0f) { }
void draw(osg::RenderInfo& ri) override
{
if (!isVisible()) return;
ImGui::Begin(name(), visible());
if (ImGui::SliderFloat("Time", &_time, 0.0f, 3.0f))
_app._time = DateTime(_time);
ImGui::End();
}
};
int
main(int argc, char** argv)
{
osgEarth::initialize();
App app;
osg::ArgumentParser arguments(&argc, argv);
osgViewer::Viewer viewer(arguments);
viewer.setThreadingModel(viewer.SingleThreaded);
viewer.setCameraManipulator(new EarthManipulator(arguments));
viewer.setRealizeOperation(new GUI::ApplicationGUI::RealizeOperation);
auto gui = new GUI::ApplicationGUI(arguments, true);
gui->add(new TimeGUI(app), true);
viewer.getEventHandlers().push_front(gui);
auto map = new Map();
map->addLayer(new TimelineLayer());
auto mapNode = new MapNode(map);
viewer.setSceneData(mapNode);
viewer.realize();
while (!viewer.done()) {
viewer.frame(app._time.asTimeStamp());
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment