luaur_vm/functions/
vector_angle.rs1use 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}