diff --git a/src/plugins/simulator/fscommon/simulatorfscommon.h b/src/plugins/simulator/fscommon/simulatorfscommon.h index 775acba6f..3602eb66e 100644 --- a/src/plugins/simulator/fscommon/simulatorfscommon.h +++ b/src/plugins/simulator/fscommon/simulatorfscommon.h @@ -20,6 +20,8 @@ #include #include +#include + namespace BlackSimPlugin { namespace FsCommon diff --git a/src/plugins/simulator/fsxcommon/simconnectobject.cpp b/src/plugins/simulator/fsxcommon/simconnectobject.cpp index b8afda935..494fcf40d 100644 --- a/src/plugins/simulator/fsxcommon/simconnectobject.cpp +++ b/src/plugins/simulator/fsxcommon/simconnectobject.cpp @@ -20,7 +20,14 @@ namespace BlackSimPlugin namespace FsxCommon { CSimConnectObject::CSimConnectObject() - { } + { + this->resetCameraPositions(); + } + + CSimConnectObject::CSimConnectObject(CSimConnectObject::SimObjectType type) : m_type(type) + { + this->resetCameraPositions(); + } CSimConnectObject::CSimConnectObject(const CSimulatedAircraft &aircraft, DWORD requestId, @@ -29,32 +36,15 @@ namespace BlackSimPlugin m_aircraft(aircraft), m_requestId(requestId), m_validRequestId(true), m_interpolator(QSharedPointer::create(aircraft.getCallsign(), simEnvProvider, setupProvider, remoteAircraftProvider, logger)) { + this->resetCameraPositions(); m_interpolator->initCorrespondingModel(aircraft.getModel()); + m_callsignByteArray = aircraft.getCallsignAsString().toLatin1(); } - void CSimConnectObject::invalidatePartsAsSent() + void CSimConnectObject::setAircraft(const CSimulatedAircraft &aircraft) { - DataDefinitionRemoteAircraftPartsWithoutLights dd; - dd.resetToInvalid(); - m_partsAsSent = dd; - } - - bool CSimConnectObject::isSameAsSent(const SIMCONNECT_DATA_INITPOSITION &position) const - { - return std::tie(m_positionAsSent.Airspeed, m_positionAsSent.Altitude, m_positionAsSent.Bank, m_positionAsSent.Heading, m_positionAsSent.Latitude, m_positionAsSent.Longitude, m_positionAsSent.Pitch, m_positionAsSent.OnGround) == - std::tie(position.Airspeed, position.Altitude, position.Bank, position.Heading, position.Latitude, position.Longitude, position.Pitch, position.OnGround); - } - - void CSimConnectObject::invalidatePositionAsSent() - { - m_positionAsSent.Airspeed = 0; - m_positionAsSent.Altitude = -1; - m_positionAsSent.Bank = -1; - m_positionAsSent.Heading = -1; - m_positionAsSent.Latitude = -1; - m_positionAsSent.Longitude = -1; - m_positionAsSent.OnGround = 0; - m_positionAsSent.Pitch = -1; + m_aircraft = aircraft; + m_callsignByteArray = aircraft.getCallsignAsString().toLatin1(); } void CSimConnectObject::setObjectId(DWORD id) @@ -86,10 +76,21 @@ namespace BlackSimPlugin m_aircraft.setRendered(false); } + void CSimConnectObject::resetCameraPositions() + { + m_cameraPosition.x = 0; + m_cameraPosition.y = 0; + m_cameraPosition.z = 0; + m_cameraRotation.Pitch = 0; + m_cameraRotation.Bank = 0; + m_cameraRotation.Heading = 0; + } + void CSimConnectObject::resetState() { m_pendingRemoved = false; m_confirmedAdded = false; + m_camera = false; m_currentLightsInSim = CAircraftLights(); m_lightsAsSent = CAircraftLights(); m_requestId = -1; @@ -97,8 +98,7 @@ namespace BlackSimPlugin m_lightsRequestedAt = -1; m_validRequestId = false; m_validObjectId = false; - this->invalidatePartsAsSent(); - this->invalidatePositionAsSent(); + this->resetCameraPositions(); } bool CSimConnectObject::hasValidRequestAndObjectId() const @@ -130,7 +130,7 @@ namespace BlackSimPlugin return m_interpolator->getLastInterpolatedSituation(mode); } - bool CSimConnectObjects::setSimConnectObjectIdForRequestId(DWORD requestId, DWORD objectId, bool resetSentParts) + bool CSimConnectObjects::setSimConnectObjectIdForRequestId(DWORD requestId, DWORD objectId) { // First check, if this request id belongs to us auto it = std::find_if(this->begin(), this->end(), [requestId](const CSimConnectObject & obj) { return obj.getRequestId() == requestId; }); @@ -138,7 +138,6 @@ namespace BlackSimPlugin // belongs to us it->setObjectId(objectId); - if (resetSentParts) { it->invalidatePartsAsSent(); } return true; } diff --git a/src/plugins/simulator/fsxcommon/simconnectobject.h b/src/plugins/simulator/fsxcommon/simconnectobject.h index f04e551fb..f1424ef87 100644 --- a/src/plugins/simulator/fsxcommon/simconnectobject.h +++ b/src/plugins/simulator/fsxcommon/simconnectobject.h @@ -17,6 +17,7 @@ #include "simconnectdatadefinition.h" #include #include +#include namespace BlackSimPlugin { @@ -37,7 +38,7 @@ namespace BlackSimPlugin CSimConnectObject(); //! Constructor - CSimConnectObject(SimObjectType type) : m_type(type) {} + CSimConnectObject(SimObjectType type); //! Constructor providing initial situation/parts CSimConnectObject(const BlackMisc::Simulation::CSimulatedAircraft &aircraft, @@ -65,7 +66,7 @@ namespace BlackSimPlugin void setType(SimObjectType type) { m_type = type; } //! Set the aircraft - void setAircraft(const BlackMisc::Simulation::CSimulatedAircraft &aircraft) { m_aircraft = aircraft; } + void setAircraft(const BlackMisc::Simulation::CSimulatedAircraft &aircraft); //! Get current lights (requested from simulator) const BlackMisc::Aviation::CAircraftLights &getCurrentLightsInSimulator() const { return m_currentLightsInSim; } @@ -79,34 +80,6 @@ namespace BlackSimPlugin //! Pretend to have received lights from simulator void fakeCurrentLightsInSimulator() { m_currentLightsInSim.setNull(false); } - //! Parts as sent to simulator - //! \deprecated KB T273 use BlackCore::CSimulatorCommon isEqual / remember functions - const DataDefinitionRemoteAircraftPartsWithoutLights &getPartsAsSent() const { return m_partsAsSent; } - - //! Parts as sent to simulator - //! \deprecated KB T273 use BlackCore::CSimulatorCommon isEqual / remember functions - void setPartsAsSent(const DataDefinitionRemoteAircraftPartsWithoutLights &parts) { m_partsAsSent = parts; } - - //! Invalidate parts as sent - //! \deprecated KB T273 use BlackCore::CSimulatorCommon isEqual / remember functions - void invalidatePartsAsSent(); - - //! Parts as sent to simulator - //! \deprecated KB T273 use BlackCore::CSimulatorCommon isEqual / remember functions - const SIMCONNECT_DATA_INITPOSITION &getPositionAsSent() const { return m_positionAsSent; } - - //! Position as sent - //! \deprecated KB T273 use BlackCore::CSimulatorCommon isEqual / remember functions - void setPositionAsSent(const SIMCONNECT_DATA_INITPOSITION &position) { m_positionAsSent = position; } - - //! Same as sent - //! \deprecated KB T273 use BlackCore::CSimulatorCommon isEqual / remember functions - bool isSameAsSent(const SIMCONNECT_DATA_INITPOSITION &position) const; - - //! Invalidate position as sent - //! \deprecated KB T273 use BlackCore::CSimulatorCommon isEqual / remember functions - void invalidatePositionAsSent(); - //! Lights as sent to simulator const BlackMisc::Aviation::CAircraftLights &getLightsAsSent() const { return m_lightsAsSent; } @@ -158,6 +131,24 @@ namespace BlackSimPlugin //! Pending added or removed? bool isPending() const { return this->isPendingAdded() || this->isPendingRemoved(); } + //! Has camera? + bool hasCamera() const { return m_camera; } + + //! Reset camera positions + void resetCameraPositions(); + + //! Camera position + const SIMCONNECT_DATA_XYZ &cameraPosition() const { return m_cameraPosition; } + + //! Camera rotation; + const SIMCONNECT_DATA_PBH &cameraRotation() const { return m_cameraRotation; } + + //! Camera GUID + GUID getCameraGUID() const { return m_cameraGuid; } + + //! Set camera GUID + void setCameraGUID(GUID guid) { m_cameraGuid = guid; m_camera = true; } + //! Reset the state (like it was a new onject) without affecting interpolator and aircraft void resetState(); @@ -170,6 +161,9 @@ namespace BlackSimPlugin //! Was the object really added to simulator bool hasValidRequestAndObjectId() const; + //! Callsign as LATIN1 + const QByteArray &getCallsignByteArray() const { return m_callsignByteArray; } + //! \copydoc BlackMisc::Simulation::CInterpolator::getInterpolatorInfo QString getInterpolatorInfo(BlackMisc::Simulation::CInterpolationAndRenderingSetupBase::InterpolatorMode mode) const; @@ -194,9 +188,12 @@ namespace BlackSimPlugin bool m_validObjectId = false; bool m_confirmedAdded = false; bool m_pendingRemoved = false; + bool m_camera = false; int m_lightsRequestedAt = -1; - DataDefinitionRemoteAircraftPartsWithoutLights m_partsAsSent {}; //!< parts as sent - SIMCONNECT_DATA_INITPOSITION m_positionAsSent {}; //!< position as sent + GUID m_cameraGuid; + SIMCONNECT_DATA_XYZ m_cameraPosition; + SIMCONNECT_DATA_PBH m_cameraRotation; + QByteArray m_callsignByteArray; BlackMisc::Aviation::CAircraftLights m_currentLightsInSim { nullptr }; //!< current lights to know state for toggling BlackMisc::Aviation::CAircraftLights m_lightsAsSent { nullptr }; //!< lights as sent to simulator SIMCONNECT_PERIOD m_requestSimDataPeriod = SIMCONNECT_PERIOD_NEVER; //!< how often do we query ground elevation @@ -208,7 +205,7 @@ namespace BlackSimPlugin { public: //! Set ID of a SimConnect object, so far we only have an request id in the object - bool setSimConnectObjectIdForRequestId(DWORD requestId, DWORD objectId, bool resetSentParts = false); + bool setSimConnectObjectIdForRequestId(DWORD requestId, DWORD objectId); //! Find which callsign belongs to the object id BlackMisc::Aviation::CCallsign getCallsignForObjectId(DWORD objectId) const; diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp index 6f6b1cbd4..5d49aaba6 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp +++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp @@ -93,7 +93,9 @@ namespace BlackSimPlugin // set structures and move on this->initEvents(); + this->initEventsP3D(); this->initDataDefinitionsWhenConnected(); + m_timerId = this->startTimer(DispatchIntervalMs); // do not start m_addPendingAircraftTimer here, it will be started when object was added return true; @@ -275,7 +277,7 @@ namespace BlackSimPlugin if (m_simConnectProbes.isEmpty()) { return this->physicallyAddAITerrainProbe(pos); } if (m_simConnectProbes.countConfirmedAdded() < 1) { return false; } // pending probes - CSimConnectObject simObject = m_simConnectProbes.values().front(); + const CSimConnectObject simObject = m_simConnectProbes.values().front(); SIMCONNECT_DATA_INITPOSITION position = this->coordinateToFsxPosition(pos); const HRESULT hr = SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSetPosition, @@ -873,12 +875,12 @@ namespace BlackSimPlugin bool CSimulatorFsxCommon::setSimConnectObjectId(DWORD requestId, DWORD objectId) { - return m_simConnectObjects.setSimConnectObjectIdForRequestId(requestId, objectId, true); + return m_simConnectObjects.setSimConnectObjectIdForRequestId(requestId, objectId); } bool CSimulatorFsxCommon::setSimConnectProbeId(DWORD requestId, DWORD objectId) { - return m_simConnectProbes.setSimConnectObjectIdForRequestId(requestId, objectId, true); + return m_simConnectProbes.setSimConnectObjectIdForRequestId(requestId, objectId); } bool CSimulatorFsxCommon::setCurrentLights(const CCallsign &callsign, const CAircraftLights &lights) @@ -1386,7 +1388,6 @@ namespace BlackSimPlugin if (!this->isEqualLastSent(result)) { SIMCONNECT_DATA_INITPOSITION position = this->aircraftSituationToFsxPosition(result, sendGround); - m_simConnectObjects[callsign].setPositionAsSent(position); const HRESULT hr = SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraftSetPosition, static_cast(objectId), 0, 0, sizeof(SIMCONNECT_DATA_INITPOSITION), &position); @@ -1478,10 +1479,6 @@ namespace BlackSimPlugin if (hr == S_OK && m_simConnectObjects.contains(simObject.getCallsign())) { if (this->isTracingSendId()) { this->traceSendId(simObject.getObjectId(), Q_FUNC_INFO);} - - // Update data - CSimConnectObject &objUdpate = m_simConnectObjects[simObject.getCallsign()]; - objUdpate.setPartsAsSent(ddRemoteAircraftPartsWithoutLights); } else { diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h index 418a7be91..cf6617b37 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h +++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h @@ -79,7 +79,8 @@ namespace BlackSimPlugin EventToggleNavLights, EventToggleRecognitionLights, EventToggleTaxiLights, - EventToggleWingLights + EventToggleWingLights, + EventFSXEndMarker }; //! Struct to trace send ids @@ -167,6 +168,9 @@ namespace BlackSimPlugin //! \sa CSimulatorFsxCommon::dispatch virtual void timerEvent(QTimerEvent *event) override; + //! Specific P3D events + virtual HRESULT initEventsP3D() { return S_OK; } + //! \addtogroup swiftdotcommands //! @{ //!
@@ -202,6 +206,8 @@ namespace BlackSimPlugin
             static constexpr qint64 AutoTraceOffsetMs = 10 * 1000;              //!< how long do we trace?
             HANDLE m_hSimConnect = nullptr;                                     //!< handle to SimConnect object
             DispatchProc m_dispatchProc = &CSimulatorFsxCommon::SimConnectProc; //!< called function for dispatch, can be overriden by specialized P3D function
