use wasm_bindgen::prelude::*;
use serde::{Serialize, Deserialize};
use crate::Matrix4;
#[wasm_bindgen]
#[derive(Copy, Clone, Serialize, Deserialize)]
pub struct Vector3 {
pub x: f64,
pub y: f64,
pub z: f64,
}
#[wasm_bindgen]
impl Vector3 {
#[wasm_bindgen(constructor)]
pub fn new(x: f64, y: f64, z: f64) -> Vector3 {
Vector3 { x, y, z }
}
pub fn add(&mut self, other: &Vector3) -> Vector3 {
self.x = self.x + other.x;
self.y = self.y + other.y;
self.z = self.z + other.z;
*self
}
pub fn add_scalar(&mut self, scalar: f64) -> Vector3 {
self.x += scalar;
self.y += scalar;
self.z += scalar;
*self
}
pub fn subtract(&mut self, other: &Vector3) -> Vector3 {
self.x = self.x - other.x;
self.y = self.y - other.y;
self.z = self.z - other.z;
*self
}
pub fn subtract_scalar(&mut self, scalar: f64) -> Vector3 {
self.x -= scalar;
self.y -= scalar;
self.z -= scalar;
*self
}
pub fn clone(&self) -> Vector3 {
Vector3 {
x: self.x,
y: self.y,
z: self.z,
}
}
pub fn zero(&mut self) {
self.x = 0.0;
self.y = 0.0;
self.z = 0.0;
}
pub fn copy(&mut self, other: &Vector3) {
self.x = other.x;
self.y = other.y;
self.z = other.z;
}
pub fn multiply_scalar(&mut self, scalar: f64) -> Vector3 {
self.x *= scalar;
self.y *= scalar;
self.z *= scalar;
*self
}
pub fn multiply(&mut self, other: &Vector3) -> Vector3 {
self.x *= other.x;
self.y *= other.y;
self.z *= other.z;
*self
}
pub fn divide(&mut self, other: &Vector3) -> Vector3 {
self.x /= other.x;
self.y /= other.y;
self.z /= other.z;
*self
}
pub fn divide_scalar(&mut self, scalar: f64) -> Vector3 {
self.x /= scalar;
self.y /= scalar;
self.z /= scalar;
*self
}
pub fn negate(&mut self) -> Vector3 {
self.x = -self.x;
self.y = -self.y;
self.z = -self.z;
*self
}
pub fn dot(&self, other: &Vector3) -> f64 {
self.x * other.x + self.y * other.y + self.z * other.z
}
pub fn magnitude(&self) -> f64 {
(self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
}
pub fn length(&self) -> f64 {
self.magnitude()
}
pub fn normalize(&mut self) -> Vector3 {
let mag = self.magnitude();
if mag > 0.0 {
self.divide_scalar(mag);
}
*self
}
pub fn cross(&self, other: &Vector3) -> Vector3 {
Vector3 {
x: (self.y * other.z) - (self.z * other.y),
y: (self.z * other.x) - (self.x * other.z),
z: (self.x * other.y) - (self.y * other.x),
}
}
pub fn distance(&self, other: &Vector3) -> f64 {
let dx = self.x - other.x;
let dy = self.y - other.y;
let dz = self.z - other.z;
(dx * dx + dy * dy + dz * dz).sqrt()
}
pub fn apply_matrix4(&mut self, matrix: Matrix4) {
let elements = matrix.flatten();
let x = self.x;
let y = self.y;
let z = self.z;
let new_x = elements[0] * x + elements[4] * y + elements[8] * z + elements[12];
let new_y = elements[1] * x + elements[5] * y + elements[9] * z + elements[13];
let new_z = elements[2] * x + elements[6] * y + elements[10] * z + elements[14];
let w = elements[3] * x + elements[7] * y + elements[11] * z + elements[15];
if w != 1.0 && w != 0.0 {
self.x = new_x / w;
self.y = new_y / w;
self.z = new_z / w;
} else {
self.x = new_x;
self.y = new_y;
self.z = new_z;
}
}
}