[prev in list] [next in list] [prev in thread] [next in thread] 

List:       flightgear-cvs
Subject:    [Flightgear-cvslogs] CVS: FlightGear/src/Model panelnode.cxx,1.1.1.1,1.2 panelnode.hxx,1.1.1.1,1.2
From:       "Curtis L. Olson" <curt () seneca ! me ! umn ! edu>
Date:       2002-10-29 19:44:08
[Download RAW message or body]

Update of /var/cvs/FlightGear-0.9/FlightGear/src/Model
In directory seneca:/tmp/cvs-serv6632/Model

Modified Files:
	panelnode.cxx panelnode.hxx 
Log Message:
Andy Ross:

The biggest and coolest patch adds mouse sensitivity to the 3D
cockpits, so we can finally work the radios.  This ended up requiring
significant modifications outside of the 3D cockpit code.  Stuff folks
will want to look at:

+ The list of all "3D" cockpits is stored statically in the
   panelnode.cxx file.  This is clumsy, and won't migrate well to a
   multiple-aircraft feature.  Really, there should be a per-model list
   of 3D panels, but I couldn't find a clean place to put this.  The
   only handle you get back after parsing a model is a generic ssg
   node, to which I obviously can't add panel-specific methods.

+ The aircraft model is parsed *very* early in the initialization
   order.  Earlier, in fact, than the static list of allowable command
   bindings is built in fgInitCommands().  This is bad, as it means
   that mouse bindings on the instruments can't work yet.  I moved the
   call to fgInitCommands, but someone should look carefully to see
   that I picked the right place.  There's a lot of initialization
   code, and I got a little lost in there... :)

+ I added yet another "update" hook to the fgRenderFrame routine to
   hook the updates for the 3D panels.  This is only required for
   "mouse press delay", and it's a fairly clumsy mechanism based on
   frame rate instead of real time.  There appears to be delay handling
   already in place in the Input stuff, and there's a discussion going
   on about different mouse behavior right now.  Maybe this is a good
   time to unify these two (now three) approaches?



Index: panelnode.cxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/FlightGear/src/Model/panelnode.cxx,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -r1.1.1.1 -r1.2
*** panelnode.cxx	10 Sep 2002 01:14:08 -0000	1.1.1.1
--- panelnode.cxx	29 Oct 2002 19:44:04 -0000	1.2
***************
*** 3,12 ****
  #endif
  
  #include <Main/fg_props.hxx>
  #include <Cockpit/panel.hxx>
  #include <Cockpit/panel_io.hxx>
- #include <GL/gl.h>
  #include "panelnode.hxx"
  
  FGPanelNode::FGPanelNode(SGPropertyNode* props)
  {
--- 3,33 ----
  #endif
  
+ #include <vector>
+ 
+ #include <GL/gl.h>
+ #include <plib/sg.h>
+ 
  #include <Main/fg_props.hxx>
  #include <Cockpit/panel.hxx>
  #include <Cockpit/panel_io.hxx>
  #include "panelnode.hxx"
  
+ // Static (!) handling for all 3D panels in the program.  Very
+ // clumsy.  Replace with per-aircraft handling.
+ vector<FGPanelNode*> all_3d_panels;
+ bool fgHandle3DPanelMouseEvent(int button, int updown, int x, int y)
+ {
+     for(int i=0; i<all_3d_panels.size(); i++)
+         if(all_3d_panels[i]->doMouseAction(button, updown, x, y))
+             return true;
+     return false;
+ }
+ 
+ void fgUpdate3DPanels()
+ {
+     for(int i=0; i<all_3d_panels.size(); i++)
+         all_3d_panels[i]->getPanel()->updateMouseDelay();
+ }
+ 
  FGPanelNode::FGPanelNode(SGPropertyNode* props)
  {
***************
*** 15,18 ****
--- 36,51 ----
      _panel = fgReadPanel(props->getStringValue("path"));
  
+     // Never mind.  We *have* to call init to make sure the static
+     // state is initialized (it's not, if there aren't any 2D
+     // panels).  This is a memory leak and should be fixed!`
+     _panel->init();
+ 
+     // Initialize the matrices to the identity.  PLib prints warnings
+     // when trying to invert singular matrices (e.g. when not using a
+     // 3D panel).
+     for(int i=0; i<4; i++)
+         for(int j=0; j<4; j++)
+             _lastModelview[4*i+j] = _lastProjection[4*i+j] = i==j ? 1 : 0;
+ 
      // Read out the pixel-space info
      _xmax = _panel->getWidth();
***************
*** 35,39 ****
      _bottomRight[2] = pt->getFloatValue("z-m");
  
!     // Now generate out transformation matrix.  For shorthand, use
      // "a", "b", and "c" as our corners and "m" as the matrix. The
      // vector u goes from a to b, v from a to c, and w is a
--- 68,72 ----
      _bottomRight[2] = pt->getFloatValue("z-m");
  
!     // Now generate our transformation matrix.  For shorthand, use
      // "a", "b", and "c" as our corners and "m" as the matrix. The
      // vector u goes from a to b, v from a to c, and w is a
***************
*** 75,78 ****
--- 108,114 ----
      bsphere.setCenter(cx, cy, cz);
      bsphere.setRadius(r);
+ 
+     // All done.  Add us to the list
+     all_3d_panels.push_back(this);
  }
  
***************
*** 93,104 ****
      glPushMatrix();
      glMultMatrixf(_xform);
      _panel->draw();
      glPopMatrix();
  }
  
  void FGPanelNode::die()
  {
      SG_LOG(SG_ALL,SG_ALERT,"Unimplemented function called on FGPanelNode");
!     *(int*)0=0;
  }
  