+            CSimConnectObjects m_simConnectObjects; //!< AI objects and their object / request ids
+            CSimConnectObjects m_simConnectProbes;  //!< AI terrain probes and their object / request ids
             QMap m_pendingProbeRequests; //!< pending elevation requests
 
         private:
@@ -441,11 +447,9 @@ namespace BlackSimPlugin
             int m_requestSimObjectDataCount  = 0; //!< requested SimObjects
 
             // objects
-            CSimConnectObjects m_simConnectObjects; //!< AI objects and their object / request ids
-            CSimConnectObjects m_simConnectProbes;  //!< AI terrain probes and their object / request ids
             CSimConnectObjects m_simConnectObjectsPositionAndPartsTraces; //!< position/parts received, but object not yet added, excluded, disabled etc.
-            SIMCONNECT_DATA_REQUEST_ID m_requestIdSimData = static_cast(RequestIdSimDataStart);    //!< request id, use obtainRequestIdForSimData() to get id
-            SIMCONNECT_DATA_REQUEST_ID m_requestIdProbe = static_cast(RequestIdTerrainProbeStart); //!< request id, use obtainRequestIdForProbe() to get id
+            SIMCONNECT_DATA_REQUEST_ID m_requestIdSimData = static_cast(RequestIdSimDataStart);      //!< request id, use obtainRequestIdForSimData() to get id
+            SIMCONNECT_DATA_REQUEST_ID m_requestIdProbe   = static_cast(RequestIdTerrainProbeStart); //!< request id, use obtainRequestIdForProbe() to get id
             BlackMisc::Simulation::CSimulatedAircraftList m_addPendingAircraft; //!< aircraft awaiting to be added
             QTimer m_addPendingSimObjTimer; //!< updating of SimObjects awaiting to be added
         };
