Add hit test information

This commit is contained in:
2026-06-03 08:20:37 -07:00
parent 8153055365
commit 3892508856

View File

@@ -139,7 +139,8 @@ struct target_data_structure {
Of this heavy structure, only the following lean mathematical footprint is submitted Of this heavy structure, only the following lean mathematical footprint is submitted
to the graphics shaders via an OpenGL Shader Storage Buffer Object (SSBO) layout(std430): to the graphics shaders via an OpenGL Shader Storage Buffer Object (SSBO) layout(std430):
struct target_data_to_shader_structure {
ssbo_target_information { // This is what is sent to the shaders as SSBO
float target_x; // Pre-converted local Cartesian offset X (meters relative to radar) float target_x; // Pre-converted local Cartesian offset X (meters relative to radar)
float target_y; // Pre-converted local Cartesian offset Y (meters relative to radar) float target_y; // Pre-converted local Cartesian offset Y (meters relative to radar)
float length; // Vessel length bounds (meters) float length; // Vessel length bounds (meters)
@@ -150,8 +151,6 @@ struct target_data_to_shader_structure {
float current_reflectivity; // derivied from vessel_type (see table below) float current_reflectivity; // derivied from vessel_type (see table below)
float height_estimate; // derived from vessel_type (see table below) float height_estimate; // derived from vessel_type (see table below)
float noiseglint; // derived from vessel_type (see table below) float noiseglint; // derived from vessel_type (see table below)
std::string vessel_name;
std::string registration;
int32_t police_boat; // this indicates that the target is for the roaming police boat. 1 = police boat int32_t police_boat; // this indicates that the target is for the roaming police boat. 1 = police boat
uint32_t mmsi; // AIS unique identifier; ICAO hex address for aircraft uint32_t mmsi; // AIS unique identifier; ICAO hex address for aircraft
int type; // target type (0 for boat 1 for aircraft) int type; // target type (0 for boat 1 for aircraft)
@@ -161,6 +160,10 @@ Please note that height and material are not included in the data received from
nor the raspberry pis. This has to be derived. That will be discussed when I talk about the nor the raspberry pis. This has to be derived. That will be discussed when I talk about the
traffic cop later in this document. traffic cop later in this document.
Please note that the ssbo_target_information
data structure does not include the vessel_name nor the registration.
Those do not go to the shaders.
============================================================================= =============================================================================
@@ -1044,6 +1047,8 @@ Thread 1 = Operation of setting up the system; ie; initializeing Opengl,
however, the Traffic Cop will need to assert mutex-target-data in order to write any however, the Traffic Cop will need to assert mutex-target-data in order to write any
target data to this Thread 1. target data to this Thread 1.
Please note that this thread also includes the hit_test as noted below.
Thread 2 = Traffic Cop. The Traffic Cop will accept Target Data from the Simulator (which Thread 2 = Traffic Cop. The Traffic Cop will accept Target Data from the Simulator (which
will be discussed here) ; and the AIS and ADS(b) data from the raspberry pis. At will be discussed here) ; and the AIS and ADS(b) data from the raspberry pis. At
this time, we need to provide only a stub withing the traffic cop to access the Raspberry pis. this time, we need to provide only a stub withing the traffic cop to access the Raspberry pis.
@@ -1097,12 +1102,14 @@ tables are for all living data. The postgress database will be used only once fo
target while the exhibit is running. Database access will become fewer the longer the target while the exhibit is running. Database access will become fewer the longer the
exhibit has been running. exhibit has been running.
Those tables will have the same format (which is sent to the shaders): Those tables will have the same format (which is sent to thread 1): Note that the strings
will not be sent to the shaders by thread 1 as they are handled by the hit_test
struct target_data_to_thread_1_structure {
struct target_data_to_shader_structure {
float target_x; // Pre-converted local Cartesian offset X (meters relative to radar) float target_x; // Pre-converted local Cartesian offset X (meters relative to radar)
float target_y; // Pre-converted local Cartesian offset Y (meters relative to radar) float target_y; // Pre-converted local Cartesian offset Y (meters relative to radar)
std::string vessel_name; // will be null for no available name
std::string registration; // will be null for no registration
float length; // Vessel length bounds (meters) float length; // Vessel length bounds (meters)
float beam; // Vessel beam bounds (meters) float beam; // Vessel beam bounds (meters)
float course; // Course over ground vector (radians relative to True North) float course; // Course over ground vector (radians relative to True North)
@@ -1111,8 +1118,6 @@ struct target_data_to_shader_structure {
float current_reflectivity; // derived from calculation based on material - is dynamic float current_reflectivity; // derived from calculation based on material - is dynamic
float height_estimate; // derived from vessel_type (see table below) float height_estimate; // derived from vessel_type (see table below)
float noiseglint; // derived from vessel_type (see table below) float noiseglint; // derived from vessel_type (see table below)
std::string vessel_name;
std::string registration;
int32_t police_boat; // this indicates that the target is for the roaming police boat. 1 = police boat int32_t police_boat; // this indicates that the target is for the roaming police boat. 1 = police boat
int type; // target type (0 for boat 1 for aircraft) int type; // target type (0 for boat 1 for aircraft)
uint32_t mmsi; // AIS unique identifier; ICAO hex address for aircraft uint32_t mmsi; // AIS unique identifier; ICAO hex address for aircraft
@@ -1126,7 +1131,6 @@ Target Processing suggestion:
(memory-bellingham-bay for marine a-scope, marine traffic control ppi, and marine police boat) (memory-bellingham-bay for marine a-scope, marine traffic control ppi, and marine police boat)
(memory-ventnor for chain home) (memory-ventnor for chain home)
3a: Yes, replace location, course, altitude, timestamp, police_boat into the memory table; 3a: Yes, replace location, course, altitude, timestamp, police_boat into the memory table;
calculate current_reflectivity using the sample code below; leave all other data alone
3b: No, initialize new entry for memory data. Bring over location, course, altitude, 3b: No, initialize new entry for memory data. Bring over location, course, altitude,
timestamp, police_boat; note that if we alredy have 300 entries; determine which timestamp, police_boat; note that if we alredy have 300 entries; determine which
entry is the least used and replace that entry with the new one entry is the least used and replace that entry with the new one
@@ -1145,7 +1149,9 @@ Target Processing suggestion:
3b1c: recalculate the current_reflectivity and insert into table; this is dynamic 3b1c: recalculate the current_reflectivity and insert into table; this is dynamic
4. After all incoming targets processed, wait for next update cycle, 4. After all incoming targets processed, wait for next update cycle,
assert mutex-target-data, and pass the table to cpu thread 1 to pass onto the shaders. assert mutex-target-data, and pass the table to cpu thread 1 to pass onto the shaders. Note
that the vessel_Name and registration are passed to the thread 1 but not passed to the SSBO
shaders.
5. As we are updating, check for the target that is the police boat, if so, check to 5. As we are updating, check for the target that is the police boat, if so, check to
see if the radar in use is for the police boat, then fill in unforms for heading and location see if the radar in use is for the police boat, then fill in unforms for heading and location
@@ -1214,9 +1220,60 @@ dynamicReflectivity = std::max(0.0f, std::min(1.0f, dynamicReflectivity));
// Enter the dynamicReflectivity int the target memory table as current_reflectivity // Enter the dynamicReflectivity int the target memory table as current_reflectivity
note that this is to be calculated for each update. It is dynamic unlike reflectivity note that this is to be calculated for each update. It is dynamic unlike reflectivity
===================================================================
HIT_TEST
Note: This is run as part of Thread 1, the thread that manages the shaders.
The Hit Test Procedure (display target name, registration and other data
in the text status field when the user's target cursor is on or very close
to the target on the scope.
Please note that this operation is not handled by the normal target update SSBO
data discussed in the traffic_cop operation.
The hit-test is entirely CPU-side, driven by cursor state
The cursor range and bearing values are already CPU state variables (they're what get sent as uniforms to the
scope shaders). Each time the visitor moves the cursor, This thread (thread 1) walks the in-memory
target table, computes each
target's polar position, and checks for intersection. No GPU involvement at all.
For PPI scopes (range cursor + bearing cursor)
for each target in memory_table:
target_range = sqrt(target_x² + target_y²)
target_bearing = atan2(target_x, target_y) in degrees
if |target_range - cursor_range| < CURSOR_RANGE_TOLERANCE_M
&& |target_bearing - cursor_bearing| < CURSOR_BEARING_TOLERANCE_DEG:
→ display vessel_name, registration, length, beam, vessel_type in text panel
For A-scopes
- Marine A-scope: antenna bearing is already the selection mechanism — when the antenna bearing falls within the
beamwidth of a target bearing, that target is already producing a pip. At that moment it's also the "selected"
target for text display.
- Chain Home: same idea — when the radiogoniometer bearing is near a target's bearing (within some null-point
window), that target is selected for text display.
What this means for the design
- vessel_name and registration stay in the in-memory table as CPU-only strings — never touched by SSBO or any
shader
- The SSBO layout is unchanged from what it was before your commit (no strings, only numeric fields)
- The text display is triggered by the existing cursor/bearing input callbacks, not by a GPU readback
- One settings.h entry for each tolerance value so you can tune the "snap" feel:
#define CURSOR_RANGE_TOLERANCE_M 200.0f // meters
#define CURSOR_BEARING_TOLERANCE_DEG 1.5f // degrees
#define ASCOPE_BEARING_TOLERANCE_DEG 2.0f // degrees (within beamwidth)
- When no target is under the cursor, the text panel shows the default status info (range, bearing, scope name).
When a hit is detected, it switches to showing vessel name, registration, length × beam, and vessel type
description.
- When more than one target is under the cursor (small boats crammed together) the one closest to the center
of the cursor shall be the one mentioend in the status text window.
=============================================================== ===============================================================