use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum CollisionMode {
None,
Plane,
TerrainHeightfield,
DepthBuffer,
SignedDistanceField,
ProxyCollider,
VoxelGrid,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum CollisionResponse {
Bounce,
Slide,
Stick,
Die,
Split,
Shatter,
Embed,
Sleep,
Promote,
TriggerSubEmitter,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CollisionPolicy {
pub mode: CollisionMode,
pub response: CollisionResponse,
pub restitution: f32,
pub friction: f32,
pub radius: f32,
pub max_collisions: u32,
pub material_response_table: Option<String>,
}
impl Default for CollisionPolicy {
fn default() -> Self {
Self {
mode: CollisionMode::None,
response: CollisionResponse::Bounce,
restitution: 0.5,
friction: 0.3,
radius: 0.05,
max_collisions: 4,
material_response_table: None,
}
}
}
impl CollisionMode {
pub const ALL: &[CollisionMode] = &[
Self::None,
Self::Plane,
Self::TerrainHeightfield,
Self::DepthBuffer,
Self::SignedDistanceField,
Self::ProxyCollider,
Self::VoxelGrid,
];
}
impl CollisionResponse {
pub const ALL: &[CollisionResponse] = &[
Self::Bounce,
Self::Slide,
Self::Stick,
Self::Die,
Self::Split,
Self::Shatter,
Self::Embed,
Self::Sleep,
Self::Promote,
Self::TriggerSubEmitter,
];
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn collision_mode_all() {
assert_eq!(CollisionMode::ALL.len(), 7);
}
#[test]
fn collision_response_all() {
assert_eq!(CollisionResponse::ALL.len(), 10);
}
#[test]
fn collision_policy_default() {
let p = CollisionPolicy::default();
assert_eq!(p.mode, CollisionMode::None);
assert_eq!(p.response, CollisionResponse::Bounce);
}
#[test]
fn collision_policy_serde() {
let p = CollisionPolicy {
mode: CollisionMode::SignedDistanceField,
response: CollisionResponse::Slide,
restitution: 0.18,
friction: 0.82,
radius: 0.06,
max_collisions: 12,
material_response_table: Some("mat/stone".into()),
};
let json = serde_json::to_string(&p).unwrap();
let restored: CollisionPolicy = serde_json::from_str(&json).unwrap();
assert_eq!(restored.mode, CollisionMode::SignedDistanceField);
assert_eq!(restored.max_collisions, 12);
}
}