diff --git a/.github/Xargo.toml b/.github/Xargo.toml new file mode 100644 index 00000000..919803b5 --- /dev/null +++ b/.github/Xargo.toml @@ -0,0 +1,5 @@ +[target.x86_64-unknown-linux-gnu.dependencies] +alloc = {} + +[target.thumbv7em-none-eabihf.dependencies] +alloc = {} \ No newline at end of file diff --git a/.github/workflows/parry-ci-build.yml b/.github/workflows/parry-ci-build.yml index 309c8b58..4125d356 100644 --- a/.github/workflows/parry-ci-build.yml +++ b/.github/workflows/parry-ci-build.yml @@ -44,3 +44,32 @@ jobs: run: cd build/parry2d && cargo build --verbose --target wasm32-unknown-unknown; - name: build parry3d run: cd build/parry3d && cargo build --verbose --target wasm32-unknown-unknown; + build-no-std: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install latest nightly + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + components: rustfmt + - name: install xargo + run: cp .github/Xargo.toml .; rustup component add rust-src; cargo install -f xargo; + - name: build x86_64-unknown-linux-gnu + run: xargo build --verbose --no-default-features --features required-features --target=x86_64-unknown-linux-gnu; + - name: build thumbv7em-none-eabihf + run: xargo build --verbose --no-default-features --features required-features --target=thumbv7em-none-eabihf; + build-cuda: + runs-on: ubuntu-latest + steps: + - uses: Jimver/cuda-toolkit@v0.2.4 + - name: Install nightly-2021-10-17 + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly-2021-10-17 + override: true + - uses: actions/checkout@v2 + - run: rustup target add nvptx64-nvidia-cuda + - run: cargo build --no-default-features --features required-features,cuda + - run: cargo build --no-default-features --features required-features,cuda --target=nvptx64-nvidia-cuda \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 0c1c71ea..a8abf899 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,11 @@ [workspace] members = ["build/parry2d", "build/parry3d", "build/parry2d-f64", "build/parry3d-f64"] +resolver = "2" [patch.crates-io] parry2d = { path = "build/parry2d" } parry3d = { path = "build/parry3d" } parry2d-f64 = { path = "build/parry2d-f64" } parry3d-f64 = { path = "build/parry3d-f64" } +simba = { git = "https://github.com/dimforge/simba" } +nalgebra = { git = "https://github.com/dimforge/nalgebra", branch = "rust-cuda" } \ No newline at end of file diff --git a/build/parry2d-f64/Cargo.toml b/build/parry2d-f64/Cargo.toml index 909fdced..ce08cfd5 100644 --- a/build/parry2d-f64/Cargo.toml +++ b/build/parry2d-f64/Cargo.toml @@ -17,13 +17,17 @@ edition = "2018" maintenance = { status = "actively-developed" } [features] -default = [ "dim2", "f64" ] +default = [ "required-features", "std" ] +required-features = [ "dim2", "f64" ] +std = [ "nalgebra/std", "slab", "rustc-hash", "simba/std", "arrayvec" ] dim2 = [ ] f64 = [ ] serde-serialize = [ "serde", "nalgebra/serde-serialize", "arrayvec/serde" ] simd-stable = [ "simba/wide", "simd-is-enabled" ] simd-nightly = [ "simba/packed_simd", "simd-is-enabled" ] enhanced-determinism = [ "simba/libm_force", "indexmap" ] +cuda = [ "cust", "nalgebra/cuda" ] + # Do not enable this feature directly. It is automatically # enabled with the "simd-stable" or "simd-nightly" feature. simd-is-enabled = [ ] @@ -31,24 +35,27 @@ simd-is-enabled = [ ] [lib] name = "parry2d_f64" path = "../../src/lib.rs" -required-features = [ "dim2", "f64" ] +required-features = [ "required-features" ] [dependencies] -either = "1" +either = { version = "1", default-features = false } bitflags = "1" -downcast-rs = "1" +downcast-rs = { version = "1", default-features = false } num-traits = { version = "0.2", default-features = false } smallvec = "1" -slab = "0.4" -arrayvec = "0.7" -simba = "0.6" -nalgebra = "0.29" +slab = { version = "0.4", optional = true } +arrayvec = { version = "0.7", optional = true } +simba = { version = "0.6", default-features = false } +nalgebra = { version = "0.29", default-features = false, features = [ "libm" ] } approx = { version = "0.5", default-features = false } serde = { version = "1.0", optional = true, features = ["derive"]} num-derive = "0.3" -indexmap = { version = "1", features = [ "serde-1" ], optional = true } -rustc-hash = "1" +indexmap = { version = "1", features = [ "serde-1" ], optional = true } +rustc-hash = { version = "1", optional = true } + +[target.'cfg(not(target_os = "cuda"))'.dependencies] +cust = { version = "0.1", optional = true } [dev-dependencies] -simba = { version = "0.6", features = [ "partial_fixed_point_support" ] } +simba = { version = "0.6", default-features = false, features = [ "partial_fixed_point_support" ] } oorandom = "11" diff --git a/build/parry2d/Cargo.toml b/build/parry2d/Cargo.toml index 6a1ec45a..c236b916 100644 --- a/build/parry2d/Cargo.toml +++ b/build/parry2d/Cargo.toml @@ -17,13 +17,17 @@ edition = "2018" maintenance = { status = "actively-developed" } [features] -default = [ "dim2", "f32" ] +default = [ "required-features", "std" ] +required-features = [ "dim2", "f32" ] +std = [ "nalgebra/std", "slab", "rustc-hash", "simba/std", "arrayvec" ] dim2 = [ ] f32 = [ ] serde-serialize = [ "serde", "nalgebra/serde-serialize", "arrayvec/serde" ] simd-stable = [ "simba/wide", "simd-is-enabled" ] simd-nightly = [ "simba/packed_simd", "simd-is-enabled" ] enhanced-determinism = [ "simba/libm_force", "indexmap" ] +cuda = [ "cust", "nalgebra/cuda" ] + # Do not enable this feature directly. It is automatically # enabled with the "simd-stable" or "simd-nightly" feature. simd-is-enabled = [ ] @@ -31,24 +35,27 @@ simd-is-enabled = [ ] [lib] name = "parry2d" path = "../../src/lib.rs" -required-features = [ "dim2", "f32" ] +required-features = [ "required-features" ] [dependencies] -either = "1" +either = { version = "1", default-features = false } bitflags = "1" -downcast-rs = "1" +downcast-rs = { version = "1", default-features = false } num-traits = { version = "0.2", default-features = false } smallvec = "1" -slab = "0.4" -arrayvec = "0.7" -simba = "0.6" -nalgebra = "0.29" +slab = { version = "0.4", optional = true } +arrayvec = { version = "0.7", optional = true } +simba = { version = "0.6", default-features = false } +nalgebra = { version = "0.29", default-features = false, features = [ "libm" ] } approx = { version = "0.5", default-features = false } serde = { version = "1.0", optional = true, features = ["derive"]} num-derive = "0.3" indexmap = { version = "1", features = [ "serde-1" ], optional = true } -rustc-hash = "1" +rustc-hash = { version = "1", optional = true } + +[target.'cfg(not(target_os = "cuda"))'.dependencies] +cust = { version = "0.1", optional = true } [dev-dependencies] -simba = { version = "0.6", features = [ "partial_fixed_point_support" ] } +simba = { version = "0.6", default-features = false, features = [ "partial_fixed_point_support" ] } oorandom = "11" diff --git a/build/parry3d-f64/Cargo.toml b/build/parry3d-f64/Cargo.toml index a1453d00..7ccb96b9 100644 --- a/build/parry3d-f64/Cargo.toml +++ b/build/parry3d-f64/Cargo.toml @@ -17,13 +17,17 @@ edition = "2018" maintenance = { status = "actively-developed" } [features] -default = [ "dim3", "f64" ] +default = [ "required-features", "std" ] +required-features = [ "dim3", "f64" ] +std = [ "nalgebra/std", "slab", "rustc-hash", "simba/std" ] dim3 = [ ] f64 = [ ] serde-serialize = [ "serde", "nalgebra/serde-serialize" ] simd-stable = [ "simba/wide", "simd-is-enabled" ] simd-nightly = [ "simba/packed_simd", "simd-is-enabled" ] enhanced-determinism = [ "simba/libm_force", "indexmap" ] +cuda = [ "cust", "nalgebra/cuda" ] + # Do not enable this feature directly. It is automatically # enabled with the "simd-stable" or "simd-nightly" feature. simd-is-enabled = [ ] @@ -31,23 +35,25 @@ simd-is-enabled = [ ] [lib] name = "parry3d_f64" path = "../../src/lib.rs" -required-features = [ "dim3", "f64" ] +required-features = [ "required-features" ] [dependencies] -either = "1" +either = { version = "1", default-features = false } bitflags = "1" -downcast-rs = "1" +downcast-rs = { version = "1", default-features = false } num-traits = { version = "0.2", default-features = false } smallvec = "1" -slab = "0.4" -simba = "0.6" -nalgebra = "0.29" +slab = { version = "0.4", optional = true } +simba = { version = "0.6", default-features = false } +nalgebra = { version = "0.29", default-features = false, features = [ "libm" ] } approx = { version = "0.5", default-features = false } serde = { version = "1.0", optional = true, features = ["derive", "rc"]} -num-derive = "0.3" -indexmap = { version = "1", features = [ "serde-1" ], optional = true } -rustc-hash = "1" +num-derive = "0.3" +indexmap = { version = "1", features = [ "serde-1" ], optional = true } +rustc-hash = { version = "1", optional = true } +[target.'cfg(not(target_os = "cuda"))'.dependencies] +cust = { version = "0.1", optional = true } [dev-dependencies] oorandom = "11" diff --git a/build/parry3d/Cargo.toml b/build/parry3d/Cargo.toml index e212833d..9bfa1f30 100644 --- a/build/parry3d/Cargo.toml +++ b/build/parry3d/Cargo.toml @@ -17,13 +17,17 @@ edition = "2018" maintenance = { status = "actively-developed" } [features] -default = [ "dim3", "f32" ] +default = [ "required-features", "std" ] +required-features = [ "dim3", "f32" ] +std = [ "nalgebra/std", "slab", "rustc-hash", "simba/std" ] dim3 = [ ] f32 = [ ] serde-serialize = [ "serde", "nalgebra/serde-serialize" ] simd-stable = [ "simba/wide", "simd-is-enabled" ] simd-nightly = [ "simba/packed_simd", "simd-is-enabled" ] enhanced-determinism = [ "simba/libm_force", "indexmap" ] +cuda = [ "cust", "nalgebra/cuda" ] + # Do not enable this feature directly. It is automatically # enabled with the "simd-stable" or "simd-nightly" feature. simd-is-enabled = [ ] @@ -31,23 +35,25 @@ simd-is-enabled = [ ] [lib] name = "parry3d" path = "../../src/lib.rs" -required-features = [ "dim3", "f32" ] +required-features = [ "required-features" ] [dependencies] -either = "1" +either = { version = "1", default-features = false } bitflags = "1" -downcast-rs = "1" +downcast-rs = { version = "1", default-features = false } num-traits = { version = "0.2", default-features = false } smallvec = "1" -slab = "0.4" -simba = "0.6" -nalgebra = "0.29" +slab = { version = "0.4", optional = true } +simba = { version = "0.6", default-features = false } +nalgebra = { version = "0.29", default-features = false, features = [ "libm" ] } approx = { version = "0.5", default-features = false } serde = { version = "1.0", optional = true, features = ["derive", "rc"]} -num-derive = "0.3" -indexmap = { version = "1", features = [ "serde-1" ], optional = true } -rustc-hash = "1" +num-derive = "0.3" +indexmap = { version = "1", features = [ "serde-1" ], optional = true } +rustc-hash = { version = "1", optional = true } +[target.'cfg(not(target_os = "cuda"))'.dependencies] +cust = { version = "0.1", optional = true } [dev-dependencies] oorandom = "11" diff --git a/src/bounding_volume/aabb.rs b/src/bounding_volume/aabb.rs index 614ffbfb..d85ccdba 100644 --- a/src/bounding_volume/aabb.rs +++ b/src/bounding_volume/aabb.rs @@ -7,6 +7,9 @@ use crate::utils::IsometryOps; use na; use num::Bounded; +#[cfg(not(feature = "std"))] +use na::ComplexField; // for .abs() + /// An Axis Aligned Bounding Box. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Debug, PartialEq, Copy, Clone)] @@ -270,6 +273,7 @@ impl AABB { } #[cfg(feature = "dim3")] + #[cfg(feature = "std")] pub fn intersects_spiral( &self, point: &Point, diff --git a/src/bounding_volume/mod.rs b/src/bounding_volume/mod.rs index 8386ae01..05dbaac6 100644 --- a/src/bounding_volume/mod.rs +++ b/src/bounding_volume/mod.rs @@ -16,11 +16,14 @@ pub mod bounding_volume; pub mod aabb; mod aabb_ball; #[cfg(feature = "dim2")] +#[cfg(feature = "std")] mod aabb_convex_polygon; #[cfg(feature = "dim3")] +#[cfg(feature = "std")] mod aabb_convex_polyhedron; mod aabb_cuboid; mod aabb_halfspace; +#[cfg(feature = "std")] mod aabb_heightfield; mod aabb_support_map; mod aabb_triangle; @@ -34,17 +37,22 @@ mod bounding_sphere_capsule; #[cfg(feature = "dim3")] mod bounding_sphere_cone; #[cfg(feature = "dim3")] +#[cfg(feature = "std")] mod bounding_sphere_convex; #[cfg(feature = "dim2")] +#[cfg(feature = "std")] mod bounding_sphere_convex_polygon; mod bounding_sphere_cuboid; #[cfg(feature = "dim3")] mod bounding_sphere_cylinder; mod bounding_sphere_halfspace; +#[cfg(feature = "std")] mod bounding_sphere_heightfield; +#[cfg(feature = "std")] mod bounding_sphere_polyline; mod bounding_sphere_segment; mod bounding_sphere_triangle; +#[cfg(feature = "std")] mod bounding_sphere_trimesh; mod bounding_sphere_utils; mod simd_aabb; diff --git a/src/lib.rs b/src/lib.rs index ef1c05d6..124b0115 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,7 @@ the rust programming language. #![warn(unused_imports)] #![allow(missing_copy_implementations)] #![doc(html_root_url = "http://docs.rs/parry/0.1.1")] +#![cfg_attr(not(feature = "std"), no_std)] #[cfg(all( feature = "simd-is-enabled", @@ -46,6 +47,13 @@ macro_rules! array( } ); +#[cfg(all(feature = "alloc", not(feature = "std")))] +#[cfg_attr(test, macro_use)] +extern crate alloc; + +#[cfg(not(feature = "std"))] +extern crate core as std; + #[cfg(feature = "serde")] #[macro_use] extern crate serde; @@ -61,9 +69,11 @@ pub extern crate simba; pub mod bounding_volume; pub mod mass_properties; +#[cfg(feature = "std")] pub mod partitioning; pub mod query; pub mod shape; +#[cfg(feature = "std")] pub mod transformation; pub mod utils; diff --git a/src/mass_properties/mass_properties.rs b/src/mass_properties/mass_properties.rs index 74bc6b26..6808574b 100644 --- a/src/mass_properties/mass_properties.rs +++ b/src/mass_properties/mass_properties.rs @@ -2,7 +2,6 @@ use crate::math::{AngVector, AngularInertia, Isometry, Point, Real, Rotation, Ve use crate::utils; use na::ComplexField; use num::Zero; -use std::iter::Sum; use std::ops::{Add, AddAssign, Sub, SubAssign}; #[cfg(feature = "dim3")] use {na::Matrix3, std::ops::MulAssign}; @@ -350,7 +349,8 @@ impl AddAssign for MassProperties { } } -impl Sum for MassProperties { +#[cfg(feature = "std")] +impl std::iter::Sum for MassProperties { #[cfg(feature = "dim2")] fn sum(iter: I) -> Self where diff --git a/src/mass_properties/mod.rs b/src/mass_properties/mod.rs index 4dd74c55..b58afa4f 100644 --- a/src/mass_properties/mod.rs +++ b/src/mass_properties/mod.rs @@ -5,30 +5,35 @@ pub use self::mass_properties::MassProperties; mod mass_properties; mod mass_properties_ball; mod mass_properties_capsule; +#[cfg(feature = "std")] mod mass_properties_compound; #[cfg(feature = "dim3")] mod mass_properties_cone; -#[cfg(featuer = "dim2")] -mod mass_properties_convex_polygon; #[cfg(feature = "dim2")] +#[cfg(feature = "std")] mod mass_properties_convex_polygon; #[cfg(feature = "dim3")] +#[cfg(feature = "std")] mod mass_properties_convex_polyhedron; mod mass_properties_cuboid; mod mass_properties_cylinder; #[cfg(feature = "dim2")] mod mass_properties_triangle; #[cfg(feature = "dim2")] +#[cfg(feature = "std")] mod mass_properties_trimesh; /// Free functions for some special-cases of mass-properties computation. pub mod details { #[cfg(feature = "dim2")] + #[cfg(feature = "std")] pub use super::mass_properties_convex_polygon::convex_polygon_area_and_center_of_mass; #[cfg(feature = "dim3")] + #[cfg(feature = "std")] pub use super::mass_properties_convex_polyhedron::{ convex_mesh_volume_and_center_of_mass_unchecked, tetrahedron_unit_inertia_tensor_wrt_point, }; #[cfg(feature = "dim2")] + #[cfg(feature = "std")] pub use super::mass_properties_trimesh::trimesh_area_and_center_of_mass; } diff --git a/src/query/clip/mod.rs b/src/query/clip/mod.rs index 26189a1f..3a17f804 100644 --- a/src/query/clip/mod.rs +++ b/src/query/clip/mod.rs @@ -1,10 +1,13 @@ pub use self::clip_aabb_line::clip_aabb_line; +#[cfg(feature = "std")] pub use self::clip_halfspace_polygon::clip_halfspace_polygon; pub use self::clip_segment_segment::clip_segment_segment; #[cfg(feature = "dim2")] pub use self::clip_segment_segment::clip_segment_segment_with_normal; mod clip_aabb_line; +#[cfg(feature = "std")] mod clip_aabb_polygon; +#[cfg(feature = "std")] mod clip_halfspace_polygon; mod clip_segment_segment; diff --git a/src/query/closest_points/mod.rs b/src/query/closest_points/mod.rs index 9204c8f8..43cae0b3 100644 --- a/src/query/closest_points/mod.rs +++ b/src/query/closest_points/mod.rs @@ -5,6 +5,7 @@ pub use self::closest_points_ball_ball::closest_points_ball_ball; pub use self::closest_points_ball_convex_polyhedron::{ closest_points_ball_convex_polyhedron, closest_points_convex_polyhedron_ball, }; +#[cfg(feature = "std")] pub use self::closest_points_composite_shape_shape::{ closest_points_composite_shape_shape, closest_points_shape_composite_shape, CompositeShapeAgainstShapeClosestPointsVisitor, @@ -31,6 +32,7 @@ pub use self::closest_points_support_map_support_map::closest_points_support_map mod closest_points; mod closest_points_ball_ball; mod closest_points_ball_convex_polyhedron; +#[cfg(feature = "std")] mod closest_points_composite_shape_shape; mod closest_points_cuboid_cuboid; mod closest_points_cuboid_triangle; diff --git a/src/query/contact/mod.rs b/src/query/contact/mod.rs index 46d61add..6a6dcd9c 100644 --- a/src/query/contact/mod.rs +++ b/src/query/contact/mod.rs @@ -5,6 +5,7 @@ pub use self::contact_ball_ball::contact_ball_ball; pub use self::contact_ball_convex_polyhedron::{ contact_ball_convex_polyhedron, contact_convex_polyhedron_ball, }; +#[cfg(feature = "std")] pub use self::contact_composite_shape_shape::{ contact_composite_shape_shape, contact_shape_composite_shape, }; @@ -13,14 +14,18 @@ pub use self::contact_halfspace_support_map::{ contact_halfspace_support_map, contact_support_map_halfspace, }; pub use self::contact_shape_shape::contact; -pub use self::contact_support_map_support_map::contact_support_map_support_map; -pub use self::contact_support_map_support_map::contact_support_map_support_map_with_params; +#[cfg(feature = "std")] // TODO: doesn’t work without std because of EPA +pub use self::contact_support_map_support_map::{ + contact_support_map_support_map, contact_support_map_support_map_with_params, +}; mod contact; mod contact_ball_ball; mod contact_ball_convex_polyhedron; +#[cfg(feature = "std")] mod contact_composite_shape_shape; mod contact_cuboid_cuboid; mod contact_halfspace_support_map; mod contact_shape_shape; +#[cfg(feature = "std")] // TODO: doesn’t work without std because of EPA mod contact_support_map_support_map; diff --git a/src/query/contact_manifolds/contact_manifolds_capsule_capsule.rs b/src/query/contact_manifolds/contact_manifolds_capsule_capsule.rs index c5cc5dac..e39464db 100644 --- a/src/query/contact_manifolds/contact_manifolds_capsule_capsule.rs +++ b/src/query/contact_manifolds/contact_manifolds_capsule_capsule.rs @@ -6,6 +6,9 @@ use crate::shape::{Capsule, Shape}; use approx::AbsDiffEq; use na::Unit; +#[cfg(not(feature = "std"))] +use na::ComplexField; // for .abs() + /// Computes the contact manifold between two capsules given as `Shape` trait-objects. pub fn contact_manifold_capsule_capsule_shapes( pos12: &Isometry, diff --git a/src/query/default_query_dispatcher.rs b/src/query/default_query_dispatcher.rs index 7ed5e015..33674d06 100644 --- a/src/query/default_query_dispatcher.rs +++ b/src/query/default_query_dispatcher.rs @@ -1,9 +1,12 @@ use crate::math::{Isometry, Point, Real, Vector}; -use crate::query::contact_manifolds::ContactManifoldsWorkspace; -use crate::query::query_dispatcher::PersistentQueryDispatcher; use crate::query::{ - self, details::NonlinearTOIMode, ClosestPoints, Contact, ContactManifold, NonlinearRigidMotion, - QueryDispatcher, Unsupported, TOI, + self, details::NonlinearTOIMode, ClosestPoints, Contact, NonlinearRigidMotion, QueryDispatcher, + Unsupported, TOI, +}; +#[cfg(feature = "std")] +use crate::query::{ + contact_manifolds::ContactManifoldsWorkspace, query_dispatcher::PersistentQueryDispatcher, + ContactManifold, }; use crate::shape::{HalfSpace, Segment, Shape, ShapeType}; @@ -57,15 +60,18 @@ impl QueryDispatcher for DefaultQueryDispatcher { Ok(query::details::intersection_test_support_map_support_map( pos12, s1, s2, )) - } else if let Some(c1) = shape1.as_composite_shape() { - Ok(query::details::intersection_test_composite_shape_shape( - self, pos12, c1, shape2, - )) - } else if let Some(c2) = shape2.as_composite_shape() { - Ok(query::details::intersection_test_shape_composite_shape( - self, pos12, shape1, c2, - )) } else { + #[cfg(feature = "std")] + if let Some(c1) = shape1.as_composite_shape() { + return Ok(query::details::intersection_test_composite_shape_shape( + self, pos12, c1, shape2, + )); + } else if let Some(c2) = shape2.as_composite_shape() { + return Ok(query::details::intersection_test_shape_composite_shape( + self, pos12, shape1, c2, + )); + } + Err(Unsupported) } } @@ -113,15 +119,18 @@ impl QueryDispatcher for DefaultQueryDispatcher { Ok(query::details::distance_support_map_support_map( pos12, s1, s2, )) - } else if let Some(c1) = shape1.as_composite_shape() { - Ok(query::details::distance_composite_shape_shape( - self, pos12, c1, shape2, - )) - } else if let Some(c2) = shape2.as_composite_shape() { - Ok(query::details::distance_shape_composite_shape( - self, pos12, shape1, c2, - )) } else { + #[cfg(feature = "std")] + if let Some(c1) = shape1.as_composite_shape() { + return Ok(query::details::distance_composite_shape_shape( + self, pos12, c1, shape2, + )); + } else if let Some(c2) = shape2.as_composite_shape() { + return Ok(query::details::distance_shape_composite_shape( + self, pos12, shape1, c2, + )); + } + Err(Unsupported) } } @@ -162,19 +171,22 @@ impl QueryDispatcher for DefaultQueryDispatcher { Ok(query::details::contact_convex_polyhedron_ball( pos12, shape1, b2, prediction, )) - } else if let (Some(s1), Some(s2)) = (shape1.as_support_map(), shape2.as_support_map()) { - Ok(query::details::contact_support_map_support_map( - pos12, s1, s2, prediction, - )) - } else if let Some(c1) = shape1.as_composite_shape() { - Ok(query::details::contact_composite_shape_shape( - self, pos12, c1, shape2, prediction, - )) - } else if let Some(c2) = shape2.as_composite_shape() { - Ok(query::details::contact_shape_composite_shape( - self, pos12, shape1, c2, prediction, - )) } else { + #[cfg(feature = "std")] + if let (Some(s1), Some(s2)) = (shape1.as_support_map(), shape2.as_support_map()) { + return Ok(query::details::contact_support_map_support_map( + pos12, s1, s2, prediction, + )); + } else if let Some(c1) = shape1.as_composite_shape() { + return Ok(query::details::contact_composite_shape_shape( + self, pos12, c1, shape2, prediction, + )); + } else if let Some(c2) = shape2.as_composite_shape() { + return Ok(query::details::contact_shape_composite_shape( + self, pos12, shape1, c2, prediction, + )); + } + Err(Unsupported) } } @@ -239,15 +251,18 @@ impl QueryDispatcher for DefaultQueryDispatcher { Ok(query::details::closest_points_support_map_support_map( &pos12, s1, s2, max_dist, )) - } else if let Some(c1) = shape1.as_composite_shape() { - Ok(query::details::closest_points_composite_shape_shape( - self, &pos12, c1, shape2, max_dist, - )) - } else if let Some(c2) = shape2.as_composite_shape() { - Ok(query::details::closest_points_shape_composite_shape( - self, &pos12, shape1, c2, max_dist, - )) } else { + #[cfg(feature = "std")] + if let Some(c1) = shape1.as_composite_shape() { + return Ok(query::details::closest_points_composite_shape_shape( + self, &pos12, c1, shape2, max_dist, + )); + } else if let Some(c2) = shape2.as_composite_shape() { + return Ok(query::details::closest_points_shape_composite_shape( + self, &pos12, shape1, c2, max_dist, + )); + } + Err(Unsupported) } } @@ -296,25 +311,28 @@ impl QueryDispatcher for DefaultQueryDispatcher { s2, max_toi, )) - } else if let Some(c1) = shape1.as_composite_shape() { - Ok(query::details::time_of_impact_composite_shape_shape( - self, - pos12, - local_vel12, - c1, - shape2, - max_toi, - )) - } else if let Some(c2) = shape2.as_composite_shape() { - Ok(query::details::time_of_impact_shape_composite_shape( - self, - pos12, - local_vel12, - shape1, - c2, - max_toi, - )) } else { + #[cfg(feature = "std")] + if let Some(c1) = shape1.as_composite_shape() { + return Ok(query::details::time_of_impact_composite_shape_shape( + self, + pos12, + local_vel12, + c1, + shape2, + max_toi, + )); + } else if let Some(c2) = shape2.as_composite_shape() { + return Ok(query::details::time_of_impact_shape_composite_shape( + self, + pos12, + local_vel12, + shape1, + c2, + max_toi, + )); + } + Err(Unsupported) } } @@ -341,44 +359,48 @@ impl QueryDispatcher for DefaultQueryDispatcher { self, motion1, sm1, shape1, motion2, sm2, shape2, start_time, end_time, mode, ), ) - } else if let Some(c1) = shape1.as_composite_shape() { - Ok( - query::details::nonlinear_time_of_impact_composite_shape_shape( - self, - motion1, - c1, - motion2, - shape2, - start_time, - end_time, - stop_at_penetration, - ), - ) - } else if let Some(c2) = shape2.as_composite_shape() { - Ok( - query::details::nonlinear_time_of_impact_shape_composite_shape( - self, - motion1, - shape1, - motion2, - c2, - start_time, - end_time, - stop_at_penetration, - ), - ) - /* } else if let (Some(p1), Some(s2)) = (shape1.as_shape::(), shape2.as_support_map()) { - // query::details::nonlinear_time_of_impact_halfspace_support_map(m1, vel1, p1, m2, vel2, s2) - unimplemented!() - } else if let (Some(s1), Some(p2)) = (shape1.as_support_map(), shape2.as_shape::()) { - // query::details::nonlinear_time_of_impact_support_map_halfspace(m1, vel1, s1, m2, vel2, p2) - unimplemented!() */ } else { + #[cfg(feature = "std")] + if let Some(c1) = shape1.as_composite_shape() { + return Ok( + query::details::nonlinear_time_of_impact_composite_shape_shape( + self, + motion1, + c1, + motion2, + shape2, + start_time, + end_time, + stop_at_penetration, + ), + ); + } else if let Some(c2) = shape2.as_composite_shape() { + return Ok( + query::details::nonlinear_time_of_impact_shape_composite_shape( + self, + motion1, + shape1, + motion2, + c2, + start_time, + end_time, + stop_at_penetration, + ), + ); + } + /* } else if let (Some(p1), Some(s2)) = (shape1.as_shape::(), shape2.as_support_map()) { + // query::details::nonlinear_time_of_impact_halfspace_support_map(m1, vel1, p1, m2, vel2, s2) + unimplemented!() + } else if let (Some(s1), Some(p2)) = (shape1.as_support_map(), shape2.as_shape::()) { + // query::details::nonlinear_time_of_impact_support_map_halfspace(m1, vel1, s1, m2, vel2, p2) + unimplemented!() */ + Err(Unsupported) } } } +#[cfg(feature = "std")] impl PersistentQueryDispatcher for DefaultQueryDispatcher where diff --git a/src/query/distance/mod.rs b/src/query/distance/mod.rs index 4bcbf360..9d243bea 100644 --- a/src/query/distance/mod.rs +++ b/src/query/distance/mod.rs @@ -5,6 +5,7 @@ pub use self::distance_ball_ball::distance_ball_ball; pub use self::distance_ball_convex_polyhedron::{ distance_ball_convex_polyhedron, distance_convex_polyhedron_ball, }; +#[cfg(feature = "std")] pub use self::distance_composite_shape_shape::{ distance_composite_shape_shape, distance_shape_composite_shape, CompositeShapeAgainstAnyDistanceVisitor, @@ -21,6 +22,7 @@ pub use self::distance_support_map_support_map::{ mod distance; mod distance_ball_ball; mod distance_ball_convex_polyhedron; +#[cfg(feature = "std")] mod distance_composite_shape_shape; mod distance_cuboid_cuboid; mod distance_halfspace_support_map; diff --git a/src/query/error.rs b/src/query/error.rs index 62da6eb5..8c8e7582 100644 --- a/src/query/error.rs +++ b/src/query/error.rs @@ -10,4 +10,5 @@ impl fmt::Display for Unsupported { } } +#[cfg(feature = "std")] impl std::error::Error for Unsupported {} diff --git a/src/query/gjk/voronoi_simplex3.rs b/src/query/gjk/voronoi_simplex3.rs index 40fa1d1b..4bf11c02 100644 --- a/src/query/gjk/voronoi_simplex3.rs +++ b/src/query/gjk/voronoi_simplex3.rs @@ -6,6 +6,9 @@ use crate::shape::{ TrianglePointLocation, }; +#[cfg(not(feature = "std"))] +use na::ComplexField; // for .abs() + /// A simplex of dimension up to 3 that uses Voronoï regions for computing point projections. #[derive(Clone, Debug)] pub struct VoronoiSimplex { diff --git a/src/query/intersection_test/mod.rs b/src/query/intersection_test/mod.rs index 152af9b8..610da44d 100644 --- a/src/query/intersection_test/mod.rs +++ b/src/query/intersection_test/mod.rs @@ -5,6 +5,7 @@ pub use self::intersection_test_ball_ball::intersection_test_ball_ball; pub use self::intersection_test_ball_point_query::{ intersection_test_ball_point_query, intersection_test_point_query_ball, }; +#[cfg(feature = "std")] pub use self::intersection_test_composite_shape_shape::{ intersection_test_composite_shape_shape, intersection_test_shape_composite_shape, IntersectionCompositeShapeShapeBestFirstVisitor, @@ -27,6 +28,7 @@ pub use self::intersection_test_support_map_support_map::intersection_test_suppo mod intersection_test; mod intersection_test_ball_ball; mod intersection_test_ball_point_query; +#[cfg(feature = "std")] mod intersection_test_composite_shape_shape; mod intersection_test_cuboid_cuboid; mod intersection_test_cuboid_segment; diff --git a/src/query/mod.rs b/src/query/mod.rs index ae0a7871..cb3915ef 100644 --- a/src/query/mod.rs +++ b/src/query/mod.rs @@ -27,6 +27,7 @@ pub use self::closest_points::{closest_points, ClosestPoints}; pub use self::contact::{contact, Contact}; +#[cfg(feature = "std")] pub use self::contact_manifolds::{ ContactManifold, ContactManifoldsWorkspace, TrackedContact, TypedWorkspaceData, WorkspaceData, }; @@ -36,18 +37,20 @@ pub use self::error::Unsupported; pub use self::intersection_test::intersection_test; pub use self::nonlinear_time_of_impact::{nonlinear_time_of_impact, NonlinearRigidMotion}; pub use self::point::{PointProjection, PointQuery, PointQueryWithLocation}; -pub use self::query_dispatcher::{ - PersistentQueryDispatcher, QueryDispatcher, QueryDispatcherChain, -}; +#[cfg(feature = "std")] +pub use self::query_dispatcher::PersistentQueryDispatcher; +pub use self::query_dispatcher::{QueryDispatcher, QueryDispatcherChain}; pub use self::ray::{Ray, RayCast, RayIntersection, SimdRay}; pub use self::time_of_impact::{time_of_impact, TOIStatus, TOI}; mod clip; pub mod closest_points; pub mod contact; +#[cfg(feature = "std")] mod contact_manifolds; mod default_query_dispatcher; mod distance; +#[cfg(feature = "std")] pub mod epa; mod error; pub mod gjk; @@ -58,61 +61,20 @@ mod query_dispatcher; mod ray; pub mod sat; mod time_of_impact; +#[cfg(feature = "std")] pub mod visitors; /// Queries dedicated to specific pairs of shapes. pub mod details { pub use super::clip::*; pub use super::closest_points::*; - pub use super::contact::{ - contact_ball_ball, contact_ball_convex_polyhedron, contact_composite_shape_shape, - contact_convex_polyhedron_ball, contact_cuboid_cuboid, contact_halfspace_support_map, - contact_shape_composite_shape, contact_support_map_halfspace, - contact_support_map_support_map, contact_support_map_support_map_with_params, - }; - pub use super::contact_manifolds::{ - contact_manifold_ball_ball, contact_manifold_ball_ball_shapes, - contact_manifold_capsule_capsule, contact_manifold_capsule_capsule_shapes, - contact_manifold_convex_ball, contact_manifold_convex_ball_shapes, - contact_manifold_cuboid_cuboid, contact_manifold_cuboid_cuboid_shapes, - contact_manifold_cuboid_triangle, contact_manifold_cuboid_triangle_shapes, - contact_manifold_halfspace_pfm, contact_manifold_halfspace_pfm_shapes, - contact_manifold_pfm_pfm, contact_manifold_pfm_pfm_shapes, - contact_manifolds_heightfield_shape, contact_manifolds_heightfield_shape_shapes, - contact_manifolds_trimesh_shape_shapes, - }; - - pub use super::distance::{ - distance_ball_ball, distance_ball_convex_polyhedron, distance_composite_shape_shape, - distance_convex_polyhedron_ball, distance_cuboid_cuboid, distance_halfspace_support_map, - distance_segment_segment, distance_shape_composite_shape, distance_support_map_halfspace, - distance_support_map_support_map, distance_support_map_support_map_with_params, - CompositeShapeAgainstAnyDistanceVisitor, - }; + pub use super::contact::*; + #[cfg(feature = "std")] + pub use super::contact_manifolds::*; + pub use super::distance::*; pub use super::intersection_test::*; - pub use super::nonlinear_time_of_impact::{ - nonlinear_time_of_impact_composite_shape_shape, - nonlinear_time_of_impact_shape_composite_shape, - nonlinear_time_of_impact_support_map_support_map, - NonlinearTOICompositeShapeShapeBestFirstVisitor, NonlinearTOIMode, - }; - pub use super::point::local_point_projection_on_support_map; - pub use super::point::{ - PointCompositeShapeProjBestFirstVisitor, - PointCompositeShapeProjWithFeatureBestFirstVisitor, - PointCompositeShapeProjWithLocationBestFirstVisitor, - }; - #[cfg(feature = "dim3")] - pub use super::ray::local_ray_intersection_with_triangle; - pub use super::ray::{ - line_toi_with_halfspace, local_ray_intersection_with_support_map_with_params, - ray_toi_with_ball, ray_toi_with_halfspace, RayCompositeShapeToiAndNormalBestFirstVisitor, - RayCompositeShapeToiBestFirstVisitor, - }; - pub use super::time_of_impact::{ - time_of_impact_ball_ball, time_of_impact_composite_shape_shape, - time_of_impact_halfspace_support_map, time_of_impact_shape_composite_shape, - time_of_impact_support_map_halfspace, time_of_impact_support_map_support_map, - TOICompositeShapeShapeBestFirstVisitor, - }; + pub use super::nonlinear_time_of_impact::*; + pub use super::point::*; + pub use super::ray::*; + pub use super::time_of_impact::*; } diff --git a/src/query/nonlinear_time_of_impact/mod.rs b/src/query/nonlinear_time_of_impact/mod.rs index b91b37ed..03e1937f 100644 --- a/src/query/nonlinear_time_of_impact/mod.rs +++ b/src/query/nonlinear_time_of_impact/mod.rs @@ -1,5 +1,6 @@ //! Implementation details of the `nonlinear_time_of_impact` function. +#[cfg(feature = "std")] pub use self::nonlinear_time_of_impact_composite_shape_shape::{ nonlinear_time_of_impact_composite_shape_shape, nonlinear_time_of_impact_shape_composite_shape, NonlinearTOICompositeShapeShapeBestFirstVisitor, @@ -11,6 +12,7 @@ pub use self::nonlinear_time_of_impact_support_map_support_map::{ nonlinear_time_of_impact_support_map_support_map, NonlinearTOIMode, }; +#[cfg(feature = "std")] mod nonlinear_time_of_impact_composite_shape_shape; //mod nonlinear_time_of_impact_halfspace_support_map; mod nonlinear_rigid_motion; diff --git a/src/query/nonlinear_time_of_impact/nonlinear_time_of_impact_support_map_support_map.rs b/src/query/nonlinear_time_of_impact/nonlinear_time_of_impact_support_map_support_map.rs index ffa2ce41..3d55f4c8 100644 --- a/src/query/nonlinear_time_of_impact/nonlinear_time_of_impact_support_map_support_map.rs +++ b/src/query/nonlinear_time_of_impact/nonlinear_time_of_impact_support_map_support_map.rs @@ -1,3 +1,5 @@ +#[cfg(not(feature = "std"))] +use na::ComplexField; // for .abs() use na::{RealField, Unit}; use crate::math::{Point, Real, Vector}; @@ -124,7 +126,7 @@ where // TODO: use the _with_params version of the closest points query. match dispatcher - .closest_points(&pos12, g1, g2, Real::max_value()) + .closest_points(&pos12, g1, g2, Bounded::max_value()) .ok()? { ClosestPoints::Intersecting => { diff --git a/src/query/point/mod.rs b/src/query/point/mod.rs index a7aa422f..2e3e3067 100644 --- a/src/query/point/mod.rs +++ b/src/query/point/mod.rs @@ -1,17 +1,20 @@ //! Point inclusion and projection. +#[cfg(feature = "std")] pub use self::point_composite_shape::{ PointCompositeShapeProjBestFirstVisitor, PointCompositeShapeProjWithFeatureBestFirstVisitor, PointCompositeShapeProjWithLocationBestFirstVisitor, }; #[doc(inline)] pub use self::point_query::{PointProjection, PointQuery, PointQueryWithLocation}; +#[cfg(feature = "std")] // TODO: can’t be used without std because of EPA pub use self::point_support_map::local_point_projection_on_support_map; mod point_aabb; mod point_ball; mod point_bounding_sphere; mod point_capsule; +#[cfg(feature = "std")] mod point_composite_shape; #[cfg(feature = "dim3")] mod point_cone; @@ -19,11 +22,13 @@ mod point_cuboid; #[cfg(feature = "dim3")] mod point_cylinder; mod point_halfspace; +#[cfg(feature = "std")] mod point_heightfield; #[doc(hidden)] pub mod point_query; mod point_round_shape; mod point_segment; +#[cfg(feature = "std")] mod point_support_map; #[cfg(feature = "dim3")] mod point_tetrahedron; diff --git a/src/query/point/point_round_shape.rs b/src/query/point/point_round_shape.rs index 10a9f245..3d0be151 100644 --- a/src/query/point/point_round_shape.rs +++ b/src/query/point/point_round_shape.rs @@ -8,12 +8,18 @@ use crate::shape::{FeatureId, RoundShape, SupportMap}; impl PointQuery for RoundShape { #[inline] fn project_local_point(&self, point: &Point, solid: bool) -> PointProjection { - crate::query::details::local_point_projection_on_support_map( + #[cfg(not(feature = "std"))] // FIXME: can’t be used without std because of EPA + return unimplemented!( + "The projection of points on a round shapes isn’t supported on no-std platforms yet." + ); + + #[cfg(feature = "std")] // FIXME: can’t be used without std because of EPA + return crate::query::details::local_point_projection_on_support_map( self, &mut VoronoiSimplex::new(), point, solid, - ) + ); } #[inline] diff --git a/src/query/point/point_support_map.rs b/src/query/point/point_support_map.rs index 0f79109c..78e2a181 100644 --- a/src/query/point/point_support_map.rs +++ b/src/query/point/point_support_map.rs @@ -1,12 +1,15 @@ use na::Unit; use crate::math::{Isometry, Point, Real, Vector}; +#[cfg(feature = "std")] use crate::query::epa::EPA; use crate::query::gjk::{self, CSOPoint, ConstantOrigin, VoronoiSimplex}; use crate::query::{PointProjection, PointQuery}; #[cfg(feature = "dim2")] +#[cfg(feature = "std")] use crate::shape::ConvexPolygon; #[cfg(feature = "dim3")] +#[cfg(feature = "std")] use crate::shape::ConvexPolyhedron; use crate::shape::{FeatureId, SupportMap}; diff --git a/src/query/query_dispatcher.rs b/src/query/query_dispatcher.rs index af4b8454..c98917bd 100644 --- a/src/query/query_dispatcher.rs +++ b/src/query/query_dispatcher.rs @@ -1,10 +1,10 @@ use crate::math::{Isometry, Real, Vector}; -use crate::query::contact_manifolds::ContactManifoldsWorkspace; -use crate::query::{ - ClosestPoints, Contact, ContactManifold, NonlinearRigidMotion, Unsupported, TOI, -}; +#[cfg(feature = "std")] +use crate::query::{contact_manifolds::ContactManifoldsWorkspace, ContactManifold}; +use crate::query::{ClosestPoints, Contact, NonlinearRigidMotion, Unsupported, TOI}; use crate::shape::Shape; +#[cfg(feature = "std")] /// A query dispatcher for queries relying on spatial coherence, including contact-manifold computation. pub trait PersistentQueryDispatcher: QueryDispatcher { /// Compute all the contacts between two shapes. @@ -200,6 +200,7 @@ where ) -> Option); } +#[cfg(feature = "std")] impl PersistentQueryDispatcher for QueryDispatcherChain where diff --git a/src/query/ray/mod.rs b/src/query/ray/mod.rs index f3ec957b..71c90f7b 100644 --- a/src/query/ray/mod.rs +++ b/src/query/ray/mod.rs @@ -3,6 +3,7 @@ #[doc(inline)] pub use self::ray::{Ray, RayCast, RayIntersection}; pub use self::ray_ball::ray_toi_with_ball; +#[cfg(feature = "std")] pub use self::ray_composite_shape::{ RayCompositeShapeToiAndNormalBestFirstVisitor, RayCompositeShapeToiBestFirstVisitor, }; @@ -17,9 +18,11 @@ pub mod ray; mod ray_aabb; mod ray_ball; mod ray_bounding_sphere; +#[cfg(feature = "std")] mod ray_composite_shape; mod ray_cuboid; mod ray_halfspace; +#[cfg(feature = "std")] mod ray_heightfield; mod ray_round_shape; mod ray_support_map; diff --git a/src/query/ray/ray.rs b/src/query/ray/ray.rs index a01c9eca..9609523d 100644 --- a/src/query/ray/ray.rs +++ b/src/query/ray/ray.rs @@ -5,6 +5,12 @@ use crate::shape::FeatureId; /// A Ray. #[derive(Debug, Clone, Copy)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] +#[repr(C)] pub struct Ray { /// Starting point of the ray. pub origin: Point, diff --git a/src/query/ray/ray_support_map.rs b/src/query/ray/ray_support_map.rs index 4a14fc11..bc25e907 100644 --- a/src/query/ray/ray_support_map.rs +++ b/src/query/ray/ray_support_map.rs @@ -1,15 +1,20 @@ use na; +#[cfg(not(feature = "std"))] +use na::ComplexField; // for .abs() use crate::math::Real; #[cfg(feature = "dim2")] use crate::query; use crate::query::gjk::{self, CSOPoint, VoronoiSimplex}; use crate::query::{Ray, RayCast, RayIntersection}; -#[cfg(feature = "dim2")] +#[cfg(all(feature = "std", feature = "dim2"))] use crate::shape::ConvexPolygon; +#[cfg(all(feature = "std", feature = "dim3"))] +use crate::shape::ConvexPolyhedron; use crate::shape::{Capsule, FeatureId, Segment, SupportMap}; #[cfg(feature = "dim3")] -use crate::shape::{Cone, ConvexPolyhedron, Cylinder}; +use crate::shape::{Cone, Cylinder}; + use num::Zero; /// Cast a ray on a shape using the GJK algorithm. @@ -114,6 +119,7 @@ impl RayCast for Capsule { } #[cfg(feature = "dim3")] +#[cfg(feature = "std")] impl RayCast for ConvexPolyhedron { fn cast_local_ray_and_get_normal( &self, @@ -132,6 +138,7 @@ impl RayCast for ConvexPolyhedron { } #[cfg(feature = "dim2")] +#[cfg(feature = "std")] impl RayCast for ConvexPolygon { fn cast_local_ray_and_get_normal( &self, diff --git a/src/query/ray/ray_triangle.rs b/src/query/ray/ray_triangle.rs index 385cf4fe..827a9137 100644 --- a/src/query/ray/ray_triangle.rs +++ b/src/query/ray/ray_triangle.rs @@ -6,6 +6,9 @@ use crate::shape::{FeatureId, Triangle}; #[cfg(feature = "dim3")] use {crate::math::Point, na::Vector3}; +#[cfg(not(feature = "std"))] +use na::ComplexField; // for .abs() + impl RayCast for Triangle { #[inline] #[cfg(feature = "dim2")] diff --git a/src/query/sat/sat_cuboid_cuboid.rs b/src/query/sat/sat_cuboid_cuboid.rs index c8caf6f9..fc28b0f1 100644 --- a/src/query/sat/sat_cuboid_cuboid.rs +++ b/src/query/sat/sat_cuboid_cuboid.rs @@ -1,5 +1,7 @@ use crate::math::{Isometry, Real, Vector, DIM}; use crate::shape::{Cuboid, SupportMap}; +#[cfg(not(feature = "std"))] +use na::RealField; // For .copysign() /// Computes the separation of two cuboids along `axis1`. #[cfg(feature = "dim3")] diff --git a/src/query/sat/sat_cuboid_triangle.rs b/src/query/sat/sat_cuboid_triangle.rs index 1960f530..48ce10a9 100644 --- a/src/query/sat/sat_cuboid_triangle.rs +++ b/src/query/sat/sat_cuboid_triangle.rs @@ -6,6 +6,7 @@ use crate::query::sat; #[cfg(feature = "dim2")] use crate::query::sat::support_map_support_map_compute_separation; use crate::shape::{Cuboid, SupportMap, Triangle}; +use na::ComplexField; /// Finds the best separating edge between a cuboid and a triangle. /// @@ -65,7 +66,7 @@ pub fn cuboid_triangle_find_local_separating_edge_twoway( let axis_norm_squared = axis.norm_squared(); if axis_norm_squared > Real::default_epsilon() { - let axis_norm = axis_norm_squared.sqrt(); + let axis_norm = ComplexField::sqrt(axis_norm_squared); // NOTE: for both axis and -axis, the dot1 will have the same // value because of the cuboid's symmetry. diff --git a/src/query/time_of_impact/mod.rs b/src/query/time_of_impact/mod.rs index cbed231f..0e96fba5 100644 --- a/src/query/time_of_impact/mod.rs +++ b/src/query/time_of_impact/mod.rs @@ -2,6 +2,7 @@ pub use self::time_of_impact::{time_of_impact, TOIStatus, TOI}; pub use self::time_of_impact_ball_ball::time_of_impact_ball_ball; +#[cfg(feature = "std")] pub use self::time_of_impact_composite_shape_shape::{ time_of_impact_composite_shape_shape, time_of_impact_shape_composite_shape, TOICompositeShapeShapeBestFirstVisitor, @@ -13,6 +14,7 @@ pub use self::time_of_impact_support_map_support_map::time_of_impact_support_map mod time_of_impact; mod time_of_impact_ball_ball; +#[cfg(feature = "std")] mod time_of_impact_composite_shape_shape; mod time_of_impact_halfspace_support_map; mod time_of_impact_support_map_support_map; diff --git a/src/shape/ball.rs b/src/shape/ball.rs index 63790543..99b76e9b 100644 --- a/src/shape/ball.rs +++ b/src/shape/ball.rs @@ -5,7 +5,12 @@ use crate::shape::SupportMap; /// A Ball shape. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] #[derive(PartialEq, Debug, Copy, Clone)] +#[repr(C)] pub struct Ball { /// The radius of the ball. pub radius: Real, diff --git a/src/shape/capsule.rs b/src/shape/capsule.rs index c190e94a..d6bde620 100644 --- a/src/shape/capsule.rs +++ b/src/shape/capsule.rs @@ -4,6 +4,11 @@ use na::Unit; #[derive(Copy, Clone, Debug)] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] +#[repr(C)] /// A capsule shape defined as a round segment. pub struct Capsule { /// The axis and endpoint of the capsule. diff --git a/src/shape/cone.rs b/src/shape/cone.rs index 91a61f64..c55f8f10 100644 --- a/src/shape/cone.rs +++ b/src/shape/cone.rs @@ -5,9 +5,17 @@ use crate::shape::SupportMap; use na; use num::Zero; +#[cfg(not(feature = "std"))] +use na::RealField; // for .copysign() + /// Cone shape with its principal axis aligned with the `y` axis. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] #[derive(PartialEq, Debug, Copy, Clone)] +#[repr(C)] pub struct Cone { /// The half-height of the cone. pub half_height: Real, diff --git a/src/shape/convex_polyhedron.rs b/src/shape/convex_polyhedron.rs index 3b8114df..f4bd6b5f 100644 --- a/src/shape/convex_polyhedron.rs +++ b/src/shape/convex_polyhedron.rs @@ -6,6 +6,9 @@ use crate::utils::{self, SortedPair}; use na::{self, ComplexField, Point2, Unit}; use std::f64; +#[cfg(not(feature = "std"))] +use na::ComplexField; // for .abs() + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(PartialEq, Debug, Copy, Clone)] pub struct Vertex { diff --git a/src/shape/cuboid.rs b/src/shape/cuboid.rs index 88b4d55e..2b60398b 100644 --- a/src/shape/cuboid.rs +++ b/src/shape/cuboid.rs @@ -7,9 +7,17 @@ use crate::shape::{FeatureId, PolygonalFeature, SupportMap}; use crate::utils::WSign; use na::Unit; +#[cfg(not(feature = "std"))] +use na::RealField; // for .copysign() + /// Shape of a box. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] #[derive(PartialEq, Debug, Copy, Clone)] +#[repr(C)] pub struct Cuboid { /// The half-extents of the cuboid. pub half_extents: Vector, diff --git a/src/shape/cylinder.rs b/src/shape/cylinder.rs index 0ad8a41f..28f43592 100644 --- a/src/shape/cylinder.rs +++ b/src/shape/cylinder.rs @@ -5,9 +5,17 @@ use crate::shape::SupportMap; use na; use num::Zero; +#[cfg(not(feature = "std"))] +use na::RealField; // for .copysign() + /// Cylinder shape with its principal axis aligned with the `y` axis. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] #[derive(PartialEq, Debug, Copy, Clone)] +#[repr(C)] pub struct Cylinder { /// The half-height of the cylinder. pub half_height: Real, diff --git a/src/shape/half_space.rs b/src/shape/half_space.rs index 29b85acf..40f3425b 100644 --- a/src/shape/half_space.rs +++ b/src/shape/half_space.rs @@ -3,8 +3,13 @@ use crate::math::{Real, Vector}; use na::Unit; /// A half-space delimited by an infinite plane. -#[derive(PartialEq, Debug, Clone)] +#[derive(PartialEq, Debug, Clone, Copy)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] +#[repr(C)] pub struct HalfSpace { /// The halfspace planar boundary outward normal. pub normal: Unit>, diff --git a/src/shape/heightfield2.rs b/src/shape/heightfield2.rs index cfec4bdc..265bc277 100644 --- a/src/shape/heightfield2.rs +++ b/src/shape/heightfield2.rs @@ -26,7 +26,7 @@ impl HeightField { let max = heights.max(); let min = heights.min(); - let hscale = scale * na::convert::<_, Real>(0.5); + let hscale = scale * 0.5; let aabb = AABB::new( Point2::new(-hscale.x, min * scale.y), Point2::new(hscale.x, max * scale.y), diff --git a/src/shape/mod.rs b/src/shape/mod.rs index 7c57566c..69b4aebb 100644 --- a/src/shape/mod.rs +++ b/src/shape/mod.rs @@ -3,12 +3,15 @@ pub use self::ball::Ball; pub use self::capsule::Capsule; #[doc(inline)] +#[cfg(feature = "std")] pub use self::composite_shape::{SimdCompositeShape, TypedSimdCompositeShape}; +#[cfg(feature = "std")] pub use self::compound::Compound; pub use self::cuboid::Cuboid; pub use self::feature_id::FeatureId; pub use self::half_space::HalfSpace; pub use self::polygonal_feature_map::PolygonalFeatureMap; +#[cfg(feature = "std")] pub use self::polyline::Polyline; pub use self::round_shape::RoundShape; pub use self::segment::{Segment, SegmentPointLocation}; @@ -16,14 +19,17 @@ pub use self::segment::{Segment, SegmentPointLocation}; pub(crate) use self::shape::DeserializableTypedShape; #[doc(inline)] pub use self::shape::{Shape, ShapeType, TypedShape}; +#[cfg(feature = "std")] pub use self::shared_shape::SharedShape; #[doc(inline)] pub use self::support_map::SupportMap; pub use self::triangle::{Triangle, TrianglePointLocation}; #[cfg(feature = "dim2")] +#[cfg(feature = "std")] pub use self::convex_polygon::ConvexPolygon; #[cfg(feature = "dim2")] +#[cfg(feature = "std")] pub use self::heightfield2::HeightField; #[cfg(feature = "dim2")] pub use self::polygonal_feature2d::PolygonalFeature; @@ -31,15 +37,18 @@ pub use self::polygonal_feature2d::PolygonalFeature; #[cfg(feature = "dim3")] pub use self::cone::Cone; #[cfg(feature = "dim3")] +#[cfg(feature = "std")] pub use self::convex_polyhedron::ConvexPolyhedron; #[cfg(feature = "dim3")] pub use self::cylinder::Cylinder; #[cfg(feature = "dim3")] +#[cfg(feature = "std")] pub use self::heightfield3::{HeightField, HeightFieldCellStatus}; #[cfg(feature = "dim3")] pub use self::polygonal_feature3d::PolygonalFeature; #[cfg(feature = "dim3")] pub use self::tetrahedron::{Tetrahedron, TetrahedronPointLocation}; +#[cfg(feature = "std")] pub use self::trimesh::TriMesh; /// A cylinder dilated by a sphere (so it has round corners). @@ -54,18 +63,23 @@ pub type RoundCuboid = RoundShape; pub type RoundTriangle = RoundShape; /// A convex polyhedron dilated by a sphere (so it has round corners). #[cfg(feature = "dim3")] +#[cfg(feature = "std")] pub type RoundConvexPolyhedron = RoundShape; /// A convex polygon dilated by a sphere (so it has round corners). #[cfg(feature = "dim2")] +#[cfg(feature = "std")] pub type RoundConvexPolygon = RoundShape; mod ball; mod capsule; #[doc(hidden)] +#[cfg(feature = "std")] pub mod composite_shape; +#[cfg(feature = "std")] mod compound; mod cuboid; mod half_space; +#[cfg(feature = "std")] mod polyline; mod round_shape; mod segment; @@ -76,26 +90,32 @@ pub mod support_map; mod triangle; #[cfg(feature = "dim2")] +#[cfg(feature = "std")] mod convex_polygon; #[cfg(feature = "dim2")] +#[cfg(feature = "std")] mod heightfield2; #[cfg(feature = "dim3")] mod cone; #[cfg(feature = "dim3")] +#[cfg(feature = "std")] mod convex_polyhedron; #[cfg(feature = "dim3")] mod cylinder; #[cfg(feature = "dim3")] +#[cfg(feature = "std")] mod heightfield3; #[cfg(feature = "dim3")] mod polygonal_feature3d; mod polygonal_feature_map; #[cfg(feature = "dim3")] mod tetrahedron; +#[cfg(feature = "std")] mod trimesh; // TODO: move this elsewhere? mod feature_id; #[cfg(feature = "dim2")] mod polygonal_feature2d; +#[cfg(feature = "std")] mod shared_shape; diff --git a/src/shape/polygonal_feature2d.rs b/src/shape/polygonal_feature2d.rs index e0f04a75..bb83ad35 100644 --- a/src/shape/polygonal_feature2d.rs +++ b/src/shape/polygonal_feature2d.rs @@ -1,4 +1,5 @@ use crate::math::{Isometry, Point, Real, Vector}; +#[cfg(feature = "std")] use crate::query::{self, ContactManifold, TrackedContact}; use crate::shape::Segment; @@ -46,6 +47,7 @@ impl PolygonalFeature { } /// Computes the contacts between two polygonal features. + #[cfg(feature = "std")] pub fn contacts( pos12: &Isometry, pos21: &Isometry, @@ -74,6 +76,7 @@ impl PolygonalFeature { /// Compute contacts points between a face and a vertex. /// /// This method assume we already know that at least one contact exists. + #[cfg(feature = "std")] pub fn face_vertex_contacts( pos12: &Isometry, face1: &Self, @@ -104,6 +107,7 @@ impl PolygonalFeature { } /// Computes the contacts between two polygonal faces. + #[cfg(feature = "std")] pub fn face_face_contacts( pos12: &Isometry, face1: &Self, diff --git a/src/shape/polygonal_feature3d.rs b/src/shape/polygonal_feature3d.rs index 1e6e6f9d..15c47314 100644 --- a/src/shape/polygonal_feature3d.rs +++ b/src/shape/polygonal_feature3d.rs @@ -1,5 +1,6 @@ use crate::approx::AbsDiffEq; use crate::math::{Isometry, Point, Real, Vector}; +#[cfg(feature = "std")] use crate::query::{ContactManifold, TrackedContact}; use crate::shape::{Segment, Triangle}; use crate::utils::WBasis; @@ -79,6 +80,7 @@ impl PolygonalFeature { } /// Computes all the contacts between two polygonal features. + #[cfg(feature = "std")] pub fn contacts( pos12: &Isometry, _pos21: &Isometry, @@ -100,6 +102,7 @@ impl PolygonalFeature { } } + #[cfg(feature = "std")] fn contacts_edge_edge( pos12: &Isometry, face1: &PolygonalFeature, @@ -208,6 +211,7 @@ impl PolygonalFeature { } } + #[cfg(feature = "std")] fn contacts_face_face( pos12: &Isometry, face1: &PolygonalFeature, diff --git a/src/shape/polygonal_feature_map.rs b/src/shape/polygonal_feature_map.rs index 80d18ece..a251823d 100644 --- a/src/shape/polygonal_feature_map.rs +++ b/src/shape/polygonal_feature_map.rs @@ -10,6 +10,9 @@ use { approx::AbsDiffEq, }; +#[cfg(not(feature = "std"))] +use na::{ComplexField, RealField}; // for .abs() and .copysign() + /// Trait implemented by convex shapes with features with polyhedral approximations. pub trait PolygonalFeatureMap: SupportMap { /// Compute the support polygonal face of `self` towards the `dir`. diff --git a/src/shape/polyline.rs b/src/shape/polyline.rs index 2b440b31..122cf59d 100644 --- a/src/shape/polyline.rs +++ b/src/shape/polyline.rs @@ -5,6 +5,9 @@ use crate::query::{PointProjection, PointQueryWithLocation}; use crate::shape::composite_shape::SimdCompositeShape; use crate::shape::{FeatureId, Segment, SegmentPointLocation, Shape, TypedSimdCompositeShape}; +#[cfg(not(feature = "std"))] +use na::ComplexField; // for .abs() + #[derive(Clone)] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] /// A polyline. diff --git a/src/shape/round_shape.rs b/src/shape/round_shape.rs index 3a18837a..8f49b8ae 100644 --- a/src/shape/round_shape.rs +++ b/src/shape/round_shape.rs @@ -3,7 +3,12 @@ use crate::shape::SupportMap; use na::Unit; #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] #[derive(Copy, Clone, Debug)] +#[repr(C)] /// A shape with rounded borders. pub struct RoundShape { /// The shape being rounded. diff --git a/src/shape/segment.rs b/src/shape/segment.rs index ca50c4ae..37f2fff6 100644 --- a/src/shape/segment.rs +++ b/src/shape/segment.rs @@ -8,8 +8,12 @@ use std::mem; /// A segment shape. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[repr(C)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] #[derive(PartialEq, Debug, Copy, Clone)] +#[repr(C)] pub struct Segment { /// The segment first point. pub a: Point, diff --git a/src/shape/shape.rs b/src/shape/shape.rs index 6467778c..75821e08 100644 --- a/src/shape/shape.rs +++ b/src/shape/shape.rs @@ -2,18 +2,23 @@ use crate::bounding_volume::{BoundingSphere, BoundingVolume, AABB}; use crate::mass_properties::MassProperties; use crate::math::{Isometry, Point, Real, Vector}; use crate::query::{PointQuery, RayCast}; -use crate::shape::composite_shape::SimdCompositeShape; #[cfg(feature = "serde-serialize")] use crate::shape::SharedShape; +#[cfg(feature = "std")] +use crate::shape::{composite_shape::SimdCompositeShape, Compound, HeightField, Polyline, TriMesh}; use crate::shape::{ - Ball, Capsule, Compound, Cuboid, FeatureId, HalfSpace, HeightField, PolygonalFeatureMap, - Polyline, RoundCuboid, RoundShape, RoundTriangle, Segment, SupportMap, TriMesh, Triangle, + Ball, Capsule, Cuboid, FeatureId, HalfSpace, PolygonalFeatureMap, RoundCuboid, RoundShape, + RoundTriangle, Segment, SupportMap, Triangle, }; #[cfg(feature = "dim3")] -use crate::shape::{ - Cone, ConvexPolyhedron, Cylinder, RoundCone, RoundConvexPolyhedron, RoundCylinder, -}; +use crate::shape::{Cone, Cylinder, RoundCone, RoundCylinder}; + +#[cfg(feature = "dim3")] +#[cfg(feature = "std")] +use crate::shape::{ConvexPolyhedron, RoundConvexPolyhedron}; + #[cfg(feature = "dim2")] +#[cfg(feature = "std")] use crate::shape::{ConvexPolygon, RoundConvexPolygon}; use downcast_rs::{impl_downcast, DowncastSync}; use na::{RealField, Unit}; @@ -95,18 +100,24 @@ pub enum TypedShape<'a> { /// A triangle shape. Triangle(&'a Triangle), /// A triangle mesh shape. + #[cfg(feature = "std")] TriMesh(&'a TriMesh), /// A set of segments. + #[cfg(feature = "std")] Polyline(&'a Polyline), /// A shape representing a full half-space. HalfSpace(&'a HalfSpace), /// A heightfield shape. + #[cfg(feature = "std")] HeightField(&'a HeightField), /// A Compound shape. + #[cfg(feature = "std")] Compound(&'a Compound), #[cfg(feature = "dim2")] + #[cfg(feature = "std")] ConvexPolygon(&'a ConvexPolygon), #[cfg(feature = "dim3")] + #[cfg(feature = "std")] /// A convex polyhedron. ConvexPolyhedron(&'a ConvexPolyhedron), #[cfg(feature = "dim3")] @@ -133,9 +144,11 @@ pub enum TypedShape<'a> { RoundCone(&'a RoundCone), /// A convex polyhedron with rounded corners. #[cfg(feature = "dim3")] + #[cfg(feature = "std")] RoundConvexPolyhedron(&'a RoundConvexPolyhedron), /// A convex polygon with rounded corners. #[cfg(feature = "dim2")] + #[cfg(feature = "std")] RoundConvexPolygon(&'a RoundConvexPolygon), /// A custom user-defined shape with a type identified by a number. Custom(u32), @@ -157,18 +170,24 @@ pub(crate) enum DeserializableTypedShape { /// A triangle shape. Triangle(Triangle), /// A triangle mesh shape. + #[cfg(feature = "std")] TriMesh(TriMesh), /// A set of segments. + #[cfg(feature = "std")] Polyline(Polyline), /// A shape representing a full half-space. HalfSpace(HalfSpace), /// A heightfield shape. + #[cfg(feature = "std")] HeightField(HeightField), /// A Compound shape. + #[cfg(feature = "std")] Compound(Compound), #[cfg(feature = "dim2")] + #[cfg(feature = "std")] ConvexPolygon(ConvexPolygon), #[cfg(feature = "dim3")] + #[cfg(feature = "std")] /// A convex polyhedron. ConvexPolyhedron(ConvexPolyhedron), #[cfg(feature = "dim3")] @@ -195,9 +214,11 @@ pub(crate) enum DeserializableTypedShape { RoundCone(RoundCone), /// A convex polyhedron with rounded corners. #[cfg(feature = "dim3")] + #[cfg(feature = "std")] RoundConvexPolyhedron(RoundConvexPolyhedron), /// A convex polygon with rounded corners. #[cfg(feature = "dim2")] + #[cfg(feature = "std")] RoundConvexPolygon(RoundConvexPolygon), /// A custom user-defined shape identified by a number. Custom(u32), @@ -213,14 +234,20 @@ impl DeserializableTypedShape { DeserializableTypedShape::Capsule(s) => Some(SharedShape::new(s)), DeserializableTypedShape::Segment(s) => Some(SharedShape::new(s)), DeserializableTypedShape::Triangle(s) => Some(SharedShape::new(s)), + #[cfg(feature = "std")] DeserializableTypedShape::TriMesh(s) => Some(SharedShape::new(s)), + #[cfg(feature = "std")] DeserializableTypedShape::Polyline(s) => Some(SharedShape::new(s)), DeserializableTypedShape::HalfSpace(s) => Some(SharedShape::new(s)), + #[cfg(feature = "std")] DeserializableTypedShape::HeightField(s) => Some(SharedShape::new(s)), + #[cfg(feature = "std")] DeserializableTypedShape::Compound(s) => Some(SharedShape::new(s)), #[cfg(feature = "dim2")] + #[cfg(feature = "std")] DeserializableTypedShape::ConvexPolygon(s) => Some(SharedShape::new(s)), #[cfg(feature = "dim3")] + #[cfg(feature = "std")] DeserializableTypedShape::ConvexPolyhedron(s) => Some(SharedShape::new(s)), #[cfg(feature = "dim3")] DeserializableTypedShape::Cylinder(s) => Some(SharedShape::new(s)), @@ -233,8 +260,10 @@ impl DeserializableTypedShape { #[cfg(feature = "dim3")] DeserializableTypedShape::RoundCone(s) => Some(SharedShape::new(s)), #[cfg(feature = "dim3")] + #[cfg(feature = "std")] DeserializableTypedShape::RoundConvexPolyhedron(s) => Some(SharedShape::new(s)), #[cfg(feature = "dim2")] + #[cfg(feature = "std")] DeserializableTypedShape::RoundConvexPolygon(s) => Some(SharedShape::new(s)), DeserializableTypedShape::Custom(_) => None, } @@ -249,6 +278,7 @@ pub trait Shape: RayCast + PointQuery + DowncastSync { fn compute_local_bounding_sphere(&self) -> BoundingSphere; /// Clones this shape into a boxed trait-object. + #[cfg(feature = "std")] fn clone_box(&self) -> Box; /// Computes the AABB of this shape with the given position. @@ -293,6 +323,7 @@ pub trait Shape: RayCast + PointQuery + DowncastSync { None } + #[cfg(feature = "std")] fn as_composite_shape(&self) -> Option<&dyn SimdCompositeShape> { None } @@ -391,37 +422,45 @@ impl dyn Shape { } /// Converts this abstract shape to a compound shape, if it is one. + #[cfg(feature = "std")] pub fn as_compound(&self) -> Option<&Compound> { self.downcast_ref() } /// Converts this abstract shape to a mutable compound shape, if it is one. + #[cfg(feature = "std")] pub fn as_compound_mut(&mut self) -> Option<&mut Compound> { self.downcast_mut() } /// Converts this abstract shape to a triangle mesh, if it is one. + #[cfg(feature = "std")] pub fn as_trimesh(&self) -> Option<&TriMesh> { self.downcast_ref() } /// Converts this abstract shape to a mutable triangle mesh, if it is one. + #[cfg(feature = "std")] pub fn as_trimesh_mut(&mut self) -> Option<&mut TriMesh> { self.downcast_mut() } /// Converts this abstract shape to a polyline, if it is one. + #[cfg(feature = "std")] pub fn as_polyline(&self) -> Option<&Polyline> { self.downcast_ref() } /// Converts this abstract shape to a mutable polyline, if it is one. + #[cfg(feature = "std")] pub fn as_polyline_mut(&mut self) -> Option<&mut Polyline> { self.downcast_mut() } /// Converts this abstract shape to a heightfield, if it is one. + #[cfg(feature = "std")] pub fn as_heightfield(&self) -> Option<&HeightField> { self.downcast_ref() } /// Converts this abstract shape to a mutable heightfield, if it is one. + #[cfg(feature = "std")] pub fn as_heightfield_mut(&mut self) -> Option<&mut HeightField> { self.downcast_mut() } @@ -446,31 +485,37 @@ impl dyn Shape { /// Converts this abstract shape to a convex polygon, if it is one. #[cfg(feature = "dim2")] + #[cfg(feature = "std")] pub fn as_convex_polygon(&self) -> Option<&ConvexPolygon> { self.downcast_ref() } /// Converts this abstract shape to a mutable convex polygon, if it is one. #[cfg(feature = "dim2")] + #[cfg(feature = "std")] pub fn as_convex_polygon_mut(&mut self) -> Option<&mut ConvexPolygon> { self.downcast_mut() } /// Converts this abstract shape to a round convex polygon, if it is one. #[cfg(feature = "dim2")] + #[cfg(feature = "std")] pub fn as_round_convex_polygon(&self) -> Option<&RoundConvexPolygon> { self.downcast_ref() } /// Converts this abstract shape to a mutable round convex polygon, if it is one. #[cfg(feature = "dim2")] + #[cfg(feature = "std")] pub fn as_round_convex_polygon_mut(&mut self) -> Option<&mut RoundConvexPolygon> { self.downcast_mut() } #[cfg(feature = "dim3")] + #[cfg(feature = "std")] pub fn as_convex_polyhedron(&self) -> Option<&ConvexPolyhedron> { self.downcast_ref() } #[cfg(feature = "dim3")] + #[cfg(feature = "std")] pub fn as_convex_polyhedron_mut(&mut self) -> Option<&mut ConvexPolyhedron> { self.downcast_mut() } @@ -521,17 +566,20 @@ impl dyn Shape { /// Converts this abstract shape to a round convex polyhedron, if it is one. #[cfg(feature = "dim3")] + #[cfg(feature = "std")] pub fn as_round_convex_polyhedron(&self) -> Option<&RoundConvexPolyhedron> { self.downcast_ref() } /// Converts this abstract shape to a mutable round convex polyhedron, if it is one. #[cfg(feature = "dim3")] + #[cfg(feature = "std")] pub fn as_round_convex_polyhedron_mut(&mut self) -> Option<&mut RoundConvexPolyhedron> { self.downcast_mut() } } impl Shape for Ball { + #[cfg(feature = "std")] fn clone_box(&self) -> Box { Box::new(self.clone()) } @@ -588,6 +636,7 @@ impl Shape for Ball { } impl Shape for Cuboid { + #[cfg(feature = "std")] fn clone_box(&self) -> Box { Box::new(self.clone()) } @@ -646,6 +695,7 @@ impl Shape for Cuboid { } impl Shape for Capsule { + #[cfg(feature = "std")] fn clone_box(&self) -> Box { Box::new(self.clone()) } @@ -696,6 +746,7 @@ impl Shape for Capsule { } impl Shape for Triangle { + #[cfg(feature = "std")] fn clone_box(&self) -> Box { Box::new(self.clone()) } @@ -758,6 +809,7 @@ impl Shape for Triangle { } impl Shape for Segment { + #[cfg(feature = "std")] fn clone_box(&self) -> Box { Box::new(self.clone()) } @@ -815,6 +867,7 @@ impl Shape for Segment { } } +#[cfg(feature = "std")] impl Shape for Compound { fn clone_box(&self) -> Box { Box::new(self.clone()) @@ -856,11 +909,13 @@ impl Shape for Compound { }) } + #[cfg(feature = "std")] fn as_composite_shape(&self) -> Option<&dyn SimdCompositeShape> { Some(self as &dyn SimdCompositeShape) } } +#[cfg(feature = "std")] impl Shape for Polyline { fn clone_box(&self) -> Box { Box::new(self.clone()) @@ -900,11 +955,13 @@ impl Shape for Polyline { Real::frac_pi_4() } + #[cfg(feature = "std")] fn as_composite_shape(&self) -> Option<&dyn SimdCompositeShape> { Some(self as &dyn SimdCompositeShape) } } +#[cfg(feature = "std")] impl Shape for TriMesh { fn clone_box(&self) -> Box { Box::new(self.clone()) @@ -948,11 +1005,13 @@ impl Shape for TriMesh { Real::frac_pi_4() } + #[cfg(feature = "std")] fn as_composite_shape(&self) -> Option<&dyn SimdCompositeShape> { Some(self as &dyn SimdCompositeShape) } } +#[cfg(feature = "std")] impl Shape for HeightField { fn clone_box(&self) -> Box { Box::new(self.clone()) @@ -994,6 +1053,7 @@ impl Shape for HeightField { } #[cfg(feature = "dim2")] +#[cfg(feature = "std")] impl Shape for ConvexPolygon { fn clone_box(&self) -> Box { Box::new(self.clone()) @@ -1056,6 +1116,7 @@ impl Shape for ConvexPolygon { } #[cfg(feature = "dim3")] +#[cfg(feature = "std")] impl Shape for ConvexPolyhedron { fn clone_box(&self) -> Box { Box::new(self.clone()) @@ -1120,6 +1181,7 @@ impl Shape for ConvexPolyhedron { #[cfg(feature = "dim3")] impl Shape for Cylinder { + #[cfg(feature = "std")] fn clone_box(&self) -> Box { Box::new(self.clone()) } @@ -1171,6 +1233,7 @@ impl Shape for Cylinder { #[cfg(feature = "dim3")] impl Shape for Cone { + #[cfg(feature = "std")] fn clone_box(&self) -> Box { Box::new(self.clone()) } @@ -1224,6 +1287,7 @@ impl Shape for Cone { } impl Shape for HalfSpace { + #[cfg(feature = "std")] fn clone_box(&self) -> Box { Box::new(self.clone()) } @@ -1268,6 +1332,7 @@ impl Shape for HalfSpace { macro_rules! impl_shape_for_round_shape( ($($S: ty, $Tag: ident);*) => {$( impl Shape for RoundShape<$S> { + #[cfg(feature = "std")] fn clone_box(&self) -> Box { Box::new(self.clone()) } @@ -1326,10 +1391,14 @@ impl_shape_for_round_shape!( Triangle, RoundTriangle ); #[cfg(feature = "dim2")] +#[cfg(feature = "std")] impl_shape_for_round_shape!(ConvexPolygon, RoundConvexPolygon); #[cfg(feature = "dim3")] impl_shape_for_round_shape!( Cylinder, RoundCylinder; - Cone, RoundCone; - ConvexPolyhedron, RoundConvexPolyhedron + Cone, RoundCone ); + +#[cfg(feature = "dim3")] +#[cfg(feature = "std")] +impl_shape_for_round_shape!(ConvexPolyhedron, RoundConvexPolyhedron); diff --git a/src/shape/tetrahedron.rs b/src/shape/tetrahedron.rs index ce937ad5..5b74efea 100644 --- a/src/shape/tetrahedron.rs +++ b/src/shape/tetrahedron.rs @@ -6,10 +6,17 @@ use crate::utils; use na::Matrix3; use std::mem; +#[cfg(not(feature = "std"))] +use na::ComplexField; // for .abs() + /// A tetrahedron with 4 vertices. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[repr(C)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] #[derive(Copy, Clone, Debug)] +#[repr(C)] pub struct Tetrahedron { /// The tetrahedron first point. pub a: Point, diff --git a/src/shape/triangle.rs b/src/shape/triangle.rs index 4d3d63e1..d1d96099 100644 --- a/src/shape/triangle.rs +++ b/src/shape/triangle.rs @@ -13,8 +13,12 @@ use std::mem; /// A triangle shape. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[repr(C)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] #[derive(PartialEq, Debug, Copy, Clone)] +#[repr(C)] pub struct Triangle { /// The triangle first point. pub a: Point, diff --git a/src/utils/isometry_ops.rs b/src/utils/isometry_ops.rs index 63ad73dc..3c6d11b2 100644 --- a/src/utils/isometry_ops.rs +++ b/src/utils/isometry_ops.rs @@ -1,4 +1,6 @@ use crate::math::{Isometry, Point, Real, Vector}; +#[cfg(not(feature = "std"))] +use na::ComplexField; // for .abs() use na::Unit; /// Extra operations with isometries. diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 46039aba..15732cf2 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -2,9 +2,11 @@ pub use self::ccw_face_normal::ccw_face_normal; pub use self::center::center; +#[cfg(feature = "std")] pub use self::deterministic_state::DeterministicState; #[cfg(feature = "dim3")] +#[cfg(feature = "std")] pub use self::cleanup::remove_unused_points; pub(crate) use self::inv::inv; pub use self::isometry_ops::{IsometryOps, IsometryOpt}; @@ -19,6 +21,7 @@ pub use self::as_bytes::AsBytes; pub(crate) use self::consts::*; pub use self::cov::{center_cov, cov}; pub use self::hashable_partial_eq::HashablePartialEq; +#[cfg(feature = "std")] pub use self::interval::{find_root_intervals, find_root_intervals_to, Interval, IntervalFunction}; pub use self::obb::obb; #[cfg(feature = "dim3")] @@ -32,12 +35,16 @@ mod as_bytes; mod ccw_face_normal; mod center; #[cfg(feature = "dim3")] +#[cfg(feature = "std")] mod cleanup; mod consts; mod cov; +#[cfg(feature = "std")] mod deterministic_state; mod hashable_partial_eq; +#[cfg(feature = "std")] pub mod hashmap; +#[cfg(feature = "std")] mod interval; mod inv; mod isometry_ops;