1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use xplm_sys::scenery::*;
use std::mem;
use position::{Vec3, Local, LatLon, LatLonAlt, world_to_local, local_to_world};
#[derive(Debug,Clone)]
pub struct ProbeResult {
pub position: Local,
pub normal: Vec3,
pub velocity: Vec3,
pub is_water: bool,
}
#[allow(raw_pointer_derive)]
#[derive(Debug)]
pub struct Probe {
probe: XPLMProbeRef,
}
impl Probe {
pub fn new() -> Probe {
Probe {
probe: unsafe { XPLMCreateProbe(xplm_ProbeY as i32) }
}
}
#[allow(non_upper_case_globals)]
pub fn probe(&self, position: &Local) -> Option<ProbeResult> {
let mut result = XPLMProbeInfo_t::default();
result.structSize = mem::size_of::<XPLMProbeInfo_t>() as i32;
let status = unsafe {
XPLMProbeTerrainXYZ(self.probe, position.x as f32, position.y as f32,
position.z as f32, &mut result)
};
match status as u32 {
xplm_ProbeHitTerrain => Some(convert_result(&result)),
_ => None,
}
}
pub fn probe_altitude(&self, position: &LatLon) -> Option<LatLonAlt> {
let position_lla = LatLonAlt::with_altitude(position, 0.0);
let local = world_to_local(&position_lla);
match self.probe(&local) {
Some(result) => {
let probed_altitude = local_to_world(&result.position).altitude;
Some(LatLonAlt::with_altitude(position, probed_altitude))
},
None => None,
}
}
}
impl Drop for Probe {
fn drop(&mut self) {
unsafe { XPLMDestroyProbe(self.probe) };
}
}
fn convert_result(xplm_result: &XPLMProbeInfo_t) -> ProbeResult {
ProbeResult {
position: Local {
x: xplm_result.locationX as f64,
y: xplm_result.locationY as f64,
z: xplm_result.locationZ as f64,
},
normal: Vec3 {
x: xplm_result.normalX as f64,
y: xplm_result.normalY as f64,
z: xplm_result.normalZ as f64,
},
velocity: Vec3 {
x: xplm_result.velocityX as f64,
y: xplm_result.velocityY as f64,
z: xplm_result.velocityZ as f64,
},
is_water: 1 == xplm_result.is_wet,
}
}