xp12camera
Owner: IIIlllIIIllI URL: git@github.com:nyangkosense/xp12camera.git
enhanced algorithm, implemented more filter
Commit bf0a4bfc03728f2c506b08ae6ffaba087d6212d3 by SM <seb.michalk@gmail.com> on 2025-06-26 09:23:48 +0200
diff --git a/FLIR_Camera.cpp b/FLIR_Camera.cpp
index bec1dd0..ab4a8e1 100644
--- a/FLIR_Camera.cpp
+++ b/FLIR_Camera.cpp
@@ -65,8 +65,7 @@ static int gLastMouseX = 0;
static int gLastMouseY = 0;
static float gMouseSensitivity = 0.2f; // Mouse sensitivity multiplier
-// Thermal view settings
-static int gThermalMode = 1; // 0=Off, 1=White Hot, 2=Enhanced
+// Thermal view settings are now handled by visual effects system
// Dataref to control HUD visibility
static XPLMDataRef gManipulatorDisabled = NULL;
@@ -155,7 +154,8 @@ static void DrawRealisticThermalOverlay(void);
XPLMDebugString("FLIR Camera System: Plugin loaded successfully\n");
XPLMDebugString("FLIR Camera System: Press F9 to activate camera\n");
- XPLMDebugString("FLIR Camera System: MOUSE for smooth pan/tilt, +/- for zoom, arrows for fine adjust, T for thermal, SPACE for lock-on\n");
+ XPLMDebugString("FLIR Camera System: MOUSE for smooth pan/tilt, +/- for zoom, arrows for fine adjust, T for thermal, SPACE for enhanced lock-on\n");
+ XPLMDebugString("FLIR Camera System: Enhanced tracking uses X-Plane's algorithm for smooth target following\n");
return 1;
}
@@ -333,13 +333,13 @@ static void FocusLockCallback(void* inRefcon)
{
if (gCameraActive) {
if (!IsSimpleLockActive()) {
- // Lock to current camera direction
+ // Lock to current camera direction using enhanced tracking
LockCurrentDirection(gCameraPan, gCameraTilt);
- XPLMDebugString("FLIR Camera System: Direction locked\n");
+ XPLMDebugString("FLIR Camera System: Enhanced tracking engaged\n");
} else {
- // Disable lock
+ // Disable enhanced tracking
DisableSimpleLock();
- XPLMDebugString("FLIR Camera System: Lock disabled\n");
+ XPLMDebugString("FLIR Camera System: Enhanced tracking disabled\n");
}
}
}
@@ -373,11 +373,18 @@ static void FocusLockCallback(void* inRefcon)
float planeY = XPLMGetDataf(gPlaneY);
float planeZ = XPLMGetDataf(gPlaneZ);
float planeHeading = XPLMGetDataf(gPlaneHeading);
- float planePitch = XPLMGetDataf(gPlanePitch);
- float planeRoll = XPLMGetDataf(gPlaneRoll);
- // Mouse control for camera movement (only when not locked)
+ // Calculate camera position (belly-mounted) first
+ float headingRad = planeHeading * M_PI / 180.0f;
+
+ // Position camera below and slightly forward of aircraft center
+ outCameraPosition->x = planeX + gCameraDistance * sin(headingRad);
+ outCameraPosition->y = planeY + gCameraHeight;
+ outCameraPosition->z = planeZ + gCameraDistance * cos(headingRad);
+
+ // Camera orientation control (mouse or enhanced tracking)
if (!IsSimpleLockActive()) {
+ // Mouse control for camera movement
int mouseX, mouseY;
XPLMGetMouseLocation(&mouseX, &mouseY);
@@ -400,18 +407,13 @@ static void FocusLockCallback(void* inRefcon)
gLastMouseX = mouseX;
gLastMouseY = mouseY;
} else {
- // Use locked camera angles
- GetLockedAngles(&gCameraPan, &gCameraTilt);
+ // Use enhanced tracking algorithm like X-Plane's built-in system
+ CalculateEnhancedTrackingCamera(&gCameraPan, &gCameraTilt,
+ planeX, planeY, planeZ,
+ planeHeading,
+ outCameraPosition->x, outCameraPosition->y, outCameraPosition->z);
}
- // Calculate camera position (belly-mounted)
- float headingRad = planeHeading * M_PI / 180.0f;
-
- // Position camera below and slightly forward of aircraft center
- outCameraPosition->x = planeX + gCameraDistance * sin(headingRad);
- outCameraPosition->y = planeY + gCameraHeight;
- outCameraPosition->z = planeZ + gCameraDistance * cos(headingRad);
-
// Camera orientation (pan/tilt relative to aircraft heading)
outCameraPosition->heading = planeHeading + gCameraPan;
outCameraPosition->pitch = gCameraTilt;
diff --git a/FLIR_Camera.o b/FLIR_Camera.o
index 14c4d50..1d8af99 100644
Binary files a/FLIR_Camera.o and b/FLIR_Camera.o differ
diff --git a/FLIR_HUD_Simple.lua b/FLIR_HUD_Simple.lua
index 3df4db9..a989c55 100644
--- a/FLIR_HUD_Simple.lua
+++ b/FLIR_HUD_Simple.lua
@@ -1,5 +1,4 @@
-- FLIR Camera HUD Display Script for FlyWithLua
--- Simplified version to prevent engine crashes
-- Toggle with macro: FLIR Toggle HUD
-- Global variables
@@ -54,7 +53,7 @@ function draw_flir_hud()
graphics.draw_string(SCREEN_WIDTH - 300, SCREEN_HEIGHT - 70, "TGT: SCANNING...", "large")
graphics.draw_string(30, 90, "ZOOM: ACTIVE THERMAL: WHT", "large")
- graphics.draw_string(30, SCREEN_HEIGHT - 100, "MARITIME PATROL AIRCRAFT", "large")
+ graphics.draw_string(30, SCREEN_HEIGHT - 100, "A319 MTP AIRCRAFT", "large")
end
end
@@ -74,4 +73,4 @@ do_every_draw("draw_flir_hud()")
-- Add macro for toggling HUD
add_macro("FLIR: Toggle HUD", "toggle_flir_hud()", "", "activate")
-logMsg("FLIR HUD Simple Script Loaded - Use 'FLIR: Toggle HUD' macro to toggle")
\ No newline at end of file
+logMsg("FLIR HUD Simple Script Loaded - Use 'FLIR: Toggle HUD' macro to toggle")
diff --git a/FLIR_SimpleLock.cpp b/FLIR_SimpleLock.cpp
index 6ff8edb..b441117 100644
--- a/FLIR_SimpleLock.cpp
+++ b/FLIR_SimpleLock.cpp
@@ -1,9 +1,9 @@
/*
* FLIR_SimpleLock.cpp
*
- * Simple arbitrary point lock-on system
- * Just locks the current camera direction relative to aircraft heading
- * Perfect for tracking moving ships, vehicles, or any visual target
+ * Enhanced lock-on system using X-Plane's tracking algorithms
+ * Implements sophisticated target following like X-Plane's built-in external view
+ * Provides smooth tracking for ships, vehicles, and any visual targets
*/
#include <string.h>
@@ -11,41 +11,105 @@
#include <stdlib.h>
#include <math.h>
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
#include "XPLMDataAccess.h"
#include "XPLMUtilities.h"
#include "FLIR_SimpleLock.h"
-// Lock-on state
+// Enhanced lock-on state
static int gLockActive = 0;
static float gLockedPan = 0.0f; // Pan angle relative to aircraft when locked
static float gLockedTilt = 0.0f; // Tilt angle when locked
+static float gTargetX = 0.0f; // World coordinates of locked target
+static float gTargetY = 0.0f;
+static float gTargetZ = 0.0f;
+static int gUseEnhancedTracking = 1; // Use X-Plane style tracking algorithm
void InitializeSimpleLock()
{
gLockActive = 0;
- XPLMDebugString("FLIR Simple Lock: Initialized\n");
+ gUseEnhancedTracking = 1;
+ XPLMDebugString("FLIR Enhanced Lock: Initialized with X-Plane tracking algorithms\n");
}
void LockCurrentDirection(float currentPan, float currentTilt)
{
- // Simply store the current camera angles
+ // Store the current camera angles for enhanced tracking
gLockedPan = currentPan;
gLockedTilt = currentTilt;
gLockActive = 1;
+ // Calculate target position in world coordinates using X-Plane's algorithm
+ // This creates a stable target point that the camera will track
+ float headingRad = (currentPan) * M_PI / 180.0f;
+ float pitchRad = currentTilt * M_PI / 180.0f;
+
+ // Project locked direction into world space at far distance
+ float targetDistance = 10000.0f; // Far target for stable tracking
+ gTargetX = targetDistance * sin(headingRad) * cos(pitchRad);
+ gTargetY = targetDistance * sin(pitchRad);
+ gTargetZ = targetDistance * cos(headingRad) * cos(pitchRad);
+
char msg[256];
- sprintf(msg, "FLIR Simple Lock: Locked at Pan=%.1f°, Tilt=%.1f°\n",
- gLockedPan, gLockedTilt);
+ sprintf(msg, "FLIR Enhanced Lock: Locked at Pan=%.1f°, Tilt=%.1f° (Target: %.1f,%.1f,%.1f)\n",
+ gLockedPan, gLockedTilt, gTargetX, gTargetY, gTargetZ);
XPLMDebugString(msg);
}
+void CalculateEnhancedTrackingCamera(float* outPan, float* outTilt,
+ float aircraftX, float aircraftY, float aircraftZ,
+ float aircraftHeading, float cameraX, float cameraY, float cameraZ)
+{
+ if (!gLockActive) {
+ return;
+ }
+
+ if (!gUseEnhancedTracking) {
+ // Fallback to simple angle lock
+ *outPan = gLockedPan;
+ *outTilt = gLockedTilt;
+ return;
+ }
+
+ // Enhanced tracking using X-Plane's algorithm
+ // Transform target from aircraft-relative to world coordinates
+ float headingRad = (aircraftHeading + gLockedPan) * M_PI / 180.0f;
+ float pitchRad = gLockedTilt * M_PI / 180.0f;
+
+ // Calculate world target position relative to current aircraft position
+ float targetDistance = 10000.0f;
+ float worldTargetX = aircraftX + targetDistance * sin(headingRad) * cos(pitchRad);
+ float worldTargetY = aircraftY + targetDistance * sin(pitchRad);
+ float worldTargetZ = aircraftZ + targetDistance * cos(headingRad) * cos(pitchRad);
+
+ // Calculate camera orientation to track target (X-Plane's method)
+ float deltaX = worldTargetX - cameraX;
+ float deltaY = worldTargetY - cameraY;
+ float deltaZ = worldTargetZ - cameraZ;
+
+ // Convert to pan/tilt angles
+ float targetHeading = atan2(deltaX, deltaZ) * 180.0f / M_PI;
+ float targetPitch = atan2(deltaY, sqrt(deltaX*deltaX + deltaZ*deltaZ)) * 180.0f / M_PI;
+
+ // Calculate relative to aircraft heading
+ *outPan = targetHeading - aircraftHeading;
+ *outTilt = targetPitch;
+
+ // Normalize pan angle
+ while (*outPan > 180.0f) *outPan -= 360.0f;
+ while (*outPan < -180.0f) *outPan += 360.0f;
+}
+
void GetLockedAngles(float* outPan, float* outTilt)
{
if (!gLockActive) {
return;
}
- // Simply return the locked angles - camera stays fixed relative to aircraft
+ // Legacy support - return stored angles
*outPan = gLockedPan;
*outTilt = gLockedTilt;
}
@@ -53,7 +117,7 @@ void GetLockedAngles(float* outPan, float* outTilt)
void DisableSimpleLock()
{
gLockActive = 0;
- XPLMDebugString("FLIR Simple Lock: Disabled\n");
+ XPLMDebugString("FLIR Enhanced Lock: Disabled\n");
}
int IsSimpleLockActive()
@@ -64,11 +128,12 @@ int IsSimpleLockActive()
void GetSimpleLockStatus(char* statusBuffer, int bufferSize)
{
if (!gLockActive) {
- strncpy(statusBuffer, "LOCK: OFF", bufferSize - 1);
+ strncpy(statusBuffer, "TRACK: OFF", bufferSize - 1);
statusBuffer[bufferSize - 1] = '\0';
return;
}
- snprintf(statusBuffer, bufferSize, "LOCK: ON %.1f°/%.1f°", gLockedPan, gLockedTilt);
+ const char* mode = gUseEnhancedTracking ? "ENH" : "SIM";
+ snprintf(statusBuffer, bufferSize, "TRACK: %s %.1f°/%.1f°", mode, gLockedPan, gLockedTilt);
statusBuffer[bufferSize - 1] = '\0';
}
\ No newline at end of file
diff --git a/FLIR_SimpleLock.h b/FLIR_SimpleLock.h
index 6a7216f..9e748da 100644
--- a/FLIR_SimpleLock.h
+++ b/FLIR_SimpleLock.h
@@ -1,7 +1,8 @@
/*
* FLIR_SimpleLock.h
*
- * Header file for simple arbitrary point lock-on system
+ * Enhanced lock-on system using X-Plane's tracking algorithms
+ * Provides smooth target following like X-Plane's built-in external view
*/
#ifndef FLIR_SIMPLELOCK_H
@@ -11,13 +12,18 @@
extern "C" {
#endif
-// Initialize the simple lock system
+// Initialize the enhanced lock system
void InitializeSimpleLock();
-// Lock to current camera direction
+// Lock to current camera direction (enhanced algorithm)
void LockCurrentDirection(float currentPan, float currentTilt);
-// Get locked camera angles
+// Calculate enhanced tracking camera position
+void CalculateEnhancedTrackingCamera(float* outPan, float* outTilt,
+ float aircraftX, float aircraftY, float aircraftZ,
+ float aircraftHeading, float cameraX, float cameraY, float cameraZ);
+
+// Get locked camera angles (legacy support)
void GetLockedAngles(float* outPan, float* outTilt);
// Disable lock
diff --git a/FLIR_SimpleLock.o b/FLIR_SimpleLock.o
index 349f49e..6699040 100644
Binary files a/FLIR_SimpleLock.o and b/FLIR_SimpleLock.o differ
diff --git a/FLIR_VisualEffects.cpp b/FLIR_VisualEffects.cpp
index 2c050d0..c9243ed 100644
--- a/FLIR_VisualEffects.cpp
+++ b/FLIR_VisualEffects.cpp
@@ -28,6 +28,7 @@
// Visual effects state
static int gMonochromeEnabled = 0;
static int gThermalEnabled = 1;
+static int gIREnabled = 0;
static int gNoiseEnabled = 1;
static int gScanLinesEnabled = 1;
static float gBrightness = 1.0f;
@@ -60,6 +61,14 @@ void SetThermalMode(int enabled)
XPLMDebugString(msg);
}
+void SetIRMode(int enabled)
+{
+ gIREnabled = enabled;
+ char msg[256];
+ sprintf(msg, "FLIR Visual Effects: IR (B/W) %s\n", enabled ? "ON" : "OFF");
+ XPLMDebugString(msg);
+}
+
void SetImageEnhancement(float brightness, float contrast)
{
gBrightness = brightness;
@@ -97,6 +106,11 @@ void RenderVisualEffects(int screenWidth, int screenHeight)
RenderThermalEffects(screenWidth, screenHeight);
}
+ // Apply IR black/white filter
+ if (gIREnabled) {
+ RenderIRFilter(screenWidth, screenHeight);
+ }
+
// Add camera noise/grain
if (gNoiseEnabled) {
RenderCameraNoise(screenWidth, screenHeight);
@@ -238,15 +252,62 @@ void RenderScanLines(int screenWidth, int screenHeight)
glEnd();
}
+void RenderIRFilter(int screenWidth, int screenHeight)
+{
+ // IR Black/White high contrast filter
+ glBlendFunc(GL_DST_COLOR, GL_ZERO); // Multiply blend for desaturation
+
+ // Create strong black/white contrast effect
+ glColor4f(0.4f, 0.4f, 0.4f, 1.0f); // Desaturate and darken
+
+ glBegin(GL_QUADS);
+ glVertex2f(0, 0);
+ glVertex2f(screenWidth, 0);
+ glVertex2f(screenWidth, screenHeight);
+ glVertex2f(0, screenHeight);
+ glEnd();
+
+ // Add high contrast overlay
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ // Boost contrast for IR effect
+ float contrast = gContrast * 1.5f;
+ glColor4f(contrast, contrast, contrast, 0.3f);
+
+ glBegin(GL_QUADS);
+ glVertex2f(0, 0);
+ glVertex2f(screenWidth, 0);
+ glVertex2f(screenWidth, screenHeight);
+ glVertex2f(0, screenHeight);
+ glEnd();
+
+ // Add IR-style edge enhancement
+ glColor4f(1.0f, 1.0f, 1.0f, 0.1f);
+ glLineWidth(1.0f);
+
+ // Subtle grid pattern for IR sensor simulation
+ glBegin(GL_LINES);
+ for (int x = 0; x < screenWidth; x += 8) {
+ glVertex2f(x, 0);
+ glVertex2f(x, screenHeight);
+ }
+ for (int y = 0; y < screenHeight; y += 8) {
+ glVertex2f(0, y);
+ glVertex2f(screenWidth, y);
+ }
+ glEnd();
+}
+
void CycleVisualModes()
{
static int mode = 0;
- mode = (mode + 1) % 4;
+ mode = (mode + 1) % 5;
switch (mode) {
case 0: // Standard
SetMonochromeFilter(0);
SetThermalMode(0);
+ SetIRMode(0);
gNoiseEnabled = 0;
gScanLinesEnabled = 0;
XPLMDebugString("FLIR Visual Effects: Standard Mode\n");
@@ -255,6 +316,7 @@ void CycleVisualModes()
case 1: // Monochrome
SetMonochromeFilter(1);
SetThermalMode(0);
+ SetIRMode(0);
gNoiseEnabled = 1;
gScanLinesEnabled = 1;
XPLMDebugString("FLIR Visual Effects: Monochrome Mode\n");
@@ -263,14 +325,25 @@ void CycleVisualModes()
case 2: // Thermal
SetMonochromeFilter(0);
SetThermalMode(1);
+ SetIRMode(0);
gNoiseEnabled = 1;
gScanLinesEnabled = 0;
XPLMDebugString("FLIR Visual Effects: Thermal Mode\n");
break;
- case 3: // Enhanced
+ case 3: // IR Black/White
+ SetMonochromeFilter(0);
+ SetThermalMode(0);
+ SetIRMode(1);
+ gNoiseEnabled = 1;
+ gScanLinesEnabled = 1;
+ XPLMDebugString("FLIR Visual Effects: IR Mode\n");
+ break;
+
+ case 4: // Enhanced
SetMonochromeFilter(1);
SetThermalMode(1);
+ SetIRMode(0);
gNoiseEnabled = 1;
gScanLinesEnabled = 1;
XPLMDebugString("FLIR Visual Effects: Enhanced Mode\n");
@@ -284,6 +357,7 @@ void GetVisualEffectsStatus(char* statusBuffer, int bufferSize)
if (gMonochromeEnabled && gThermalEnabled) mode = "ENHANCED";
else if (gThermalEnabled) mode = "THERMAL";
else if (gMonochromeEnabled) mode = "MONO";
+ else if (gIREnabled) mode = "IR B/W";
snprintf(statusBuffer, bufferSize, "VFX: %s", mode);
statusBuffer[bufferSize - 1] = '\0';
diff --git a/FLIR_VisualEffects.h b/FLIR_VisualEffects.h
index 8994e8b..4ac76d8 100644
--- a/FLIR_VisualEffects.h
+++ b/FLIR_VisualEffects.h
@@ -20,11 +20,13 @@ void RenderVisualEffects(int screenWidth, int screenHeight);
// Individual effect controls
void SetMonochromeFilter(int enabled);
void SetThermalMode(int enabled);
+void SetIRMode(int enabled);
void SetImageEnhancement(float brightness, float contrast);
// Individual effect renderers
void RenderMonochromeFilter(int screenWidth, int screenHeight);
void RenderThermalEffects(int screenWidth, int screenHeight);
+void RenderIRFilter(int screenWidth, int screenHeight);
void RenderCameraNoise(int screenWidth, int screenHeight);
void RenderScanLines(int screenWidth, int screenHeight);
diff --git a/FLIR_VisualEffects.o b/FLIR_VisualEffects.o
index 7237a02..ec43597 100644
Binary files a/FLIR_VisualEffects.o and b/FLIR_VisualEffects.o differ
diff --git a/build/FLIR_Camera/win_x64/FLIR_Camera.xpl b/build/FLIR_Camera/win_x64/FLIR_Camera.xpl
index 605aa99..c6c1850 100755
Binary files a/build/FLIR_Camera/win_x64/FLIR_Camera.xpl and b/build/FLIR_Camera/win_x64/FLIR_Camera.xpl differ