use serde::{Deserialize, Serialize};
use crate::error::ShapeError;
pub use glam::DVec3 as Vec3;
pub use glam::DQuat as Quat;
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Scope {
pub position: Vec3,
pub rotation: Quat,
pub size: Vec3,
}
impl Scope {
pub fn unit() -> Self {
Self {
position: Vec3::ZERO,
rotation: Quat::IDENTITY,
size: Vec3::ONE,
}
}
pub fn new(position: Vec3, rotation: Quat, size: Vec3) -> Self {
Self {
position,
rotation,
size,
}
}
pub fn validate(&self) -> Result<(), ShapeError> {
if !self.position.is_finite() || !self.rotation.is_finite() || !self.size.is_finite() {
return Err(ShapeError::InvalidNumericValue);
}
if !self.rotation.is_normalized() {
return Err(ShapeError::InvalidNumericValue);
}
if self.size.x < 0.0 || self.size.y < 0.0 || self.size.z < 0.0 {
return Err(ShapeError::InvalidNumericValue);
}
Ok(())
}
pub fn world_point(&self, u: f64, v: f64, w: f64) -> Vec3 {
let local = Vec3::new(u * self.size.x, v * self.size.y, w * self.size.z);
self.position + self.rotation * local
}
}