#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
pub use ai_bindings;
use std::f32::{INFINITY, NAN};
use std::ops::{Add, Sub, Mul};
#[doc(hidden)]
pub fn clamp(val: f32, min: f32, max: f32) -> f32 {
if val < min {
min
} else if val > max {
max
} else {
val
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct AtVector{
pub x: f32,
pub y: f32,
pub z: f32
}
impl PartialEq for AtVector {
fn eq(&self, other: &AtVector) -> bool {
self.x == other.x
&& self.y == other.y
&& self.z == other.z
}
}
impl Add for AtVector {
type Output = AtVector;
fn add(self, other: AtVector) -> AtVector {
AtVector{
x: self.x + other.x,
y: self.y + other.y,
z: self.z + other.z,
}
}
}
impl<'a, 'b> Sub<&'b AtVector> for &'a AtVector {
type Output = AtVector;
fn sub(self, other: &'b AtVector) -> AtVector {
AtVector {
x: self.x - other.x,
y: self.y - other.y,
z: self.z - other.z,
}
}
}
impl Mul for AtVector {
type Output = AtVector;
fn mul(self, other: AtVector) -> AtVector {
AtVector{
x: self.x * other.x,
y: self.y * other.y,
z: self.z * other.z,
}
}
}
impl<'a> Mul for &'a AtVector {
type Output = AtVector;
fn mul(self, other: &'a AtVector) -> AtVector {
AtVector{
x: self.x * other.x,
y: self.y * other.y,
z: self.z * other.z,
}
}
}
impl<'a> Mul<&'a AtVector> for f32 {
type Output = AtVector;
fn mul(self, other: &'a AtVector) -> AtVector {
AtVector{
x: self * other.x,
y: self * other.y,
z: self * other.z,
}
}
}
impl<'a> Mul<f32> for &'a AtVector {
type Output = AtVector;
fn mul(self, other: f32) -> AtVector {
AtVector{
x: self.x * other,
y: self.y * other,
z: self.z * other,
}
}
}
impl<'a> Mul<&'a mut AtVector> for f32 {
type Output = AtVector;
fn mul(self, other: &'a mut AtVector) -> AtVector {
AtVector{
x: self * other.x,
y: self * other.y,
z: self * other.z,
}
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct AtVector2{
pub x: f32,
pub y: f32,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct AtHPoint {
pub x: f32,
pub y: f32,
pub z: f32,
pub w: f32,
}
pub trait Vector {
fn length(&self) -> f32;
fn dot(&self, b: &Self) -> f32;
fn dist(&self, b: &Self) -> f32;
fn dist_plane(&self, p: &Self, n: &Self) -> f32;
fn cross(&self, b: &Self) -> Self;
fn normalize(&self) -> Self;
fn lerp(&self, t: f32, hi: &Self) -> Self;
fn clamp(&self, lo: f32, hi: f32) -> Self;
fn min(&self, b: &Self) -> Self;
fn max(&self, b: &Self) -> Self;
fn abs(&self) -> Self;
fn max_element(&self) -> f32;
fn min_element(&self) -> f32;
fn berp_xyz(&self, a: f32, b: f32, p1: &Self, p2: &Self) -> Self;
fn is_finite(&self) -> bool;
fn is_small(&self, epsilon: f32) -> bool;
fn rotate_to_frame(&mut self, u: &Self, v: &Self, v: &Self); }
impl Vector for AtVector {
fn length(&self) -> f32 {
(self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
}
fn dot(&self, b: &Self) -> f32 {
self.x * b.x + self.y * b.y + self.z * b.z
}
fn dist(&self, b: &Self) -> f32 {
(b - self).length()
}
fn dist_plane(&self, p: &Self, n: &Self) -> f32 {
self.dot(n) - p.dot(n)
}
fn cross(&self, b: &AtVector) -> Self {
Self {
x: self.y * b.z - self.z * b.y,
y: self.z * b.x - self.x * b.z,
z: self.x * b.y - self.y * b.x
}
}
fn normalize(&self) -> Self {
let mut temp = (self.x * self.x + self.y * self.y + self.z * self.z).sqrt();
if temp != 0.0{
temp = 1.0 / temp;
}
Self {
x: self.x * temp,
y: self.y * temp,
z: self.z * temp
}
}
fn lerp(&self, t: f32, hi: &Self) -> Self{
Self {
x: self.x * t + (hi.x*1.0-t),
y: self.y * t + (hi.y*1.0-t),
z: self.z * t + (hi.z*1.0-t)
}
}
fn clamp(&self, lo: f32, hi: f32) -> Self{
Self {
x: clamp(self.x, lo, hi),
y: clamp(self.y, lo, hi),
z: clamp(self.z, lo, hi),
}
}
fn min(&self, b: &Self) -> Self{
Self {
x: self.x.min(b.x),
y: self.y.min(b.y),
z: self.z.min(b.z),
}
}
fn max(&self, b: &Self) -> Self{
Self {
x: self.x.max(b.x),
y: self.y.max(b.y),
z: self.z.max(b.z),
}
}
fn abs(&self) -> Self {
Self {
x: self.x.abs(),
y: self.y.abs(),
z: self.z.abs(),
}
}
fn max_element(&self) -> f32{
self.x.max(self.y).max(self.z)
}
fn min_element(&self) -> f32{
self.x.min(self.y).min(self.z)
}
fn berp_xyz(&self, a: f32, b: f32, p1: &Self, p2: &Self) -> Self{
let c: f32 = 1.0 - (a + b);
c*self + a*p1 + b*p2
}
fn is_finite(&self) -> bool {
!(self.x.abs() == INFINITY
|| self.x.abs() == NAN
|| self.y.abs() == INFINITY
|| self.y.abs() == NAN
|| self.z.abs() == INFINITY
|| self.z.abs() == NAN)
}
fn is_small(&self, epsilon: f32) -> bool {
self.x.abs() < epsilon && self.y.abs() < epsilon && self.z.abs() < epsilon
}
fn rotate_to_frame(&mut self, u: &Self, v: &Self, w: &Self){
let tmp = u * self.x + v * self.y + w * self.z;
self.x = tmp.x;
self.y = tmp.y;
self.z = tmp.z;
}
}
pub fn AiV3Length<T: Vector>(a: &T) -> f32 {
a.length()
}
pub fn AiV3Dot<T: Vector>(a: &T, b: &T) -> f32 {
a.dot(b)
}
pub fn AiV3Dist<T: Vector + Sub>(a: &AtVector, b: &AtVector) -> f32 {
(b - a).length()
}
pub fn AiV3Dist2<T: Vector + Sub>(a: &AtVector, b: &AtVector) -> f32 {
(b - a).length().powf(2.0)
}
pub fn AiV3DistPlane<T: Vector>(x: &AtVector, p: &AtVector, n: &AtVector) -> f32 {
x.dist_plane(p, n)
}
pub fn AiV3Cross(a: &AtVector, b: &AtVector) -> AtVector {
a.cross(b)
}
pub fn AiV3Normalize(a: &AtVector) -> AtVector {
a.normalize()
}
pub fn AiV3Lerp(t: f32, lo: &AtVector, hi: &AtVector) -> AtVector {
lo.lerp(t, hi)
}
pub fn AiV3Clamp(a: &AtVector, lo: f32, hi: f32) -> AtVector {
a.clamp(lo, hi)
}
pub fn AiV3Min(a: &AtVector, b: &AtVector) -> AtVector {
a.min(b)
}
pub fn AiV3Max(a: &AtVector, b: &AtVector) -> AtVector {
a.max(b)
}
pub fn ABS(a: &AtVector) -> AtVector {
a.abs()
}
pub fn AiMaxElement<T: Vector>(a: &T) -> f32 {
a.max_element()
}
pub fn AiMinElement<T: Vector>(a: &T) -> f32 {
a.min_element()
}
pub fn AiV3IsFinite<T: Vector>(a: &T) -> bool {
a.is_finite()
}
pub fn AiV3IsSmall<T: Vector>(a: &T, epsilon: f32) -> bool {
a.is_small(epsilon)
}
pub fn AiBerpXYZ<T: Vector>(a: f32, b: f32, c0: &T, c1: &T, c2: &T) -> T {
c0.berp_xyz(a, b, c1, c2)
}
pub fn AiV3RotateToFrame<T: Vector>(a: &mut T, u: &T, v: &T, w: &T) {
a.rotate_to_frame(u, v, w);
}
pub fn AiBerpUV(a: f32, b: f32, u0: f32, v0: f32, u1: f32, v1: f32, u2: f32, v2: f32, u: &mut f32, v: &mut f32) {
let c : f32 = 1.0 - (a + b);
*u = c * u0 + a * u1 + b * u2;
*v = c * v0 + a * v1 + b * v2;
}
pub fn AiV4CreatePoint (v: &AtVector) -> AtHPoint {
AtHPoint{
x: v.x,
y: v.y,
z: v.z,
w: 1.0
}
}
pub fn AiV4CreateVector (v: &AtVector) -> AtHPoint {
AtHPoint{
x: v.x,
y: v.y,
z: v.z,
w: 0.0
}
}
pub fn AiV4Add(vout: &mut AtHPoint, v1: &AtHPoint, v2: &AtHPoint){
vout.x = v1.x+v2.x;
vout.y = v1.y+v2.y;
vout.z = v1.z+v2.z;
}
pub fn AiV4Sub(vout: &mut AtHPoint, v1: &AtHPoint, v2: &AtHPoint){
vout.x = v1.x-v2.x;
vout.y = v1.y-v2.y;
vout.z = v1.z-v2.z;
}
pub fn AiV4Scale(vout: &mut AtHPoint, vin: &AtHPoint, k: f32){
vout.x = vin.x*k;
vout.y = vin.y*k;
vout.z = vin.z*k;
vout.w = vin.w*k;
}
pub fn AiV4Neg(vout: &mut AtHPoint, vin: &AtHPoint){
vout.x = -vin.x;
vout.y = -vin.y;
vout.z = -vin.z;
vout.w = -vin.w;
}
pub fn AiV4Project(vout: &mut AtVector, vin: &AtHPoint){
let mut tmp = AI_V3_ZERO;
if vin.w != 0.0 {
tmp = AtVector{x: vin.x / vin.w, y: vin.y / vin.w, z: vin.z / vin.w};
}
vout.x = tmp.x;
vout.y = tmp.y;
vout.z = tmp.z;
}
pub const AI_P3_ZERO :AtVector = AtVector{x: 0.0, y: 0.0, z: 0.0};
pub const AI_V3_ZERO :AtVector = AtVector{x: 0.0, y: 0.0, z: 0.0};
pub const AI_V3_HALF :AtVector = AtVector{x: 0.5, y: 0.5, z: 0.5};
pub const AI_V3_ONE :AtVector = AtVector{x: 1.0, y: 1.0, z: 1.0};
pub const AI_V3_X :AtVector = AtVector{x: 1.0, y: 0.0, z: 0.0};
pub const AI_V3_Y :AtVector = AtVector{x: 0.0, y: 1.0, z: 0.0};
pub const AI_V3_Z :AtVector = AtVector{x: 0.0, y: 0.0, z: 1.0};
pub const AI_V3_NEGX :AtVector = AtVector{x:-1.0, y: 0.0, z: 0.0};
pub const AI_V3_NEGY :AtVector = AtVector{x: 0.0, y: 1.0, z: 0.0};
pub const AI_V3_NEGZ :AtVector = AtVector{x: 0.0, y: 0.0, z: 1.0};
pub const AI_P2_ZERO :AtVector2 = AtVector2{x: 0.0, y: 0.0};
pub const AI_P2_ONE :AtVector2 = AtVector2{x: 1.0, y: 1.0};