DYT/Tool/OpenSceneGraph-3.6.5/include/osgEarth/ExampleResources
2024-12-25 07:49:36 +08:00

315 lines
9.9 KiB
C++

/* -*-c++-*- */
/* osgEarth - Geospatial SDK for OpenSceneGraph
* Copyright 2020 Pelican Mapping
* http://osgearth.org
*
* osgEarth is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#pragma once
#include <osgEarth/Common>
#include <osgEarth/EarthManipulator>
#include <osgEarth/Sky>
#include <osgEarth/SimpleOceanLayer>
#include <osgEarth/Viewpoint>
#include <osgGA/GUIEventHandler>
#include <osgViewer/View>
namespace osgEarth {
class MapNode;
}
namespace osg {
class ArgumentParser;
}
namespace osgViewer {
class ViewerBase;
};
struct EnumClassHash
{
template <typename T>
std::size_t operator()(T t) const noexcept
{
return static_cast<std::size_t>(t);
}
};
/**
* This is a collection of resources used by the osgEarth example applications.
*/
namespace osgEarth { namespace Util
{
using namespace osgEarth;
/**
* Parses a set of built-in example arguments. Any Controls created by parsing
* command-line parameters will appear in the lower-left corner of the display.
*/
class OSGEARTH_EXPORT MapNodeHelper
{
public:
/**
* Loads a map file and processes all the built-in example command line
* arguemnts and XML externals. Disables the Controls library.
*/
osg::ref_ptr<osg::Node> load(
osg::ArgumentParser& args,
osgViewer::ViewerBase* viewer) const;
//! Takes an existing map node and processes all the built-in example
//! command line arguments.
void parse(
MapNode* mapNode,
osg::ArgumentParser& args,
osgViewer::View* view,
osg::Group* parentGroup) const;
//! Configures a view with a stock set of event handlers that are useful
//! for demos, and performs some other common view configuration for osgEarth.
void configureView(osgViewer::View* view) const;
//! Enumerates the command line arguments that this helper will process
std::string usage() const;
};
#if 0
/**
* Creates a UI Control with a list of clickable viewpoints.
*/
class OSGEARTH_EXPORT ViewpointControlFactory
{
public:
Control* create(
const std::vector<Viewpoint>& list,
osgViewer::View* view) const;
};
/**
* Creates UI controls that show the map coordinates under the mouse
*/
class OSGEARTH_EXPORT MouseCoordsControlFactory
{
public:
Control* create(
MapNode* mapNode,
osgViewer::View* view ) const;
};
/**
* Creates a UI Control reflecting all the named Annotations found in a
* scene graph.
*/
class OSGEARTH_EXPORT AnnotationGraphControlFactory
{
public:
Control* create(
osg::Node* node,
osgViewer::View* view) const;
};
/**
* Creates a set of controls for manipulating the Sky model.
*/
class OSGEARTH_EXPORT SkyControlFactory
{
public:
static Control* create(SkyNode* sky);
};
/**
* Creates a set of controls for manipulating the Ocean surface model.
*/
class OSGEARTH_EXPORT OceanControlFactory
{
public:
static Control* create(SimpleOceanLayer* ocean);
};
/**
* Creates UI controls displaying the map attribution
*/
class OSGEARTH_EXPORT AttributionControlFactory
{
public:
Control* create(MapNode* mapNode) const;
};
#endif
/**
* Helper class for easily creating event handlers
*/
struct EventRouter : public osgGA::GUIEventHandler, public osgGA::GUIEventAdapter
{
using Function = std::function<void()>;
using ViewFunction = std::function<void(osg::View*, float, float)>;
template<typename FUNC_TYPE>
struct Action {
FUNC_TYPE func;
bool eat = true;
Action(const FUNC_TYPE& f, bool e) : func(f), eat(e) { }
};
struct Push {
Push() : _value(false) { }
bool _value;
int _modkeymask;
void set(bool value, int mask) { _value = value, _modkeymask = mask; }
operator bool() { return _value; }
};
//std::unordered_map<KeySymbol, std::list<Action<Function>>, EnumClassHash> _keypress_simple;
std::unordered_map<KeySymbol, std::list<Action<ViewFunction>>, EnumClassHash> _keypress;
std::unordered_map<int, Push> _pushes;
std::unordered_map<int, std::list<Action<ViewFunction>>> _click;
std::list<Action<ViewFunction>> _move;
std::list<Action<ViewFunction>> _drag;
//EventRouter& onKeyPress(KeySymbol key, const Function& func, bool eat=true) {
// _keypress_simple[key].emplace_back(Action<Function>(func, eat));
// return *this;
//}
EventRouter& onKeyPress(KeySymbol key, const ViewFunction& func, bool eat=true) {
_keypress[key].emplace_back(Action<ViewFunction>(func, eat));
return *this;
}
EventRouter& popKeyPress(KeySymbol key) {
if (!_keypress[key].empty())
_keypress[key].pop_back();
return *this;
}
EventRouter& onClick(const ViewFunction& func, bool eat=true) {
onClick(LEFT_MOUSE_BUTTON, 0, func, eat);
return *this;
}
EventRouter& onClick(int button, const ViewFunction& func, bool eat=true) {
_click[button].emplace_back(Action<ViewFunction>(func, eat));
return *this;
}
EventRouter& onClick(int button, int modkey, const ViewFunction& func, bool eat=true) {
_click[button | (modkey<<3)].emplace_back(Action<ViewFunction>(func, eat));
return *this;
}
EventRouter& popClick(int button = LEFT_MOUSE_BUTTON, int modkey = 0) {
if (!_click[button | (modkey << 3)].empty())
_click[button | (modkey << 3)].pop_back();
_pushes.clear();
return *this;
}
EventRouter& onMove(const ViewFunction& func, bool eat=false) {
_move.emplace_back(Action<ViewFunction>(func, eat));
return *this;
}
EventRouter& popMove() {
if (!_move.empty())
_move.pop_back();
return *this;
}
EventRouter& onDrag(const ViewFunction& func, bool eat=false) {
_drag.emplace_back(Action<ViewFunction>(func, eat));
return *this;
}
EventRouter& popDrag() {
if (!_drag.empty())
_drag.pop_back();
return *this;
}
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) override
{
unsigned count = 0u;
if (ea.getEventType() == ea.KEYUP) {
//for (auto& action : _keypress_simple[(KeySymbol)ea.getKey()]) {
// action.func();
// if (action.eat) count++;
//}
for (auto& action : _keypress[(KeySymbol)ea.getKey()]) {
action.func(aa.asView(), ea.getX(), ea.getY());
if (action.eat) count++;
}
}
else if (ea.getEventType() == ea.PUSH) {
_pushes[ea.getButton()].set(true, ea.getModKeyMask());
int combo = ea.getButton() | ea.getModKeyMask();
for (auto& action : _click[combo]) {
if (action.eat) count++;
}
}
else if (ea.getEventType() == ea.RELEASE) {
Push& push = _pushes[ea.getButton()];
if (push == true) {
int combo = ea.getButton() | push._modkeymask;
push.set(false, 0);
for (auto& action : _click[combo]) {
action.func(aa.asView(), ea.getX(), ea.getY());
if (action.eat) count++;
}
}
}
else if (ea.getEventType() == ea.MOVE) {
for (auto& action : _move) {
action.func(aa.asView(), ea.getX(), ea.getY());
if (action.eat) count++;
}
}
else if (ea.getEventType() == ea.DRAG) {
for (auto& action : _drag) {
action.func(aa.asView(), ea.getX(), ea.getY());
if (action.eat) count++;
}
}
return count > 0u;
}
//! Accesses the router on the given view, creating one if necessary
static EventRouter& get(osgViewer::View* v) {
OE_HARD_ASSERT(v != nullptr);
for (auto& eh : v->getEventHandlers()) {
EventRouter* r = dynamic_cast<EventRouter*>(eh.get());
if (r)
return *r;
}
EventRouter* r = new EventRouter();
v->getEventHandlers().push_front(r);
return *r;
}
static EventRouter& get(osg::ref_ptr<osgViewer::View>& v) {
return get(v.get());
}
};
} } // namespace osgEarth::Util