Remove some irrelevant code.

This commit is contained in:
Crozet Sébastien
2020-12-17 18:37:16 +01:00
parent 29717c2887
commit 8fe2df126a
26 changed files with 89 additions and 474 deletions

View File

@@ -3,7 +3,7 @@
//! See https://github.com/fitzgen/generational-arena/blob/master/src/lib.rs.
//! This has been modified to have a fully deterministic deserialization (including for the order of
//! Index attribution after a deserialization of the arena.
use eagl::partitioning::IndexedData;
use cdl::partitioning::IndexedData;
use std::cmp;
use std::iter::{self, Extend, FromIterator, FusedIterator};
use std::mem;

View File

@@ -1,7 +1,7 @@
//! Data structures modified with guaranteed deterministic behavior after deserialization.
pub use self::coarena::Coarena;
pub use eagl::utils::MaybeSerializableData;
pub use cdl::utils::MaybeSerializableData;
pub mod arena;
mod coarena;

View File

@@ -9,7 +9,7 @@ pub use self::joint::{
};
pub use self::rigid_body::{ActivationStatus, BodyStatus, RigidBody, RigidBodyBuilder};
pub use self::rigid_body_set::{BodyPair, RigidBodyHandle, RigidBodySet};
pub use eagl::shape::MassProperties;
pub use cdl::shape::MassProperties;
// #[cfg(not(feature = "parallel"))]
pub(crate) use self::joint::JointGraphEdge;
pub(crate) use self::rigid_body::RigidBodyChanges;

View File

@@ -13,7 +13,7 @@ use crate::utils::{WAngularInertia, WCross, WCrossMatrix};
use na::{Cholesky, Matrix6, Vector6, U3};
#[cfg(feature = "dim2")]
use {
eagl::utils::SdpMatrix3,
cdl::utils::SdpMatrix3,
na::{Matrix3, Vector3},
};

View File

@@ -8,7 +8,7 @@ use crate::utils::{WAngularInertia, WCross, WCrossMatrix};
use na::{Cholesky, Matrix3x2, Matrix5, Vector5, U2, U3};
#[cfg(feature = "dim2")]
use {
eagl::utils::SdpMatrix2,
cdl::utils::SdpMatrix2,
na::{Matrix2, Vector2},
};

View File

@@ -12,7 +12,7 @@ use crate::utils::{WAngularInertia, WCross, WCrossMatrix};
use na::{Cholesky, Matrix3x2, Matrix5, Vector5, U2, U3};
#[cfg(feature = "dim2")]
use {
eagl::utils::SdpMatrix2,
cdl::utils::SdpMatrix2,
na::{Matrix2, Vector2},
};

View File

@@ -1,16 +0,0 @@
#[cfg(feature = "simd-is-enabled")]
use crate::math::{Point, SimdReal};
#[cfg(feature = "simd-is-enabled")]
#[derive(Copy, Clone, Debug)]
pub(crate) struct WBall {
pub center: Point<SimdReal>,
pub radius: SimdReal,
}
#[cfg(feature = "simd-is-enabled")]
impl WBall {
pub fn new(center: Point<SimdReal>, radius: SimdReal) -> Self {
WBall { center, radius }
}
}

View File

@@ -3,8 +3,8 @@ use crate::dynamics::RigidBodySet;
use crate::geometry::{ColliderHandle, ColliderSet, RemovedCollider};
use crate::math::{Point, Vector, DIM};
use bit_vec::BitVec;
use eagl::bounding_volume::{BoundingVolume, AABB};
use eagl::utils::hashmap::HashMap;
use cdl::bounding_volume::{BoundingVolume, AABB};
use cdl::utils::hashmap::HashMap;
use std::cmp::Ordering;
use std::ops::{Index, IndexMut};
@@ -477,8 +477,8 @@ pub struct BroadPhase {
#[cfg_attr(
feature = "serde-serialize",
serde(
serialize_with = "eagl::utils::hashmap::serialize_hashmap_capacity",
deserialize_with = "eagl::utils::hashmap::deserialize_hashmap_capacity"
serialize_with = "cdl::utils::hashmap::serialize_hashmap_capacity",
deserialize_with = "cdl::utils::hashmap::deserialize_hashmap_capacity"
)
)]
reporting: HashMap<(u32, u32), bool>, // Workspace

