Skip to main content

luaur_vm/functions/
vector_angle.rs

1use crate::functions::lua_l_checkvector::lua_l_checkvector;
2use crate::functions::lua_l_optvector::lua_l_optvector;
3use crate::functions::lua_pushnumber::lua_pushnumber;
4use crate::type_aliases::lua_state::lua_State;
5
6#[no_mangle]
7pub unsafe fn vector_angle(l: *mut lua_State) -> i32 {
8    let a = lua_l_checkvector(l, 1);
9    let b = lua_l_optvector(l, 2, core::ptr::null());
10    let axis = lua_l_optvector(l, 3, core::ptr::null());
11
12    let a_val = core::slice::from_raw_parts(a, 3);
13    let b_val = core::slice::from_raw_parts(b, 3);
14
15    let cross = [
16        a_val[1] * b_val[2] - a_val[2] * b_val[1],
17        a_val[2] * b_val[0] - a_val[0] * b_val[2],
18        a_val[0] * b_val[1] - a_val[1] * b_val[0],
19    ];
20
21    let sin_a = ((cross[0] * cross[0] + cross[1] * cross[1] + cross[2] * cross[2]) as f64).sqrt();
22    let cos_a = (a_val[0] * b_val[0] + a_val[1] * b_val[1] + a_val[2] * b_val[2]) as f64;
23    let mut angle = sin_a.atan2(cos_a);
24
25    if !axis.is_null() {
26        let axis_val = core::slice::from_raw_parts(axis, 3);
27        if cross[0] * axis_val[0] + cross[1] * axis_val[1] + cross[2] * axis_val[2] < 0.0 {
28            angle = -angle;
29        }
30    }
31
32    lua_pushnumber(l, angle);
33    1
34}