Skip to content

Commit

Permalink
feat(a380x): TERR on ND for A380X (#92)
Browse files Browse the repository at this point in the history
- introduce TERR ON ND for the A380
- Changes extent of terrain map on a380x: Map also visible behind
aircraft
- Remove clip mask / circular cut-off for a380x
- Fix peaks mode information in ROSE mode (for both a32nx and a380x)

**Testing instructions (A32NX and A380X):**
1. Download release candidate version from
https://www.swisstransfer.com/d/37d8fdf4-89f0-4a3f-9f78-9732b8801543
2. Replace existing SimBridge installation with downloaded version,
start SimBridge
3. Load into airport with known terrain and match
navaids/waypoints/airports on the ND with elevation maps (e.g. the VFR
layer on the Navigraph app)
4. Make sure that display and positions remain accurate in both ROSE and
ARC modes


Example:

![grafik](https://github.com/flybywiresim/simbridge/assets/64070348/a144d382-10bb-4255-9860-4a3ede6a7809)

![grafik](https://github.com/flybywiresim/simbridge/assets/64070348/36426ed1-8287-4a4a-84fd-a1e297b3b05e)

---------

Co-authored-by: Florian Gross <[email protected]>
Co-authored-by: Florian Gross <[email protected]>
  • Loading branch information
3 people authored Sep 30, 2024
1 parent dbddf3e commit 1946a22
Show file tree
Hide file tree
Showing 16 changed files with 9,876 additions and 129 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,4 @@ lerna-debug.log*

# Secrets
/secrets
tools/output/
4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
"editor.formatOnSave": true
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"source.fixAll.eslint": "explicit"
},
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,
Expand Down
29 changes: 23 additions & 6 deletions apps/server/src/terrain/processing/generic/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,31 @@ export const DefaultTileSize = 300;
// navigation display parameters
export const NavigationDisplayMapStartOffsetY = 128;
export const NavigationDisplayMaxPixelWidth = 768;
export const NavigationDisplayArcModePixelHeight = 492;
export const NavigationDisplayRoseModePixelHeight = 250;
export const NavigationDisplayArcModePixelHeightA32NX = 492;
export const NavigationDisplayRoseModePixelHeightA32NX = 250;
export const NavigationDisplayArcModePixelHeightA380X = 592;
export const NavigationDisplayRoseModePixelHeightA380X = 592;
export const NavigationDisplayMaxPixelHeight = Math.max(
NavigationDisplayArcModePixelHeight,
NavigationDisplayRoseModePixelHeight,
NavigationDisplayArcModePixelHeightA32NX,
NavigationDisplayRoseModePixelHeightA32NX,
NavigationDisplayArcModePixelHeightA380X,
NavigationDisplayRoseModePixelHeightA380X,
);
export const NavigationDisplayCenterOffsetYA32NX = 0;
export const NavigationDisplayArcModeCenterOffsetYA380X = 100;
export const NavigationDisplayRoseModeCenterOffsetYA380X = 342;

// vertical display parameters
export const VerticalDisplayMapStartOffsetY = 800;
export const VerticalDisplayMapStartOffsetX = 150;

// rendering parameters
export const RenderingMapTransitionDeltaTime = 40;
export const RenderingMapTransitionDuration = 1000;
export const RenderingMapUpdateTimeout = 1500;
export const RenderingMapTransitionDurationArcMode = 1500;
export const RenderingMapUpdateTimeoutArcMode = 1000;
export const RenderingMapTransitionDurationScanlineMode = 600;
export const RenderingMapUpdateTimeoutScanlineMode = 500;
export const RenderingMapFrameValidityTimeArcMode =
RenderingMapTransitionDurationArcMode + RenderingMapUpdateTimeoutArcMode;
export const RenderingMapFrameValidityTimeScanlineMode =
RenderingMapTransitionDurationScanlineMode + RenderingMapUpdateTimeoutScanlineMode;
6 changes: 4 additions & 2 deletions apps/server/src/terrain/processing/gpu/elevationmap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@ export function createLocalElevationMap(
ndHeight: number,
meterPerPixel: number,
arcMode: boolean,
centerOffsetY: number,
): number {
const centerX = ndWidth / 2.0;
const delta = [this.thread.x - centerX, ndHeight - this.thread.y];
const delta = [this.thread.x - centerX, ndHeight - this.thread.y - centerOffsetY];
if (this.thread.x >= ndWidth || this.thread.y >= ndHeight) return this.constants.invalidElevation;

// calculate distance and bearing for the projection
const distancePixels = Math.sqrt(delta[0] ** 2 + delta[1] ** 2);
if (arcMode === true && distancePixels > ndHeight) return this.constants.invalidElevation;
// Cut off ARC shape when in A32NX and arc mode
if (centerOffsetY === 0 && arcMode === true && distancePixels > ndHeight) return this.constants.invalidElevation;

const distance = distancePixels * (meterPerPixel / 2.0);
const angle = rad2deg(Math.acos(delta[1] / distancePixels));
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/terrain/processing/gpu/patterns/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './arcmode';
export * from './scanlinemode';
9,066 changes: 9,066 additions & 0 deletions apps/server/src/terrain/processing/gpu/patterns/scanlinemode.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export function drawDensityPixel(
if (Math.round(patternValue % patternIndex) === 0) {
return color;
}
return [4, 4, 5, 255];
return [4, 4, 5, 0];
}

export function renderNormalMode(
Expand Down Expand Up @@ -163,7 +163,7 @@ export function renderNormalMode(
return drawDensityPixel(patternMapValue, 5, [255, 148, 255, 255]);
}

return [4, 4, 5, 255];
return [4, 4, 5, 0];
}

export function renderPeaksMode(
Expand Down Expand Up @@ -227,7 +227,7 @@ export function renderPeaksMode(
return drawDensityPixel(patternMapValue, 5, [255, 148, 255, 255]);
}

return [4, 4, 5, 255];
return [4, 4, 5, 0];
}

export function renderNavigationDisplay(
Expand Down Expand Up @@ -311,30 +311,28 @@ export function renderNavigationDisplay(
let patternValue = 0;

// check the corner cases only for pixels inside the real rendering area
if (this.thread.y < this.constants.maxImageHeight) {
if (this.thread.y < height) {
// find highest elevation in 8x8 patch to simulate the lower resolution of the real system
const patchXStart = pixelX - (pixelX % 8);
const patchXEnd = Math.min(width, patchXStart + 8);
const patchYStart = this.thread.y - (this.thread.y % 8);
const patchYEnd = Math.min(height, patchYStart + 8);

for (let y = patchYStart; y < patchYEnd; ++y) {
for (let x = patchXStart; x < patchXEnd; ++x) {
const currentElevation = elevationGrid[y][x];
if (currentElevation > pixelElevation && currentElevation !== this.constants.invalidElevation) {
pixelElevation = currentElevation;
}
if (this.thread.y < height) {
// find highest elevation in 8x8 patch to simulate the lower resolution of the real system
const patchXStart = pixelX - (pixelX % 8);
const patchXEnd = Math.min(width, patchXStart + 8);
const patchYStart = this.thread.y - (this.thread.y % 8);
const patchYEnd = Math.min(height, patchYStart + 8);

for (let y = patchYStart; y < patchYEnd; ++y) {
for (let x = patchXStart; x < patchXEnd; ++x) {
const currentElevation = elevationGrid[y][x];
if (currentElevation > pixelElevation && currentElevation !== this.constants.invalidElevation) {
pixelElevation = currentElevation;
}
}

patternValue = patternMap[this.thread.y][pixelX];
}

// the pixel is disabled at all or the ROSE mode is active and the areas are clipped
if (patternValue === 0 || this.thread.y >= height) {
return [4, 4, 5, 255][colorChannel];
}
patternValue = patternMap[this.thread.y][pixelX];
}

// the pixel is disabled at all or the areas are clipped. Be sure not to overdraw the metadata line though
if (patternValue === 0 && this.thread.y !== height) {
return [4, 4, 5, 0][colorChannel];
}

if (maxElevation >= referenceAltitude - gearDownAltitudeOffset) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function renderVerticalDisplay(
const colorChannel = this.thread.x % 4;

if (pixelX >= this.constants.elevationProfileEntryCount) {
return [4, 4, 5, 255][colorChannel];
return [0, 0, 0, 0][colorChannel];
}

const elevation = elevationProfile[pixelX];
Expand All @@ -23,17 +23,17 @@ export function renderVerticalDisplay(

// altitude is above the elevation -> draw the background
if (altitude > elevation) {
return [4, 4, 5, 255][colorChannel];
return [0, 0, 0, 0][colorChannel];
}

// elevation is water -> check if we draw the water until 0
if (elevation === this.constants.waterElevation) {
if (altitude <= 0) {
return [0, 255, 255, 255][colorChannel];
}
return [4, 4, 5, 255][colorChannel];
return [0, 0, 0, 0][colorChannel];
}

// draw the obstacle
return [59, 21, 0, 255][colorChannel];
return [160, 83, 34, 255][colorChannel];
}
10 changes: 9 additions & 1 deletion apps/server/src/terrain/processing/maphandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ export class MapHandler {
mapOffsetX: 0,
mapWidth: NavigationDisplayMaxPixelWidth,
mapHeight: NavigationDisplayMaxPixelHeight,
centerOffsetY: 0,
};
const startupStatus: AircraftStatus = {
adiruDataValid: true,
Expand Down Expand Up @@ -379,7 +380,7 @@ export class MapHandler {
this.extractLocalElevationMap = this.extractLocalElevationMap.setOutput([config.mapWidth, config.mapHeight]);
}

let metresPerPixel = Math.round((config.range * NauticalMilesToMetres) / config.mapHeight);
let metresPerPixel = Math.round((config.range * NauticalMilesToMetres) / (config.mapHeight - config.centerOffsetY));
if (config.arcMode) metresPerPixel *= 2.0;

// create the local elevation map
Expand All @@ -402,6 +403,7 @@ export class MapHandler {
config.mapHeight,
metresPerPixel,
config.arcMode,
config.centerOffsetY,
) as Texture;

// some GPU drivers require the flush call to release internal memory
Expand All @@ -412,6 +414,12 @@ export class MapHandler {

public createElevationProfile(profile: ElevationProfile, profileWidth: number): Texture {
if (this.cachedElevationData.gpuData === null) return null;
if (profile.waypointsLatitudes === undefined || profile.waypointsLongitudes === undefined) return null;
if (
profile.waypointsLatitudes.length === 0 ||
profile.waypointsLatitudes.length !== profile.waypointsLongitudes.length
)
return null;

if (this.extractElevationProfile.output === null || this.extractElevationProfile.output[0] !== profileWidth) {
this.extractElevationProfile = this.extractElevationProfile.setOutput([profileWidth]);
Expand Down
Loading

0 comments on commit 1946a22

Please sign in to comment.