make cloth shape and cry

This commit is contained in:
Raptorox 2025-05-22 10:41:38 +02:00
parent 2c457ae91f
commit 8c713df698
3 changed files with 51 additions and 20 deletions

View file

@ -21,9 +21,16 @@ impl Link {
let vec = self.p2.borrow().pos - self.p1.borrow().pos; let vec = self.p2.borrow().pos - self.p1.borrow().pos;
let vec_len = (vec.x*vec.x + vec.y*vec.y).sqrt(); let vec_len = (vec.x*vec.x + vec.y*vec.y).sqrt();
let vec_norm = vec/vec_len; let vec_norm = vec/vec_len;
let vec_scaled = vec_norm * (self.length-vec_len) * 99.;
self.p1.borrow_mut().apply_force(-vec_scaled); let max_stretch = 50.;
self.p2.borrow_mut().apply_force(vec_scaled); let clamped_len = vec_len.min(self.length + max_stretch);
let displacement = clamped_len - vec_len;
let stiffness = 99.;
let vec_scaled = vec_norm * displacement * stiffness;
let damping = 0.98;
self.p1.borrow_mut().apply_force(-vec_scaled * damping);
self.p2.borrow_mut().apply_force(vec_scaled * damping);
} }
} }

View file

@ -11,11 +11,15 @@ use particle::Particle;
mod link; mod link;
use link::Link; use link::Link;
//const GRAVITY: f32 = 100.; const GRAVITY: f32 = 100.;
fn populate_particles(particles: &mut Vec<Rc<RefCell<Particle>>>, num: u32) { fn populate_particles(particles: &mut Vec<Rc<RefCell<Particle>>>, num: u32, cols: u32) {
for i in 0..num { for i in 0..num {
particles.push(Rc::new(RefCell::new(Particle::new(Vector2f::new(300. + 100. * i as f32, 300.))))); let x_pos = 200. + 50. * (i % cols) as f32;
let y_pos = 100. + 50. * (i / cols) as f32;
let immovable = i < cols;
let particle = Particle::new(Vector2f::new(x_pos, y_pos), immovable);
particles.push(Rc::new(RefCell::new(particle)));
} }
} }
@ -39,11 +43,16 @@ fn populate_links(links: &mut Vec<Link>, particles: &Vec<Rc<RefCell<Particle>>>,
} }
} }
fn apply_forces(particles: Vec<Rc<RefCell<Particle>>>) { /*fn populate_lines(lines: &mut Vec<RectangleShape>, circles: &Vec<CircleShape>, num: u32) {
for i in 0..num {
let rect = RectangleShape::with_size(Vector2f::new(100., 100.));
}
}*/
fn apply_forces(particles: &Vec<Rc<RefCell<Particle>>>) {
for particle in particles { for particle in particles {
let mut borrowed = particle.borrow_mut(); let mut borrowed = particle.borrow_mut();
// borrowed.apply_force(Vector2f::new(0., GRAVITY)); borrowed.apply_force(Vector2f::new(0., GRAVITY));
borrowed.apply_force(Vector2f::new(1., 1.));
} }
} }
@ -62,10 +71,14 @@ fn update_positions(circles: &mut Vec<CircleShape>, particles: &Vec<Rc<RefCell<P
} }
} }
fn draw_all(window: &mut RenderWindow, circles: &Vec<CircleShape>, /* links: Vec<Link> */ ) { fn draw_all(window: &mut RenderWindow, circles: &Vec<CircleShape>, /* lines: &Vec<RectangleShape> */) {
for circle in circles { for circle in circles {
window.draw(circle); window.draw(circle);
} }
// for line in lines {
// window.draw(line);
// }
} }
fn main() -> SfResult<()> { fn main() -> SfResult<()> {
@ -75,14 +88,15 @@ fn main() -> SfResult<()> {
Style::CLOSE, Style::CLOSE,
&Default::default() &Default::default()
)?; )?;
window.set_framerate_limit(144); window.set_framerate_limit(60);
let mut clock = Clock::start()?; let mut clock = Clock::start()?;
let particle_count: u32 = 6; let particle_count: u32 = 60;
let column_count: u32 = 10;
let mut particles: Vec<Rc<RefCell<Particle>>> = vec![]; let mut particles: Vec<Rc<RefCell<Particle>>> = vec![];
populate_particles(&mut particles, particle_count); populate_particles(&mut particles, particle_count, column_count);
let mut links: Vec<Link> = vec![]; let mut links: Vec<Link> = vec![];
populate_links(&mut links, &particles, particle_count); populate_links(&mut links, &particles, particle_count);
@ -93,6 +107,9 @@ fn main() -> SfResult<()> {
let mut circles: Vec<CircleShape> = vec![]; let mut circles: Vec<CircleShape> = vec![];
populate_circles(&mut circles, particle_count, radius, point_count); populate_circles(&mut circles, particle_count, radius, point_count);
// let mut lines: Vec<RectangleShape> = vec![];
// populate_lines(&mut lines, &circles, particle_count);
while window.is_open() { while window.is_open() {
while let Some(event) = window.poll_event() { while let Some(event) = window.poll_event() {
match event { match event {
@ -104,14 +121,15 @@ fn main() -> SfResult<()> {
if mouse::Button::is_pressed(mouse::Button::Left) { if mouse::Button::is_pressed(mouse::Button::Left) {
let mouse_pos = window.mouse_position(); let mouse_pos = window.mouse_position();
let mouse_coords = window.map_pixel_to_coords_current_view(mouse_pos); let mouse_coords = window.map_pixel_to_coords_current_view(mouse_pos);
let p_pos = particles[0].borrow().pos; let p_pos = particles[10].borrow().pos;
particles[0].borrow_mut().apply_force((mouse_coords - p_pos)*8.); particles[10].borrow_mut().apply_force((mouse_coords - p_pos)*4.);
} }
let dt = clock.restart().as_seconds(); let dt = clock.restart().as_seconds();
//particle.apply_force(Vector2f::new(0., GRAVITY)); //particle.apply_force(Vector2f::new(0., GRAVITY));
apply_forces(&particles);
update_particles(&particles, dt); update_particles(&particles, dt);
solve_links(&mut links); solve_links(&mut links);
@ -119,7 +137,7 @@ fn main() -> SfResult<()> {
update_positions(&mut circles, &particles); update_positions(&mut circles, &particles);
window.clear(Color::BLACK); window.clear(Color::BLACK);
draw_all(&mut window, &circles); draw_all(&mut window, &circles, /* &lines */);
window.display(); window.display();
} }

View file

@ -3,15 +3,19 @@ use sfml::system::Vector2f;
pub struct Particle { pub struct Particle {
pub pos: Vector2f, pub pos: Vector2f,
prev_pos: Vector2f, prev_pos: Vector2f,
accel: Vector2f accel: Vector2f,
immovable: bool
} }
impl Particle { impl Particle {
pub fn new(pos: Vector2f) -> Self { pub fn new(pos: Vector2f, immovable: bool) -> Self {
Particle { Particle {
pos: pos, pos: pos,
prev_pos: pos, prev_pos: pos,
accel: Vector2f::default() accel: Vector2f::default(),
immovable: immovable
} }
} }
@ -20,7 +24,9 @@ impl Particle {
} }
pub fn update(&mut self, dt: f32) { pub fn update(&mut self, dt: f32) {
let vel = (self.pos - self.prev_pos) * 0.99; if self.immovable { return; }
let damping = 0.99;
let vel = (self.pos - self.prev_pos) * damping;
let new_pos = self.pos + vel + self.accel * (dt * dt); let new_pos = self.pos + vel + self.accel * (dt * dt);
self.prev_pos = self.pos; self.prev_pos = self.pos;