use crate::{
global::{EntityId, Vec3},
internal::{
conversion::{FromBindgen, IntoBindgen},
wit,
},
};
use glam::Mat4;
pub fn add_force(entity: EntityId, force: Vec3) {
wit::server_physics::add_force(entity.into_bindgen(), force.into_bindgen())
}
pub fn add_impulse(entity: EntityId, impulse: Vec3) {
wit::server_physics::add_force(entity.into_bindgen(), impulse.into_bindgen())
}
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub enum FalloffRadius {
#[default]
None,
FalloffToZeroAt(f32),
}
impl From<FalloffRadius> for Option<f32> {
fn from(radius: FalloffRadius) -> Option<f32> {
match radius {
FalloffRadius::None => None,
FalloffRadius::FalloffToZeroAt(r) => Some(r),
}
}
}
pub fn add_radial_impulse(
position: Vec3,
impulse: f32,
radius: f32,
falloff_radius: FalloffRadius,
) {
wit::server_physics::add_radial_impulse(
position.into_bindgen(),
impulse,
radius,
falloff_radius.into(),
)
}
pub fn add_force_at_position(entity: EntityId, force: Vec3, position: Vec3) {
wit::server_physics::add_force_at_position(
entity.into_bindgen(),
force.into_bindgen(),
position.into_bindgen(),
)
}
pub fn add_impulse_at_position(entity: EntityId, impulse: Vec3, position: Vec3) {
wit::server_physics::add_impulse_at_position(
entity.into_bindgen(),
impulse.into_bindgen(),
position.into_bindgen(),
)
}
pub fn get_velocity_at_position(entity: EntityId, position: Vec3) -> Vec3 {
wit::server_physics::get_velocity_at_position(entity.into_bindgen(), position.into_bindgen())
.from_bindgen()
}
pub fn set_gravity(gravity: Vec3) {
wit::server_physics::set_gravity(gravity.into_bindgen())
}
pub fn unfreeze(entity: EntityId) {
wit::server_physics::unfreeze(entity.into_bindgen())
}
pub fn freeze(entity: EntityId) {
wit::server_physics::freeze(entity.into_bindgen())
}
pub fn start_motor(entity: EntityId, velocity: f32) {
wit::server_physics::start_motor(entity.into_bindgen(), velocity)
}
pub fn stop_motor(entity: EntityId) {
wit::server_physics::stop_motor(entity.into_bindgen())
}
pub fn create_revolute_joint(
entity0: EntityId,
transform0: Mat4,
entity1: EntityId,
transform1: Mat4,
) {
wit::server_physics::create_revolute_joint(
entity0.into_bindgen(),
transform0.into_bindgen(),
entity1.into_bindgen(),
transform1.into_bindgen(),
)
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct RaycastHit {
pub position: Vec3,
pub distance: f32,
pub entity: EntityId,
}
pub fn raycast(origin: Vec3, direction: Vec3) -> Vec<RaycastHit> {
wit::server_physics::raycast(origin.into_bindgen(), direction.into_bindgen())
.into_iter()
.map(|(entity, distance)| raycast_result_to_hit(origin, direction, entity, distance))
.collect()
}
pub fn raycast_first(origin: Vec3, direction: Vec3) -> Option<RaycastHit> {
wit::server_physics::raycast_first(origin.into_bindgen(), direction.into_bindgen())
.map(|(entity, distance)| raycast_result_to_hit(origin, direction, entity, distance))
}
fn raycast_result_to_hit(
origin: Vec3,
direction: Vec3,
entity: wit::types::EntityId,
distance: f32,
) -> RaycastHit {
RaycastHit {
position: origin + direction * distance,
distance,
entity: entity.from_bindgen(),
}
}
pub struct CharacterCollision {
pub side: bool,
pub up: bool,
pub down: bool,
}
pub fn move_character(
entity: EntityId,
displacement: Vec3,
min_dist: f32,
elapsed_time: f32,
) -> CharacterCollision {
let res = wit::server_physics::move_character(
entity.into_bindgen(),
displacement.into_bindgen(),
min_dist,
elapsed_time,
);
CharacterCollision {
side: res.side,
up: res.up,
down: res.down,
}
}
pub fn set_character_position(entity: EntityId, position: Vec3) {
wit::server_physics::set_character_position(entity.into_bindgen(), position.into_bindgen());
}
pub fn set_character_foot_position(entity: EntityId, position: Vec3) {
wit::server_physics::set_character_foot_position(
entity.into_bindgen(),
position.into_bindgen(),
);
}