use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct Quaternion {
pub x: f32,
pub y: f32,
pub z: f32,
pub w: f32,
}
#[wasm_bindgen]
impl Quaternion {
#[wasm_bindgen(constructor)]
pub fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
Self { x, y, z, w }
}
pub fn identity() -> Self {
Self {
x: 0.0,
y: 0.0,
z: 0.0,
w: 1.0,
}
}
pub fn multiply(&self, other: &Self) -> Self {
Self {
x: self.w * other.x + self.x * other.w + self.y * other.z - self.z * other.y,
y: self.w * other.y - self.x * other.z + self.y * other.w + self.z * other.x,
z: self.w * other.z + self.x * other.y - self.y * other.x + self.z * other.w,
w: self.w * other.w - self.x * other.x - self.y * other.y - self.z * other.z,
}
}
pub fn dot(&self, other: &Self) -> f32 {
self.x * other.x + self.y * other.y + self.z * other.z + self.w * other.w
}
pub fn similarity(&self, other: &Self) -> f32 {
self.dot(other).abs()
}
pub fn angular_distance(&self, other: &Self) -> f32 {
1.0 - self.similarity(other)
}
pub fn from_axis_angle(axis: Vector3, degrees: f32) -> Self {
if degrees.abs() < 0.0001 {
return Self::identity();
}
let radians = degrees * (std::f32::consts::PI / 180.0);
let half = radians / 2.0;
let sin = half.sin();
let cos = half.cos();
let n = axis.normalize();
Self::new(n.x * sin, n.y * sin, n.z * sin, cos)
}
}
#[wasm_bindgen]
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct Vector3 {
pub x: f32,
pub y: f32,
pub z: f32,
}
#[wasm_bindgen]
impl Vector3 {
#[wasm_bindgen(constructor)]
pub fn new(x: f32, y: f32, z: f32) -> Self {
Self { x, y, z }
}
pub fn normalize(&self) -> Self {
let magnitude = (self.x * self.x + self.y * self.y + self.z * self.z).sqrt();
Self {
x: self.x / magnitude,
y: self.y / magnitude,
z: self.z / magnitude,
}
}
pub fn dot(&self, other: &Self) -> f32 {
self.x * other.x + self.y * other.y + self.z * other.z
}
pub fn add(&self, other: &Self) -> Self {
Self {
x: self.x + other.x,
y: self.y + other.y,
z: self.z + other.z,
}
}
pub fn multiply_by_scalar(&self, scalar: f32) -> Self {
Self {
x: self.x * scalar,
y: self.y * scalar,
z: self.z * scalar,
}
}
}