#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct FurCard {
pub root: [f32; 3],
pub tip: [f32; 3],
pub width: f32,
pub uvs: [[f32; 2]; 4],
}
impl FurCard {
pub fn new(root: [f32; 3], direction: [f32; 3], length: f32, width: f32) -> Self {
let tip = [
root[0] + direction[0] * length,
root[1] + direction[1] * length,
root[2] + direction[2] * length,
];
let uvs = [[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]];
Self {
root,
tip,
width,
uvs,
}
}
pub fn length(&self) -> f32 {
let dx = self.tip[0] - self.root[0];
let dy = self.tip[1] - self.root[1];
let dz = self.tip[2] - self.root[2];
(dx * dx + dy * dy + dz * dz).sqrt()
}
}
#[derive(Debug, Clone)]
pub struct FurCardMesh {
pub cards: Vec<FurCard>,
}
impl FurCardMesh {
pub fn new() -> Self {
Self { cards: Vec::new() }
}
pub fn add_card(&mut self, card: FurCard) {
self.cards.push(card);
}
pub fn card_count(&self) -> usize {
self.cards.len()
}
pub fn vertex_count(&self) -> usize {
self.cards.len() * 4
}
pub fn index_count(&self) -> usize {
self.cards.len() * 6
}
}
impl Default for FurCardMesh {
fn default() -> Self {
Self::new()
}
}
pub fn generate_fur_cards(
positions: &[[f32; 3]],
normals: &[[f32; 3]],
length: f32,
width: f32,
) -> FurCardMesh {
let mut mesh = FurCardMesh::new();
let count = positions.len().min(normals.len());
for i in 0..count {
let card = FurCard::new(positions[i], normals[i], length, width);
mesh.add_card(card);
}
mesh
}
pub fn average_card_length(mesh: &FurCardMesh) -> f32 {
if mesh.cards.is_empty() {
return 0.0;
}
let sum: f32 = mesh.cards.iter().map(|c| c.length()).sum();
sum / mesh.cards.len() as f32
}
#[cfg(test)]
mod tests {
use super::*;
fn card() -> FurCard {
FurCard::new([0.0, 0.0, 0.0], [0.0, 1.0, 0.0], 5.0, 0.1)
}
#[test]
fn test_card_length() {
let c = card();
assert!((c.length() - 5.0).abs() < 1e-5);
}
#[test]
fn test_add_card() {
let mut mesh = FurCardMesh::new();
mesh.add_card(card());
assert_eq!(mesh.card_count(), 1);
}
#[test]
fn test_vertex_count() {
let mut mesh = FurCardMesh::new();
mesh.add_card(card());
mesh.add_card(card());
assert_eq!(mesh.vertex_count(), 8);
}
#[test]
fn test_index_count() {
let mut mesh = FurCardMesh::new();
mesh.add_card(card());
assert_eq!(mesh.index_count(), 6);
}
#[test]
fn test_generate_fur_cards() {
let positions = vec![[0.0_f32; 3]; 5];
let normals = vec![[0.0_f32, 1.0, 0.0]; 5];
let mesh = generate_fur_cards(&positions, &normals, 3.0, 0.1);
assert_eq!(mesh.card_count(), 5);
}
#[test]
fn test_average_card_length_empty() {
let mesh = FurCardMesh::new();
assert_eq!(average_card_length(&mesh), 0.0);
}
#[test]
fn test_average_card_length() {
let mut mesh = FurCardMesh::new();
mesh.add_card(FurCard::new([0.0; 3], [1.0, 0.0, 0.0], 4.0, 0.1));
mesh.add_card(FurCard::new([0.0; 3], [1.0, 0.0, 0.0], 6.0, 0.1));
assert!((average_card_length(&mesh) - 5.0).abs() < 1e-4);
}
#[test]
fn test_generate_mismatched_lengths() {
let positions = vec![[0.0_f32; 3]; 3];
let normals = vec![[0.0_f32, 1.0, 0.0]; 5];
let mesh = generate_fur_cards(&positions, &normals, 2.0, 0.05);
assert_eq!(mesh.card_count(), 3);
}
}