Skip to content

Commit 0cbbe51

Browse files
committed
Better collisions with freeze
1 parent d1b2ae2 commit 0cbbe51

File tree

2 files changed

+56
-23
lines changed

2 files changed

+56
-23
lines changed

index.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ import('./pkg')
99
// Set world to the collision preset
1010
function worldCollision() {
1111
world = wasm.World.new();
12-
world.add_object(0., -380., 40., -100., 20., 20., 0.8);
13-
world.add_object(-80., 0., 100., -400., 30., 30., 0.8);
12+
world.add_object(0., -380., 40., -100., 20., 20., 0.8, false);
13+
world.add_object(-80., 0., 100., -400., 30., 30., 0.8, false);
1414
}
1515

1616
// Set world to the universal gravitation preset
1717
function worldUniversal() {
1818
world = wasm.World.new();
19-
world.add_object(0., 0., 0., 0., 50., 100000000000000000., 0.5);
20-
world.add_object(0., -300., 600., 0., 20., 10000000., 0.5);
21-
world.add_object(0., 200., -700., 0., 15., 5000000., 0.5);
19+
world.add_object(0., 0., 0., 0., 50., 100000000000000000., 0.5, false);
20+
world.add_object(0., -300., 600., 0., 20., 10000000., 0.5, false);
21+
world.add_object(0., 200., -700., 0., 15., 5000000., 0.5, false);
2222
world.set_gravity_y(0.);
2323
world.set_meter_size(0.001);
2424
}

src/lib.rs

+51-18
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ pub struct Object {
1616
velocity_y: f64,
1717
radius: f64,
1818
mass: f64,
19-
restitution_coef: f64
19+
restitution_coef: f64,
20+
is_freeze: bool
2021
}
2122

2223
#[derive(Clone, Serialize, Deserialize)]
@@ -89,10 +90,11 @@ impl World {
8990
pub fn add_object(
9091
&mut self, pos_x: f64, pos_y: f64,
9192
velocity_x: f64, velocity_y: f64,
92-
radius: f64, mass: f64, restitution_coef: f64
93+
radius: f64, mass: f64, restitution_coef: f64,
94+
is_freeze: bool
9395
) {
9496
self.objects.push(
95-
Object{pos_x, pos_y, velocity_x, velocity_y, radius, mass, restitution_coef});
97+
Object{pos_x, pos_y, velocity_x, velocity_y, radius, mass, restitution_coef, is_freeze});
9698
}
9799

98100
pub fn get_world(&self) -> JsValue {
@@ -142,32 +144,63 @@ impl World {
142144
let overlap = obj.radius + obj_.radius - distance;
143145

144146
if overlap > 0. {
145-
let correction_ratio = overlap / distance;
146-
obj.pos_x -= delta_x * correction_ratio;
147-
obj.pos_y -= delta_y * correction_ratio;
148-
obj_.pos_x += delta_x * correction_ratio;
149-
obj_.pos_y += delta_y * correction_ratio;
147+
let a = (obj_.pos_y - obj.pos_y).atan2(obj_.pos_x - obj.pos_x);
148+
if(obj.is_freeze) {
149+
obj_.pos_x += overlap * a.cos();
150+
obj_.pos_y += overlap * a.sin();
151+
}
152+
else if(obj_.is_freeze) {
153+
obj.pos_x -= overlap * a.cos();
154+
obj.pos_y -= overlap * a.sin();
155+
} else {
156+
let correction_ratio = overlap / distance;
157+
obj.pos_x -= delta_x * correction_ratio;
158+
obj.pos_y -= delta_y * correction_ratio;
159+
obj_.pos_x += delta_x * correction_ratio;
160+
obj_.pos_y += delta_y * correction_ratio;
161+
}
162+
150163

151164
let relative_velocity_x = obj_.velocity_x - obj.velocity_x;
152165
let relative_velocity_y = obj_.velocity_y - obj.velocity_y;
153166

154167
let restitution_coef = obj.restitution_coef.max(obj_.restitution_coef);
155-
168+
156169
let dot_product = delta_x * relative_velocity_x + delta_y * relative_velocity_y;
157-
let impulse = (2. * dot_product) / (distance * (obj.mass + obj_.mass));
158-
159-
obj.velocity_x += (impulse * obj_.mass * delta_x * restitution_coef) / distance;
160-
obj.velocity_y += (impulse * obj_.mass * delta_y * restitution_coef) / distance;
161-
162-
obj_.velocity_x -= (impulse * obj.mass * delta_x * restitution_coef) / distance;
163-
obj_.velocity_y -= (impulse * obj.mass * delta_y * restitution_coef) / distance;
170+
171+
if (obj.is_freeze) {
172+
let impulse = (2. * dot_product) / (distance * (obj_.mass + obj_.mass));
173+
let bounce_x = (impulse * obj_.mass * delta_x) / distance + restitution_coef * ((impulse * obj_.mass * delta_x) / distance);
174+
let bounce_y = (impulse * obj_.mass * delta_y) / distance + restitution_coef * ((impulse * obj_.mass * delta_y) / distance);
175+
176+
obj_.velocity_x -= bounce_x;
177+
obj_.velocity_y -= bounce_y;
178+
}
179+
else if (obj_.is_freeze) {
180+
let impulse = (2. * dot_product) / (distance * (obj.mass + obj.mass));
181+
let bounce_x = (impulse * obj.mass * delta_x) / distance + restitution_coef * ((impulse * obj.mass * delta_x) / distance);
182+
let bounce_y = (impulse * obj.mass * delta_y) / distance +restitution_coef * ((impulse * obj.mass * delta_y) / distance);
183+
obj.velocity_x += bounce_x;
184+
obj.velocity_y += bounce_y;
185+
}
186+
else {
187+
let impulse = (2. * dot_product) / (distance * (obj.mass + obj_.mass));
188+
189+
obj.velocity_x += (impulse * obj_.mass * delta_x * restitution_coef) / distance;
190+
obj.velocity_y += (impulse * obj_.mass * delta_y * restitution_coef) / distance;
191+
192+
obj_.velocity_x -= (impulse * obj.mass * delta_x * restitution_coef) / distance;
193+
obj_.velocity_y -= (impulse * obj.mass * delta_y * restitution_coef) / distance;
194+
}
164195
}
165196
}
166197

167198
// position
168199
for obj in self.objects.iter_mut() {
169-
obj.pos_x += obj.velocity_x * elapsed_time;
170-
obj.pos_y += obj.velocity_y * elapsed_time;
200+
if(!obj.is_freeze) {
201+
obj.pos_x += obj.velocity_x * elapsed_time;
202+
obj.pos_y += obj.velocity_y * elapsed_time;
203+
}
171204
}
172205
}
173206
}

0 commit comments

Comments
 (0)