@@ -489,7 +493,7 @@ namespace BlackSimPlugin
             //! \sa CSimConnectObjects::SimConnectProc
             static void CALLBACK SimConnectProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContext);
         };
-    }
+    } // namespace
 } // namespace
 
 #endif // guard
diff --git a/src/plugins/simulator/p3d/simulatorp3d.cpp b/src/plugins/simulator/p3d/simulatorp3d.cpp
index f61be620f..252b3f56f 100644
--- a/src/plugins/simulator/p3d/simulatorp3d.cpp
+++ b/src/plugins/simulator/p3d/simulatorp3d.cpp
@@ -20,6 +20,7 @@ using namespace BlackMisc::Geo;
 using namespace BlackMisc::Network;
 using namespace BlackMisc::Simulation;
 using namespace BlackMisc::Simulation::FsCommon;
+using namespace BlackSimPlugin::FsxCommon;
 using namespace BlackMisc::Weather;
 using namespace BlackCore;
 
@@ -52,6 +53,12 @@ namespace BlackSimPlugin
 
             switch (pData->dwID)
             {
+            // case SIMCONNECT_RECV_ID_CAMERA_6DOF: break;
+            // case SIMCONNECT_RECV_ID_CAMERA_FOV: break;
+            // case SIMCONNECT_RECV_ID_CAMERA_SENSOR_MODE: break;
+            // case SIMCONNECT_RECV_ID_CAMERA_WINDOW_POSITION: break;
+            // case SIMCONNECT_RECV_ID_CAMERA_WINDOW_SIZE: break;
+
             case SIMCONNECT_RECV_ID_GROUND_INFO:
                 {
                     // https://www.prepar3d.com/SDKv4/sdk/simconnect_api/references/structures_and_enumerations.html#SIMCONNECT_RECV_GROUND_INFO
@@ -117,6 +124,65 @@ namespace BlackSimPlugin
 
             return ok;
         }
+
+        bool CSimulatorP3D::followAircraft(const CCallsign &callsign)
+        {
+            if (this->isShuttingDownOrDisconnected()) { return false; }
+            if (!CBuildConfig::isLocalDeveloperDebugBuild()) { return false; }
+
+            // Experimental code, suffering from bugs and also requiring
+            // P3D v4.2 (bugs in V4.1
+            CSimConnectObject &simObject = m_simConnectObjects[callsign];
+
+            const CAircraftModel model = simObject.getAircraft().getModel();
+            const QString viewName = "Commercial Jet-" + callsign.asString();
+            const char *view = viewName.toLatin1().constData();
+            CLogMessage(this).warning("Modelview %1") << viewName;
+            Q_UNUSED(model);
+
+            HRESULT hr = SimConnect_ChangeView(m_hSimConnect, view);
+            return hr == S_OK;
+
+            /**
+            if (!simObject.hasValidRequestAndObjectId()) { return false; }
+            if (simObject.getCallsignByteArray().isEmpty()) { return false; }
+            const char *cs = simObject.getCallsignByteArray().constData();
+
+            HRESULT hr = S_FALSE;
+            if (!simObject.hasCamera())
+            {
+                GUID guid;
+                CoCreateGuid(&guid);
+                const SIMCONNECT_CAMERA_TYPE cameraType = SIMCONNECT_CAMERA_TYPE_OBJECT_CENTER;
+                hr = SimConnect_CreateCameraDefinition(m_hSimConnect, guid, cameraType, cs, simObject.cameraPosition(), simObject.cameraRotation());
+                if (hr == S_OK)
+                {
+                    const SIMCONNECT_OBJECT_ID objectId = static_cast(simObject.getObjectId());
+                    const SIMCONNECT_DATA_REQUEST_ID requestId = this->obtainRequestIdForSimData();
+                    hr = SimConnect_CreateCameraInstance(m_hSimConnect, guid, cs, objectId, requestId);
+                    if (hr == S_OK)
+                    {
+                        simObject.setCameraGUID(guid);
+                    }
+                }
+            }
+
+            if (!simObject.hasCamera()) { return false; }
+            hr = SimConnect_OpenView(m_hSimConnect, cs);
+            return hr == S_OK;
+            **/
+        }
+
+        HRESULT CSimulatorP3D::initEventsP3D()
+        {
+            HRESULT hr = S_OK;
+            if (hr != S_OK)
+            {
+                CLogMessage(this).error("P3D plugin error: %1") << "initEventsP3D failed";
+                return hr;
+            }
+            return hr;
+        }
 #else
         void CSimulatorP3D::SimConnectProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContext)
         {
diff --git a/src/plugins/simulator/p3d/simulatorp3d.h b/src/plugins/simulator/p3d/simulatorp3d.h
index c4f1d1dab..65052104d 100644
--- a/src/plugins/simulator/p3d/simulatorp3d.h
+++ b/src/plugins/simulator/p3d/simulatorp3d.h
@@ -18,6 +18,12 @@ namespace BlackSimPlugin
 {
     namespace P3D
     {
+        //! P3D specific events
+        enum EventsIdsP3D
+        {
+            EventP3dFoo = FsxCommon::EventFSXEndMarker + 1
+        };
+
         //! P3D Simulator Implementation
         class CSimulatorP3D : public FsxCommon::CSimulatorFsxCommon
         {
@@ -38,7 +44,13 @@ namespace BlackSimPlugin
             //! \copydoc BlackMisc::Simulation::ISimulationEnvironmentProvider::requestElevation
             virtual bool requestElevation(const BlackMisc::Geo::ICoordinateGeodetic &reference, const BlackMisc::Aviation::CCallsign &callsign) override;
 
+            //! \copydoc ISimulator::followAircraft
+            virtual bool followAircraft(const BlackMisc::Aviation::CCallsign &callsign) override;
+
         protected:
+            //! \copydoc FsxCommon::CSimulatorFsxCommon::initEventsP3D
+            virtual HRESULT initEventsP3D() override;
+
             //! SimConnect Callback
             static void CALLBACK SimConnectProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContext);
         };