1/* -*-c++-*- */
2/* osgEarth - Geospatial SDK for OpenSceneGraph
3 * Copyright 2019 Pelican Mapping
4 * http://osgearth.org
5 *
6 * osgEarth is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>
18 */
19#ifndef OSGEARTH_VIEWPOINT
20#define OSGEARTH_VIEWPOINT
21
22#include <osgEarth/Config>
23#include <osgEarth/GeoData>
24#include <osgEarth/Units>
25#include <osgEarth/optional>
26#include <osg/Node>
27#include <osg/observer_ptr>
28
29namespace osgEarth
30{
31    /**
32     * Viewpoint stores a focal point (or a focal node) and camera parameters
33     * relative to that point.
34     */
35    class OSGEARTH_EXPORT Viewpoint
36    {
37    public:
38        /**
39         * Constructs a blank (invalid) viewpoint.
40         */
41        Viewpoint();
42
43        /**
44         * Copy constructor.
45         */
46        Viewpoint(const Viewpoint& rhs);
47
48        /**
49         * Deserialize a Config into this viewpoint object.
50         */
51        Viewpoint(const Config& conf);
52
53    public:
54
55        /**
56         * Returns true if this viewpoint contains either a valid focal point or
57         * a valid tracked node.
58         */
59        bool isValid() const;
60
61        /**
62         * Gets or sets the name of the viewpoint.
63         */
64        optional<std::string>& name()             { return _name; }
65        const optional<std::string>& name() const { return _name; }
66
67        /**
68         * The geospatial location at which the camera is pointing. If the Node (below)
69         * is set, this is ignored.
70         */
71        optional<GeoPoint>& focalPoint()             { return _point; }
72        const optional<GeoPoint>& focalPoint() const { return _point; }
73
74        /**
75         * The node in the scene graph at which the camera is pointing. The "getter" follows
76         * the observer pattern; i.e. you must copy its value into a ref_ptr before safely
77         * accessing it. getNode() returns true if the safe-reference was successful.
78         *
79         * If a node is set, the Focal Point is ignored.
80         * Node will not serialize into a Config.
81         */
82        void setNode(osg::Node* value)                    { _node = value; }
83        osg::ref_ptr<osg::Node> getNode() const;
84        bool nodeIsSet() const                            { return _node.valid(); }
85
86        //! @deprecated - use getNode() instead
87        bool getNode(osg::ref_ptr<osg::Node>& safe) const { return _node.lock(safe); }
88
89        /**
90         * Heading (in degrees) of the camera relative to the focal point.
91         */
92        optional<Angle>& heading()             { return _heading; }
93        const optional<Angle>& heading() const { return _heading; }
94
95        /**
96         * The pitch of the camera relative to the focal point.
97         */
98        optional<Angle>& pitch()             { return _pitch; }
99        const optional<Angle>& pitch() const { return _pitch; }
100
101        /**
102         * The distance from the camera to the focal point.
103         */
104        optional<Distance>& range()             { return _range; }
105        const optional<Distance>& range() const { return _range; }
106
107        /**
108         * Local offsets from the focal point, in meters. For example if the Viewpoint
109         * is looking at a Node, this will shift the focal point so it is offset from
110         * the node in a cartesian coordinate system where X=east, Y=north, Z=up.
111         */
112        optional<osg::Vec3d>& positionOffset()             { return _posOffset; }
113        const optional<osg::Vec3d>& positionOffset() const { return _posOffset; }
114
115        /**
116         * Returns a printable string with the viewpoint data
117         */
118        std::string toString() const;
119
120        /**
121         * Serialize this viewpoint to a config object.
122         */
123        Config getConfig() const;
124
125
126    public: // Backwards compatibility functions. Please don't use these in view code.
127
128        /** SRS is WGS84, angles are in degrees, range is in meters. */
129
130        /** @deprecated */
131        Viewpoint(const char* name, double lon, double lat, double z, double heading, double pitch, double range);
132
133        /** @deprecated */
134        void setHeading(double value) { _heading->set(value, Units::DEGREES); }
135
136        /** @deprecated */
137        void setPitch  (double value) { _pitch->set(value, Units::DEGREES); }
138
139        /** @deprecated */
140        void setRange  (double value) { _range->set(value, Units::METERS); }
141
142        /** @deprecated */
143        double getHeading() const { return _heading->as(Units::DEGREES); }
144
145        /** @deprecated */
146        double getPitch()   const { return _pitch->as(Units::DEGREES); }
147
148        /** @deprecated */
149        double getRange()   const { return _range->as(Units::METERS); }
150
151    public:
152
153        /** dtor */
154        ~Viewpoint() { }
155
156    private:
157        optional<std::string> _name;
158        optional<GeoPoint>    _point;
159        optional<Angle>       _heading;
160        optional<Angle>       _pitch;
161        optional<Distance>    _range;
162        optional<osg::Vec3d>  _posOffset;
163
164        osg::observer_ptr<osg::Node> _node;
165    };
166
167} // namespace osgEarth
168
169#endif // OSGEARTH_VIEWPOINT
170