]> git.mxchange.org Git - flightgear.git/blobdiff - src/Viewer/CameraGroup.cxx
GUI picks only traverse nodes with PICK_BIT set.
[flightgear.git] / src / Viewer / CameraGroup.cxx
index f45a293a569f377f5955120cac15261314359aea..7d903a5a179b6b0505fc21f4a0a320ee76ac6af5 100644 (file)
 #include "FGEventHandler.hxx"
 #include "WindowBuilder.hxx"
 #include "WindowSystemAdapter.hxx"
+
+#include <simgear/math/SGRect.hxx>
 #include <simgear/props/props.hxx>
 #include <simgear/structure/OSGUtils.hxx>
 #include <simgear/structure/OSGVersion.hxx>
 #include <simgear/scene/material/EffectCullVisitor.hxx>
 #include <simgear/scene/util/RenderConstants.hxx>
-#include <simgear/scene/tgdb/userdata.hxx>
 
 #include <algorithm>
 #include <cstring>
 #include <osgViewer/GraphicsWindow>
 #include <osgViewer/Renderer>
 
+namespace flightgear {
+const char* MAIN_CAMERA = "main";
+const char* FAR_CAMERA = "far";
+const char* GEOMETRY_CAMERA = "geometry";
+const char* SHADOW_CAMERA = "shadow";
+const char* LIGHTING_CAMERA = "lighting";
+const char* DISPLAY_CAMERA = "display";
+}
+
 static osg::Matrix
 invert(const osg::Matrix& matrix)
 {
@@ -188,7 +198,11 @@ void CameraInfo::updateCameras()
     for (CameraMap::iterator ii = cameras.begin(); ii != cameras.end(); ++ii ) {
         float f = ii->second.scaleFactor;
         if ( f == 0.0f ) continue;
-        ii->second.camera->getViewport()->setViewport(x*f, y*f, width*f, height*f);
+
+        if (ii->second.camera->getRenderTargetImplementation() == osg::Camera::FRAME_BUFFER_OBJECT)
+            ii->second.camera->getViewport()->setViewport(0, 0, width*f, height*f);
+        else
+            ii->second.camera->getViewport()->setViewport(x*f, y*f, width*f, height*f);
     }
 
     for (RenderBufferMap::iterator ii = buffers.begin(); ii != buffers.end(); ++ii ) {
@@ -204,6 +218,9 @@ void CameraInfo::updateCameras()
 
 void CameraInfo::resized(double w, double h)
 {
+    if (w == 1.0 && h == 1.0)
+        return;
+
     bufferSize->set( osg::Vec2f( w, h ) );
 
     for (RenderBufferMap::iterator ii = buffers.begin(); ii != buffers.end(); ++ii) {
@@ -242,7 +259,7 @@ void CameraInfo::resized(double w, double h)
     }
 }
 
-osg::Camera* CameraInfo::getCamera(CameraKind k) const
+osg::Camera* CameraInfo::getCamera(const std::string& k) const
 {
     CameraMap::const_iterator ii = cameras.find( k );
     if (ii == cameras.end())
@@ -266,8 +283,13 @@ int CameraInfo::getMainSlaveIndex() const
 void CameraInfo::setMatrices(osg::Camera* c)
 {
     view->set( c->getViewMatrix() );
-    viewInverse->set( osg::Matrix::inverse( c->getViewMatrix() ) );
+    osg::Matrixd vi = c->getInverseViewMatrix();
+    viewInverse->set( vi );
     projInverse->set( osg::Matrix::inverse( c->getProjectionMatrix() ) );
+    osg::Vec4d pos = osg::Vec4d(0., 0., 0., 1.) * vi;
+    worldPosCart->set( osg::Vec3f( pos.x(), pos.y(), pos.z() ) );
+    SGGeod pos2 = SGGeod::fromCart( SGVec3d( pos.x(), pos.y(), pos.z() ) );
+    worldPosGeod->set( osg::Vec3f( pos2.getLongitudeRad(), pos2.getLatitudeRad(), pos2.getElevationM() ) );
 }
 
 void CameraGroup::update(const osg::Vec3d& position,
@@ -734,6 +756,7 @@ CameraInfo* CameraGroup::buildCamera(SGPropertyNode* cameraNode)
         return 0;
     }
     Camera* camera = new Camera;
+    camera->setName("windowCamera");
     camera->setAllowEventFocus(false);
     camera->setGraphicsContext(window->gc.get());
     camera->setViewport(new Viewport);
@@ -742,9 +765,7 @@ CameraInfo* CameraGroup::buildCamera(SGPropertyNode* cameraNode)
     camera->setInheritanceMask(CullSettings::ALL_VARIABLES
                                & ~(CullSettings::CULL_MASK
                                    | CullSettings::CULLING_MODE
-#if defined(HAVE_CULLSETTINGS_CLEAR_MASK)
                                    | CullSettings::CLEAR_MASK
-#endif
                                    ));
 
     osg::Matrix vOff;
@@ -991,9 +1012,7 @@ CameraInfo* CameraGroup::buildGUICamera(SGPropertyNode* cameraNode,
     camera->setInheritanceMask(CullSettings::ALL_VARIABLES
                                & ~(CullSettings::COMPUTE_NEAR_FAR_MODE
                                    | CullSettings::CULLING_MODE
-#if defined(HAVE_CULLSETTINGS_CLEAR_MASK)
                                    | CullSettings::CLEAR_MASK
-#endif
                                    ));
     camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
     camera->setCullingMode(osg::CullSettings::NO_CULLING);
@@ -1002,6 +1021,7 @@ CameraInfo* CameraGroup::buildGUICamera(SGPropertyNode* cameraNode,
     const int cameraFlags = GUI | DO_INTERSECTION_TEST;
 
     CameraInfo* result = new CameraInfo(cameraFlags);
+    result->name = "GUI camera";
     // The camera group will always update the camera
     camera->setReferenceFrame(Transform::ABSOLUTE_RF);
 
@@ -1027,8 +1047,6 @@ CameraInfo* CameraGroup::buildGUICamera(SGPropertyNode* cameraNode,
 CameraGroup* CameraGroup::buildCameraGroup(osgViewer::Viewer* viewer,
                                            SGPropertyNode* gnode)
 {
-    sgUserDataInit( globals->get_props() );
-
     CameraGroup* cgroup = new CameraGroup(viewer);
     for (int i = 0; i < gnode->nChildren(); ++i) {
         SGPropertyNode* pNode = gnode->getChild(i);
@@ -1073,6 +1091,18 @@ void CameraGroup::setCameraCullMasks(Node::NodeMask nm)
             camera = info->getCamera( GEOMETRY_CAMERA );
             if (camera == 0) continue;
             camera->setCullMask( nm & ~simgear::MODELLIGHT_BIT );
+
+            camera = info->getCamera( LIGHTING_CAMERA );
+            if (camera == 0) continue;
+            osg::Switch* sw = camera->getChild(0)->asSwitch();
+            for (unsigned int i = 0; i < sw->getNumChildren(); ++i) {
+                osg::Camera* lc = dynamic_cast<osg::Camera*>(sw->getChild(i));
+                if (lc == 0) continue;
+                string name = lc->getName();
+                if (name == "LightCamera") {
+                    lc->setCullMask( (nm & simgear::LIGHTS_BITS) | (lc->getCullMask() & ~simgear::LIGHTS_BITS) );
+                }
+            }
         }
     }
 }
@@ -1116,34 +1146,34 @@ Camera* getGUICamera(CameraGroup* cgroup)
     return info->getCamera(MAIN_CAMERA);
 }
 
-static bool computeCameraIntersection(const CameraInfo* cinfo,
-                                      const osgGA::GUIEventAdapter* ea,
+
+static bool computeCameraIntersection(const CameraInfo* cinfo, const osg::Vec2d& windowPos,
                                       osgUtil::LineSegmentIntersector::Intersections& intersections)
 {
   using osgUtil::Intersector;
   using osgUtil::LineSegmentIntersector;
-  double x, y;
-  eventToWindowCoords(ea, x, y);
-  
+
   if (!(cinfo->flags & CameraGroup::DO_INTERSECTION_TEST))
     return false;
   
   const Camera* camera = cinfo->getCamera(MAIN_CAMERA);
   if ( !camera )
     camera = cinfo->getCamera( GEOMETRY_CAMERA );
-  if (camera->getGraphicsContext() != ea->getGraphicsContext())
-    return false;
+  // if (camera->getGraphicsContext() != ea->getGraphicsContext())
+ //   return false;
   
   const Viewport* viewport = camera->getViewport();
+  SGRect<double> viewportRect(viewport->x(), viewport->y(),
+                              viewport->x() + viewport->width() - 1.0,
+                              viewport->y() + viewport->height()- 1.0);
+    
   double epsilon = 0.5;
-  if (!(x >= viewport->x() - epsilon
-        && x < viewport->x() + viewport->width() -1.0 + epsilon
-        && y >= viewport->y() - epsilon
-        && y < viewport->y() + viewport->height() -1.0 + epsilon))
+  if (!viewportRect.contains(windowPos.x(), windowPos.y(), epsilon))
     return false;
   
-  Vec4d start(x, y, 0.0, 1.0);
-  Vec4d end(x, y, 1.0, 1.0);
+  Vec4d start(windowPos.x(), windowPos.y(), 0.0, 1.0);
+  Vec4d end(windowPos.x(), windowPos.y(), 1.0, 1.0);
   Matrix windowMat = viewport->computeWindowMatrix();
   Matrix startPtMat = Matrix::inverse(camera->getProjectionMatrix()
                                       * windowMat);
@@ -1163,7 +1193,8 @@ static bool computeCameraIntersection(const CameraInfo* cinfo,
                                Vec3d(start.x(), start.y(), start.z()),
                                Vec3d(end.x(), end.y(), end.z()));
   osgUtil::IntersectionVisitor iv(picker.get());
-  iv.setTraversalMask( ~simgear::MODELLIGHT_BIT );
+  iv.setTraversalMask( simgear::PICK_BIT );
+    
   const_cast<Camera*>(camera)->accept(iv);
   if (picker->containsIntersections()) {
     intersections = picker->getIntersections();
@@ -1174,12 +1205,12 @@ static bool computeCameraIntersection(const CameraInfo* cinfo,
 }
   
 bool computeIntersections(const CameraGroup* cgroup,
-                          const osgGA::GUIEventAdapter* ea,
+                          const osg::Vec2d& windowPos,
                           osgUtil::LineSegmentIntersector::Intersections& intersections)
 {
     // test the GUI first
     const CameraInfo* guiCamera = cgroup->getGUICamera();
-    if (guiCamera && computeCameraIntersection(guiCamera, ea, intersections))
+    if (guiCamera && computeCameraIntersection(guiCamera, windowPos, intersections))
         return true;
     
     // Find camera that contains event
@@ -1191,7 +1222,7 @@ bool computeIntersections(const CameraGroup* cgroup,
         if (cinfo == guiCamera)
             continue;
         
-        if (computeCameraIntersection(cinfo, ea, intersections))
+        if (computeCameraIntersection(cinfo, windowPos, intersections))
             return true;
     }