View File

@@ -1,13 +1,13 @@
use crate::cdl::shape::HalfSpace;
use crate::dynamics::{MassProperties, RigidBodyHandle, RigidBodySet};
use crate::eagl::shape::HalfSpace;
use crate::geometry::InteractionGroups;
use crate::math::{AngVector, Isometry, Point, Rotation, Vector};
use eagl::bounding_volume::AABB;
use eagl::shape::{
use cdl::bounding_volume::AABB;
use cdl::shape::{
Ball, Capsule, Cuboid, HeightField, Segment, Shape, ShapeType, TriMesh, Triangle,
};
#[cfg(feature = "dim3")]
use eagl::shape::{Cone, Cylinder, RoundCylinder};
use cdl::shape::{Cone, Cylinder, RoundCylinder};
use na::Point3;
use std::ops::Deref;
use std::sync::Arc;

View File

@@ -1,8 +1,8 @@
use crate::dynamics::{BodyPair, RigidBodyHandle, RigidBodySet};
use crate::geometry::{Collider, ColliderPair, ColliderSet, Contact, ContactManifold};
use crate::math::{Isometry, Point, Vector};
use eagl::query::ContactManifoldsWorkspace;
use eagl::utils::MaybeSerializableData;
use cdl::query::ContactManifoldsWorkspace;
use cdl::utils::MaybeSerializableData;
#[cfg(feature = "simd-is-enabled")]
use {
crate::math::{SimdReal, SIMD_WIDTH},

View File

@@ -10,39 +10,38 @@ pub use self::interaction_graph::{
ColliderGraphIndex, InteractionGraph, RigidBodyGraphIndex, TemporaryInteractionIndex,
};
pub use self::narrow_phase::NarrowPhase;
pub use self::polygon::Polygon;
pub use self::user_callbacks::{ContactPairFilter, PairFilterContext, ProximityPairFilter};
pub use self::pair_filter::{ContactPairFilter, PairFilterContext, ProximityPairFilter};
pub use eagl::query::{KinematicsCategory, TrackedContact};
pub use cdl::query::{KinematicsCategory, TrackedContact};
pub type Contact = eagl::query::TrackedContact<ContactData>;
pub type ContactManifold = eagl::query::ContactManifold<ContactManifoldData, ContactData>;
pub type Contact = cdl::query::TrackedContact<ContactData>;
pub type ContactManifold = cdl::query::ContactManifold<ContactManifoldData, ContactData>;
/// A segment shape.
pub type Segment = eagl::shape::Segment;
pub type Segment = cdl::shape::Segment;
/// A cuboid shape.
pub type Cuboid = eagl::shape::Cuboid;
pub type Cuboid = cdl::shape::Cuboid;
/// A triangle shape.
pub type Triangle = eagl::shape::Triangle;
pub type Triangle = cdl::shape::Triangle;
/// A ball shape.
pub type Ball = eagl::shape::Ball;
pub type Ball = cdl::shape::Ball;
/// A capsule shape.
pub type Capsule = eagl::shape::Capsule;
pub type Capsule = cdl::shape::Capsule;
/// A heightfield shape.
pub type HeightField = eagl::shape::HeightField;
pub type HeightField = cdl::shape::HeightField;
/// A cylindrical shape.
#[cfg(feature = "dim3")]
pub type Cylinder = eagl::shape::Cylinder;
pub type Cylinder = cdl::shape::Cylinder;
/// A cone shape.
#[cfg(feature = "dim3")]
pub type Cone = eagl::shape::Cone;
pub type Cone = cdl::shape::Cone;
/// An axis-aligned bounding box.
pub type AABB = eagl::bounding_volume::AABB;
pub type AABB = cdl::bounding_volume::AABB;
/// A ray that can be cast against colliders.
pub type Ray = eagl::query::Ray;
pub type Ray = cdl::query::Ray;
/// The intersection between a ray and a collider.
pub type RayIntersection = eagl::query::RayIntersection;
pub type RayIntersection = cdl::query::RayIntersection;
/// The the projection of a point on a collider.
pub type PointProjection = eagl::query::PointProjection;
pub type PointProjection = cdl::query::PointProjection;
#[derive(Copy, Clone, Hash, Debug)]
/// Events occurring when two collision objects start or stop being in contact (or penetration).
@@ -81,19 +80,16 @@ impl IntersectionEvent {
}
}
#[cfg(feature = "simd-is-enabled")]
pub(crate) use self::ball::WBall;
pub(crate) use self::broad_phase_multi_sap::{BroadPhasePairEvent, ColliderPair};
pub(crate) use self::collider_set::RemovedCollider;
#[cfg(feature = "simd-is-enabled")]
pub(crate) use self::contact_pair::WContact;
pub(crate) use self::narrow_phase::ContactManifoldIndex;
pub(crate) use eagl::partitioning::WQuadtree;
pub(crate) use cdl::partitioning::WQuadtree;
//pub(crate) use self::z_order::z_cmp_floats;
pub use self::interaction_groups::InteractionGroups;
pub use eagl::shape::*;
pub use cdl::shape::*;
mod ball;
mod broad_phase_multi_sap;
mod collider;
mod collider_set;
@@ -101,8 +97,6 @@ mod collider_set;
mod contact_pair;
mod interaction_graph;
mod narrow_phase;
mod polygon;
pub(crate) mod sat;
//mod z_order;
mod interaction_groups;
mod user_callbacks;
mod pair_filter;

View File

@@ -1,26 +1,19 @@
#[cfg(feature = "parallel")]
use rayon::prelude::*;
use crate::dynamics::RigidBodySet;
use eagl::query::{DefaultQueryDispatcher, PersistentQueryDispatcher, QueryDispatcher};
//#[cfg(feature = "simd-is-enabled")]
//use crate::geometry::{
// contact_generator::ContactGenerationContextSimd,
// intersection_detector::ProximityDetectionContextSimd, WBall,
//};
use crate::geometry::{
BroadPhasePairEvent, ColliderGraphIndex, ColliderHandle, ContactEvent, ContactManifoldData,
ContactPairFilter, IntersectionEvent, PairFilterContext, ProximityPairFilter, RemovedCollider,
SolverFlags,
};
use crate::geometry::{ColliderSet, ContactManifold, ContactPair, InteractionGraph};
//#[cfg(feature = "simd-is-enabled")]
//use crate::math::{SimdReal, SIMD_WIDTH};
use crate::data::pubsub::Subscription;
use crate::data::Coarena;
use crate::dynamics::RigidBodySet;
use crate::geometry::{
BroadPhasePairEvent, ColliderGraphIndex, ColliderHandle, ContactData, ContactEvent,
ContactManifoldData, ContactPairFilter, IntersectionEvent, PairFilterContext,
ProximityPairFilter, RemovedCollider, SolverFlags,
};
use crate::geometry::{ColliderSet, ContactManifold, ContactPair, InteractionGraph};
use crate::pipeline::EventHandler;
use cdl::query::{DefaultQueryDispatcher, PersistentQueryDispatcher, QueryDispatcher};
use std::collections::HashMap;
//use simba::simd::SimdValue;
use std::sync::Arc;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -42,14 +35,17 @@ impl ColliderGraphIndices {
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[derive(Clone)]
pub struct NarrowPhase {
#[serde(skip, default = "default_query_dispatcher")]
query_dispatcher: Arc<dyn PersistentQueryDispatcher<ContactManifoldData, ContactData>>,
contact_graph: InteractionGraph<ContactPair>,
intersection_graph: InteractionGraph<bool>,
graph_indices: Coarena<ColliderGraphIndices>,
removed_colliders: Option<Subscription<RemovedCollider>>,
// ball_ball: Vec<usize>, // Workspace: Vec<*mut ContactPair>,
// shape_shape: Vec<usize>, // Workspace: Vec<*mut ContactPair>,
// ball_ball_prox: Vec<usize>, // Workspace: Vec<*mut bool>,
// shape_shape_prox: Vec<usize>, // Workspace: Vec<*mut bool>,
}
fn default_query_dispatcher() -> Arc<dyn PersistentQueryDispatcher<ContactManifoldData, ContactData>>
{
Arc::new(DefaultQueryDispatcher)
}
pub(crate) type ContactManifoldIndex = usize;
@@ -57,15 +53,20 @@ pub(crate) type ContactManifoldIndex = usize;
impl NarrowPhase {
/// Creates a new empty narrow-phase.
pub fn new() -> Self {
Self::with_query_dispatcher(DefaultQueryDispatcher)
}
/// Creates a new empty narrow-phase with a custom query dispatcher.
pub fn with_query_dispatcher<D>(d: D) -> Self
where
D: 'static + PersistentQueryDispatcher<ContactManifoldData, ContactData>,
{
Self {
query_dispatcher: Arc::new(d),
contact_graph: InteractionGraph::new(),
intersection_graph: InteractionGraph::new(),
graph_indices: Coarena::new(),
removed_colliders: None,
// ball_ball: Vec::new(),
// shape_shape: Vec::new(),
// ball_ball_prox: Vec::new(),
// shape_shape_prox: Vec::new(),
}
}
@@ -391,6 +392,7 @@ impl NarrowPhase {
events: &dyn EventHandler,
) {
let nodes = &self.intersection_graph.graph.nodes;
let query_dispatcher = &*self.query_dispatcher;
par_iter_mut!(&mut self.intersection_graph.graph.edges).for_each(|edge| {
let handle1 = nodes[edge.source().index()].weight;
let handle2 = nodes[edge.target().index()].weight;
@@ -434,9 +436,9 @@ impl NarrowPhase {
}
let pos12 = co1.position().inverse() * co2.position();
let dispatcher = DefaultQueryDispatcher;
if let Ok(intersection) = dispatcher.intersection_test(&pos12, co1.shape(), co2.shape())
if let Ok(intersection) =
query_dispatcher.intersection_test(&pos12, co1.shape(), co2.shape())
{
if intersection != edge.weight {
edge.weight = intersection;
@@ -458,6 +460,8 @@ impl NarrowPhase {
pair_filter: Option<&dyn ContactPairFilter>,
events: &dyn EventHandler,
) {
let query_dispatcher = &*self.query_dispatcher;
par_iter_mut!(&mut self.contact_graph.graph.edges).for_each(|edge| {
let pair = &mut edge.weight;
let co1 = &colliders[pair.pair.collider1];
@@ -507,9 +511,8 @@ impl NarrowPhase {
solver_flags.remove(SolverFlags::COMPUTE_IMPULSES);
}
let dispatcher = DefaultQueryDispatcher;
let pos12 = co1.position().inverse() * co2.position();
dispatcher.contact_manifolds(
query_dispatcher.contact_manifolds(
&pos12,
co1.shape(),
co2.shape(),

View File

@@ -1,78 +0,0 @@
#![allow(dead_code)] // TODO: remove this once we support polygons.
use crate::math::{Isometry, Point, Vector};
use eagl::bounding_volume::AABB;
#[derive(Clone)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
/// A convex planar polygon.
pub struct Polygon {
pub(crate) vertices: Vec<Point<f32>>,
pub(crate) normals: Vec<Vector<f32>>,
}
impl Polygon {
/// Builds a new polygon from a set of vertices and normals.
///
/// The vertices must be ordered in such a way that two consecutive
/// vertices determines an edge of the polygon. For example `vertices[0], vertices[1]`
/// is an edge, `vertices[1], vertices[2]` is the next edge, etc. The last edge will
/// be `vertices[vertices.len() - 1], vertices[0]`.
/// The vertices must be given in counter-clockwise order.
/// The vertices must form a convex polygon.
///
/// One normal must be provided per edge and mut point towards the outside of the polygon.
pub fn new(vertices: Vec<Point<f32>>, normals: Vec<Vector<f32>>) -> Self {
Self { vertices, normals }
}
/// Compute the axis-aligned bounding box of the polygon.
pub fn aabb(&self, pos: &Isometry<f32>) -> AABB {
let p0 = pos * self.vertices[0];
let mut mins = p0;
let mut maxs = p0;
for pt in &self.vertices[1..] {
let pt = pos * pt;
mins = mins.inf(&pt);
maxs = maxs.sup(&pt);
}
AABB::new(mins.into(), maxs.into())
}
/// The vertices of this polygon.
pub fn vertices(&self) -> &[Point<f32>] {
&self.vertices
}
pub(crate) fn support_point(&self, dir: &Vector<f32>) -> usize {
let mut best_dot = -f32::MAX;
let mut best_i = 0;
for (i, pt) in self.vertices.iter().enumerate() {
let dot = pt.coords.dot(&dir);
if dot > best_dot {
best_dot = dot;
best_i = i;
}
}
best_i
}
pub(crate) fn support_face(&self, dir: &Vector<f32>) -> usize {
let mut max_dot = -f32::MAX;
let mut max_dot_i = 0;
for (i, normal) in self.normals.iter().enumerate() {
let dot = normal.dot(dir);
if dot > max_dot {
max_dot = dot;
max_dot_i = i;
}
}
max_dot_i
}
}

View File

@@ -1,263 +0,0 @@
use na::{Point2, Real};
use shape::SegmentPointLocation;
use utils::{self, SegmentsIntersection, TriangleOrientation};
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum InFlag {
PIn,
QIn,
Unknown,
}
/// Location of a point on a polyline.
pub enum PolylinePointLocation<N> {
/// Point on a vertex.
OnVertex(usize),
/// Point on an edge.
OnEdge(usize, usize, [N; 2]),
}
impl<N: Real> PolylinePointLocation<N> {
/// Computes the point corresponding to this location.
pub fn to_point(&self, pts: &[Point2<N>]) -> Point2<N> {
match self {
PolylinePointLocation::OnVertex(i) => pts[*i],
PolylinePointLocation::OnEdge(i1, i2, bcoords) => {
pts[*i1] * bcoords[0] + pts[*i2].coords * bcoords[1]
}
}
}
fn from_segment_point_location(a: usize, b: usize, loc: SegmentPointLocation<N>) -> Self {
match loc {
SegmentPointLocation::OnVertex(0) => PolylinePointLocation::OnVertex(a),
SegmentPointLocation::OnVertex(1) => PolylinePointLocation::OnVertex(b),
SegmentPointLocation::OnVertex(_) => unreachable!(),
SegmentPointLocation::OnEdge(bcoords) => PolylinePointLocation::OnEdge(a, b, bcoords),
}
}
}
/// Computes the intersection points of two convex polygons.
///
/// The resulting polygon is output vertex-by-vertex to the `out` closure.
pub fn convex_polygons_intersection_points<N: Real>(
poly1: &[Point2<N>],
poly2: &[Point2<N>],
out: &mut Vec<Point2<N>>,
) {
convex_polygons_intersection(poly1, poly2, |loc1, loc2| {
if let Some(loc1) = loc1 {
out.push(loc1.to_point(poly1))
} else if let Some(loc2) = loc2 {
out.push(loc2.to_point(poly2))
}
})
}
/// Computes the intersection of two convex polygons.
///
/// The resulting polygon is output vertex-by-vertex to the `out` closure.
pub fn convex_polygons_intersection<N: Real>(
poly1: &[Point2<N>],
poly2: &[Point2<N>],
mut out: impl FnMut(Option<PolylinePointLocation<N>>, Option<PolylinePointLocation<N>>),
) {
// FIXME: this does not handle correctly the case where the
// first triangle of the polygon is degenerate.
let rev1 = poly1.len() > 2
&& utils::triangle_orientation(&poly1[0], &poly1[1], &poly1[2])
== TriangleOrientation::Clockwise;
let rev2 = poly2.len() > 2
&& utils::triangle_orientation(&poly2[0], &poly2[1], &poly2[2])
== TriangleOrientation::Clockwise;
// println!("rev1: {}, rev2: {}", rev1, rev2);
let n = poly1.len();
let m = poly2.len();
let mut a = 0;
let mut b = 0;
let mut aa = 0;
let mut ba = 0;
let mut inflag = InFlag::Unknown;
let mut first_point_found = false;
// Quit when both adv. indices have cycled, or one has cycled twice.
while (aa < n || ba < m) && aa < 2 * n && ba < 2 * m {
let (a1, a2) = if rev1 {
((n - a) % n, n - a - 1)
} else {
((a + n - 1) % n, a)
};
let (b1, b2) = if rev2 {
((m - b) % m, m - b - 1)
} else {
((b + m - 1) % m, b)
};
// println!("Current indices: ({}, {}), ({}, {})", a1, a2, b1, b2);
let dir_edge1 = poly1[a2] - poly1[a1];
let dir_edge2 = poly2[b2] - poly2[b1];
let cross = utils::triangle_orientation(
&Point2::origin(),
&Point2::from_coordinates(dir_edge1),
&Point2::from_coordinates(dir_edge2),
);
let aHB = utils::triangle_orientation(&poly2[b1], &poly2[b2], &poly1[a2]);
let bHA = utils::triangle_orientation(&poly1[a1], &poly1[a2], &poly2[b2]);
// If edge1 & edge2 intersect, update inflag.
if let Some(inter) =
utils::segments_intersection(&poly1[a1], &poly1[a2], &poly2[b1], &poly2[b2])
{
match inter {
SegmentsIntersection::Point { loc1, loc2 } => {
let loc1 = PolylinePointLocation::from_segment_point_location(a1, a2, loc1);
let loc2 = PolylinePointLocation::from_segment_point_location(b1, b2, loc2);
out(Some(loc1), Some(loc2));
if inflag == InFlag::Unknown && !first_point_found {
// This is the first point.
aa = 0;
ba = 0;
first_point_found = true;
}
// Update inflag.
if aHB == TriangleOrientation::Counterclockwise {
inflag = InFlag::PIn;
} else if bHA == TriangleOrientation::Counterclockwise {
inflag = InFlag::QIn;
}
}
SegmentsIntersection::Segment {
first_loc1,
first_loc2,
second_loc1,
second_loc2,
} => {
// Special case: edge1 & edge2 overlap and oppositely oriented.
if dir_edge1.dot(&dir_edge2) < N::zero() {
let loc1 =
PolylinePointLocation::from_segment_point_location(a1, a2, first_loc1);
let loc2 =
PolylinePointLocation::from_segment_point_location(b1, b2, first_loc2);
out(Some(loc1), Some(loc2));
let loc1 =
PolylinePointLocation::from_segment_point_location(a1, a2, second_loc1);
let loc2 =
PolylinePointLocation::from_segment_point_location(b1, b2, second_loc2);
out(Some(loc1), Some(loc2));
return;
}
}
}
}
// Special case: edge1 & edge2 parallel and separated.
if cross == TriangleOrientation::Degenerate
&& aHB == TriangleOrientation::Clockwise
&& bHA == TriangleOrientation::Clockwise
{
return;
}
// Special case: edge1 & edge2 collinear.
else if cross == TriangleOrientation::Degenerate
&& aHB == TriangleOrientation::Degenerate
&& bHA == TriangleOrientation::Degenerate
{
// Advance but do not output point.
if inflag == InFlag::PIn {
b = advance(b, &mut ba, m);
} else {
a = advance(a, &mut aa, n);
}
}
// Generic cases.
else if cross == TriangleOrientation::Counterclockwise {
if bHA == TriangleOrientation::Counterclockwise {
if inflag == InFlag::PIn {
out(Some(PolylinePointLocation::OnVertex(a2)), None)
}
a = advance(a, &mut aa, n);
} else {
if inflag == InFlag::QIn {
out(None, Some(PolylinePointLocation::OnVertex(b2)))
}
b = advance(b, &mut ba, m);
}
} else {
// We have cross == TriangleOrientation::Clockwise.
if aHB == TriangleOrientation::Counterclockwise {
if inflag == InFlag::QIn {
out(None, Some(PolylinePointLocation::OnVertex(b2)))
}
b = advance(b, &mut ba, m);
} else {
if inflag == InFlag::PIn {
out(Some(PolylinePointLocation::OnVertex(a2)), None)
}
a = advance(a, &mut aa, n);
}
}
}
if !first_point_found {
// No intersection: test if one polygon completely encloses the other.
let mut orient = TriangleOrientation::Degenerate;
let mut ok = true;
for a in 0..n {
let a1 = (a + n - 1) % n; // a - 1
let new_orient = utils::triangle_orientation(&poly1[a1], &poly1[a], &poly2[0]);
if orient == TriangleOrientation::Degenerate {
orient = new_orient
} else if new_orient != orient && new_orient != TriangleOrientation::Degenerate {
ok = false;
break;
}
}
if ok {
for b in 0..m {
out(None, Some(PolylinePointLocation::OnVertex(b)))
}
}
let mut orient = TriangleOrientation::Degenerate;
let mut ok = true;
for b in 0..m {
let b1 = (b + m - 1) % m; // b - 1
let new_orient = utils::triangle_orientation(&poly2[b1], &poly2[b], &poly1[0]);
if orient == TriangleOrientation::Degenerate {
orient = new_orient
} else if new_orient != orient && new_orient != TriangleOrientation::Degenerate {
ok = false;
break;
}
}
if ok {
for a in 0..n {
out(Some(PolylinePointLocation::OnVertex(a)), None)
}
}
}
}
#[inline]
fn advance(a: usize, aa: &mut usize, n: usize) -> usize {
*aa += 1;
(a + 1) % n
}

View File

@@ -1,27 +0,0 @@
use crate::geometry::{Cuboid, Polygon, Segment, Triangle};
use crate::math::{Isometry, Point, Vector, DIM};
use crate::utils::WSign;
use na::Unit;
#[allow(dead_code)]
pub fn polygon_polygon_compute_separation_features(
p1: &Polygon,
p2: &Polygon,
m12: &Isometry<f32>,
) -> (f32, usize, usize) {
let mut max_separation = -f32::MAX;
let mut separation_features = (0, 0);
for (i, (p1, n1)) in p1.vertices.iter().zip(p1.normals.iter()).enumerate() {
let j = p2.support_point(&m12.inverse_transform_vector(&-n1));
let dpt = m12 * p2.vertices[j] - p1;
let separation = dpt.dot(n1);
if separation > max_separation {
max_separation = separation;
separation_features = (i, j);
}
}
(max_separation, separation_features.0, separation_features.1)
}

View File

@@ -11,11 +11,11 @@
// FIXME: deny that
#![allow(missing_docs)]
pub extern crate crossbeam;
#[cfg(feature = "dim2")]
pub extern crate eagl2d as eagl;
pub extern crate cdl2d as cdl;
#[cfg(feature = "dim3")]
pub extern crate eagl3d as eagl;
pub extern crate cdl3d as cdl;
pub extern crate crossbeam;
pub extern crate nalgebra as na;
#[cfg(feature = "serde")]
#[macro_use]
@@ -128,4 +128,4 @@ pub mod dynamics;
pub mod geometry;
pub mod pipeline;
pub mod utils;
pub use eagl::math;
pub use cdl::math;

View File

@@ -5,7 +5,7 @@ use na::{Matrix2, Matrix3, Matrix3x2, Point2, Point3, Scalar, SimdRealField, Vec
use num::Zero;
use simba::simd::SimdValue;
use eagl::utils::SdpMatrix3;
use cdl::utils::SdpMatrix3;
use std::ops::{Add, Mul};
use {
crate::math::{AngularInertia, SimdBool, SimdReal},