1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright 2017 Matthew Plant. This file is part of MGF.
//
// MGF is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// MGF is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with MGF. If not, see <http://www.gnu.org/licenses/>.

//! A low-level 3D collision and physics library intended for use in 3D video
//! game development.
//!
//! # Collision detection overview
//!
//! An object implements collision detection routines through the various traits
//! provided by MGF. Each trait provides a disparate form of collision detection:
//!
//! - `Overlaps`: Specifies a collision where the only information required is
//!   whether or not two objects overlap. 
//! - `Contains`: Specifies a collision where one object completely contains
//!   another. For bounding volumes.
//! - `Intersection`: For linear geometries, describes a collision at some time
//!   during the motion of a particle (represented with a Ray or Segment) with
//!   only one point of contact.
//! - `Contacts`: For moving volumetric geometries, describes a collision with
//!   possibly multiple contacts occuring at some time during the motion of the
//!   geometries.
//! - `LocalContacts`: Similar to `Contacts`, but returns contacts with local
//!    contact points as well as globals.
//!
//! In addition to these traits, MGF supports broad-phase colision detection
//! through a bounding volume hierarch (`BVH`)
//!
//! # Physics Overview
//!
//! Physics is implemented through the following objects:
//!
//! - `RigidBodyVec`, a vector of rigid bodies.
//! - `Solver`, a generic constraint-based solver.
//! - `ContactConstraint`, a constraint modeling the collision of two objects.
//!
//! After contact points are accumulated, they are pruned via a `ContactPruner` and put
//! through a constraint solver.
//!
//! ```rust
//! use mgf::cgmath::prelude::*;
//! use mgf::cgmath::*;
//! use mgf::*;
//!
//! const TIMESTEP: f32 = 1.0;
//! const RESTITUTION: f32 = 0.3;
//! const FRICTION: f32 = 0.5;
//! const MASS: f32 = 1.0;
//! const SOLVER_ITERS: usize = 20;
//!
//! let gravity = Vector3::new(0.0, -9.8, 0.0);
//!
//! let mut rigid_bodies = RigidBodyVec::new();
//! let mut sphere = Component::from(Sphere{ c: Point3::new(0.0, 0.0, 0.0), r: 1.0 });
//!
//! sphere.set_pos(Point3::new(-5.0, 0.0, 0.0));
//! let body_a = rigid_bodies.add_body(sphere, MASS, RESTITUTION, FRICTION, gravity);
//!
//! sphere.set_pos(Point3::new(5.0, 0.0, 0.0));
//! let body_b = rigid_bodies.add_body(sphere, MASS, RESTITUTION, FRICTION, gravity);
//!
//! // Set the velocity for the objects.
//! rigid_bodies.set(body_a, Velocity{ linear: Vector3::new(0.0,  4.0, 0.0), angular: Vector3::zero() });
//! rigid_bodies.set(body_b, Velocity{ linear: Vector3::new(0.0, -4.0, 0.0), angular: Vector3::zero() });
//!
//! // Integrate the objects, creating colliders for each.
//! rigid_bodies.integrate(TIMESTEP);
//!
//! // Collide the objects:
//! let mut pruner: ContactPruner = ContactPruner::new();
//! let body_ai: usize = body_a.into();
//! let body_bi: usize = body_b.into();
//! rigid_bodies.collider[body_ai].local_contacts(
//!     &rigid_bodies.collider[body_bi],
//!     | lc | {
//!         pruner.push(lc);
//!     }
//! );
//!
//! // Create the constraint solver:
//! let mut solver = Solver::<ContactConstraint<_>>::new();
//!
//! // Create a manifold to pass to the contact solver as a constraint:
//!
//! // Obviously two spheres will only produce one contact. To avoid using a
//! // pruner in this case a Manifold may be constructed from a single LocalContact:
//! // let manifold = Manifold::from(local_contact);
//!
//! let manifold = Manifold::from(pruner);
//! solver.add_constraint(
//!     ContactConstraint::new(
//!         &rigid_bodies,
//!         body_a, body_b,
//!         manifold,
//!         TIMESTEP
//!     )
//! );
//!
//! // Solve the collision:
//! solver.solve(&mut rigid_bodies, SOLVER_ITERS);
//! ```
#[macro_use]
pub extern crate cgmath;
extern crate smallvec;

mod bvh;
pub use crate::bvh::*;

mod bounds;
pub use crate::bounds::*;

pub mod bitset;

mod compound;
pub use crate::compound::*;

mod collision;
pub use crate::collision::*;

mod solver;
pub use crate::solver::*;

mod geom;
pub use crate::geom::*;

mod manifold;
pub use crate::manifold::*;

mod mesh;
pub use crate::mesh::*;

mod physics;
pub use crate::physics::*;

mod pool;
pub use crate::pool::*;

mod simplex;
pub use crate::simplex::*;