*
******************************************************************/
+#include <stdint.h>
#include <plib/sg.h>
// Message identifiers
#define CHAT_MSG_ID 1
-#define POS_DATA_ID 2
-
-#define MAX_CALLSIGN_LEN 10
+#define UNUSABLE_POS_DATA_ID 2
+#define POS_DATA_ID 3
+/* should be a multiple of 8! */
+#define MAX_CALLSIGN_LEN 8
/** Header for use with all messages sent */
typedef struct {
- /** Message identifier */
- char MsgId;
+ /** Message identifier, multiple of 8! */
+ uint32_t MsgId;
/** Length of the message inclusive of this header */
- unsigned int iMsgLen;
+ uint32_t iMsgLen;
/** IP address for reply to message (player's receiver address) */
- unsigned long int lReplyAddress;
+ uint32_t lReplyAddress;
/** Port for replies (player's receiver port) */
- unsigned int iReplyPort;
+ uint32_t iReplyPort;
/** Callsign used by the player */
char sCallsign[MAX_CALLSIGN_LEN];
} T_MsgHdr;
-#define MAX_CHAT_MSG_LEN 50
+#define MAX_CHAT_MSG_LEN 48
/** Chat message */
typedef struct {
} T_ChatMsg;
-
-#define MAX_MODEL_NAME_LEN 50
+/* should be a multiple of 8! */
+#define MAX_MODEL_NAME_LEN 48
/** Aircraft position message */
typedef struct {
char sModel[MAX_MODEL_NAME_LEN];
/** Position data for the aircraft */
- sgMat4 PlayerPos;
+ sgdVec3 PlayerPosition;
+ sgQuat PlayerOrientation;
} T_PositionMsg;
-
#endif
#include <plib/sg.h>
#include <simgear/scene/model/modellib.hxx>
+#include <simgear/scene/model/placementtrans.hxx>
#include <Main/globals.hxx>
#include <Scenery/scenery.hxx>
// 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
* 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) {
- sgCopyMat4(m_ModelPos, PlayerPosMat4);
+ sgdCopyVec3(m_ModelPosition, PlayerPosition);
+ sgCopyVec4(m_ModelOrientation, PlayerOrientation);
time(&m_LastUpdate);
m_bUpdated = true;
}
MPPlayer::TPlayerDataState eResult = PLAYER_DATA_NOT_AVAILABLE;
- sgCoord sgPlayerCoord;
-
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
- sgSetCoord( &sgPlayerCoord, m_ModelPos);
- m_ModelTrans->setTransform( &sgPlayerCoord );
+ sgMat4 orMat;
+ sgMakeIdentMat4(orMat);
+ sgQuatToMatrix(orMat, m_ModelOrientation);
+ m_ModelTrans->setTransform(m_ModelPosition, orMat);
eResult = PLAYER_DATA_AVAILABLE;
void MPPlayer::LoadModel(void) {
- m_ModelTrans = new ssgTransform;
+ m_ModelTrans = new ssgPlacementTransform;
// Load the model
m_Model = globals->get_model_lib()->load_model( globals->get_fg_root(),
// 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';
- sgCopyMat4(PosMsg->PlayerPos, m_ModelPos);
+ sgdCopyVec3(PosMsg->PlayerPosition, m_ModelPosition);
+ sgCopyQuat(PosMsg->PlayerOrientation, m_ModelOrientation);
}
class ssgEntity;
-class ssgTransform;
+class ssgPlacementTransform;
class MPPlayer {
/** Sets the positioning matrix held for this player
* @param PlayerPosMat4 Matrix for positioning player's aircraft
*/
- void SetPosition(const sgMat4 PlayerPosMat4);
+ void SetPosition(const sgQuat PlayerOrientation,
+ const sgdVec3 PlayerPosition);
/** Transform and place model for player
*/
/** True if object is initialised */
bool m_bInitialised;
- /** Position matrix for the player's aircraft */
- sgMat4 m_ModelPos;
+ /** Position of the player's aircraft wrt the earth fixed global system */
+ sgdVec3 m_ModelPosition;
+
+ /** Orientation the player's aircraft wrt the earth fixed global system */
+ sgQuat m_ModelOrientation;
/** Used to remove player if no activity */
time_t m_LastUpdate;
ssgEntity *m_Model;
/** Model transform */
- ssgTransform *m_ModelTrans;
+ ssgPlacementTransform *m_ModelTrans;
/** True if this player is the local player */
bool m_bLocalPlayer;
if (m_Player[iPlayerCnt]->CompareCallsign(MsgHdr->sCallsign)) {
// Player found. Update the data for the player.
- m_Player[iPlayerCnt]->SetPosition(PosMsg->PlayerPos);
+ m_Player[iPlayerCnt]->SetPosition(PosMsg->PlayerOrientation, PosMsg->PlayerPosition);
bActivePlayer = true;
}
SG_LOG( SG_NETWORK, SG_INFO, "FGMultiplayRxMgr::ProcessRxData - Add new player. IP: " << sIpAddress << ", Call: " << sCallsign << ", model: " << sModelName );
m_Player[iPlayerCnt] = new MPPlayer;
m_Player[iPlayerCnt]->Open(sIpAddress, iPort, sCallsign, sModelName, false);
- m_Player[iPlayerCnt]->SetPosition(PosMsg->PlayerPos);
+ m_Player[iPlayerCnt]->SetPosition(PosMsg->PlayerOrientation, PosMsg->PlayerPosition);
bActivePlayer = true;
}
iPlayerCnt++;
* Name: SendMyPosition
* Description: Sends the position data for the local position.
******************************************************************/
-void FGMultiplayTxMgr::SendMyPosition(const sgMat4 PlayerPosMat4) {
+void FGMultiplayTxMgr::SendMyPosition(const sgQuat PlayerOrientation,
+ const sgdVec3 PlayerPosition) {
T_MsgHdr MsgHdr;
T_PositionMsg PosMsg;
char sMsg[sizeof(T_MsgHdr) + sizeof(T_PositionMsg)];
if (m_bInitialised) {
- mLocalPlayer->SetPosition(PlayerPosMat4);
+ mLocalPlayer->SetPosition(PlayerOrientation, PlayerPosition);
mLocalPlayer->FillPosMsg(&MsgHdr, &PosMsg);
memcpy(sMsg, &MsgHdr, sizeof(T_MsgHdr));
memcpy(sMsg + sizeof(T_MsgHdr), &PosMsg, sizeof(T_PositionMsg));
/** Sends the position data for the local player
* @param PlayerPosMat4 Transformation matrix for the player's position
*/
- void SendMyPosition(const sgMat4 PlayerPosMat4);
+ void SendMyPosition(const sgQuat PlayerOrientation, const sgdVec3 PlayerPosition);
/** Sends a tex chat message.
* @param sMsgText Message text to send
#include <simgear/debug/logstream.hxx>
#include <simgear/scene/model/placement.hxx>
+#include <Scenery/scenery.hxx>
+
#include "multiplay.hxx"
SG_USING_STD(string);
} else if (get_direction() == SG_IO_OUT) {
- globals->get_multiplayer_tx_mgr()->
- SendMyPosition(globals->get_aircraft_model()->get3DModel()->get_POS());
+ sgMat4 posTrans;
+ sgCopyMat4(posTrans, globals->get_aircraft_model()->get3DModel()->get_POS());
+ 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);
}