-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathelastic_cut3.rs
101 lines (93 loc) · 3.27 KB
/
elastic_cut3.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use wgsparkl_testbed3d::{wgsparkl, RapierData};
use bevy::prelude::*;
use bevy::render::renderer::RenderDevice;
use nalgebra::{vector, DMatrix, Isometry3};
use rapier3d::geometry::HeightField;
use rapier3d::prelude::{ColliderBuilder, RigidBodyBuilder};
use wgsparkl::{
models::ElasticCoefficients,
pipeline::MpmData,
solver::{Particle, ParticleDynamics, ParticlePhase, SimulationParams},
};
use wgsparkl_testbed3d::{AppState, PhysicsContext};
pub fn elastic_cut_demo(
mut commands: Commands,
device: Res<RenderDevice>,
mut app_state: ResMut<AppState>,
) {
let mut rapier_data = RapierData::default();
let device = device.wgpu_device();
let nxz = 50;
let cell_width = 1.0;
let mut particles = vec![];
for i in 0..nxz {
for j in 0..30 {
for k in 0..nxz {
let position = vector![
i as f32 + 0.5 - nxz as f32 / 2.0,
j as f32 + 0.5 + 60.0,
k as f32 + 0.5 - nxz as f32 / 2.0
] * cell_width
/ 2.0;
let density = 2700.0;
let radius = cell_width / 4.0;
particles.push(Particle {
position,
dynamics: ParticleDynamics::with_density(radius, density),
model: ElasticCoefficients::from_young_modulus(10_000_000.0, 0.2),
plasticity: None,
phase: Some(ParticlePhase {
phase: 1.0,
max_stretch: f32::MAX,
}),
color: None,
});
}
}
}
if !app_state.restarting {
app_state.num_substeps = 20;
app_state.gravity_factor = 4.0;
};
let params = SimulationParams {
gravity: vector![0.0, -9.81, 0.0] * app_state.gravity_factor,
dt: (1.0 / 60.0) / (app_state.num_substeps as f32),
};
let rb = RigidBodyBuilder::fixed().translation(vector![0.0, -4.0, 0.0]);
let rb_handle = rapier_data.bodies.insert(rb);
let co = ColliderBuilder::cuboid(100.0, 1.0, 100.0);
rapier_data
.colliders
.insert_with_parent(co, rb_handle, &mut rapier_data.bodies);
// TODO: use only two rectangle per cutting tool.
// We can’t right now since we don’t really sample the triangles.
for k in 0..3 {
let heights = DMatrix::zeros(10, 10);
let heightfield = HeightField::new(heights, vector![35.0, 1.0, 10.0]);
let (mut vtx, idx) = heightfield.to_trimesh();
vtx.iter_mut().for_each(|pt| {
*pt = Isometry3::rotation(vector![1.3, 0.0, 0.0]) * *pt
+ vector![0.0, 10.0, k as f32 * 10.0 - 10.0]
});
let rb = RigidBodyBuilder::fixed();
let rb_handle = rapier_data.bodies.insert(rb);
let co = ColliderBuilder::trimesh(vtx, idx).unwrap();
rapier_data
.colliders
.insert_with_parent(co, rb_handle, &mut rapier_data.bodies);
}
let data = MpmData::new(
device,
params,
&particles,
&rapier_data.bodies,
&rapier_data.colliders,
cell_width,
60_000,
);
commands.insert_resource(PhysicsContext {
data,
rapier_data,
particles,
});
}