Skip to content

Commit

Permalink
Merge pull request #1 from AndreaCatania/phyUpd
Browse files Browse the repository at this point in the history
Implemented the new amethyst_physics APIs.
  • Loading branch information
AndreaCatania authored Oct 5, 2019
2 parents 39af5b5 + af216b9 commit 36c2e32
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 60 deletions.
10 changes: 5 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ rust:
- stable
before_script:
- rustup component add rustfmt --toolchain stable-x86_64-unknown-linux-gnu
- rustup component add clippy
script:
- |
cargo fmt -- --check &&
cargo build &&
cargo test -- --all &&
cargo --only stable doc
- cargo fmt -- --check
- cargo build
- cargo test --all
- cargo clippy --all
cache: cargo
env:
global:
Expand Down
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "amethyst_nphysics"
version = "0.0.1"
version = "0.1.0"
authors = ["Andrea Catania <info@andreacatania.com>"]
edition = "2018"
repository = "https://github.com/AndreaCatania/amethyst_nphysics"
Expand All @@ -11,8 +11,8 @@ readme = "README.md"
license = "MIT"

[dependencies]
amethyst_core = "0.8"
amethyst_physics = "0.0.1"
amethyst_core = "0.8.0"
amethyst_physics = "0.1.0"
log = "0.4.6"
ncollide3d = "0.20.1"
nphysics3d = "0.12.2"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# NPhysics Amethyst backend
![Build Status] ![License] ![Line of code][loc]
[![Build Status]](https://travis-ci.com/AndreaCatania/amethyst_nphysics) [![License]](https://github.com/AndreaCatania/amethyst_nphysics/blob/master/LICENSE) [![Line of code][loc]](https://github.com/AndreaCatania/amethyst_nphysics/pulse)

[Build Status]: https://travis-ci.com/AndreaCatania/amethyst_nphysics.svg?branch=master
[License]: https://img.shields.io/badge/License-MIT-green.svg
Expand Down
92 changes: 78 additions & 14 deletions src/area_physics_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use amethyst_core::ecs::Entity;
use amethyst_core::math::{zero, Isometry3};
use amethyst_physics::{
objects::*,
servers::{AreaPhysicsServerTrait, OverlapEvent},
servers::{AreaDesc, AreaPhysicsServerTrait, OverlapEvent},
PtReal,
};
use log::error;
use nphysics3d::object::{
BodyPartHandle as NpBodyPartHandle, BodyStatus as NpBodyStatus, Collider as NpCollider,
ColliderDesc as NpColliderDesc, RigidBody as NpRigidBody, RigidBodyDesc as NpRigidBodyDesc,
ColliderDesc as NpColliderDesc, RigidBodyDesc as NpRigidBodyDesc,
};

use crate::{
Expand Down Expand Up @@ -107,21 +107,32 @@ impl<N: PtReal> AreaNpServer<N> {
))));
}

pub fn extract_collider_desc(
_np_rigid_body: &NpRigidBody<N>, // Even if not used still here because in future this will be used.
_shape: &RigidShape<N>, // Even if not used still here because in future this will be used.
np_collider_desc: &mut NpColliderDesc<N>,
) {
np_collider_desc.set_density(zero());
np_collider_desc.set_is_sensor(true);
pub fn create_collider_desc(body: &Body<N>, shape: &RigidShape<N>) -> NpColliderDesc<N> {
NpColliderDesc::new(shape.shape_handle().clone())
.collision_groups(body.np_collision_groups)
.density(zero())
.sensor(true)
}
}

// This is a collection of utility function to perform common operations.
impl<N: crate::PtReal> AreaNpServer<N> {
/// Update the collider collision group.
pub fn update_collider_collision_groups(&self, area: &Body<N>) {
// Update the collider collision groups.
if let Some(key) = area.collider_key {
let colliders = self.storages.colliders_r();
let mut collider = colliders.get_collider(key).unwrap();
collider.set_collision_groups(area.np_collision_groups);
}
}
}

