X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=src%2FNetwork%2Fmultiplay.cxx;h=f6e0e30c7865f2b7000d34edb3b209f992ff31f2;hb=e653ed4598dfcfea634470d16b49b97fc87e1840;hp=0b6118b36939b92cc805cb0f5a91ac9615e09a9b;hpb=12fc19080b8bae18b25c1cf6e5361852cc534a2f;p=flightgear.git diff --git a/src/Network/multiplay.cxx b/src/Network/multiplay.cxx index 0b6118b36..f6e0e30c7 100644 --- a/src/Network/multiplay.cxx +++ b/src/Network/multiplay.cxx @@ -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 @@ -17,7 +19,7 @@ // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // #ifdef HAVE_CONFIG_H @@ -26,19 +28,21 @@ #include -#include STL_STRING +#include #include +#include +#include #include -#include -#include +#include -#include +#include +#include #include "multiplay.hxx" -SG_USING_STD(string); +using std::string; // These constants are provided so that the ident command can list file versions. @@ -94,6 +98,17 @@ bool FGMultiplay::open() { set_enabled(true); + SGPropertyNode* root = globals->get_props(); + + /// Build up the id to property map + + for (unsigned i = 0; i < FGMultiplayMgr::numProperties; ++i) { + const char* name = FGMultiplayMgr::sIdPropertyList[i].name; + SGPropertyNode* pNode = root->getNode(name); + if (pNode) + mPropertyMap[FGMultiplayMgr::sIdPropertyList[i].id] = pNode; + } + return is_enabled(); } @@ -104,27 +119,149 @@ bool FGMultiplay::open() { * or receive data over the network ******************************************************************/ bool FGMultiplay::process() { + using namespace simgear; + 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 = SGVec3d::fromGeod(geod); + + // The quaternion rotating from the earth centered frame to the + // horizontal local frame + SGQuatf qEc2Hl = SGQuatf::fromLonLatRad((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(); + } - 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); - - globals->get_multiplayer_tx_mgr()->SendMyPosition(PlayerOrientation, PlayerPosition); + // now send the properties + PropertyMap::iterator it; + for (it = mPropertyMap.begin(); it != mPropertyMap.end(); ++it) { + FGPropertyData* pData = new FGPropertyData; + pData->id = it->first; + pData->type = it->second->getType(); + + switch (pData->type) { + case props::INT: + case props::LONG: + case props::BOOL: + pData->int_value = it->second->getIntValue(); + break; + case props::FLOAT: + case props::DOUBLE: + pData->float_value = it->second->getFloatValue(); + break; + case props::STRING: + case props::UNSPECIFIED: + { + // FIXME: We assume unspecified are strings for the moment. + + const char* cstr = it->second->getStringValue(); + int len = strlen(cstr); + + if (len > 0) + { + pData->string_value = new char[len + 1]; + strcpy(pData->string_value, cstr); + } + else + { + // Size 0 - ignore + pData->string_value = 0; + } + + //cout << " Sending property " << pData->id << " " << pData->type << " " << pData->string_value << "\n"; + break; + } + default: + // FIXME Currently default to a float. + //cout << "Unknown type when iterating through props: " << pData->type << "\n"; + pData->float_value = it->second->getFloatValue(); + break; + } + + motionInfo.properties.push_back(pData); + } + FGMultiplayMgr* mpmgr = globals->get_multiplayer_mgr(); + mpmgr->SendMyPosition(motionInfo); + + // Now remove the data + std::vector::const_iterator propIt; + std::vector::const_iterator propItEnd; + propIt = motionInfo.properties.begin(); + propItEnd = motionInfo.properties.end(); + + //cout << "Deleting data\n"; + + while (propIt != propItEnd) + { + delete *propIt; + propIt++; + } } - return true; + return true; } @@ -135,16 +272,22 @@ bool FGMultiplay::process() { ******************************************************************/ bool FGMultiplay::close() { + FGMultiplayMgr *mgr = globals->get_multiplayer_mgr(); + + if (mgr == 0) { + return false; + } + if (get_direction() == SG_IO_IN) { - globals->get_multiplayer_rx_mgr()->Close(); + mgr->Close(); } else if (get_direction() == SG_IO_OUT) { - globals->get_multiplayer_tx_mgr()->Close(); + mgr->Close(); } - return true; + return true; }