]> git.mxchange.org Git - flightgear.git/blobdiff - src/Network/multiplay.cxx
Fix line endings
[flightgear.git] / src / Network / multiplay.cxx
index 6772f07c1beaae3453d88b80b3d5f90ccc63189c..00d6dcefad706023049f77a02bb9ba5383ee76fe 100644 (file)
@@ -3,6 +3,8 @@
 // Written by Diarmuid Tyson, started February 2003.
 // diarmuid.tyson@airservicesaustralia.com
 //
+// With addtions by Vivian Meazza, January 2006
+//
 // Copyright (C) 2003  Airservices Australia
 //
 // This program is free software; you can redistribute it and/or
 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 //
 
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
 
 #include <simgear/compiler.h>
 
 #include STL_STRING
 
 #include <iostream>
+#include <map>
+#include <string>
 
 #include <simgear/debug/logstream.hxx>
-#include <simgear/scene/model/placement.hxx>
-#include <simgear/scene/model/placementtrans.hxx>
+#include <simgear/math/SGMath.hxx>
 
-#include <Scenery/scenery.hxx>
+#include <FDM/flight.hxx>
+#include <MultiPlayer/mpmessages.hxx>
 
 #include "multiplay.hxx"
 
@@ -91,6 +98,18 @@ bool FGMultiplay::open() {
 
     set_enabled(true);
 
+    SGPropertyNode* root = globals->get_props();
+
+    /// Build up the id to property map
+    unsigned i = 0;
+    while (FGMultiplayMgr::sIdPropertyList[i].name) {
+      const char* name = FGMultiplayMgr::sIdPropertyList[i].name;
+      SGPropertyNode* pNode = root->getNode(name);
+      if (pNode)
+        mPropertyMap[FGMultiplayMgr::sIdPropertyList[i].id] = pNode;
+      ++i;
+    }
+
     return is_enabled();
 }
 
@@ -102,26 +121,94 @@ bool FGMultiplay::open() {
 ******************************************************************/
 bool FGMultiplay::process() {
 
-  if (get_direction() == SG_IO_IN) {
-
-    globals->get_multiplayer_rx_mgr()->ProcessData();
-
-  } else if (get_direction() == SG_IO_OUT) {
-
-    sgMat4 posTrans;
-    globals->get_aircraft_model()->get3DModel()->getTransform()->getTransform(posTrans);
-    Point3D center = globals->get_scenery()->get_center();
-    sgdVec3 PlayerPosition;
-    sgdSetVec3(PlayerPosition, posTrans[3][0] + center[0],
-               posTrans[3][1] + center[1], posTrans[3][2] + center[2]);
-    sgQuat PlayerOrientation;
-    sgMatrixToQuat(PlayerOrientation, posTrans);
+  if (get_direction() == SG_IO_OUT) {
+
+    // check if we have left initialization phase. That will not provide
+    // interresting data, also the freeze in simulation time hurts the
+    // multiplayer clients
+    double sim_time = globals->get_sim_time_sec();
+//     if (sim_time < 20)
+//       return true;
+
+    FGInterface *ifce = cur_fdm_state;
+
+    // put together a motion info struct, you will get that later
+    // from FGInterface directly ...
+    FGExternalMotionData motionInfo;
+
+    // The current simulation time we need to update for,
+    // note that the simulation time is updated before calling all the
+    // update methods. Thus it contains the time intervals *end* time.
+    // The FDM is already run, so the states belong to that time.
+    motionInfo.time = sim_time;
+
+    // The typical lag will be the reciprocal of the output frequency
+    double hz = get_hz();
+    if (hz != 0) // I guess we can test a double for exact zero in this case
+      motionInfo.lag = 1/get_hz();
+    else
+      motionInfo.lag = 0.1; //??
+
+    // These are for now converted from lat/lon/alt and euler angles.
+    // But this should change in FGInterface ...
+    double lon = ifce->get_Longitude();
+    double lat = ifce->get_Latitude();
+    // first the aprioriate structure for the geodetic one
+    SGGeod geod = SGGeod::fromRadFt(lon, lat, ifce->get_Altitude());
+    // Convert to cartesion coordinate
+    motionInfo.position = geod;
+    
+    // The quaternion rotating from the earth centered frame to the
+    // horizontal local frame
+    SGQuatf qEc2Hl = SGQuatf::fromLonLat((float)lon, (float)lat);
+    // The orientation wrt the horizontal local frame
+    float heading = ifce->get_Psi();
+    float pitch = ifce->get_Theta();
+    float roll = ifce->get_Phi();
+    SGQuatf hlOr = SGQuatf::fromYawPitchRoll(heading, pitch, roll);
+    // The orientation of the vehicle wrt the earth centered frame
+    motionInfo.orientation = qEc2Hl*hlOr;
+
+    if (!ifce->is_suspended()) {
+      // velocities
+      motionInfo.linearVel = SG_FEET_TO_METER*SGVec3f(ifce->get_U_body(),
+                                                      ifce->get_V_body(),
+                                                      ifce->get_W_body());
+      motionInfo.angularVel = SGVec3f(ifce->get_P_body(),
+                                      ifce->get_Q_body(),
+                                      ifce->get_R_body());
+      
+      // accels, set that to zero for now.
+      // Angular accelerations are missing from the interface anyway,
+      // linear accelerations are screwed up at least for JSBSim.
+//  motionInfo.linearAccel = SG_FEET_TO_METER*SGVec3f(ifce->get_U_dot_body(),
+//                                                    ifce->get_V_dot_body(),
+//                                                    ifce->get_W_dot_body());
+      motionInfo.linearAccel = SGVec3f::zeros();
+      motionInfo.angularAccel = SGVec3f::zeros();
+    } else {
+      // if the interface is suspendend, prevent the client from
+      // wild extrapolations
+      motionInfo.linearVel = SGVec3f::zeros();
+      motionInfo.angularVel = SGVec3f::zeros();
+      motionInfo.linearAccel = SGVec3f::zeros();
+      motionInfo.angularAccel = SGVec3f::zeros();
+    }
 
-    globals->get_multiplayer_tx_mgr()->SendMyPosition(PlayerOrientation, PlayerPosition);
+    // now send the properties
+    PropertyMap::iterator it;
+    for (it = mPropertyMap.begin(); it != mPropertyMap.end(); ++it) {
+      FGFloatPropertyData pData;
+      pData.id = it->first;
+      pData.value = it->second->getFloatValue();
+      motionInfo.properties.push_back(pData);
+    }
 
+    FGMultiplayMgr* mpmgr = globals->get_multiplayer_mgr();
+    mpmgr->SendMyPosition(motionInfo);
   }
 
-    return true;
+  return true;
 }
 
 
@@ -134,14 +221,14 @@ bool FGMultiplay::close() {
 
   if (get_direction() == SG_IO_IN) {
 
-    globals->get_multiplayer_rx_mgr()->Close();
+    globals->get_multiplayer_mgr()->Close();
 
   } else if (get_direction() == SG_IO_OUT) {
 
-    globals->get_multiplayer_tx_mgr()->Close();
+    globals->get_multiplayer_mgr()->Close();
 
   }
 
-    return true;
+  return true;
 }