use amethyst_core::ecs::Entity;
use amethyst_core::math::{convert, one, zero, Isometry3, Point3, Unit, Vector3};
use crate::objects::*;
pub trait RBodyPhysicsServerTrait<N: crate::PtReal> {
fn create(&self, body_desc: &RigidBodyDesc<N>) -> PhysicsHandle<PhysicsRigidBodyTag>;
fn set_entity(&self, body_tag: PhysicsRigidBodyTag, index: Option<Entity>);
fn entity(&self, body_tag: PhysicsRigidBodyTag) -> Option<Entity>;
fn set_shape(&self, body_tag: PhysicsRigidBodyTag, shape_tag: Option<PhysicsShapeTag>);
fn shape(&self, body_tag: PhysicsRigidBodyTag) -> Option<PhysicsShapeTag>;
fn set_transform(&self, body: PhysicsRigidBodyTag, transf: &Isometry3<N>);
fn transform(&self, body_tag: PhysicsRigidBodyTag) -> Isometry3<N>;
fn set_mode(&self, body_tag: PhysicsRigidBodyTag, mode: BodyMode);
fn mode(&self, body_tag: PhysicsRigidBodyTag) -> BodyMode;
fn set_friction(&self, body_tag: PhysicsRigidBodyTag, friction: N);
fn friction(&self, body_tag: PhysicsRigidBodyTag) -> N;
fn set_bounciness(&self, body_tag: PhysicsRigidBodyTag, bounciness: N);
fn bounciness(&self, body_tag: PhysicsRigidBodyTag) -> N;
fn set_belong_to(&self, body_tag: PhysicsRigidBodyTag, groups: Vec<CollisionGroup>);
fn belong_to(&self, body_tag: PhysicsRigidBodyTag) -> Vec<CollisionGroup>;
fn set_collide_with(&self, body_tag: PhysicsRigidBodyTag, groups: Vec<CollisionGroup>);
fn collide_with(&self, body_tag: PhysicsRigidBodyTag) -> Vec<CollisionGroup>;
fn set_lock_translation(&self, body_tag: PhysicsRigidBodyTag, axis: Vector3<bool>);
fn lock_translation(&self, body_tag: PhysicsRigidBodyTag) -> Vector3<bool>;
fn set_lock_rotation(&self, body_tag: PhysicsRigidBodyTag, axis: Vector3<bool>);
fn lock_rotation(&self, body_tag: PhysicsRigidBodyTag) -> Vector3<bool>;
fn clear_forces(&self, body: PhysicsRigidBodyTag);
fn apply_force(&self, body: PhysicsRigidBodyTag, force: &Vector3<N>);
fn apply_torque(&self, body: PhysicsRigidBodyTag, force: &Vector3<N>);
fn apply_force_at_position(
&self,
body: PhysicsRigidBodyTag,
force: &Vector3<N>,
position: &Vector3<N>,
);
fn apply_impulse(&self, body: PhysicsRigidBodyTag, impulse: &Vector3<N>);
fn apply_angular_impulse(&self, body: PhysicsRigidBodyTag, impulse: &Vector3<N>);
fn apply_impulse_at_position(
&self,
body: PhysicsRigidBodyTag,
impulse: &Vector3<N>,
position: &Vector3<N>,
);
fn set_linear_velocity(&self, body: PhysicsRigidBodyTag, velocity: &Vector3<N>);
fn linear_velocity(&self, body: PhysicsRigidBodyTag) -> Vector3<N>;
fn set_angular_velocity(&self, body: PhysicsRigidBodyTag, velocity: &Vector3<N>);
fn angular_velocity(&self, body: PhysicsRigidBodyTag) -> Vector3<N>;
fn linear_velocity_at_position(
&self,
body: PhysicsRigidBodyTag,
position: &Vector3<N>,
) -> Vector3<N>;
fn set_contacts_to_report(&self, body_tag: PhysicsRigidBodyTag, count: usize);
fn contacts_to_report(&self, body_tag: PhysicsRigidBodyTag) -> usize;
fn contact_events(&self, body_tag: PhysicsRigidBodyTag, contacts: &mut Vec<ContactEvent<N>>);
}
#[derive(Debug)]
pub struct RigidBodyDesc<N> {
pub mode: BodyMode,
pub mass: N,
pub friction: N,
pub bounciness: N,
pub belong_to: Vec<CollisionGroup>,
pub collide_with: Vec<CollisionGroup>,
pub lock_translation_x: bool,
pub lock_translation_y: bool,
pub lock_translation_z: bool,
pub lock_rotation_x: bool,
pub lock_rotation_y: bool,
pub lock_rotation_z: bool,
pub contacts_to_report: usize,
}
impl<N: crate::PtReal> Default for RigidBodyDesc<N> {
fn default() -> Self {
RigidBodyDesc {
mode: BodyMode::default(),
mass: one(),
friction: convert(0.2),
bounciness: zero(),
belong_to: vec![CollisionGroup::default()],
collide_with: vec![CollisionGroup::default()],
lock_translation_x: false,
lock_translation_y: false,
lock_translation_z: false,
lock_rotation_x: false,
lock_rotation_y: false,
lock_rotation_z: false,
contacts_to_report: 0,
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum BodyMode {
Disabled,
Static,
Dynamic,
Kinematic,
}
impl Default for BodyMode {
fn default() -> Self {
BodyMode::Dynamic
}
}
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct ContactEvent<N: crate::PtReal> {
pub other_body: PhysicsRigidBodyTag,
pub other_entity: Option<Entity>,
pub normal: Unit<Vector3<N>>,
pub location: Point3<N>,
pub impulse: Vector3<N>,
}
impl<N: crate::PtReal> Default for ContactEvent<N> {
fn default() -> Self {
ContactEvent {
other_body: PhysicsRigidBodyTag::U32(0),
other_entity: None,
normal: Vector3::y_axis(),
location: Point3::origin(),
impulse: Vector3::zeros(),
}
}
}