use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PhysicsMaterial {
pub name: String,
pub friction: f32,
pub restitution: f32,
pub density: f32,
}
impl PhysicsMaterial {
pub fn new(name: String, friction: f32, restitution: f32, density: f32) -> Self {
Self {
name,
friction,
restitution,
density,
}
}
pub fn default_material() -> Self {
Self::new("Default".to_string(), 0.5, 0.2, 1.0)
}
pub fn ice() -> Self {
Self::new("Ice".to_string(), 0.02, 0.95, 0.9)
}
pub fn rubber() -> Self {
Self::new("Rubber".to_string(), 1.0, 0.9, 0.95)
}
pub fn metal() -> Self {
Self::new("Metal".to_string(), 0.4, 0.1, 7.8)
}
pub fn wood() -> Self {
Self::new("Wood".to_string(), 0.6, 0.3, 0.6)
}
pub fn concrete() -> Self {
Self::new("Concrete".to_string(), 0.8, 0.1, 2.4)
}
pub fn plastic() -> Self {
Self::new("Plastic".to_string(), 0.3, 0.4, 0.9)
}
pub fn glass() -> Self {
Self::new("Glass".to_string(), 0.9, 0.05, 2.5)
}
pub fn bouncy_ball() -> Self {
Self::new("Bouncy Ball".to_string(), 0.8, 0.95, 0.5)
}
pub fn sand() -> Self {
Self::new("Sand".to_string(), 0.9, 0.0, 1.6)
}
pub fn get_predefined_materials() -> Vec<PhysicsMaterial> {
vec![
Self::default_material(),
Self::ice(),
Self::rubber(),
Self::metal(),
Self::wood(),
Self::concrete(),
Self::plastic(),
Self::glass(),
Self::bouncy_ball(),
Self::sand(),
]
}
pub fn apply_to_collider(&self, collider: &mut super::ColliderComponent) {
collider.friction = self.friction;
collider.restitution = self.restitution;
collider.density = self.density;
}
pub fn apply_to_collider_builder(
&self,
mut collider: super::ColliderComponent,
) -> super::ColliderComponent {
collider.friction = self.friction;
collider.restitution = self.restitution;
collider.density = self.density;
collider
}
}
impl Default for PhysicsMaterial {
fn default() -> Self {
Self::default_material()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct PhysicsMaterialComponent {
pub material: PhysicsMaterial,
}
impl PhysicsMaterialComponent {
pub fn new(material: PhysicsMaterial) -> Self {
Self { material }
}
pub fn with_material_name(material_name: &str) -> Self {
let material = match material_name {
"Ice" => PhysicsMaterial::ice(),
"Rubber" => PhysicsMaterial::rubber(),
"Metal" => PhysicsMaterial::metal(),
"Wood" => PhysicsMaterial::wood(),
"Concrete" => PhysicsMaterial::concrete(),
"Plastic" => PhysicsMaterial::plastic(),
"Glass" => PhysicsMaterial::glass(),
"Bouncy Ball" => PhysicsMaterial::bouncy_ball(),
"Sand" => PhysicsMaterial::sand(),
_ => PhysicsMaterial::default_material(),
};
Self::new(material)
}
}