impl<N> AreaPhysicsServerTrait<N> for AreaNpServer<N>
where
N: PtReal,
{
fn create(&self) -> PhysicsHandle<PhysicsAreaTag> {
fn create(&self, area_desc: &AreaDesc) -> PhysicsHandle<PhysicsAreaTag> {
let mut bodies_storage = self.storages.bodies_w();

// Create Rigid body
Expand All @@ -130,8 +141,11 @@ where
.set_mass(N::from(0.0f32))
.build();

let a_key =
bodies_storage.insert_body(Body::new_area(Box::new(np_rigid_body), zero(), zero()));
let cg =
collision_group_conversor::to_nphysics(&area_desc.belong_to, &area_desc.collide_with);

let a_key = bodies_storage.insert_body(Body::new_area(Box::new(np_rigid_body), cg));

let mut area = bodies_storage.get_body(a_key).unwrap();
area.self_key = Some(a_key);

Expand Down Expand Up @@ -195,8 +209,7 @@ where

if let Some(mut shape) = shapes.get(shape_key) {
// Create and attach the collider
let collider_desc =
NpColliderDesc::new(shape.shape_handle().clone()).sensor(true);
let collider_desc = AreaNpServer::create_collider_desc(&area, &shape);

AreaNpServer::install_shape(
&mut *area,
Expand Down Expand Up @@ -250,6 +263,57 @@ where
}
}

fn set_belong_to(&self, area_tag: PhysicsAreaTag, groups: Vec<CollisionGroup>) {
let area_key = area_tag_to_store_key(area_tag);
let bodies = self.storages.bodies_r();

let area = bodies.get_body(area_key);
if let Some(mut area) = area {
let (_, collide_with) =
collision_group_conversor::from_nphysics(&area.np_collision_groups);
area.np_collision_groups =
collision_group_conversor::to_nphysics(&groups, &collide_with);
self.update_collider_collision_groups(&area);
}
}

fn belong_to(&self, area_tag: PhysicsAreaTag) -> Vec<CollisionGroup> {
let area_key = area_tag_to_store_key(area_tag);
let bodies = self.storages.bodies_r();

let area = bodies.get_body(area_key);
if let Some(area) = area {
collision_group_conversor::from_nphysics(&area.np_collision_groups).0
} else {
Vec::new()
}
}

fn set_collide_with(&self, area_tag: PhysicsAreaTag, groups: Vec<CollisionGroup>) {
let area_key = area_tag_to_store_key(area_tag);
let bodies = self.storages.bodies_r();

let area = bodies.get_body(area_key);
if let Some(mut area) = area {
let (belong_to, _) =
collision_group_conversor::from_nphysics(&area.np_collision_groups);
area.np_collision_groups = collision_group_conversor::to_nphysics(&belong_to, &groups);
self.update_collider_collision_groups(&area);
}
}

fn collide_with(&self, area_tag: PhysicsAreaTag) -> Vec<CollisionGroup> {
let area_key = area_tag_to_store_key(area_tag);
let bodies = self.storages.bodies_r();

let area = bodies.get_body(area_key);
if let Some(area) = area {
collision_group_conversor::from_nphysics(&area.np_collision_groups).1
} else {
Vec::new()
}
}

fn overlap_events(&self, area_tag: PhysicsAreaTag) -> Vec<OverlapEvent> {
let area_key = area_tag_to_store_key(area_tag);
let bodies = self.storages.bodies_r();
Expand Down
17 changes: 14 additions & 3 deletions src/body.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use amethyst_core::{ecs::Entity, math::Isometry3};
use amethyst_core::{
ecs::Entity,
math::{zero, Isometry3},
};
use amethyst_physics::{servers::OverlapEvent, PtReal};
use ncollide3d::pipeline::object::CollisionGroups as NpCollisionGroups;
use nphysics3d::{
material::{BasicMaterial, MaterialHandle},
object::{Body as NpBody, RigidBody as NpRigidBody},
Expand All @@ -21,6 +25,7 @@ pub struct Body<N: PtReal> {
pub shape_key: Option<StoreKey>,
pub entity: Option<Entity>,
pub material_handle: MaterialHandle<N>, // TODO share this material across many bodies
pub np_collision_groups: NpCollisionGroups,
}

impl<N: PtReal> Body<N> {
Expand All @@ -29,6 +34,7 @@ impl<N: PtReal> Body<N> {
np_rigid_body: Box<NpRigidBody<N>>,
friction: N,
bounciness: N,
np_collision_groups: NpCollisionGroups,
) -> Self {
Body {
self_key: None,
Expand All @@ -38,19 +44,24 @@ impl<N: PtReal> Body<N> {
shape_key: None,
entity: None,
material_handle: MaterialHandle::new(BasicMaterial::new(bounciness, friction)),
np_collision_groups,
}
}

/// Creates an Area `Body`
pub(crate) fn new_area(np_rigid_body: Box<NpRigidBody<N>>, friction: N, bounciness: N) -> Self {
pub(crate) fn new_area(
np_rigid_body: Box<NpRigidBody<N>>,
np_collision_groups: NpCollisionGroups,
) -> Self {
Body {
self_key: None,
np_body: np_rigid_body,
body_data: BodyData::Area(Vec::new()),
collider_key: None,
shape_key: None,
entity: None,
material_handle: MaterialHandle::new(BasicMaterial::new(bounciness, friction)),
material_handle: MaterialHandle::new(BasicMaterial::new(zero(), zero())),
np_collision_groups,
}
}

Expand Down
45 changes: 45 additions & 0 deletions src/conversors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,51 @@ pub mod body_mode_conversor {
}
}

pub mod collision_group_conversor {
use amethyst_physics::objects::CollisionGroup;
use ncollide3d::pipeline::object::CollisionGroups as NcCollisionGroups;

pub fn to_nphysics(
belong_to: &[CollisionGroup],
collide_with: &[CollisionGroup],
) -> NcCollisionGroups {
let mut membership: Vec<usize> = belong_to.iter().map(|v| v.get().into()).collect();
membership.sort();
membership.dedup();
let mut white_list: Vec<usize> = collide_with.iter().map(|v| v.get().into()).collect();
white_list.sort();
white_list.dedup();
let mut black_list = Vec::<usize>::new();
for e in &membership {
if let Err(..) = white_list.binary_search(e) {
black_list.push(*e);
}
}
let mut collision_groups = NcCollisionGroups::new();
collision_groups.set_membership(membership.as_slice());
collision_groups.set_whitelist(white_list.as_slice());
collision_groups.set_blacklist(black_list.as_slice());

collision_groups
}

pub fn from_nphysics(groups: &NcCollisionGroups) -> (Vec<CollisionGroup>, Vec<CollisionGroup>) {
let mut belong_to = Vec::<CollisionGroup>::with_capacity(NcCollisionGroups::max_group_id());
let mut collide_with =
Vec::<CollisionGroup>::with_capacity(NcCollisionGroups::max_group_id());

for group in 0..NcCollisionGroups::max_group_id() {
if groups.is_member_of(group) {
belong_to.push(CollisionGroup::new(group as u8));
}
if groups.is_group_whitelisted(group) {
collide_with.push(CollisionGroup::new(group as u8));
}
}
(belong_to, collide_with)
}
}

macro_rules! opaque_conversors {
($t:ident, $to:ident, $from:ident, $test_mod:ident) => {
pub fn $to(tag: $t) -> StoreKey {
Expand Down
Loading

0 comments on commit 36c2e32

Please sign in to comment.