// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef FG_MPLAYER_AS
/******************************************************************
* $Id$
#include "mpplayer.hxx"
#include <stdlib.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
+#if !(defined(_MSC_VER) || defined(__MINGW32__))
+# include <netdb.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+#endif
#include <plib/netSocket.h>
+#include <plib/sg.h>
+
+#include <simgear/scene/model/modellib.hxx>
+#include <simgear/scene/model/placementtrans.hxx>
#include <Main/globals.hxx>
-#include <Model/loader.hxx>
#include <Scenery/scenery.hxx>
m_bInitialised = false;
m_LastUpdate = 0;
m_PlayerAddress.set("localhost", 0);
+ m_sCallsign = "none";
}
m_sCallsign = sCallsign;
m_sModelName = sModelName;
m_bLocalPlayer = bLocalPlayer;
+ SG_LOG( SG_NETWORK, SG_ALERT, "Initialising " << m_sCallsign
+ << " using '" << m_sModelName << "'" );
// If the player is remote then load the model
if (!bLocalPlayer) {
-
- LoadModel();
-
+ try {
+ LoadModel();
+ } catch (...) {
+ SG_LOG( SG_NETWORK, SG_ALERT, "Failed to load remote model '" << sModelName << "'." );
+ return false;
+ }
}
m_bInitialised = bSuccess;
} else {
- cerr << "MPPlayer::Open - Attempt to open an already open player connection." << endl;
+ SG_LOG( SG_NETWORK, SG_ALERT, "MPPlayer::Open - Attempt to open an already open player connection." );
bSuccess = false;
}
******************************************************************/
void MPPlayer::Close(void) {
-
// Remove the model from the game
- if (!m_bLocalPlayer) {
- globals->get_scenery()->get_scene_graph()->removeKid(m_ModelSel);
+ if (m_bInitialised && !m_bLocalPlayer) {
+
+ // Disconnect the model from the transform, then the transform from the scene.
+ m_ModelTrans->removeKid(m_Model);
+ globals->get_scenery()->unregister_placement_transform(m_ModelTrans);
+ globals->get_scenery()->get_aircraft_branch()->removeKid( m_ModelTrans);
+
+ // Flush the model loader so that it erases the model from its list of
+ // models.
+// globals->get_model_lib()->flush1();
+
+ // Assume that plib/ssg deletes the model and transform as their
+ // refcounts should be zero.
+
}
m_bInitialised = false;
m_bUpdated = false;
m_LastUpdate = 0;
+ m_sCallsign = "none";
}
* Description: Updates position data held for this player and resets
* the last update time.
******************************************************************/
-void MPPlayer::SetPosition(const sgMat4 PlayerPosMat4) {
-
+void MPPlayer::SetPosition(const sgQuat PlayerOrientation,
+ const sgdVec3 PlayerPosition) {
// Save the position matrix and update time
if (m_bInitialised) {
- memcpy(m_ModelPos, PlayerPosMat4, sizeof(sgMat4));
+ sgdCopyVec3(m_ModelPosition, PlayerPosition);
+ sgCopyVec4(m_ModelOrientation, PlayerOrientation);
time(&m_LastUpdate);
m_bUpdated = true;
}
-
}
/******************************************************************
* Name: Draw
* Description: Updates the position for the player's model
-* The state of the player (old, initialised etc)
-* is returned.
+* The state of the player's data is returned.
******************************************************************/
-int MPPlayer::Draw(void) {
+MPPlayer::TPlayerDataState MPPlayer::Draw(void) {
- int iResult = PLAYER_DATA_NOT_AVAILABLE;
+ MPPlayer::TPlayerDataState eResult = PLAYER_DATA_NOT_AVAILABLE;
- sgCoord sgPlayerCoord;
-
- if (m_bInitialised) {
+ if (m_bInitialised && !m_bLocalPlayer) {
if ((time(NULL) - m_LastUpdate < TIME_TO_LIVE)) {
// Peform an update if it has changed since the last update
if (m_bUpdated) {
// Transform and update player model
- m_ModelSel->select(1);
- sgSetCoord( &sgPlayerCoord, m_ModelPos);
- m_ModelTrans->setTransform( &sgPlayerCoord );
+ sgMat4 orMat;
+ sgMakeIdentMat4(orMat);
+ sgQuatToMatrix(orMat, m_ModelOrientation);
+ m_ModelTrans->setTransform(m_ModelPosition, orMat);
- iResult = PLAYER_DATA_AVAILABLE;
+ eResult = PLAYER_DATA_AVAILABLE;
// Clear the updated flag so that the position data
// is only available if it has changed
// Data has not been updated for some time.
} else {
- iResult = PLAYER_DATA_EXPIRED;
+ eResult = PLAYER_DATA_EXPIRED;
}
}
- return iResult;
+ return eResult;
}
void MPPlayer::LoadModel(void) {
- m_ModelSel = new ssgSelector;
- m_ModelTrans = new ssgTransform;
+ m_ModelTrans = new ssgPlacementTransform;
+
+ // Load the model
+ m_Model = globals->get_model_lib()->load_model( globals->get_fg_root(),
+ m_sModelName,
+ globals->get_props(),
+ globals->get_sim_time_sec() );
+ m_Model->clrTraversalMaskBits( SSGTRAV_HOT );
- ssgEntity *Model = globals->get_model_loader()->load_model(m_sModelName);
- Model->clrTraversalMaskBits( SSGTRAV_HOT );
- m_ModelTrans->addKid( Model );
- m_ModelSel->addKid( m_ModelTrans );
- ssgFlatten( Model );
- ssgStripify( m_ModelSel );
+ // Add model to transform
+ m_ModelTrans->addKid( m_Model );
- globals->get_scenery()->get_scene_graph()->addKid( m_ModelSel );
- globals->get_scenery()->get_scene_graph()->addKid( Model );
+ // Place on scene under aircraft branch
+ globals->get_scenery()->get_aircraft_branch()->addKid( m_ModelTrans );
+ globals->get_scenery()->register_placement_transform( m_ModelTrans);
}
strncpy(PosMsg->sModel, m_sModelName.c_str(), MAX_MODEL_NAME_LEN);
PosMsg->sModel[MAX_MODEL_NAME_LEN - 1] = '\0';
-
- memcpy(PosMsg->PlayerPos, m_ModelPos, sizeof(sgMat4));
-
-
+ /*
+ sgdCopyVec3(PosMsg->PlayerPosition, m_ModelPosition);
+ sgCopyQuat(PosMsg->PlayerOrientation, m_ModelOrientation);
+ */
+ PosMsg->PlayerPosition[0] = XDR_encode_double (m_ModelPosition[0]);
+ PosMsg->PlayerPosition[1] = XDR_encode_double (m_ModelPosition[1]);
+ PosMsg->PlayerPosition[2] = XDR_encode_double (m_ModelPosition[2]);
+ PosMsg->PlayerOrientation[0] = XDR_encode_float (m_ModelOrientation[0]);
+ PosMsg->PlayerOrientation[1] = XDR_encode_float (m_ModelOrientation[1]);
+ PosMsg->PlayerOrientation[2] = XDR_encode_float (m_ModelOrientation[2]);
+ PosMsg->PlayerOrientation[3] = XDR_encode_float (m_ModelOrientation[3]);
}
******************************************************************/
void MPPlayer::FillMsgHdr(T_MsgHdr *MsgHdr, const int iMsgId) {
- struct in_addr address;
-
- MsgHdr->MsgId = iMsgId;
+ struct in_addr address;
+ uint32_t len;
switch (iMsgId) {
case CHAT_MSG_ID:
- MsgHdr->iMsgLen = sizeof(T_MsgHdr) + sizeof(T_ChatMsg);
+ len = sizeof(T_MsgHdr) + sizeof(T_ChatMsg);
break;
case POS_DATA_ID:
- MsgHdr->iMsgLen = sizeof(T_MsgHdr) + sizeof(T_PositionMsg);
+ len = sizeof(T_MsgHdr) + sizeof(T_PositionMsg);
break;
default:
- MsgHdr->iMsgLen = sizeof(T_MsgHdr);
+ len = sizeof(T_MsgHdr);
break;
}
-
- inet_aton(m_PlayerAddress.getHost(), &address);
- MsgHdr->lReplyAddress = address.s_addr;
-
- MsgHdr->iReplyPort = m_PlayerAddress.getPort();
+ MsgHdr->Magic = XDR_encode_uint32 (MSG_MAGIC);
+ MsgHdr->Version = XDR_encode_uint32 (PROTO_VER);
+ MsgHdr->MsgId = XDR_encode_uint32 (iMsgId);
+ MsgHdr->iMsgLen = XDR_encode_uint32 (len);
+ // inet_addr returns address in network byte order
+ // no need to encode it
+ MsgHdr->lReplyAddress = inet_addr( m_PlayerAddress.getHost() );
+ MsgHdr->iReplyPort = XDR_encode_uint32 (m_PlayerAddress.getPort());
strncpy(MsgHdr->sCallsign, m_sCallsign.c_str(), MAX_CALLSIGN_LEN);
MsgHdr->sCallsign[MAX_CALLSIGN_LEN - 1] = '\0';
-
}
+#endif // FG_MPLAYER_AS
+