mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-31 12:55:33 +08:00
Reflecting discussed changes for interpolation performance refs #386
(based on FSX testing) * Only send changed situation to SIM * Split sending of parts / situations * Only send parts with a reduced frequency (means slower as positions) * Mark geodetic height as null for default values (the value is usually unavailable) * Fixed altitude to MSL for network data * Trace which aircrafts support aircraft parts via network * Renamed insert_fron push_front (as proposed by Roland) Status quo / lessons learnt * On slower PCs jitter is still noticed for interpolated aircraft. * Running interpolation in an independent process (aka core, not in GUI) reduced load dependencies => it seems to make sense to run driver in own thread * The onGround flag in parts seems clumsy as it required to retrieve parts for position updates * In interpolation performance really matters
This commit is contained in:
@@ -81,31 +81,14 @@ namespace BlackSimPlugin
|
||||
if (m_clientStatus == Disconnected) { return; }
|
||||
|
||||
|
||||
bool ok;
|
||||
CAircraftSituation situation = this->m_interpolator->getCurrentInterpolatedSituation(this->m_interpolator->getSituationsByCallsign(), m_callsign, -1, &ok);
|
||||
if (!ok) { return; }
|
||||
MPPositionSlewMode positionSlewMode = aircraftSituationToFS9(situation);
|
||||
IInterpolator::InterpolationStatus status;
|
||||
CAircraftSituation situation = this->m_interpolator->getInterpolatedSituation(m_callsign, -1, status);
|
||||
|
||||
QByteArray positionMessage;
|
||||
MultiPlayerPacketParser::writeType(positionMessage, CFs9Sdk::MULTIPLAYER_PACKET_ID_POSITION_SLEWMODE);
|
||||
MultiPlayerPacketParser::writeSize(positionMessage, positionSlewMode.size());
|
||||
positionSlewMode.packet_index = m_packetIndex;
|
||||
++m_packetIndex;
|
||||
positionMessage = MultiPlayerPacketParser::writeMessage(positionMessage, positionSlewMode);
|
||||
|
||||
sendMessage(positionMessage);
|
||||
|
||||
QByteArray paramMessage;
|
||||
MPParam param;
|
||||
MultiPlayerPacketParser::writeType(paramMessage, CFs9Sdk::MULTIPLAYER_PACKET_ID_PARAMS);
|
||||
MultiPlayerPacketParser::writeSize(paramMessage, param.size());
|
||||
param.packet_index = m_packetIndex;
|
||||
++m_packetIndex;
|
||||
paramMessage = MultiPlayerPacketParser::writeMessage(paramMessage, param);
|
||||
sendMessage(paramMessage);
|
||||
|
||||
m_lastAircraftSituation = situation;
|
||||
// Test only for successful interpolation. FS9 requires constant positions
|
||||
if (!status.interpolationSucceeded) return;
|
||||
|
||||
sendMultiplayerPosition(situation);
|
||||
sendMultiplayerParamaters();
|
||||
}
|
||||
|
||||
void CFs9Client::initialize()
|
||||
|
||||
@@ -71,31 +71,32 @@ namespace BlackSimPlugin
|
||||
HRESULT CSimConnectDefinitions::initRemoteAircraft(const HANDLE hSimConnect)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "Initial Position", NULL, SIMCONNECT_DATATYPE_INITPOSITION);
|
||||
// Position
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPosition, "Initial Position", NULL, SIMCONNECT_DATATYPE_INITPOSITION);
|
||||
|
||||
// Lights
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "LIGHT STROBE", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "LIGHT LANDING", "Bool");
|
||||
// hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "LIGHT TAXI", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "LIGHT BEACON", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "LIGHT NAV", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "LIGHT LOGO", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "LIGHT STROBE", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "LIGHT LANDING", "Bool");
|
||||
// hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "LIGHT TAXI", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "LIGHT BEACON", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "LIGHT NAV", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "LIGHT LOGO", "Bool");
|
||||
|
||||
// Flaps
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "LEADING EDGE FLAPS LEFT PERCENT", "Percent Over 100");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "LEADING EDGE FLAPS RIGHT PERCENT", "Percent Over 100");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "TRAILING EDGE FLAPS LEFT PERCENT", "Percent Over 100");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "TRAILING EDGE FLAPS RIGHT PERCENT", "Percent Over 100");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "LEADING EDGE FLAPS LEFT PERCENT", "Percent Over 100");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "LEADING EDGE FLAPS RIGHT PERCENT", "Percent Over 100");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "TRAILING EDGE FLAPS LEFT PERCENT", "Percent Over 100");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "TRAILING EDGE FLAPS RIGHT PERCENT", "Percent Over 100");
|
||||
|
||||
// Gear & Spoiler
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "GEAR HANDLE POSITION", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "SPOILERS HANDLE POSITION", "Percent Over 100");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "GEAR HANDLE POSITION", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "SPOILERS HANDLE POSITION", "Percent Over 100");
|
||||
|
||||
// Engines
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "GENERAL ENG COMBUSTION:1", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "GENERAL ENG COMBUSTION:2", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "GENERAL ENG COMBUSTION:3", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraft, "GENERAL ENG COMBUSTION:4", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "GENERAL ENG COMBUSTION:1", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "GENERAL ENG COMBUSTION:2", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "GENERAL ENG COMBUSTION:3", "Bool");
|
||||
hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "GENERAL ENG COMBUSTION:4", "Bool");
|
||||
|
||||
if (hr != S_OK)
|
||||
{
|
||||
|
||||
@@ -70,13 +70,12 @@ namespace BlackSimPlugin
|
||||
char title[256]; //!< Aircraft model string
|
||||
};
|
||||
|
||||
//! Data struct of remote aircraft
|
||||
struct DataDefinitionRemoteAircraft
|
||||
//! Data struct of remote aircraft parts
|
||||
struct DataDefinitionRemoteAircraftParts
|
||||
{
|
||||
SIMCONNECT_DATA_INITPOSITION position; //!< Aircrafts position
|
||||
double lightStrobe; //!< Is strobe light on?
|
||||
double lightLanding; //!< Is landing light on?
|
||||
// double lightTaxi; //!< Is taxi light on?
|
||||
// double lightTaxi; //!< Is taxi light on?
|
||||
double lightBeacon; //!< Is beacon light on?
|
||||
double lightNav; //!< Is nav light on?
|
||||
double lightLogo; //!< Is logo light on?
|
||||
@@ -141,7 +140,8 @@ namespace BlackSimPlugin
|
||||
{
|
||||
DataOwnAircraft,
|
||||
DataOwnAircraftTitle,
|
||||
DataRemoteAircraft,
|
||||
DataRemoteAircraftParts,
|
||||
DataRemoteAircraftPosition,
|
||||
DataSimEnvironment,
|
||||
DataClientAreaSb, //!< whole SB area
|
||||
DataClientAreaSbIdent, //!< ident single value
|
||||
|
||||
@@ -597,111 +597,138 @@ namespace BlackSimPlugin
|
||||
|
||||
void CSimulatorFsx::updateRemoteAircraft()
|
||||
{
|
||||
static_assert(sizeof(DataDefinitionRemoteAircraft) == 176, "DataDefinitionRemoteAircraft has an incorrect size.");
|
||||
static_assert(sizeof(DataDefinitionRemoteAircraftParts) == 120, "DataDefinitionRemoteAircraftParts has an incorrect size.");
|
||||
Q_ASSERT(this->m_interpolator);
|
||||
Q_ASSERT_X(this->m_interpolator->thread() != this->thread(), "updateOtherAircraft", "interpolator should run in its own thread");
|
||||
|
||||
// nothing to do, reset request id and exit
|
||||
if (this->isPaused()) { return; } // no interpolation while paused
|
||||
int remoteAircraftNo = this->remoteAircraft().size();
|
||||
if (remoteAircraftNo < 1) { m_interpolationRequest = 0; return; }
|
||||
|
||||
// initial request, and bye. First time we have aircraft
|
||||
if (m_interpolationRequest == 0)
|
||||
{
|
||||
m_interpolator->syncRequestSituationsCalculationsForAllCallsigns(++m_interpolationRequest);
|
||||
return;
|
||||
}
|
||||
// interpolate and send to SIM
|
||||
m_interpolationRequest++;
|
||||
|
||||
// try to get old request
|
||||
bool lastRequestAvailable = false;
|
||||
CAircraftSituationList interpolations = m_interpolator->getRequest(m_interpolationRequest, &lastRequestAvailable);
|
||||
if (!lastRequestAvailable)
|
||||
{
|
||||
// warning the 1st and every 10th time
|
||||
bool warning = m_interpolationsSkipped % 10;
|
||||
m_interpolationsSkipped++;
|
||||
if (warning)
|
||||
{
|
||||
CLogMessage(this).warning("Skipped interpolation %1 time(s)") << m_interpolationsSkipped;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// values used for position and parts
|
||||
bool isOnGround = false;
|
||||
|
||||
// non blocking calculations in background
|
||||
m_interpolator->syncRequestSituationsCalculationsForAllCallsigns(++m_interpolationRequest);
|
||||
|
||||
// now send to sim
|
||||
for (const CAircraftSituation ¤tSituation : interpolations)
|
||||
qint64 currentTimestamp = QDateTime::currentMSecsSinceEpoch();
|
||||
for (const CSimConnectObject &simObj : m_simConnectObjects)
|
||||
{
|
||||
const CCallsign callsign(currentSituation.getCallsign());
|
||||
if (!m_simConnectObjects.contains(callsign)) { continue; } // only if aircraft is already available
|
||||
bool hasParts;
|
||||
const CSimConnectObject &simObj = m_simConnectObjects[callsign];
|
||||
const CCallsign callsign(simObj.getCallsign());
|
||||
IInterpolator::InterpolationStatus interpolatorStatus;
|
||||
IInterpolator::PartsStatus partsStatus;
|
||||
if (simObj.getObjectId() == 0) { continue; }
|
||||
SIMCONNECT_DATA_INITPOSITION position = aircraftSituationToFsxInitPosition(currentSituation);
|
||||
CAircraftParts parts = m_interpolator->getLatestPartsBeforeOffset(callsign, IInterpolator::TimeOffsetMs, &hasParts);
|
||||
CAircraftSituation interpolatedSituation = this->m_interpolator->getInterpolatedSituation(callsign, currentTimestamp, interpolatorStatus);
|
||||
|
||||
DataDefinitionRemoteAircraft ddRemoteAircraft;
|
||||
if (hasParts)
|
||||
// having the on gground flag in parts forces me to obtain parts here
|
||||
// which is not hte smartest thing regarding performance
|
||||
CAircraftPartsList parts = this->m_interpolator->getAndRemovePartsBeforeOffset(callsign, currentTimestamp - IInterpolator::TimeOffsetMs, partsStatus);
|
||||
if (interpolatorStatus.allTrue())
|
||||
{
|
||||
// update situation
|
||||
SIMCONNECT_DATA_INITPOSITION position = aircraftSituationToFsxInitPosition(interpolatedSituation);
|
||||
|
||||
//! \todo The onGround in parts is nuts, as already mentioned in the discussion
|
||||
// a) I am forced to read parts even if i just want to update position
|
||||
// b) Unlike the other values it is not a fire aforget value, as I need it again in the next cycle
|
||||
if (partsStatus.supportsParts && !parts.isEmpty())
|
||||
{
|
||||
// we have parts, and use the closest ground
|
||||
isOnGround = parts.front().isOnGround();
|
||||
}
|
||||
else
|
||||
{
|
||||
isOnGround = interpolatedSituation.isOnGroundGuessed();
|
||||
}
|
||||
|
||||
position.OnGround = isOnGround ? 1 : 0;
|
||||
HRESULT hr = S_OK;
|
||||
hr += SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraftPosition,
|
||||
simObj.getObjectId(), 0, 0,
|
||||
sizeof(SIMCONNECT_DATA_INITPOSITION), &position);
|
||||
if (hr != S_OK) { CLogMessage(this).warning("Failed so set position on SimObject %1 callsign: %2") << simObj.getObjectId() << callsign; }
|
||||
}
|
||||
|
||||
|
||||
// set parts
|
||||
DataDefinitionRemoteAircraftParts ddRemoteAircraftParts;
|
||||
if (partsStatus.supportsParts)
|
||||
{
|
||||
// parts is supported, but do we need to update?
|
||||
if (parts.isEmpty()) { continue; }
|
||||
|
||||
// we have parts
|
||||
position.OnGround = parts.isOnGround() ? 1 : 0;
|
||||
ddRemoteAircraft.position = position;
|
||||
ddRemoteAircraft.lightStrobe = parts.getLights().isStrobeOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.lightLanding = parts.getLights().isLandingOn() ? 1.0 : 0.0;
|
||||
// ddRemoteAircraft.lightTaxi = parts.getLights().isTaxiOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.lightBeacon = parts.getLights().isBeaconOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.lightNav = parts.getLights().isNavOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.lightLogo = parts.getLights().isLogoOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.flapsLeadingEdgeLeftPercent = parts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraft.flapsLeadingEdgeRightPercent = parts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraft.flapsTrailingEdgeLeftPercent = parts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraft.flapsTrailingEdgeRightPercent = parts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraft.spoilersHandlePosition = parts.isSpoilersOut() ? 1.0 : 0.0;
|
||||
ddRemoteAircraft.gearHandlePosition = parts.isGearDown() ? 1 : 0;
|
||||
ddRemoteAircraft.engine1Combustion = parts.isEngineOn(1) ? 1 : 0;
|
||||
ddRemoteAircraft.engine2Combustion = parts.isEngineOn(2) ? 1 : 0;;
|
||||
ddRemoteAircraft.engine3Combustion = parts.isEngineOn(3) ? 1 : 0;
|
||||
ddRemoteAircraft.engine4Combustion = parts.isEngineOn(4) ? 1 : 0;
|
||||
CAircraftParts newestParts = parts.front();
|
||||
ddRemoteAircraftParts.lightStrobe = newestParts.getLights().isStrobeOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraftParts.lightLanding = newestParts.getLights().isLandingOn() ? 1.0 : 0.0;
|
||||
// ddRemoteAircraftParts.lightTaxi = newestParts.getLights().isTaxiOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraftParts.lightBeacon = newestParts.getLights().isBeaconOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraftParts.lightNav = newestParts.getLights().isNavOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraftParts.lightLogo = newestParts.getLights().isLogoOn() ? 1.0 : 0.0;
|
||||
ddRemoteAircraftParts.flapsLeadingEdgeLeftPercent = newestParts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraftParts.flapsLeadingEdgeRightPercent = newestParts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraftParts.flapsTrailingEdgeLeftPercent = newestParts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraftParts.flapsTrailingEdgeRightPercent = newestParts.getFlapsPercent() / 100.0;
|
||||
ddRemoteAircraftParts.spoilersHandlePosition = newestParts.isSpoilersOut() ? 1.0 : 0.0;
|
||||
ddRemoteAircraftParts.gearHandlePosition = newestParts.isGearDown() ? 1 : 0;
|
||||
ddRemoteAircraftParts.engine1Combustion = newestParts.isEngineOn(1) ? 1 : 0;
|
||||
ddRemoteAircraftParts.engine2Combustion = newestParts.isEngineOn(2) ? 1 : 0;;
|
||||
ddRemoteAircraftParts.engine3Combustion = newestParts.isEngineOn(3) ? 1 : 0;
|
||||
ddRemoteAircraftParts.engine4Combustion = newestParts.isEngineOn(4) ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//! \todo interpolator, set data without parts by educated guessing whatsoever
|
||||
bool onGround = currentSituation.isOnGroundGuessed();
|
||||
position.OnGround = onGround ? 1 : 0;
|
||||
ddRemoteAircraft.position = position;
|
||||
ddRemoteAircraft.gearHandlePosition = onGround ? 1 : 0;
|
||||
// mode is guessing parts
|
||||
if (this->m_interpolationRequest % 20 != 0) { continue; } // only update every 20th cycle
|
||||
if (!interpolatorStatus.allTrue()) { continue; } // no position, no really guess possible
|
||||
|
||||
ddRemoteAircraftParts.gearHandlePosition = isOnGround ? 1 : 0;
|
||||
|
||||
// when first detected moving, lights on
|
||||
if (onGround && currentSituation.getGroundSpeed().value(CSpeedUnit::km_h()) > 15)
|
||||
if (isOnGround)
|
||||
{
|
||||
// ddRemoteAircraft.light = 1.0;
|
||||
ddRemoteAircraft.lightBeacon = 1.0;
|
||||
ddRemoteAircraft.lightNav = 1.0;
|
||||
ddRemoteAircraft.lightLanding = 0.0;
|
||||
// ddRemoteAircraftParts.lightTaxi = 1.0;
|
||||
ddRemoteAircraftParts.lightBeacon = 1.0;
|
||||
ddRemoteAircraftParts.lightNav = 1.0;
|
||||
|
||||
double gskmh = interpolatedSituation.getGroundSpeed().value(CSpeedUnit::km_h());
|
||||
if (gskmh > 7.5)
|
||||
{
|
||||
// mode taxi
|
||||
// ddRemoteAircraftParts.lightTaxi = 1.0;
|
||||
ddRemoteAircraftParts.lightLanding = 0.0;
|
||||
}
|
||||
else if (gskmh > 25)
|
||||
{
|
||||
// mode accelaration for takeoff
|
||||
// ddRemoteAircraftParts.lightTaxi = 0.0;
|
||||
ddRemoteAircraftParts.lightLanding = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// slow movements or parking
|
||||
// ddRemoteAircraftParts.lightTaxi = 0.0;
|
||||
ddRemoteAircraftParts.lightLanding = 0.0;
|
||||
}
|
||||
}
|
||||
else if (onGround)
|
||||
else
|
||||
{
|
||||
// ddRemoteAircraft.lightTaxi = 0.0;
|
||||
ddRemoteAircraft.lightBeacon = 1.0;
|
||||
ddRemoteAircraft.lightNav = 1.0;
|
||||
ddRemoteAircraft.lightLanding = 0.0;
|
||||
}
|
||||
else if (!onGround)
|
||||
{
|
||||
// ddRemoteAircraft.lightTaxi = 0.0;
|
||||
ddRemoteAircraft.lightBeacon = 1.0;
|
||||
ddRemoteAircraft.lightNav = 1.0;
|
||||
// ddRemoteAircraftParts.lightTaxi = 0.0;
|
||||
ddRemoteAircraftParts.lightBeacon = 1.0;
|
||||
ddRemoteAircraftParts.lightNav = 1.0;
|
||||
// landing lights for < 10000ft (normally MSL, here ignored)
|
||||
ddRemoteAircraftParts.lightLanding = (interpolatedSituation.getAltitude().value(CLengthUnit::ft()) < 10000) ? 1.0 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
hr += SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraft,
|
||||
hr += SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts,
|
||||
simObj.getObjectId(), 0, 0,
|
||||
sizeof(DataDefinitionRemoteAircraft), &ddRemoteAircraft);
|
||||
sizeof(DataDefinitionRemoteAircraftParts), &ddRemoteAircraftParts);
|
||||
if (hr != S_OK) { CLogMessage(this).warning("Failed so set parts on SimObject %1 callsign: %2") << simObj.getObjectId() << callsign; }
|
||||
|
||||
if (hr != S_OK) { CLogMessage(this).warning("Failed so set data on SimObject"); }
|
||||
} // all situations
|
||||
} // all callsigns
|
||||
}
|
||||
|
||||
SIMCONNECT_DATA_INITPOSITION CSimulatorFsx::aircraftSituationToFsxInitPosition(const CAircraftSituation &situation)
|
||||
|
||||
Reference in New Issue
Block a user