1 // Copyright (C) 2008 Tim Moore 2 // 3 // This program is free software; you can redistribute it and/or 4 // modify it under the terms of the GNU General Public License as 5 // published by the Free Software Foundation; either version 2 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, but 9 // WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 // General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with this program; if not, write to the Free Software 15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 17 #ifndef CAMERAGROUP_HXX 18 #define CAMERAGROUP_HXX 1 19 20 #include <map> 21 #include <string> 22 #include <vector> 23 #include <memory> 24 25 #include <osg/Matrix> 26 #include <osg/ref_ptr> 27 #include <osg/Referenced> 28 #include <osg/Node> 29 #include <osg/TextureRectangle> 30 #include <osg/Texture2D> 31 #include <osg/TexGen> 32 #include <osgUtil/RenderBin> 33 34 #include <simgear/scene/viewer/Compositor.hxx> 35 36 namespace osg 37 { 38 class Camera; 39 } 40 41 namespace osgViewer 42 { 43 class Viewer; 44 } 45 46 class SGPropertyNode; 47 48 namespace flightgear 49 { 50 51 class CameraGroupListener; 52 class GraphicsWindow; 53 54 /** A wrapper around osg::Camera that contains some extra information. 55 */ 56 struct CameraInfo : public osg::Referenced 57 { 58 /** properties of a camera. 59 */ 60 enum Flags 61 { 62 VIEW_ABSOLUTE = 0x1, /**< The camera view is absolute, not 63 relative to the master camera. */ 64 PROJECTION_ABSOLUTE = 0x2, /**< The projection is absolute. */ 65 ORTHO = 0x4, /**< The projection is orthographic */ 66 GUI = 0x8, /**< Camera draws the GUI. */ 67 DO_INTERSECTION_TEST = 0x10,/**< scene intersection tests this 68 camera. */ 69 FIXED_NEAR_FAR = 0x20, /**< take the near far values in the 70 projection for real. */ 71 ENABLE_MASTER_ZOOM = 0x40 /**< Can apply the zoom algorithm. */ 72 }; 73 CameraInfoflightgear::CameraInfo74 CameraInfo(unsigned flags_) : 75 flags(flags_), 76 physicalWidth(0), physicalHeight(0), bezelHeightTop(0), 77 bezelHeightBottom(0), bezelWidthLeft(0), bezelWidthRight(0), 78 relativeCameraParent(0) { } 79 /** The name as given in the config file. 80 */ 81 std::string name; 82 /** Properties of the camera. @see CameraGroup::Flags. 83 */ 84 unsigned flags; 85 /** Physical size parameters. 86 */ 87 double physicalWidth; 88 double physicalHeight; 89 double bezelHeightTop; 90 double bezelHeightBottom; 91 double bezelWidthLeft; 92 double bezelWidthRight; 93 /** Non-owning reference to the parent camera for relative camera 94 * configurations. 95 */ 96 const CameraInfo *relativeCameraParent; 97 /** The reference points in the parents projection space. 98 */ 99 osg::Vec2d parentReference[2]; 100 /** The reference points in the current projection space. 101 */ 102 osg::Vec2d thisReference[2]; 103 /** View offset from the viewer master camera. 104 */ 105 osg::Matrix viewOffset; 106 /** Projection offset from the viewer master camera. 107 */ 108 osg::Matrix projOffset; 109 /** Current view and projection matrices for this camera. 110 * They are only used by other child cameras through relativeCameraParent 111 * so they can avoid recalculating them. 112 */ 113 osg::Matrix viewMatrix, projMatrix; 114 /** The Compositor used to manage the pipeline of this camera. 115 */ 116 osg::ref_ptr<simgear::compositor::Compositor> compositor; 117 }; 118 119 class CameraGroup : public osg::Referenced 120 { 121 public: 122 /** Create a camera group associated with an osgViewer::Viewer. 123 * @param viewer the viewer 124 */ 125 CameraGroup(osgViewer::Viewer* viewer); 126 virtual ~CameraGroup(); 127 128 /** Set the default CameraGroup, which is the only one that 129 * matters at this time. 130 * @param group the group to set. 131 */ 132 static void buildDefaultGroup(osgViewer::Viewer* viewer); setDefault(CameraGroup * group)133 static void setDefault(CameraGroup* group) { _defaultGroup = group; } 134 /** Get the default CameraGroup. 135 * @return the default camera group. 136 */ getDefault()137 static CameraGroup* getDefault() { return _defaultGroup.get(); } 138 /** Get the camera group's Viewer. 139 * @return the viewer 140 */ getViewer()141 osgViewer::Viewer* getViewer() { return _viewer.get(); } 142 /** Create an osg::Camera from a property node and add it to the 143 * camera group. 144 * @param cameraNode the property node. 145 * @return a CameraInfo object for the camera. 146 */ 147 void buildCamera(SGPropertyNode* cameraNode); 148 /** Create a camera from properties that will draw the GUI and add 149 * it to the camera group. 150 * @param cameraNode the property node. This can be 0, in which 151 * case a default GUI camera is created. 152 * @param window the GraphicsWindow to use for the GUI camera. If 153 * this is 0, the window is determined from the property node. 154 * @return a CameraInfo object for the GUI camera. 155 */ 156 void buildGUICamera(SGPropertyNode* cameraNode, 157 GraphicsWindow* window = 0); 158 /** Update the view for the camera group. 159 * @param position the world position of the view 160 * @param orientation the world orientation of the view. 161 */ 162 void update(const osg::Vec3d& position, 163 const osg::Quat& orientation); 164 /** Set the parameters of the viewer's master camera. This won't 165 * affect cameras that have CameraFlags::PROJECTION_ABSOLUTE set. 166 * XXX Should znear and zfar be settable? 167 * @param vfov the vertical field of view angle 168 * @param aspectRatio the master camera's aspect ratio. This 169 * doesn't actually change the viewport, but should reflect the 170 * current viewport. 171 */ 172 void setCameraParameters(float vfov, float aspectRatio); 173 /** Update camera properties after a resize event. 174 */ 175 void resized(); 176 177 void buildDistortionCamera(const SGPropertyNode* psNode, 178 osg::Camera* camera); 179 /** 180 * get aspect ratio of master camera's viewport 181 */ 182 double getMasterAspectRatio() const; 183 184 CameraInfo *getGUICamera() const; 185 186 protected: 187 friend CameraGroupListener; 188 friend bool computeIntersections(const CameraGroup* cgroup, 189 const osg::Vec2d& windowPos, 190 osgUtil::LineSegmentIntersector::Intersections& 191 intersections); 192 193 typedef std::vector<osg::ref_ptr<CameraInfo>> CameraList; 194 CameraList _cameras; 195 osg::ref_ptr<osgViewer::Viewer> _viewer; 196 static osg::ref_ptr<CameraGroup> _defaultGroup; 197 std::unique_ptr<CameraGroupListener> _listener; 198 199 // Near, far for the master camera if used. 200 float _zNear; 201 float _zFar; 202 float _nearField; 203 204 /** Build a complete CameraGroup from a property node. 205 * @param viewer the viewer associated with this camera group. 206 * @param wbuilder the window builder to be used for this camera group. 207 * @param the camera group property node. 208 */ 209 static CameraGroup* buildCameraGroup(osgViewer::Viewer* viewer, 210 SGPropertyNode* node); 211 }; 212 213 /** Get the osg::Camera that draws the GUI, if any, from a camera 214 * group. 215 * @param cgroup the camera group 216 * @return the GUI camera or 0 217 */ 218 osg::Camera* getGUICamera(CameraGroup* cgroup); 219 /** Choose a camera using an event and do intersection testing on its 220 * view of the scene. Only cameras with the DO_INTERSECTION_TEST flag 221 * set are considered. 222 * @param cgroup the CameraGroup 223 * @param ea the event containing a window and mouse coordinates 224 * @param intersections container for the result of intersection 225 * testing. 226 * @return true if any intersections are found 227 */ 228 bool computeIntersections(const CameraGroup* cgroup, 229 const osg::Vec2d& windowPos, 230 osgUtil::LineSegmentIntersector::Intersections& 231 intersections); 232 /** Warp the pointer to coordinates in the GUI camera of a camera group. 233 * @param cgroup the camera group 234 * @param x x window coordinate of pointer 235 * @param y y window coordinate of pointer, in "y down" coordinates. 236 */ 237 void warpGUIPointer(CameraGroup* cgroup, int x, int y); 238 239 } 240 241 #endif 242