dimforge / salva Goto Github PK
View Code? Open in Web Editor NEW2 and 3-dimensional fluid simulation library in Rust.
Home Page: https://salva.rs
License: Apache License 2.0
2 and 3-dimensional fluid simulation library in Rust.
Home Page: https://salva.rs
License: Apache License 2.0
There is no changelog in salva, but there is one in rapier. Is there a reason for that?
Say I wanted to simulate an adhesive of some sort, that would proactively stick to things.
Is this possible to simulate? If so, could explicit properties be added to enable it? From things like cyanoacrylate (very thin at first, but then it cures solid) all the way to hot glue (very thick and rubbery, changes state based on temperature).
I'm not sure how it would look, but at least adhesion and cohesion would be the two most important properties to consider, in addition to whatever you already have.
A quick dig command dig salva.rs TXT +short
outputs "v=spf1 +all"
.
Page 54 of RFC 7208 shows this is an all-inclusive mechanism allowing all IP addresses to pass the SPF check. In simple terms, it means malicious actors could spam on behalf of your domain name and therefore negatively affect domain reputation.
EDIT: I just noticed that you have a separate repository for the website, sorry for posting here.
sampling the surface of a heightfield, causes lines to appear in the sampled partices, where it should be a continuous 'plane' of particles.
This is an example, where there should be 100 particles, but only 81. It usually happens along an axis, but sometimes at 45 deg angles (I havent been able to repro that).
Repro here:
Hi, in the Salva documentation I read it has "WASM support". So is there a WASM port of Salva? How could I get it?
https://docs.rs/salva3d/latest/salva3d/
Thanks!
Is there anything I am doing wrong with this:
Removing a boundary, causes a panic.
Reproduction is here: https://github.com/rezural/salva/tree/panic-heightfield-boundaries
I changed the example heightfield3
: rezural@0b94f1e#diff-6e95f7a94394df65d066f26ea4ce4087aa8caf504133160fef8dea6c01a75642
can be run with :
RUST_BACKTRACE=1 cargo run --release --features=parallel --bin all_examples3 -- --pause --example 'Height field'
basically:
#[derive(Clone, Copy)]
struct BoundaryHandles {
collider: ColliderHandle,
boundary: BoundaryHandle,
body: RigidBodyHandle,
}
fn remove_boundary(
handles: BoundaryHandles,
fluids_pipeline: &mut FluidsPipeline,
bodies: &mut RigidBodySet,
colliders: &mut ColliderSet,
) {
fluids_pipeline
.coupling
.unregister_coupling(handles.collider);
fluids_pipeline
.liquid_world
.remove_boundary(handles.boundary);
// bodies.remove(bodies);
}
removing previous boundaries
thread 'main' panicked at 'No element at index', build/salva3d/../../src/object/contiguous_arena.rs:128:13
stack backtrace:
0: rust_begin_unwind
at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/std/src/panicking.rs:515:5
1: core::panicking::panic_fmt
at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/panicking.rs:92:14
2: core::option::expect_failed
at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/option.rs:1578:5
3: core::option::Option<T>::expect
at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/option.rs:685:21
4: <generational_arena::Arena<T> as core::ops::index::IndexMut<generational_arena::Index>>::index_mut
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/generational-arena-0.2.8/src/lib.rs:1305:9
5: salva3d::object::contiguous_arena::ContiguousArena<Idx,T>::remove
at /home/rezural/data/code/fluidsim/dm-examples/vendor/salva/build/salva3d/../../src/object/contiguous_arena.rs:128:13
6: salva3d::liquid_world::LiquidWorld::remove_boundary
at /home/rezural/data/code/fluidsim/dm-examples/vendor/salva/build/salva3d/../../src/liquid_world.rs:174:9
7: all_examples3::heightfield3::remove_boundary
at ./heightfield3.rs:110:5
8: all_examples3::heightfield3::init_world::{{closure}}
at ./heightfield3.rs:61:17
9: <alloc::boxed::Box<F,A> as core::ops::function::FnMut<Args>>::call_mut
at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/alloc/src/boxed.rs:1579:9
10: <salva3d::integrations::rapier::testbed_plugin::FluidsTestbedPlugin as rapier_testbed3d::plugin::TestbedPlugin>::run_callbacks
at /home/rezural/data/code/fluidsim/dm-examples/vendor/salva/build/salva3d/../../src/integrations/rapier/testbed_plugin.rs:315:13
11: rapier_testbed3d::testbed::update_testbed
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/rapier_testbed3d-0.10.0/src_testbed/testbed.rs:1164:17
12: core::ops::function::Fn::call
at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/ops/function.rs:70:5
13: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &F>::call_mut
at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/ops/function.rs:247:13
14: <Func as bevy_ecs::system::into_system::SystemParamFunction<(),Out,(F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11),()>>::run
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.5.0/src/system/into_system.rs:207:21
15: <bevy_ecs::system::into_system::FunctionSystem<In,Out,Param,Marker,F> as bevy_ecs::system::system::System>::run_unsafe
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.5.0/src/system/into_system.rs:147:19
16: bevy_ecs::system::system::System::run
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.5.0/src/system/system.rs:48:18
17: <bevy_ecs::schedule::executor::SingleThreadedExecutor as bevy_ecs::schedule::executor::ParallelSystemExecutor>::run_systems
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.5.0/src/schedule/executor.rs:34:17
18: <bevy_ecs::schedule::stage::SystemStage as bevy_ecs::schedule::stage::Stage>::run
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.5.0/src/schedule/stage.rs:822:17
19: bevy_ecs::schedule::Schedule::run_once
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.5.0/src/schedule/mod.rs:201:13
20: <bevy_ecs::schedule::Schedule as bevy_ecs::schedule::stage::Stage>::run
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.5.0/src/schedule/mod.rs:219:21
21: bevy_app::app::App::update
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_app-0.5.0/src/app.rs:58:9
22: bevy_winit::winit_runner_with::{{closure}}
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_winit-0.5.0/src/lib.rs:485:17
23: winit::platform_impl::platform::sticky_exit_callback
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/linux/mod.rs:736:5
24: winit::platform_impl::platform::x11::EventLoop<T>::run_return
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/linux/x11/mod.rs:303:17
25: winit::platform_impl::platform::x11::EventLoop<T>::run
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/linux/x11/mod.rs:398:9
26: winit::platform_impl::platform::EventLoop<T>::run
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/linux/mod.rs:652:56
27: winit::event_loop::EventLoop<T>::run
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/event_loop.rs:154:9
28: bevy_winit::run
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_winit-0.5.0/src/lib.rs:171:5
29: bevy_winit::winit_runner_with
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_winit-0.5.0/src/lib.rs:493:9
30: bevy_winit::winit_runner
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_winit-0.5.0/src/lib.rs:211:5
31: core::ops::function::Fn::call
at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/ops/function.rs:70:5
32: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/alloc/src/boxed.rs:1586:9
33: bevy_app::app::App::run
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_app-0.5.0/src/app.rs:68:9
34: bevy_app::app_builder::AppBuilder::run
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_app-0.5.0/src/app_builder.rs:49:9
35: rapier_testbed3d::testbed::TestbedApp::run
at /home/rezural/.cargo/registry/src/github.com-1ecc6299db9ec823/rapier_testbed3d-0.10.0/src_testbed/testbed.rs:418:13
36: all_examples3::main
at ./all_examples3.rs:76:5
37: core::ops::function::FnOnce::call_once
at /rustc/c8dfcfe046a7680554bf4eb612bad840e7631c4b/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Segmentation fault (core dumped)
There are some cases when the asserts are hit, and stop simulation. The ask of this issue is, are all the asserts needed? Could the simulation be continued in any way, even if some things go wrong. Not sure about all, but I know sometimes some particles seems to almost explode and go out a lot, and then all stop. I would be ok with them exploding, I could lower some parameters, but maybe not all asserts are needed.
Eg an assert of where an index from array is out of bounds, thats needed. But if a value is 0 where a division by 0 happens, in that case you could put EPSILON instead of 0 and somehow continue the simulation.
I think the implementation of the Poly6 gradient has a bug:
https://github.com/rustsim/salva/blob/master/src/kernel/poly6_kernel.rs#L34
The is second multiplication with r which is incorrect, to my understanding it should be normalizer * (h * h - r * r).powi(2) * na::convert(-6.0)
Derivative of the original function (used 2d normalizer here)
https://www.wolframalpha.com/input/?i=%284%2F%28pi+*+h%5E8%29+*+%28h%5E2+-+x%5E2%29%5E3%29+d%2Fdx
(for the "gradient factor" just taking the derivative is enough, but for completeness here's a proper gradient :) https://www.wolframalpha.com/input/?i=grad+%284%2F%28pi+*+h%5E8%29+*+%28h%5E2+-+sqrt%28x%5E2+%2B+y%5E2%29%5E2%29%5E3%29)
I'll just leave this idea here. MPM (Material Point Method) is a great thing for simulation of Rigid Bodies interactions. Some examples:
Panics with:
thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 0', build/salva3d/../../src/geometry/contacts.rs:99:10
here is a patch to apply to master:
diff --git a/examples3d/faucet3.rs b/examples3d/faucet3.rs
index 2bcbc7f..b5ca801 100644
--- a/examples3d/faucet3.rs
+++ b/examples3d/faucet3.rs
@@ -4,9 +4,11 @@ use na::{Point3, Vector3};
use rapier3d::dynamics::{JointSet, RigidBodyBuilder, RigidBodySet};
use rapier3d::geometry::{ColliderBuilder, ColliderSet};
use rapier_testbed3d::{Testbed, TestbedApp};
-use salva3d::integrations::rapier::{ColliderSampling, FluidsPipeline, FluidsTestbedPlugin};
+use salva3d::integrations::rapier::{
+ ColliderCouplingSet, ColliderSampling, FluidsPipeline, FluidsTestbedPlugin,
+};
use salva3d::object::{Boundary, Fluid};
-use salva3d::solver::{Akinci2013SurfaceTension, XSPHViscosity};
+use salva3d::solver::{Akinci2013SurfaceTension, IISPHSolver, XSPHViscosity};
use std::f32;
#[path = "./helper.rs"]
@@ -24,7 +26,12 @@ pub fn init_world(testbed: &mut Testbed) {
let mut bodies = RigidBodySet::new();
let mut colliders = ColliderSet::new();
let joints = JointSet::new();
- let mut fluids_pipeline = FluidsPipeline::new(PARTICLE_RADIUS, SMOOTHING_FACTOR);
+ let solver: IISPHSolver = IISPHSolver::new();
+
+ let mut fluids_pipeline = FluidsPipeline {
+ liquid_world: salva3d::LiquidWorld::new(solver, PARTICLE_RADIUS, SMOOTHING_FACTOR),
+ coupling: ColliderCouplingSet::new(),
+ };
let ground_rad = 0.15;
I wasn't able to get the all_examples3 binary to run. It panics with this error on startup:
$ cd examples3d
$ cargo run --bin all_examples3
wgpu error: Validation Error
Caused by:
In a RenderPass
note: encoder = `<CommandBuffer-(1, 2, Metal)>`
In a pass parameter
note: command buffer = `<CommandBuffer-(1, 2, Metal)>`
attachment's sample count 2 is invalid
thread 'main' panicked at 'Handling wgpu errors as fatal by default', [...]/wgpu-0.7.1/src/backend/direct.rs:1896:5
After doing a small amount of research it seems related to MSAA levels.
in salva/build/salva3d, running
cargo build --features sampling
# cargo build --features sampling,rapier #works however
Errors with:
error[E0433]: failed to resolve: use of undeclared type or module `rapier`
--> build/salva3d/../../src/sampling/ray_sampling.rs:5:5
|
5 | use rapier::geometry::Shape;
| ^^^^^^ use of undeclared type or module `rapier`
error[E0405]: cannot find trait `Shape` in this scope
--> build/salva3d/../../src/sampling/ray_sampling.rs:9:45
|
9 | pub fn shape_surface_ray_sample<S: ?Sized + Shape>(
| ^^^^^ not found in this scope
|
help: consider importing this trait
|
1 | use ncollide3d::shape::Shape;
|
error[E0405]: cannot find trait `Shape` in this scope
--> build/salva3d/../../src/sampling/ray_sampling.rs:18:44
|
18 | pub fn shape_volume_ray_sample<S: ?Sized + Shape>(
| ^^^^^ not found in this scope
|
help: consider importing this trait
|
1 | use ncollide3d::shape::Shape;
|
It took me a little while to work out why this was not working.
I can create a pr with sampling depending on rapier?
Currently, the rapier is in version 0.17, I am not sure whether salva 0.7 is still good to use.
I got this error when trying to compile basic2.rs
and helpers.rs
for salva2d example
esbuah git:(master) ✗ cargo run
Compiling esbuah v0.1.0 (/home/andraantariksa/Projects/esbuah)
error[E0432]: unresolved import `nphysics_testbed2d::objects::FluidRenderingMode`
--> src/main.rs:12:26
|
12 | use nphysics_testbed2d::{objects::FluidRenderingMode, Testbed};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `FluidRenderingMode` in `objects`
error[E0308]: mismatched types
--> src/main.rs:58:29
|
58 | testbed.set_fluid_color(fluid_handle, Point3::new(0.8, 0.7, 1.0));
| ^^^^^^^^^^^^ expected `usize`, found struct `salva2d::object::fluid::FluidHandle`
error[E0308]: mismatched types
--> src/main.rs:58:43
|
58 | testbed.set_fluid_color(fluid_handle, Point3::new(0.8, 0.7, 1.0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `nalgebra::geometry::point::Point`, found struct `na::Point`
|
= note: expected struct `nalgebra::geometry::point::Point<f32, nalgebra::base::dimension::U3>`
found struct `na::Point<{float}, na::U3>`
= note: perhaps two different versions of crate `nalgebra` are being used?
error[E0308]: mismatched types
--> src/main.rs:63:29
|
63 | testbed.set_fluid_color(fluid_handle, Point3::new(0.6, 0.8, 0.5));
| ^^^^^^^^^^^^ expected `usize`, found struct `salva2d::object::fluid::FluidHandle`
error[E0308]: mismatched types
--> src/main.rs:63:43
|
63 | testbed.set_fluid_color(fluid_handle, Point3::new(0.6, 0.8, 0.5));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `nalgebra::geometry::point::Point`, found struct `na::Point`
|
= note: expected struct `nalgebra::geometry::point::Point<f32, nalgebra::base::dimension::U3>`
found struct `na::Point<{float}, na::U3>`
= note: perhaps two different versions of crate `nalgebra` are being used?
error[E0308]: mismatched types
--> src/main.rs:115:39
|
115 | testbed.set_body_color(rb_handle, Point3::new(0.3, 0.3, 0.7));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `nalgebra::geometry::point::Point`, found struct `na::Point`
|
= note: expected struct `nalgebra::geometry::point::Point<f32, nalgebra::base::dimension::U3>`
found struct `na::Point<{float}, na::U3>`
= note: perhaps two different versions of crate `nalgebra` are being used?
error[E0308]: mismatched types
--> src/main.rs:194:9
|
194 | mechanical_world,
| ^^^^^^^^^^^^^^^^ expected struct `nphysics2d::world::mechanical_world::MechanicalWorld`, found struct `nphysics2d::world::MechanicalWorld`
|
= note: expected struct `nphysics2d::world::mechanical_world::MechanicalWorld<f32, generational_arena::Index, generational_arena::Index>`
found struct `nphysics2d::world::MechanicalWorld<{float}, generational_arena::Index, generational_arena::Index>`
= note: perhaps two different versions of crate `nphysics2d` are being used?
error[E0308]: mismatched types
--> src/main.rs:195:9
|
195 | geometrical_world,
| ^^^^^^^^^^^^^^^^^ expected struct `nphysics2d::world::geometrical_world::GeometricalWorld`, found struct `nphysics2d::world::GeometricalWorld`
|
= note: expected struct `nphysics2d::world::geometrical_world::GeometricalWorld<f32, generational_arena::Index, generational_arena::Index>`
found struct `nphysics2d::world::GeometricalWorld<_, generational_arena::Index, generational_arena::Index>`
= note: perhaps two different versions of crate `nphysics2d` are being used?
error[E0308]: mismatched types
--> src/main.rs:196:9
|
196 | bodies,
| ^^^^^^ expected struct `nphysics2d::object::body_set::DefaultBodySet`, found struct `nphysics2d::object::DefaultBodySet`
|
= note: expected struct `nphysics2d::object::body_set::DefaultBodySet<f32>`
found struct `nphysics2d::object::DefaultBodySet<{float}>`
= note: perhaps two different versions of crate `nphysics2d` are being used?
error[E0308]: mismatched types
--> src/main.rs:197:9
|
197 | colliders,
| ^^^^^^^^^ expected struct `nphysics2d::object::collider_set::DefaultColliderSet`, found struct `nphysics2d::object::DefaultColliderSet`
|
= note: expected struct `nphysics2d::object::collider_set::DefaultColliderSet<f32>`
found struct `nphysics2d::object::DefaultColliderSet<f32>`
= note: perhaps two different versions of crate `nphysics2d` are being used?
error[E0308]: mismatched types
--> src/main.rs:198:9
|
198 | joint_constraints,
| ^^^^^^^^^^^^^^^^^ expected struct `nphysics2d::joint::joint_constraint::DefaultJointConstraintSet`, found struct `nphysics2d::joint::DefaultJointConstraintSet`
|
= note: expected struct `nphysics2d::joint::joint_constraint::DefaultJointConstraintSet<f32>`
found struct `nphysics2d::joint::DefaultJointConstraintSet<_, _>`
= note: perhaps two different versions of crate `nphysics2d` are being used?
error[E0308]: mismatched types
--> src/main.rs:199:9
|
199 | force_generators,
| ^^^^^^^^^^^^^^^^ expected trait `nphysics2d::force_generator::force_generator::ForceGenerator`, found trait `nphysics2d::force_generator::ForceGenerator`
|
= note: expected struct `generational_arena::Arena<std::boxed::Box<(dyn nphysics2d::force_generator::force_generator::ForceGenerator<f32, generational_arena::Index> + 'static)>>`
found struct `generational_arena::Arena<std::boxed::Box<dyn nphysics2d::force_generator::ForceGenerator<_, _>>>`
= note: perhaps two different versions of crate `nphysics2d` are being used?
error[E0308]: mismatched types
--> src/main.rs:201:30
|
201 | testbed.set_liquid_world(liquid_world, coupling_set);
| ^^^^^^^^^^^^ expected struct `salva2d::liquid_world::LiquidWorld`, found a different struct `salva2d::liquid_world::LiquidWorld`
|
= note: expected struct `salva2d::liquid_world::LiquidWorld<f32>` (struct `salva2d::liquid_world::LiquidWorld`)
found struct `salva2d::liquid_world::LiquidWorld<f32>` (struct `salva2d::liquid_world::LiquidWorld`)
= note: perhaps two different versions of crate `salva2d` are being used?
error[E0308]: mismatched types
--> src/main.rs:201:44
|
201 | testbed.set_liquid_world(liquid_world, coupling_set);
| ^^^^^^^^^^^^ expected struct `salva2d::coupling::collider_coupling_manager::ColliderCouplingManager`, found struct `salva2d::coupling::collider_coupling_manager::ColliderCouplingSet`
|
= note: expected struct `salva2d::coupling::collider_coupling_manager::ColliderCouplingManager<f32, generational_arena::Index>`
found struct `salva2d::coupling::collider_coupling_manager::ColliderCouplingSet<f32, generational_arena::Index>`
error[E0308]: mismatched types
--> src/main.rs:202:21
|
202 | testbed.look_at(Point2::new(0.0, 2.5), 95.0);
| ^^^^^^^^^^^^^^^^^^^^^ expected struct `nalgebra::geometry::point::Point`, found struct `na::Point`
|
= note: expected struct `nalgebra::geometry::point::Point<f32, nalgebra::base::dimension::U2>`
found struct `na::Point<{float}, na::U2>`
= note: perhaps two different versions of crate `nalgebra` are being used?
error[E0599]: no method named `set_fluid_rendering_mode` found for mutable reference `&mut nphysics_testbed2d::testbed::Testbed` in the current scope
--> src/main.rs:203:13
|
203 | testbed.set_fluid_rendering_mode(FluidRenderingMode::VelocityColor { min: 0.0, max: 5.0 });
| ^^^^^^^^^^^^^^^^^^^^^^^^ method not found in `&mut nphysics_testbed2d::testbed::Testbed`
error[E0599]: no method named `mechanical_world_mut` found for mutable reference `&mut nphysics_testbed2d::testbed::Testbed` in the current scope
--> src/main.rs:204:13
|
204 | testbed.mechanical_world_mut().set_timestep(1.0 / 100.0);
| ^^^^^^^^^^^^^^^^^^^^ method not found in `&mut nphysics_testbed2d::testbed::Testbed`
error: aborting due to 17 previous errors
Some errors have detailed explanations: E0308, E0432, E0599.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `esbuah`.
To learn more, run the command again with --verbose.
Here's my Cargo.toml
file
[package]
name = "esbuah"
version = "0.1.0"
authors = ["Andra Antariksa <[email protected]>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
parallel = [ "nphysics_testbed2d/parallel"]
[dependencies]
Inflector = "0.11"
alga = "0.9"
salva2d = { version = "0.2.0", features = [ "nphysics", "sampling" ] }
nalgebra = "0.20"
ncollide2d = "0.22"
nphysics2d = "0.14"
nphysics_testbed2d = { version = "0.7", features = [ "fluids" ] }
I'm testing nphysics, salva and legion (entity component system) together. I need all the physics data to be a legion resource (and that it means that it will be shared between threads). The problem is with the LiquidWorld that is non Send, so I can not included inside the physics bundle resource. If I wrap everything with a Arc<Mutex<>> like the following code:
pub struct PhysicsResourceInner {
pub mechanical_world: DefaultMechanicalWorld<Real>,
pub geometrical_world: DefaultGeometricalWorld<Real>,
pub bodies: DefaultBodySet<Real>,
pub colliders: DefaultColliderSet<Real>,
pub joint_constraints: DefaultJointConstraintSet<Real>,
pub force_generators: DefaultForceGeneratorSet<Real>,
// Fluid
pub fluid_world: LiquidWorld::<Real>,
pub fluid_couplings: ColliderCouplingSet::<Real, DefaultBodyHandle>,
}
#[derive(Clone)]
pub struct PhysicsResource {
pub inner: Arc<Mutex<PhysicsResourceInner>>,
}
Then I can mark it as Send using an "unsafe" impl (like the above). Is this really safe or there is some hidden problems that will arise?
unsafe impl Send for PhysicsResource {}
EDIT: Not even the unsafe impl makes it compile. The important part of the error messages goes like:
error[E0277]: `(dyn salva2d::solver::pressure::pressure_solver::PressureSolver<f32> + 'static)` cannot be sent between threads safely
--> src/app/mod.rs:106:73
|
106 | if let Some(physics_resource) = &mut self.resources.get_mut::<PhysicsResource>() {
| ^^^^^^^ `(dyn salva2d::solver::pressure::pressure_solver::PressureSolver<f32> + 'static)` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `(dyn salva2d::solver::pressure::pressure_solver::PressureSolver<f32> + 'static)`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<(dyn salva2d::solver::pressure::pressure_solver::PressureSolver<f32> + 'static)>`
= note: required because it appears within the type `std::boxed::Box<(dyn salva2d::solver::pressure::pressure_solver::PressureSolver<f32> + 'static)>`
= note: required because it appears within the type `salva2d::liquid_world::LiquidWorld<f32>`
= note: required because it appears within the type `resources::physics::PhysicsResourceInner`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Mutex<resources::physics::PhysicsResourceInner>`
= note: required because of the requirements on the impl of `std::marker::Sync` for `std::sync::Arc<std::sync::Mutex<resources::physics::PhysicsResourceInner>>`
= note: required because it appears within the type `resources::physics::PhysicsResource`
= note: required because of the requirements on the impl of `legion_systems::resource::Resource` for `resources::physics::PhysicsResource`
Edit 2: If I change on the salva source "liquid_world.rs" (the two lines above), I can compile (without the unsafe impl). But I'm not sure if it ok or I'm missing something. Above the changes I made:
On the LiquidWorld struct definition add + Send to the solve:
solver: Box<dyn PressureSolver<N> + Send>,
And also add + Send to the new function:
solver: impl PressureSolver<N> + 'static + Send,
Today I do not see a way to correctly delete particles over time; it would be nice if some api functionality were exposed to allow clients to delete particles over time, instead of from spatial properties. Perhaps a timestamp, or a monotonically increasing "batch id" that would allow selective deletions of particles of the lowest batch id, for example?
Steps to reproduce:
cargo run --bin all_examples3 --release
I integrated rapier and rapier-f64. Then I added salva, but now it doesn't build and salva only works with rapier, not rapier64(eg. features="rapier")
https://github.com/appsinacup/godot-rapier-2d
appsinacup/godot-rapier-physics#61
One solution could be to add same as for rapier, single or double builds, and then for feature add rapier or rapier-f64.
I assume it is a historical leftover, but it can be confusing for new users.
when adding particles to the system (either on initialization, or via testbed.add_callback_with_fluids), it is difficult know for certain that there is not a particle (or collider) already in this position. adding a particle that intersects causes explosions basically.
I am currently testing that none of the existant particles intersect new particles using ncollide3d::query::proximity_ball_ball, but this is sub optimal.
Is there a performant way of testing whether a particle is intersecting with the fluid at all?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.