viam_rust_utils/ffi/spatialmath/
vector3.rs

1use ffi_helpers::null_pointer_check;
2use libc::c_double;
3
4use nalgebra::Vector3;
5
6/// The FFI interface wrapping the nalgebra crate for Vector functions and
7/// initialization. All public functions are meant to be called externally
8/// from other languages
9
10/// Allocates the vector to the heap with a stable memory address and
11/// returns the raw pointer (for use by the FFI interface)
12pub(crate) fn to_raw_pointer(vec: Vector3<f64>) -> *mut Vector3<f64> {
13    Box::into_raw(Box::new(vec))
14}
15
16/// Initialize a 3-vector from raw components and retrieve the C pointer
17/// to its address.
18///
19/// # Safety
20///
21/// When finished with the underlying vector initialized by this function
22/// the caller must remember to free the vector memory using the
23/// free_vector_memory FFI function
24#[no_mangle]
25pub extern "C" fn viam_new_vector3(x: f64, y: f64, z: f64) -> *mut Vector3<f64> {
26    let new_vec = Vector3::new(x, y, z);
27    to_raw_pointer(new_vec)
28}
29
30#[no_mangle]
31#[deprecated]
32pub unsafe extern "C" fn new_vector3(x: f64, y: f64, z: f64) -> *mut Vector3<f64> {
33    viam_new_vector3(x, y, z)
34}
35
36/// Free memory at the address of the vector pointer.
37///
38/// # Safety
39/// Outer processes that work with Vectors via the FFI interface MUST remember
40/// to call this function when finished with a vector
41#[no_mangle]
42pub unsafe extern "C" fn viam_free_vector_memory(ptr: *mut Vector3<f64>) {
43    if ptr.is_null() {
44        return;
45    }
46    let _ = Box::from_raw(ptr);
47}
48
49#[no_mangle]
50#[deprecated]
51pub unsafe extern "C" fn free_vector_memory(ptr: *mut Vector3<f64>) {
52    viam_free_vector_memory(ptr)
53}
54
55/// Get the components of a vector as a list of C doubles, the order of the
56/// components will be (x, y, z).
57///
58/// # Safety
59///
60/// When finished with the underlying vector, the caller must remember to
61/// free the vector memory using the free_vector_memory FFI function
62#[no_mangle]
63pub unsafe extern "C" fn viam_vector_get_components(
64    vec_ptr: *const Vector3<f64>,
65) -> *const c_double {
66    null_pointer_check!(vec_ptr);
67    let components: [c_double; 3] = [(&(*vec_ptr))[0], (&(*vec_ptr))[1], (&(*vec_ptr))[2]];
68    Box::into_raw(Box::new(components)) as *const _
69}
70
71#[no_mangle]
72#[deprecated]
73pub unsafe extern "C" fn vector_get_components(vec_ptr: *const Vector3<f64>) -> *const c_double {
74    viam_vector_get_components(vec_ptr)
75}
76
77/// Set the x component of an existing vector stored at the address
78/// of a pointer.
79///
80/// # Safety
81///
82/// When finished with the underlying vector, the caller must remember to
83/// free the vector memory using the free_vector_memory FFI function
84#[no_mangle]
85pub unsafe extern "C" fn viam_vector_set_x(vec_ptr: *mut Vector3<f64>, x_val: f64) {
86    null_pointer_check!(vec_ptr);
87    (&mut (*vec_ptr))[0] = x_val;
88}
89
90#[no_mangle]
91#[deprecated]
92pub unsafe extern "C" fn vector_set_x(vec_ptr: *mut Vector3<f64>, x_val: f64) {
93    viam_vector_set_x(vec_ptr, x_val)
94}
95
96/// Set the y component of an existing vector stored at the address
97/// of a pointer.
98///
99/// # Safety
100///
101/// When finished with the underlying vector, the caller must remember to
102/// free the vector memory using the free_vector_memory FFI function
103#[no_mangle]
104pub unsafe extern "C" fn viam_vector_set_y(vec_ptr: *mut Vector3<f64>, y_val: f64) {
105    null_pointer_check!(vec_ptr);
106    (&mut (*vec_ptr))[1] = y_val;
107}
108
109#[no_mangle]
110#[deprecated]
111pub unsafe extern "C" fn vector_set_y(vec_ptr: *mut Vector3<f64>, y_val: f64) {
112    viam_vector_set_y(vec_ptr, y_val)
113}
114
115/// Set the z component of an existing vector stored at the address
116/// of a pointer.
117///
118/// # Safety
119///
120/// When finished with the underlying vector, the caller must remember to
121/// free the vector memory using the free_vector_memory FFI function
122#[no_mangle]
123pub unsafe extern "C" fn viam_vector_set_z(vec_ptr: *mut Vector3<f64>, z_val: f64) {
124    null_pointer_check!(vec_ptr);
125    (&mut (*vec_ptr))[2] = z_val;
126}
127
128#[no_mangle]
129#[deprecated]
130pub unsafe extern "C" fn vector_set_z(vec_ptr: *mut Vector3<f64>, z_val: f64) {
131    viam_vector_set_z(vec_ptr, z_val)
132}
133
134/// Normalizes an existing vector stored at the address of
135/// a pointer (vec_ptr)
136///
137/// # Safety
138///
139/// When finished with the underlying vector, the caller must remember to
140/// free the vector memory using the free_vector_memory FFI function
141#[no_mangle]
142pub unsafe extern "C" fn viam_normalize_vector(vec_ptr: *mut Vector3<f64>) {
143    null_pointer_check!(vec_ptr);
144    (*vec_ptr).normalize_mut();
145}
146
147#[no_mangle]
148#[deprecated]
149pub unsafe extern "C" fn normalize_vector(vec_ptr: *mut Vector3<f64>) {
150    viam_normalize_vector(vec_ptr)
151}
152
153/// Initializes a normalized copy of a vector stored at the
154/// address of a pointer (vec_ptr) and returns a pointer to the
155/// memory of the result
156///
157/// # Safety
158///
159/// The caller must remember to free the vector memory of *both* the input and
160/// output vectors when finished with them using the free_vector_memory FFI function
161#[no_mangle]
162pub unsafe extern "C" fn viam_vector_get_normalized(
163    vec_ptr: *const Vector3<f64>,
164) -> *mut Vector3<f64> {
165    null_pointer_check!(vec_ptr);
166    let vec = (*vec_ptr).normalize();
167    to_raw_pointer(vec)
168}
169
170#[no_mangle]
171#[deprecated]
172pub unsafe extern "C" fn vector_get_normalized(vec_ptr: *const Vector3<f64>) -> *mut Vector3<f64> {
173    viam_vector_get_normalized(vec_ptr)
174}
175
176/// Scales an existing vector stored at the address of
177/// a pointer (vec_ptr) by a float factor
178///
179/// # Safety
180///
181/// When finished with the underlying vector, the caller must remember to
182/// free the vector memory using the free_vector_memory FFI function
183#[no_mangle]
184pub unsafe extern "C" fn viam_scale_vector(vec_ptr: *mut Vector3<f64>, factor: f64) {
185    null_pointer_check!(vec_ptr);
186    (*vec_ptr).scale_mut(factor);
187}
188
189#[no_mangle]
190#[deprecated]
191pub unsafe extern "C" fn scale_vector(vec_ptr: *mut Vector3<f64>, factor: f64) {
192    viam_scale_vector(vec_ptr, factor)
193}
194
195/// Initializes a scaled copy of a vector stored at the
196/// address of a pointer (vec_ptr) and returns a pointer to the
197/// memory of the result
198///
199/// # Safety
200///
201/// The caller must remember to free the vector memory of *both* the input and
202/// output vectors when finished with them using the free_vector_memory FFI function
203#[no_mangle]
204pub unsafe extern "C" fn viam_vector_get_scaled(
205    vec_ptr: *const Vector3<f64>,
206    factor: f64,
207) -> *mut Vector3<f64> {
208    null_pointer_check!(vec_ptr);
209    let vec = (*vec_ptr).scale(factor);
210    to_raw_pointer(vec)
211}
212
213#[no_mangle]
214#[deprecated]
215pub unsafe extern "C" fn vector_get_scaled(
216    vec_ptr: *const Vector3<f64>,
217    factor: f64,
218) -> *mut Vector3<f64> {
219    viam_vector_get_scaled(vec_ptr, factor)
220}
221
222/// Adds two vectors and returns a pointer to the
223/// memory of the result
224///
225/// # Safety
226///
227/// The caller must remember to free the vector memory of *both* the input and
228/// output vectors when finished with them using the free_vector_memory FFI function
229#[no_mangle]
230pub unsafe extern "C" fn viam_vector_add(
231    vec_ptr_1: *const Vector3<f64>,
232    vec_ptr_2: *const Vector3<f64>,
233) -> *mut Vector3<f64> {
234    null_pointer_check!(vec_ptr_1);
235    null_pointer_check!(vec_ptr_2);
236    to_raw_pointer((*vec_ptr_1) + (*vec_ptr_2))
237}
238
239#[no_mangle]
240#[deprecated]
241pub unsafe extern "C" fn vector_add(
242    vec_ptr_1: *const Vector3<f64>,
243    vec_ptr_2: *const Vector3<f64>,
244) -> *mut Vector3<f64> {
245    viam_vector_add(vec_ptr_1, vec_ptr_2)
246}
247
248/// Subtracts two vectors and returns a pointer to the
249/// memory of the result
250///
251/// # Safety
252///
253/// The caller must remember to free the vector memory of *both* the input and
254/// output vectors when finished with them using the free_vector_memory FFI function
255#[no_mangle]
256pub unsafe extern "C" fn viam_vector_subtract(
257    vec_ptr_1: *const Vector3<f64>,
258    vec_ptr_2: *const Vector3<f64>,
259) -> *mut Vector3<f64> {
260    null_pointer_check!(vec_ptr_1);
261    null_pointer_check!(vec_ptr_2);
262    to_raw_pointer((*vec_ptr_1) - (*vec_ptr_2))
263}
264
265#[no_mangle]
266#[deprecated]
267pub unsafe extern "C" fn vector_subtract(
268    vec_ptr_1: *const Vector3<f64>,
269    vec_ptr_2: *const Vector3<f64>,
270) -> *mut Vector3<f64> {
271    viam_vector_subtract(vec_ptr_1, vec_ptr_2)
272}
273
274/// Computes the dot product of two vectors
275///
276/// # Safety
277///
278/// The caller must remember to free the vector memory of the input vectors
279/// when finished with them using the free_vector_memory FFI function
280#[no_mangle]
281pub unsafe extern "C" fn viam_vector_dot_product(
282    vec_ptr_1: *const Vector3<f64>,
283    vec_ptr_2: *const Vector3<f64>,
284) -> f64 {
285    null_pointer_check!(vec_ptr_1, f64::NAN);
286    null_pointer_check!(vec_ptr_2, f64::NAN);
287    (*vec_ptr_1).dot(&*vec_ptr_2)
288}
289
290#[no_mangle]
291#[deprecated]
292pub unsafe extern "C" fn vector_dot_product(
293    vec_ptr_1: *const Vector3<f64>,
294    vec_ptr_2: *const Vector3<f64>,
295) -> f64 {
296    viam_vector_dot_product(vec_ptr_1, vec_ptr_2)
297}
298
299/// Computes the cross product of two vectors and returns
300/// a pointer to the memory of the result
301///
302/// # Safety
303///
304/// The caller must remember to free the vector memory of *both* the input and
305/// output vectors when finished with them using the free_vector_memory FFI function
306#[no_mangle]
307pub unsafe extern "C" fn viam_vector_cross_product(
308    vec_ptr_1: *mut Vector3<f64>,
309    vec_ptr_2: *mut Vector3<f64>,
310) -> *mut Vector3<f64> {
311    null_pointer_check!(vec_ptr_1);
312    null_pointer_check!(vec_ptr_2);
313    let vec = (*vec_ptr_1).cross(&*vec_ptr_2);
314    to_raw_pointer(vec)
315}
316
317#[no_mangle]
318#[deprecated]
319pub unsafe extern "C" fn vector_cross_product(
320    vec_ptr_1: *mut Vector3<f64>,
321    vec_ptr_2: *mut Vector3<f64>,
322) -> *mut Vector3<f64> {
323    viam_vector_cross_product(vec_ptr_1, vec_ptr_2)
324}
325
326/// Free memory of an array of vector components at the given address.
327///
328/// # Safety
329///
330/// Outer processes that request the components of a vector should call this function
331/// to free the memory allocated to the array once finished
332#[no_mangle]
333pub unsafe extern "C" fn viam_free_vector_components(ptr: *mut c_double) {
334    if ptr.is_null() {
335        return;
336    }
337    let ptr = ptr as *mut [c_double; 3];
338    let _: Box<[c_double; 3]> = Box::from_raw(ptr);
339}
340
341#[no_mangle]
342#[deprecated]
343pub unsafe extern "C" fn free_vector_components(ptr: *mut c_double) {
344    viam_free_vector_components(ptr)
345}