feat: update to parry 0.21
This commit is contained in:
committed by
Sébastien Crozet
parent
b798e1942d
commit
ef47848fba
@@ -14,11 +14,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
|
|
||||||
let settings = testbed.example_settings_mut();
|
let settings = testbed.example_settings_mut();
|
||||||
|
|
||||||
let geometry_mode = settings.get_or_set_string(
|
|
||||||
"Voxels mode",
|
|
||||||
0,
|
|
||||||
vec!["PseudoCube".to_string(), "PseudoBall".to_string()],
|
|
||||||
);
|
|
||||||
let falling_objects = settings.get_or_set_string(
|
let falling_objects = settings.get_or_set_string(
|
||||||
"Falling objects",
|
"Falling objects",
|
||||||
5, // Defaults to Mixed.
|
5, // Defaults to Mixed.
|
||||||
@@ -40,12 +35,6 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
// settings.get_or_set_bool("Load .obj", false);
|
// settings.get_or_set_bool("Load .obj", false);
|
||||||
let load_obj = false;
|
let load_obj = false;
|
||||||
|
|
||||||
let primitive_geometry = if geometry_mode == 0 {
|
|
||||||
VoxelPrimitiveGeometry::PseudoCube
|
|
||||||
} else {
|
|
||||||
VoxelPrimitiveGeometry::PseudoBall
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* World
|
* World
|
||||||
*/
|
*/
|
||||||
@@ -112,13 +101,8 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
.map(|idx| [idx[0] as u32, idx[1] as u32, idx[2] as u32])
|
.map(|idx| [idx[0] as u32, idx[1] as u32, idx[2] as u32])
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let decomposed_shape = SharedShape::voxelized_mesh(
|
let decomposed_shape =
|
||||||
primitive_geometry,
|
SharedShape::voxelized_mesh(&vertices, &indices, 0.1, FillMode::default());
|
||||||
&vertices,
|
|
||||||
&indices,
|
|
||||||
0.1,
|
|
||||||
FillMode::default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
shapes.push(decomposed_shape);
|
shapes.push(decomposed_shape);
|
||||||
|
|
||||||
@@ -160,8 +144,7 @@ pub fn init_world(testbed: &mut Testbed) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let collider =
|
let collider = ColliderBuilder::voxels_from_points(voxel_size, &samples).build();
|
||||||
ColliderBuilder::voxels_from_points(primitive_geometry, voxel_size, &samples).build();
|
|
||||||
let floor_aabb = collider.compute_aabb();
|
let floor_aabb = collider.compute_aabb();
|
||||||
colliders.insert(collider);
|
colliders.insert(collider);
|
||||||
|
|
||||||
|
|||||||
@@ -738,7 +738,6 @@ impl RigidBodyVelocity {
|
|||||||
impl std::ops::Mul<Real> for RigidBodyVelocity {
|
impl std::ops::Mul<Real> for RigidBodyVelocity {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
fn mul(self, rhs: Real) -> Self {
|
fn mul(self, rhs: Real) -> Self {
|
||||||
RigidBodyVelocity {
|
RigidBodyVelocity {
|
||||||
linvel: self.linvel * rhs,
|
linvel: self.linvel * rhs,
|
||||||
@@ -750,7 +749,6 @@ impl std::ops::Mul<Real> for RigidBodyVelocity {
|
|||||||
impl std::ops::Add<RigidBodyVelocity> for RigidBodyVelocity {
|
impl std::ops::Add<RigidBodyVelocity> for RigidBodyVelocity {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
fn add(self, rhs: Self) -> Self {
|
fn add(self, rhs: Self) -> Self {
|
||||||
RigidBodyVelocity {
|
RigidBodyVelocity {
|
||||||
linvel: self.linvel + rhs.linvel,
|
linvel: self.linvel + rhs.linvel,
|
||||||
@@ -769,7 +767,6 @@ impl std::ops::AddAssign<RigidBodyVelocity> for RigidBodyVelocity {
|
|||||||
impl std::ops::Sub<RigidBodyVelocity> for RigidBodyVelocity {
|
impl std::ops::Sub<RigidBodyVelocity> for RigidBodyVelocity {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
fn sub(self, rhs: Self) -> Self {
|
fn sub(self, rhs: Self) -> Self {
|
||||||
RigidBodyVelocity {
|
RigidBodyVelocity {
|
||||||
linvel: self.linvel - rhs.linvel,
|
linvel: self.linvel - rhs.linvel,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::geometry::{BroadPhasePairEvent, ColliderHandle, ColliderPair, ColliderSet};
|
use crate::dynamics::RigidBodySet;
|
||||||
|
use crate::geometry::{BroadPhase, BroadPhasePairEvent, ColliderHandle, ColliderPair, ColliderSet};
|
||||||
use parry::math::Real;
|
use parry::math::Real;
|
||||||
use parry::partitioning::Qbvh;
|
use parry::partitioning::Qbvh;
|
||||||
use parry::partitioning::QbvhUpdateWorkspace;
|
use parry::partitioning::QbvhUpdateWorkspace;
|
||||||
@@ -27,12 +28,15 @@ impl BroadPhaseQbvh {
|
|||||||
workspace: QbvhUpdateWorkspace::default(),
|
workspace: QbvhUpdateWorkspace::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)] // This broad-phase is just experimental right now.
|
impl BroadPhase for BroadPhaseQbvh {
|
||||||
pub fn update(
|
fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
dt: Real,
|
||||||
prediction_distance: Real,
|
prediction_distance: Real,
|
||||||
colliders: &ColliderSet,
|
colliders: &mut ColliderSet,
|
||||||
|
bodies: &RigidBodySet,
|
||||||
modified_colliders: &[ColliderHandle],
|
modified_colliders: &[ColliderHandle],
|
||||||
removed_colliders: &[ColliderHandle],
|
removed_colliders: &[ColliderHandle],
|
||||||
events: &mut Vec<BroadPhasePairEvent>,
|
events: &mut Vec<BroadPhasePairEvent>,
|
||||||
@@ -46,7 +50,9 @@ impl BroadPhaseQbvh {
|
|||||||
// Visitor to find collision pairs.
|
// Visitor to find collision pairs.
|
||||||
let mut visitor = BoundingVolumeIntersectionsSimultaneousVisitor::new(
|
let mut visitor = BoundingVolumeIntersectionsSimultaneousVisitor::new(
|
||||||
|co1: &ColliderHandle, co2: &ColliderHandle| {
|
|co1: &ColliderHandle, co2: &ColliderHandle| {
|
||||||
events.push(BroadPhasePairEvent::AddPair(ColliderPair::new(*co1, *co2)));
|
if *co1 != *co2 {
|
||||||
|
events.push(BroadPhasePairEvent::AddPair(ColliderPair::new(*co1, *co2)));
|
||||||
|
}
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -77,6 +83,8 @@ impl BroadPhaseQbvh {
|
|||||||
let _ = self.qbvh.refit(margin, &mut self.workspace, |handle| {
|
let _ = self.qbvh.refit(margin, &mut self.workspace, |handle| {
|
||||||
colliders[*handle].compute_collision_aabb(prediction_distance / 2.0)
|
colliders[*handle].compute_collision_aabb(prediction_distance / 2.0)
|
||||||
});
|
});
|
||||||
|
// self.qbvh
|
||||||
|
// .traverse_bvtt_with_stack(&self.qbvh, &mut visitor, &mut self.stack);
|
||||||
self.qbvh
|
self.qbvh
|
||||||
.traverse_modified_bvtt_with_stack(&self.qbvh, &mut visitor, &mut self.stack);
|
.traverse_modified_bvtt_with_stack(&self.qbvh, &mut visitor, &mut self.stack);
|
||||||
self.qbvh.rebalance(margin, &mut self.workspace);
|
self.qbvh.rebalance(margin, &mut self.workspace);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use crate::pipeline::{ActiveEvents, ActiveHooks};
|
|||||||
use crate::prelude::ColliderEnabled;
|
use crate::prelude::ColliderEnabled;
|
||||||
use na::Unit;
|
use na::Unit;
|
||||||
use parry::bounding_volume::{Aabb, BoundingVolume};
|
use parry::bounding_volume::{Aabb, BoundingVolume};
|
||||||
use parry::shape::{Shape, TriMeshBuilderError, TriMeshFlags, VoxelPrimitiveGeometry};
|
use parry::shape::{Shape, TriMeshBuilderError, TriMeshFlags};
|
||||||
use parry::transformation::voxelization::FillMode;
|
use parry::transformation::voxelization::FillMode;
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
@@ -580,45 +580,28 @@ impl ColliderBuilder {
|
|||||||
///
|
///
|
||||||
/// For initializing a voxels shape from points in space, see [`Self::voxels_from_points`].
|
/// For initializing a voxels shape from points in space, see [`Self::voxels_from_points`].
|
||||||
/// For initializing a voxels shape from a mesh to voxelize, see [`Self::voxelized_mesh`].
|
/// For initializing a voxels shape from a mesh to voxelize, see [`Self::voxelized_mesh`].
|
||||||
pub fn voxels(
|
pub fn voxels(voxel_size: Vector<Real>, voxels: &[Point<i32>]) -> Self {
|
||||||
primitive_geometry: VoxelPrimitiveGeometry,
|
Self::new(SharedShape::voxels(voxel_size, voxels))
|
||||||
voxel_size: Vector<Real>,
|
|
||||||
voxels: &[Point<i32>],
|
|
||||||
) -> Self {
|
|
||||||
Self::new(SharedShape::voxels(primitive_geometry, voxel_size, voxels))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes a collider made of voxels.
|
/// Initializes a collider made of voxels.
|
||||||
///
|
///
|
||||||
/// Each voxel has the size `voxel_size` and contains at least one point from `centers`.
|
/// Each voxel has the size `voxel_size` and contains at least one point from `centers`.
|
||||||
/// The `primitive_geometry` controls the behavior of collision detection at voxels boundaries.
|
/// The `primitive_geometry` controls the behavior of collision detection at voxels boundaries.
|
||||||
pub fn voxels_from_points(
|
pub fn voxels_from_points(voxel_size: Vector<Real>, points: &[Point<Real>]) -> Self {
|
||||||
primitive_geometry: VoxelPrimitiveGeometry,
|
Self::new(SharedShape::voxels_from_points(voxel_size, points))
|
||||||
voxel_size: Vector<Real>,
|
|
||||||
points: &[Point<Real>],
|
|
||||||
) -> Self {
|
|
||||||
Self::new(SharedShape::voxels_from_points(
|
|
||||||
primitive_geometry,
|
|
||||||
voxel_size,
|
|
||||||
points,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes a voxels obtained from the decomposition of the given trimesh (in 3D)
|
/// Initializes a voxels obtained from the decomposition of the given trimesh (in 3D)
|
||||||
/// or polyline (in 2D) into voxelized convex parts.
|
/// or polyline (in 2D) into voxelized convex parts.
|
||||||
pub fn voxelized_mesh(
|
pub fn voxelized_mesh(
|
||||||
primitive_geometry: VoxelPrimitiveGeometry,
|
|
||||||
vertices: &[Point<Real>],
|
vertices: &[Point<Real>],
|
||||||
indices: &[[u32; DIM]],
|
indices: &[[u32; DIM]],
|
||||||
voxel_size: Real,
|
voxel_size: Real,
|
||||||
fill_mode: FillMode,
|
fill_mode: FillMode,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(SharedShape::voxelized_mesh(
|
Self::new(SharedShape::voxelized_mesh(
|
||||||
primitive_geometry,
|
vertices, indices, voxel_size, fill_mode,
|
||||||
vertices,
|
|
||||||
indices,
|
|
||||||
voxel_size,
|
|
||||||
fill_mode,
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ pub use self::narrow_phase::NarrowPhase;
|
|||||||
|
|
||||||
pub use parry::bounding_volume::BoundingVolume;
|
pub use parry::bounding_volume::BoundingVolume;
|
||||||
pub use parry::query::{PointQuery, PointQueryWithLocation, RayCast, TrackedContact};
|
pub use parry::query::{PointQuery, PointQueryWithLocation, RayCast, TrackedContact};
|
||||||
pub use parry::shape::{SharedShape, VoxelPrimitiveGeometry, VoxelState, VoxelType, Voxels};
|
pub use parry::shape::{SharedShape, VoxelState, VoxelType, Voxels};
|
||||||
|
|
||||||
use crate::math::{Real, Vector};
|
use crate::math::{Real, Vector};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use na::{point, Point3};
|
use na::{point, Point3, Point4};
|
||||||
|
|
||||||
use crate::objects::node::EntityWithGraphics;
|
use crate::objects::node::EntityWithGraphics;
|
||||||
use rapier::dynamics::{RigidBodyHandle, RigidBodySet};
|
use rapier::dynamics::{RigidBodyHandle, RigidBodySet};
|
||||||
@@ -27,8 +27,60 @@ pub type BevyMaterialComponent = MeshMaterial2d<BevyMaterial>;
|
|||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
pub type BevyMaterialComponent = MeshMaterial3d<BevyMaterial>;
|
pub type BevyMaterialComponent = MeshMaterial3d<BevyMaterial>;
|
||||||
|
|
||||||
pub type InstancedMaterials = HashMap<Point3<usize>, Handle<BevyMaterial>>;
|
#[derive(Clone, Default)]
|
||||||
pub const SELECTED_OBJECT_MATERIAL_KEY: Point3<usize> = point![42, 42, 42];
|
pub struct InstancedMaterials {
|
||||||
|
cache: HashMap<Point4<usize>, Handle<BevyMaterial>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InstancedMaterials {
|
||||||
|
pub fn insert(
|
||||||
|
&mut self,
|
||||||
|
materials: &mut Assets<BevyMaterial>,
|
||||||
|
color: Point3<f32>,
|
||||||
|
opacity: f32,
|
||||||
|
) -> Handle<BevyMaterial> {
|
||||||
|
let key = color
|
||||||
|
.coords
|
||||||
|
.push(opacity)
|
||||||
|
.map(|c| (c * 255.0) as usize)
|
||||||
|
.into();
|
||||||
|
let bevy_color = Color::from(Srgba::new(color.x, color.y, color.z, opacity));
|
||||||
|
|
||||||
|
#[cfg(feature = "dim2")]
|
||||||
|
let material = bevy_sprite::ColorMaterial {
|
||||||
|
color: bevy_color,
|
||||||
|
texture: None,
|
||||||
|
..default()
|
||||||
|
};
|
||||||
|
#[cfg(feature = "dim3")]
|
||||||
|
let material = StandardMaterial {
|
||||||
|
metallic: 0.5,
|
||||||
|
perceptual_roughness: 0.5,
|
||||||
|
double_sided: true, // TODO: this doesn't do anything?
|
||||||
|
..StandardMaterial::from(bevy_color)
|
||||||
|
};
|
||||||
|
|
||||||
|
self.cache
|
||||||
|
.entry(key)
|
||||||
|
.or_insert_with(|| materials.add(material))
|
||||||
|
.clone_weak()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, color: &Point3<f32>, opacity: f32) -> Option<Handle<BevyMaterial>> {
|
||||||
|
let key = color
|
||||||
|
.coords
|
||||||
|
.push(opacity)
|
||||||
|
.map(|c| (c * 255.0) as usize)
|
||||||
|
.into();
|
||||||
|
self.cache.get(&key).map(|h| h.clone_weak())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.cache.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const SELECTED_OBJECT_COLOR: Point3<f32> = point![1.0, 0.0, 0.0];
|
||||||
|
|
||||||
pub struct GraphicsManager {
|
pub struct GraphicsManager {
|
||||||
rand: Pcg32,
|
rand: Pcg32,
|
||||||
@@ -52,13 +104,16 @@ impl GraphicsManager {
|
|||||||
ground_color: point![0.5, 0.5, 0.5],
|
ground_color: point![0.5, 0.5, 0.5],
|
||||||
b2wireframe: HashMap::new(),
|
b2wireframe: HashMap::new(),
|
||||||
prefab_meshes: HashMap::new(),
|
prefab_meshes: HashMap::new(),
|
||||||
instanced_materials: HashMap::new(),
|
instanced_materials: Default::default(),
|
||||||
gfx_shift: Vector::zeros(),
|
gfx_shift: Vector::zeros(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn selection_material(&self) -> Handle<BevyMaterial> {
|
pub fn selection_material(&self) -> Handle<BevyMaterial> {
|
||||||
self.instanced_materials[&SELECTED_OBJECT_MATERIAL_KEY].clone_weak()
|
self.instanced_materials
|
||||||
|
.get(&SELECTED_OBJECT_COLOR, 1.0)
|
||||||
|
.unwrap()
|
||||||
|
.clone_weak()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self, commands: &mut Commands) {
|
pub fn clear(&mut self, commands: &mut Commands) {
|
||||||
@@ -110,6 +165,7 @@ impl GraphicsManager {
|
|||||||
pub fn set_body_color(
|
pub fn set_body_color(
|
||||||
&mut self,
|
&mut self,
|
||||||
materials: &mut Assets<BevyMaterial>,
|
materials: &mut Assets<BevyMaterial>,
|
||||||
|
material_handles: &mut Query<&mut BevyMaterialComponent>,
|
||||||
b: RigidBodyHandle,
|
b: RigidBodyHandle,
|
||||||
color: [f32; 3],
|
color: [f32; 3],
|
||||||
) {
|
) {
|
||||||
@@ -117,7 +173,11 @@ impl GraphicsManager {
|
|||||||
|
|
||||||
if let Some(ns) = self.b2sn.get_mut(&b) {
|
if let Some(ns) = self.b2sn.get_mut(&b) {
|
||||||
for n in ns.iter_mut() {
|
for n in ns.iter_mut() {
|
||||||
n.set_color(materials, color.into())
|
n.set_color(materials, &mut self.instanced_materials, color.into());
|
||||||
|
|
||||||
|
if let Ok(mut mat) = material_handles.get_mut(n.entity) {
|
||||||
|
mat.0 = n.material.clone_weak();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,12 +245,7 @@ impl GraphicsManager {
|
|||||||
color
|
color
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_color(
|
fn alloc_color(&mut self, handle: RigidBodyHandle, is_fixed: bool) -> Point3<f32> {
|
||||||
&mut self,
|
|
||||||
materials: &mut Assets<BevyMaterial>,
|
|
||||||
handle: RigidBodyHandle,
|
|
||||||
is_fixed: bool,
|
|
||||||
) -> Point3<f32> {
|
|
||||||
let mut color = self.ground_color;
|
let mut color = self.ground_color;
|
||||||
|
|
||||||
if !is_fixed {
|
if !is_fixed {
|
||||||
@@ -200,7 +255,7 @@ impl GraphicsManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.set_body_color(materials, handle, color.into());
|
self.b2color.insert(handle, color.into());
|
||||||
|
|
||||||
color
|
color
|
||||||
}
|
}
|
||||||
@@ -221,7 +276,7 @@ impl GraphicsManager {
|
|||||||
.b2color
|
.b2color
|
||||||
.get(&handle)
|
.get(&handle)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_else(|| self.alloc_color(materials, handle, !body.is_dynamic()));
|
.unwrap_or_else(|| self.alloc_color(handle, !body.is_dynamic()));
|
||||||
|
|
||||||
let _ = self.add_body_colliders_with_color(
|
let _ = self.add_body_colliders_with_color(
|
||||||
commands, meshes, materials, components, handle, bodies, colliders, color,
|
commands, meshes, materials, components, handle, bodies, colliders, color,
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ impl Harness {
|
|||||||
self.physics.hooks = Box::new(hooks);
|
self.physics.hooks = Box::new(hooks);
|
||||||
|
|
||||||
self.physics.islands = IslandManager::new();
|
self.physics.islands = IslandManager::new();
|
||||||
self.physics.broad_phase = DefaultBroadPhase::new();
|
self.physics.broad_phase = DefaultBroadPhase::default();
|
||||||
self.physics.narrow_phase = NarrowPhase::new();
|
self.physics.narrow_phase = NarrowPhase::new();
|
||||||
self.state.timestep_id = 0;
|
self.state.timestep_id = 0;
|
||||||
self.state.time = 0.0;
|
self.state.time = 0.0;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use rapier::geometry::{ColliderHandle, ColliderSet, Shape, ShapeType};
|
|||||||
use rapier::geometry::{Cone, Cylinder};
|
use rapier::geometry::{Cone, Cylinder};
|
||||||
use rapier::math::{Isometry, Real, Vector};
|
use rapier::math::{Isometry, Real, Vector};
|
||||||
|
|
||||||
use crate::graphics::{BevyMaterial, InstancedMaterials, SELECTED_OBJECT_MATERIAL_KEY};
|
use crate::graphics::{BevyMaterial, InstancedMaterials, SELECTED_OBJECT_COLOR};
|
||||||
#[cfg(feature = "dim2")]
|
#[cfg(feature = "dim2")]
|
||||||
use {
|
use {
|
||||||
na::{vector, Point2, Vector2},
|
na::{vector, Point2, Vector2},
|
||||||
@@ -37,28 +37,7 @@ impl EntityWithGraphics {
|
|||||||
materials: &mut Assets<BevyMaterial>,
|
materials: &mut Assets<BevyMaterial>,
|
||||||
instanced_materials: &mut InstancedMaterials,
|
instanced_materials: &mut InstancedMaterials,
|
||||||
) {
|
) {
|
||||||
if instanced_materials.contains_key(&SELECTED_OBJECT_MATERIAL_KEY) {
|
instanced_materials.insert(materials, SELECTED_OBJECT_COLOR, 1.0);
|
||||||
return; // Already added.
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "dim2")]
|
|
||||||
let selection_material = bevy_sprite::ColorMaterial {
|
|
||||||
color: Color::from(Srgba::rgb(1.0, 0.0, 0.0)),
|
|
||||||
texture: None,
|
|
||||||
..default()
|
|
||||||
};
|
|
||||||
#[cfg(feature = "dim3")]
|
|
||||||
let selection_material = StandardMaterial {
|
|
||||||
metallic: 0.5,
|
|
||||||
perceptual_roughness: 0.5,
|
|
||||||
double_sided: true, // TODO: this doesn't do anything?
|
|
||||||
..StandardMaterial::from(Color::from(Srgba::rgb(1.0, 0.0, 0.0)))
|
|
||||||
};
|
|
||||||
|
|
||||||
instanced_materials.insert(
|
|
||||||
SELECTED_OBJECT_MATERIAL_KEY,
|
|
||||||
materials.add(selection_material),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn(
|
pub fn spawn(
|
||||||
@@ -84,8 +63,7 @@ impl EntityWithGraphics {
|
|||||||
.cloned()
|
.cloned()
|
||||||
.or_else(|| generate_collider_mesh(shape).map(|m| meshes.add(m)));
|
.or_else(|| generate_collider_mesh(shape).map(|m| meshes.add(m)));
|
||||||
|
|
||||||
let opacity = 1.0;
|
let opacity = if sensor { 0.25 } else { 1.0 };
|
||||||
let bevy_color = Color::from(Srgba::new(color.x, color.y, color.z, opacity));
|
|
||||||
let shape_pos = collider_pos * delta;
|
let shape_pos = collider_pos * delta;
|
||||||
let mut transform = Transform::from_scale(scale);
|
let mut transform = Transform::from_scale(scale);
|
||||||
transform.translation.x = shape_pos.translation.vector.x as f32;
|
transform.translation.x = shape_pos.translation.vector.x as f32;
|
||||||
@@ -108,23 +86,7 @@ impl EntityWithGraphics {
|
|||||||
transform.rotation = Quat::from_rotation_z(shape_pos.rotation.angle() as f32);
|
transform.rotation = Quat::from_rotation_z(shape_pos.rotation.angle() as f32);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "dim2")]
|
let material_handle = instanced_materials.insert(materials, color, opacity);
|
||||||
let material = bevy_sprite::ColorMaterial {
|
|
||||||
color: bevy_color,
|
|
||||||
texture: None,
|
|
||||||
..default()
|
|
||||||
};
|
|
||||||
#[cfg(feature = "dim3")]
|
|
||||||
let material = StandardMaterial {
|
|
||||||
metallic: 0.5,
|
|
||||||
perceptual_roughness: 0.5,
|
|
||||||
double_sided: true, // TODO: this doesn't do anything?
|
|
||||||
..StandardMaterial::from(bevy_color)
|
|
||||||
};
|
|
||||||
let material_handle = instanced_materials
|
|
||||||
.entry(color.coords.map(|c| (c * 255.0) as usize).into())
|
|
||||||
.or_insert_with(|| materials.add(material));
|
|
||||||
let material_weak_handle = material_handle.clone_weak();
|
|
||||||
|
|
||||||
if let Some(mesh) = mesh {
|
if let Some(mesh) = mesh {
|
||||||
#[cfg(feature = "dim2")]
|
#[cfg(feature = "dim2")]
|
||||||
@@ -154,7 +116,7 @@ impl EntityWithGraphics {
|
|||||||
base_color: color,
|
base_color: color,
|
||||||
collider,
|
collider,
|
||||||
delta,
|
delta,
|
||||||
material: material_weak_handle,
|
material: material_handle,
|
||||||
opacity,
|
opacity,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,18 +126,13 @@ impl EntityWithGraphics {
|
|||||||
commands.entity(self.entity).despawn();
|
commands.entity(self.entity).despawn();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_color(&mut self, materials: &mut Assets<BevyMaterial>, color: Point3<f32>) {
|
pub fn set_color(
|
||||||
if let Some(material) = materials.get_mut(&self.material) {
|
&mut self,
|
||||||
#[cfg(feature = "dim2")]
|
materials: &mut Assets<BevyMaterial>,
|
||||||
{
|
instanced_materials: &mut InstancedMaterials,
|
||||||
material.color = Color::from(Srgba::new(color.x, color.y, color.z, self.opacity));
|
color: Point3<f32>,
|
||||||
}
|
) {
|
||||||
#[cfg(feature = "dim3")]
|
self.material = instanced_materials.insert(materials, color, self.opacity);
|
||||||
{
|
|
||||||
material.base_color =
|
|
||||||
Color::from(Srgba::new(color.x, color.y, color.z, self.opacity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.color = color;
|
self.color = color;
|
||||||
self.base_color = color;
|
self.base_color = color;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ impl PhysicsState {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
islands: IslandManager::new(),
|
islands: IslandManager::new(),
|
||||||
broad_phase: DefaultBroadPhase::new(),
|
broad_phase: DefaultBroadPhase::default(),
|
||||||
narrow_phase: NarrowPhase::new(),
|
narrow_phase: NarrowPhase::new(),
|
||||||
bodies: RigidBodySet::new(),
|
bodies: RigidBodySet::new(),
|
||||||
colliders: ColliderSet::new(),
|
colliders: ColliderSet::new(),
|
||||||
|
|||||||
@@ -178,11 +178,12 @@ struct OtherBackends {
|
|||||||
}
|
}
|
||||||
struct Plugins(Vec<Box<dyn TestbedPlugin>>);
|
struct Plugins(Vec<Box<dyn TestbedPlugin>>);
|
||||||
|
|
||||||
pub struct TestbedGraphics<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h> {
|
pub struct TestbedGraphics<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k> {
|
||||||
graphics: &'a mut GraphicsManager,
|
graphics: &'a mut GraphicsManager,
|
||||||
commands: &'a mut Commands<'d, 'e>,
|
commands: &'a mut Commands<'d, 'e>,
|
||||||
meshes: &'a mut Assets<Mesh>,
|
meshes: &'a mut Assets<Mesh>,
|
||||||
materials: &'a mut Assets<BevyMaterial>,
|
materials: &'a mut Assets<BevyMaterial>,
|
||||||
|
material_handles: &'a mut Query<'i, 'j, &'k mut BevyMaterialComponent>,
|
||||||
components: &'a mut Query<'b, 'f, &'c mut Transform>,
|
components: &'a mut Query<'b, 'f, &'c mut Transform>,
|
||||||
#[allow(dead_code)] // Dead in 2D but not in 3D.
|
#[allow(dead_code)] // Dead in 2D but not in 3D.
|
||||||
camera_transform: GlobalTransform,
|
camera_transform: GlobalTransform,
|
||||||
@@ -192,8 +193,8 @@ pub struct TestbedGraphics<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h> {
|
|||||||
mouse: &'a SceneMouse,
|
mouse: &'a SceneMouse,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Testbed<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h> {
|
pub struct Testbed<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k> {
|
||||||
graphics: Option<TestbedGraphics<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>>,
|
graphics: Option<TestbedGraphics<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k>>,
|
||||||
harness: &'a mut Harness,
|
harness: &'a mut Harness,
|
||||||
state: &'a mut TestbedState,
|
state: &'a mut TestbedState,
|
||||||
#[cfg(feature = "other-backends")]
|
#[cfg(feature = "other-backends")]
|
||||||
@@ -508,9 +509,10 @@ impl TestbedApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'g, 'h> TestbedGraphics<'_, '_, '_, '_, '_, '_, 'g, 'h> {
|
impl<'g, 'h> TestbedGraphics<'_, '_, '_, '_, '_, '_, 'g, 'h, '_, '_, '_> {
|
||||||
pub fn set_body_color(&mut self, body: RigidBodyHandle, color: [f32; 3]) {
|
pub fn set_body_color(&mut self, body: RigidBodyHandle, color: [f32; 3]) {
|
||||||
self.graphics.set_body_color(self.materials, body, color);
|
self.graphics
|
||||||
|
.set_body_color(self.materials, self.material_handles, body, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ui_context_mut(&mut self) -> &mut EguiContexts<'g, 'h> {
|
pub fn ui_context_mut(&mut self) -> &mut EguiContexts<'g, 'h> {
|
||||||
@@ -585,7 +587,7 @@ impl<'g, 'h> TestbedGraphics<'_, '_, '_, '_, '_, '_, 'g, 'h> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Testbed<'_, '_, '_, '_, '_, '_, '_, '_> {
|
impl Testbed<'_, '_, '_, '_, '_, '_, '_, '_, '_, '_, '_> {
|
||||||
pub fn set_number_of_steps_per_frame(&mut self, nsteps: usize) {
|
pub fn set_number_of_steps_per_frame(&mut self, nsteps: usize) {
|
||||||
self.state.nsteps = nsteps
|
self.state.nsteps = nsteps
|
||||||
}
|
}
|
||||||
@@ -1131,6 +1133,7 @@ fn update_testbed(
|
|||||||
commands: &mut commands,
|
commands: &mut commands,
|
||||||
meshes: &mut *meshes,
|
meshes: &mut *meshes,
|
||||||
materials: &mut *materials,
|
materials: &mut *materials,
|
||||||
|
material_handles: &mut material_handles,
|
||||||
components: &mut gfx_components,
|
components: &mut gfx_components,
|
||||||
camera_transform: *cameras.single().1,
|
camera_transform: *cameras.single().1,
|
||||||
camera: &mut cameras.single_mut().2,
|
camera: &mut cameras.single_mut().2,
|
||||||
@@ -1246,6 +1249,7 @@ fn update_testbed(
|
|||||||
commands: &mut commands,
|
commands: &mut commands,
|
||||||
meshes: &mut *meshes,
|
meshes: &mut *meshes,
|
||||||
materials: &mut *materials,
|
materials: &mut *materials,
|
||||||
|
material_handles: &mut material_handles,
|
||||||
components: &mut gfx_components,
|
components: &mut gfx_components,
|
||||||
camera_transform: *cameras.single().1,
|
camera_transform: *cameras.single().1,
|
||||||
camera: &mut cameras.single_mut().2,
|
camera: &mut cameras.single_mut().2,
|
||||||
@@ -1421,6 +1425,7 @@ fn update_testbed(
|
|||||||
commands: &mut commands,
|
commands: &mut commands,
|
||||||
meshes: &mut *meshes,
|
meshes: &mut *meshes,
|
||||||
materials: &mut *materials,
|
materials: &mut *materials,
|
||||||
|
material_handles: &mut material_handles,
|
||||||
components: &mut gfx_components,
|
components: &mut gfx_components,
|
||||||
camera_transform: *cameras.single().1,
|
camera_transform: *cameras.single().1,
|
||||||
camera: &mut cameras.single_mut().2,
|
camera: &mut cameras.single_mut().2,
|
||||||
|
|||||||
Reference in New Issue
Block a user