Skip to content

Commit

Permalink
Stub some joint concepts in physics
Browse files Browse the repository at this point in the history
  • Loading branch information
mattkleiny committed Apr 5, 2024
1 parent c0c7385 commit e7cd8d1
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 20 deletions.
2 changes: 1 addition & 1 deletion common/src/abstractions/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{
pub use exporters::*;
pub use importers::*;

use crate::{FastHashMap, FileSystemError, Guid, impl_from_error, StreamError, StringName, ToVirtualPath, VirtualPath};
use crate::{FastHashMap, FileSystemError, Guid, StreamError, StringName, ToVirtualPath, VirtualPath};

/// Represents a reference to an asset that can either be loaded or unloaded.
///
Expand Down
5 changes: 3 additions & 2 deletions common/src/collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::{
hash::BuildHasherDefault,
};

pub use smallvec::{smallvec, SmallVec};

pub use anymap::*;
pub use arena::*;
pub use graphs::*;
Expand All @@ -13,7 +15,6 @@ pub use multimap::*;
pub use priorityqueue::*;
pub use quadtree::*;
pub use ringbuffer::*;
pub use smallvec::{smallvec, SmallVec};
pub use spatialhash::*;

mod anymap;
Expand All @@ -32,7 +33,7 @@ pub type FastHashSet<K> = HashSet<K, BuildHasherDefault<rustc_hash::FxHasher>>;
/// A faster hash map that is not resilient to DoS attacks.
pub type FastHashMap<K, V> = HashMap<K, V, BuildHasherDefault<rustc_hash::FxHasher>>;

/// A faster multi-map that is not resilient to DoS attacks.
/// A faster multimap that is not resilient to DoS attacks.
pub type FastMultiMap<K, V> = MultiMap<K, V, FastHashMap<K, BuildHasherDefault<rustc_hash::FxHasher>>>;

/// A faster any-map that is not resilient to DoS attacks.
Expand Down
5 changes: 2 additions & 3 deletions common/src/maths/linear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};

pub use glam::*;

pub use aabb::*;
pub use bsp::*;
pub use fields::*;
pub use frustum::*;
pub use glam::*;
pub use planes::*;
pub use rays::*;
pub use scalars::*;
Expand All @@ -17,7 +17,6 @@ use super::*;

mod aabb;
mod bsp;
mod fields;
mod frustum;
mod planes;
mod rays;
Expand Down
8 changes: 0 additions & 8 deletions common/src/maths/linear/fields.rs

This file was deleted.

9 changes: 8 additions & 1 deletion common/src/maths/linear/frustum.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::*;
use crate::reinterpret_cast;

use super::*;

/// A frustum in 3-space.
#[repr(C)]
#[derive(Default, Clone, Debug)]
Expand Down Expand Up @@ -109,16 +110,22 @@ impl Frustum {
}

/// Converts this frustum to an array of planes.
///
/// The order is Near, Far, Left, Right, Top, Bottom.
pub fn into_array(self) -> [Plane; 6] {
[self.near, self.far, self.left, self.right, self.top, self.bottom]
}

/// Converts this frustum to an array of planes.
///
/// The order is Near, Far, Left, Right, Top, Bottom.
pub fn to_array(&self) -> [Plane; 6] {
[self.near, self.far, self.left, self.right, self.top, self.bottom]
}

/// Converts this frustum to a slice of planes.
///
/// The order is Near, Far, Left, Right, Top, Bottom.
pub fn as_slice(&self) -> &[Plane; 6] {
unsafe { reinterpret_cast(self) }
}
Expand Down
5 changes: 0 additions & 5 deletions common/src/maths/linear/sdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ pub trait SDF {

/// Computes the distance to the shape at the given point.
fn distance_to(&self, point: Self::Vector) -> <Self::Vector as Vector>::Scalar;

/// Converts this signed distance field into an evaluated field structure.
fn to_field(&self, _size: Self::Vector, _step: Self::Vector) -> Field<Self::Vector> {
todo!()
}
}