--- 129,187 ----
      glPushMatrix();
      glMultMatrixf(_xform);
+ 
+     // Grab the matrix state, so that we can get back from screen
+     // coordinates to panel coordinates when the user clicks the
+     // mouse.
+     glGetFloatv(GL_MODELVIEW_MATRIX, _lastModelview);
+     glGetFloatv(GL_PROJECTION_MATRIX, _lastProjection);
+     glGetIntegerv(GL_VIEWPORT, _lastViewport);
+ 
      _panel->draw();
+ 
+ 
      glPopMatrix();
  }
  
+ bool FGPanelNode::doMouseAction(int button, int updown, int x, int y)
+ {
+     // Covert the screen coordinates to viewport coordinates in the
+     // range [0:1], then transform to OpenGL "post projection" coords
+     // in [-1:1].  Remember the difference in Y direction!
+     float vx = (x + 0.5 - _lastViewport[0]) / _lastViewport[2];
+     float vy = (y + 0.5 - _lastViewport[1]) / _lastViewport[3];
+     vx = 2*vx - 1;
+     vy = 1 - 2*vy;
+ 
+     // Make two vectors in post-projection coordinates at the given
+     // screen, one in the near field and one in the far field.
+     sgVec3 a, b;
+     a[0] = b[0] = vx;
+     a[1] = b[1] = vy;
+     a[2] =  0.75; // "Near" Z value
+     b[2] = -0.75; // "Far" Z value
+ 
+     // Run both vectors "backwards" through the OpenGL matrix
+     // transformation.  Remember to w-normalize the vectors!
+     sgMat4 m;
+     sgMultMat4(m, *(sgMat4*)_lastProjection, *(sgMat4*)_lastModelview);
+     sgInvertMat4(m);
+ 
+     sgFullXformPnt3(a, m);
+     sgFullXformPnt3(b, m);
+ 
+     // And find their intersection on the z=0 plane.  The resulting X
+     // and Y coordinates are the hit location in panel coordinates.
+     float dxdz = (b[0] - a[0]) / (b[2] - a[2]);
+     float dydz = (b[1] - a[1]) / (b[2] - a[2]);
+     int panelX = (int)(a[0] - a[2]*dxdz + 0.5);
+     int panelY = (int)(a[1] - a[2]*dydz + 0.5);
+ 
+     return _panel->doLocalMouseAction(button, updown, panelX, panelY);
+ }
+ 
  void FGPanelNode::die()
  {
      SG_LOG(SG_ALL,SG_ALERT,"Unimplemented function called on FGPanelNode");
!     exit(1);
  }
  

Index: panelnode.hxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/FlightGear/src/Model/panelnode.hxx,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -r1.1.1.1 -r1.2
*** panelnode.hxx	10 Sep 2002 01:14:08 -0000	1.1.1.1
--- panelnode.hxx	29 Oct 2002 19:44:04 -0000	1.2
***************
*** 9,12 ****
--- 9,18 ----
  // inspection, are unimplemented.
  
+ // Static mouse handler for all FGPanelNodes.  Very clumsy; this
+ // should really be done through our container (an aircraft model,
+ // typically).
+ bool fgHandle3DPanelMouseEvent(int button, int updown, int x, int y);
+ void fgUpdate3DPanels();
+ 
  class FGPanelNode : public ssgLeaf 
  {
***************
*** 19,23 ****
  
      virtual void draw();
!     void mouseEvent(int button, int updown, int x, int y);
  
      virtual void recalcBSphere() { bsphere_is_invalid = 0; }
--- 25,31 ----
  
      virtual void draw();
!     bool doMouseAction(int button, int updown, int x, int y);
! 
!     FGPanel* getPanel() { return _panel; }
  
      virtual void recalcBSphere() { bsphere_is_invalid = 0; }


_______________________________________________
Flightgear-cvslogs mailing list
Flightgear-cvslogs@flightgear.org
http://mail.flightgear.org/mailman/listinfo/flightgear-cvslogs
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic