rocketsim 0.2.0

Simulate Rocket League games at maximum efficiency
Documentation
use std::f32::consts::FRAC_1_SQRT_2;

use glam::{Vec3A, Vec4};

#[inline]
pub fn interpolate_3(v0: Vec3A, v1: Vec3A, rt: f32) -> Vec3A {
    let s = 1.0 - rt;
    s * v0 + rt * v1
}

pub fn plane_space_1(n: Vec3A) -> Vec3A {
    if n.z.abs() > FRAC_1_SQRT_2 {
        let a = n.y * n.y + n.z * n.z;
        let k = a.sqrt().recip();
        Vec3A::new(0., -n.z * k, n.y * k)
    } else {
        let a = n.x * n.x + n.y * n.y;
        let k = a.sqrt().recip();
        Vec3A::new(-n.y * k, n.x * k, 0.)
    }
}

pub fn max_dot(simd_points: &[[Vec4; 3]], points: &[Vec3A], direction: Vec3A) -> Vec3A {
    let mut max_dot = f32::NEG_INFINITY;
    let mut support_vertex = Vec3A::ZERO;

    let dir_x = Vec4::splat(direction.x);
    let dir_y = Vec4::splat(direction.y);
    let dir_z = Vec4::splat(direction.z);

    for (i, pts) in simd_points.iter().enumerate() {
        let dots = pts[0] * dir_x + pts[1] * dir_y + pts[2] * dir_z;

        let this_max_dot = dots.max_element();
        if this_max_dot > max_dot {
            max_dot = this_max_dot;
            support_vertex = points[i * 4 + dots.max_position()];
        }
    }

    for &point in &points[simd_points.len() * 4..] {
        let dot = direction.dot(point);
        if dot > max_dot {
            support_vertex = point;
            max_dot = dot;
        }
    }

    support_vertex
}