impl SDF for Circle {
Expand Down
10 changes: 10 additions & 0 deletions modules/physics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod simplex;
common::impl_arena_index!(ColliderId, "Identifies a collider.");
common::impl_arena_index!(BodyId, "Identifies a physics body.");
common::impl_arena_index!(EffectorId, "Identifies an effector.");
common::impl_arena_index!(JointId, "Identifies a joint.");

common::impl_server!(PhysicsEngine, PhysicsBackend);

Expand Down Expand Up @@ -111,6 +112,15 @@ pub trait PhysicsWorld2D: PhysicsWorld {
fn effector_set_strength(&self, effector: EffectorId, strength: f32);
fn effector_get_strength(&self, effector: EffectorId) -> f32;
fn effector_delete(&self, effector: EffectorId);

// joints
fn joint_create(&self) -> JointId;
fn joint_attach(&self, joint: JointId, body_a: BodyId, body_b: BodyId);
fn joint_detach(&self, joint: JointId);
fn joint_get_bodies(&self, joint: JointId) -> (BodyId, BodyId);
fn joint_set_anchor(&self, joint: JointId, anchor: Vec2);
fn joint_get_anchor(&self, joint: JointId) -> Vec2;
fn joint_delete(&self, joint: JointId);
}

/// A world of 3D physics.
Expand Down
84 changes: 84 additions & 0 deletions modules/physics/src/simplex/world2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub struct SimplexWorld2D {
bodies: RwLock<Arena<BodyId, Body>>,
colliders: RwLock<Arena<ColliderId, Collider>>,
effectors: RwLock<Arena<EffectorId, Effector>>,
joints: RwLock<Arena<JointId, Joint>>,
}

/// Internal settings for a physics world.
Expand Down Expand Up @@ -82,6 +83,13 @@ enum EffectorShape {
Cylinder { radius: f32, height: f32 },
}

/// A joint in the 2d physics world.
struct Joint {
body_a: Option<BodyId>,
body_b: Option<BodyId>,
anchor: Vec2,
}

impl Default for Settings {
fn default() -> Self {
Self {
Expand Down Expand Up @@ -615,6 +623,69 @@ impl PhysicsWorld2D for SimplexWorld2D {

effectors.remove(effector);
}

#[profiling]
fn joint_create(&self) -> JointId {
let mut joints = self.joints.write().unwrap();

joints.insert(Joint {
body_a: None,
body_b: None,
anchor: Vec2::ZERO,
})
}

#[profiling]
fn joint_attach(&self, joint: JointId, body_a: BodyId, body_b: BodyId) {
let mut joints = self.joints.write().unwrap();

if let Some(joint) = joints.get_mut(joint) {
joint.body_a = Some(body_a);
joint.body_b = Some(body_b);
}
}

#[profiling]
fn joint_detach(&self, joint: JointId) {
let mut joints = self.joints.write().unwrap();

if let Some(joint) = joints.get_mut(joint) {
joint.body_a = None;
joint.body_b = None;
}
}

#[profiling]
fn joint_get_bodies(&self, joint: JointId) -> (BodyId, BodyId) {
let joints = self.joints.read().unwrap();

joints.get(joint).map_or((BodyId::default(), BodyId::default()), |it| {
(it.body_a.unwrap_or_default(), it.body_b.unwrap_or_default())
})
}

#[profiling]
fn joint_set_anchor(&self, joint: JointId, anchor: Vec2) {
let mut joints = self.joints.write().unwrap();

if let Some(joint) = joints.get_mut(joint) {
joint.anchor = anchor;
}
}

#[profiling]
fn joint_get_anchor(&self, joint: JointId) -> Vec2 {
let joints = self.joints.read().unwrap();

joints.get(joint).map_or(Vec2::ZERO, |it| it.anchor)
}

#[profiling]
fn joint_delete(&self, joint: JointId) {
let mut joints = self.joints.write().unwrap();

joints.remove(joint);
}
}

#[cfg(test)]
Expand Down Expand Up @@ -648,4 +719,17 @@ mod tests {

assert_eq!(world.body_get_velocity(body_id), Vec2::ZERO);
}

#[test]
fn it_should_create_a_simple_joint() {
let world = SimplexWorld2D::default();
let body1 = world.body_create(BodyKind::Kinematic, Vec2::ZERO);
let body2 = world.body_create(BodyKind::Kinematic, Vec2::ZERO);

let joint = world.joint_create();

world.joint_attach(joint, body1, body2);

assert_eq!(world.joint_get_bodies(joint), (body1, body2));
}
}

0 comments on commit e7cd8d1

Please sign in to comment.