Skip to content

Commit 41205ab

Browse files
committed
Optimize trajectory calculation
1 parent f2f7bfa commit 41205ab

5 files changed

Lines changed: 137 additions & 93 deletions

File tree

build_all.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/bash
2+
cargo build --release --target wasm32-unknown-unknown
3+
cargo build --release --target x86_64-pc-windows-gnu
4+
cargo build --release --target x86_64-apple-darwin
5+
6+
cp -r res ./target/wasm32-unknown-unknown/release/ &&
7+
cp -r res ./target/x86_64-pc-windows-gnu/release/ &&
8+
cp -r res ./target/x86_64-apple-darwin/release/
9+
10+
cd target || exit
11+
12+
cd wasm32-unknown-unknown/release/ || exit
13+
zip -r ../../gravity-sim-web.zip gravity-sim.wasm res index.html
14+
cd ../../
15+
16+
cd x86_64-pc-windows-gnu/release/ || exit
17+
zip -r ../../gravity-sim-windows.zip gravity-sim.exe res
18+
cd ../../
19+
20+
cd x86_64-apple-darwin/release/ || exit
21+
zip -r ../../gravity-sim-mac.zip gravity-sim res
22+
cd ../../

src/control.rs

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,19 @@ pub struct ControlHandler {
99
move_speed: f32,
1010
scale_speed: f32,
1111
place_elevation: f32,
12-
traj_update_interval: u64,
1312
control_state: ControlState,
1413
ghost_obj: Option<Object>,
15-
traj_update_counter: u64,
1614
trajectories: HashMap<usize, Trajectory>,
1715
}
1816

1917
impl ControlHandler {
20-
fn new(move_speed: f32, scale_speed: f32, traj_update_interval: u64) -> Self {
18+
fn new(move_speed: f32, scale_speed: f32) -> Self {
2119
ControlHandler {
2220
move_speed,
2321
scale_speed,
24-
traj_update_interval,
2522
place_elevation: 0.0,
2623
control_state: ControlState::Idle,
2724
ghost_obj: None,
28-
traj_update_counter: 0,
2925
trajectories: HashMap::new(),
3026
}
3127
}
@@ -60,8 +56,7 @@ impl ControlHandler {
6056
};
6157

6258
renderer.draw_halo(obj.position, obj.radius * 1.1, Some(color));
63-
let traj = obj.calculate_trajectory(objects, physics_handler, 10_000, 10);
64-
traj.draw(renderer, Some(obj.color), obj.radius);
59+
self.draw_obj_trajectory(physics_handler, renderer, objects, &obj);
6560
}
6661

6762
if is_key_released(KeyCode::R) {
@@ -116,7 +111,7 @@ impl ControlHandler {
116111
let ray = Ray::new_from_mouse(renderer.get_cam());
117112

118113
if let Some(obj) = &mut self.ghost_obj {
119-
let veloc = (ray.plane_intersect(Some(self.place_elevation)) - obj.position) / 100.0;
114+
let veloc = (ray.plane_intersect(Some(self.place_elevation)) - obj.position) / 10.0;
120115

121116
let mut virtual_obj: Object = obj.clone();
122117
virtual_obj.add_velocity(veloc);
@@ -128,37 +123,16 @@ impl ControlHandler {
128123
);
129124

130125
obj.draw(renderer);
131-
let traj = virtual_obj.calculate_trajectory(objects, physics_handler, 10_000, 20);
132-
traj.draw(renderer, Some(obj.color), obj.radius);
133-
134-
let mut clones = objects.get_all_in_area(obj.position, 100.0);
135-
let id = clones.push(virtual_obj.clone());
136-
137-
for (id, traj) in &self.trajectories {
138-
let obj = match clones.get(*id) {
139-
Some(obj) => obj,
140-
None => continue,
141-
};
142-
143-
traj.draw(renderer, Some(obj.color), obj.radius);
144-
}
145126

146-
if self.traj_update_counter % self.traj_update_interval == 0 {
147-
self.trajectories =
148-
clones.calculate_trajectories_except(id, physics_handler, 5_000, 20);
149-
}
150-
151-
self.traj_update_counter += 1;
127+
let mut clones = objects.clone().get_all_in_area(virtual_obj.position, 500.0);
128+
clones.push(virtual_obj.clone());
152129

153-
if self.traj_update_counter == (2u128.pow(64) - 1) as u64 {
154-
self.traj_update_counter = 0;
155-
}
130+
self.draw_objects_trajectories(physics_handler, renderer, &clones);
156131
}
157132

158133
if is_mouse_button_released(MouseButton::Left) {
159134
if let Some(obj) = &mut self.ghost_obj {
160-
let veloc =
161-
(ray.plane_intersect(Some(self.place_elevation)) - obj.position) / 100.0;
135+
let veloc = (ray.plane_intersect(Some(self.place_elevation)) - obj.position) / 10.0;
162136
obj.add_velocity(veloc);
163137
objects.push(obj.clone());
164138
self.ghost_obj = None;
@@ -237,6 +211,35 @@ impl ControlHandler {
237211
None
238212
}
239213

214+
fn draw_obj_trajectory(
215+
&mut self,
216+
physics_handler: &PhysicsHandler,
217+
renderer: &Renderer,
218+
objects: &ObjectPool,
219+
object: &Object,
220+
) {
221+
let traj = object.calculate_trajectory(objects, physics_handler, 10_000, 2);
222+
traj.draw(renderer, Some(object.color), object.radius);
223+
}
224+
225+
fn draw_objects_trajectories(
226+
&mut self,
227+
physics_handler: &PhysicsHandler,
228+
renderer: &Renderer,
229+
objects: &ObjectPool,
230+
) {
231+
self.trajectories = objects.calculate_trajectories(physics_handler, 10_000, 2);
232+
233+
for (id, traj) in &self.trajectories {
234+
let obj = match objects.get(*id) {
235+
Some(obj) => obj,
236+
None => continue,
237+
};
238+
239+
traj.draw(renderer, Some(obj.color), obj.radius);
240+
}
241+
}
242+
240243
fn random_color() -> Color {
241244
Color {
242245
r: rand::gen_range(0.0, 1.0),
@@ -249,7 +252,7 @@ impl ControlHandler {
249252

250253
impl Default for ControlHandler {
251254
fn default() -> Self {
252-
ControlHandler::new(20.0, 5.0, 5)
255+
ControlHandler::new(20.0, 5.0)
253256
}
254257
}
255258

src/object.rs

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ impl Object {
6060
self
6161
}
6262

63-
pub fn update_pos(&mut self) -> &mut Self {
64-
self.position += self.velocity;
63+
pub fn update_pos(&mut self, time: f32) -> &mut Self {
64+
self.position += self.velocity * time;
6565
self
6666
}
6767

@@ -75,10 +75,8 @@ impl Object {
7575
objects: &ObjectPool,
7676
physics_handler: &PhysicsHandler,
7777
point_count: u32,
78-
skip: u32,
78+
step: u32,
7979
) -> Trajectory {
80-
let mut physics_handler = physics_handler.clone();
81-
8280
let mut objects = objects.clone();
8381
let mut id = self.id;
8482
if objects.get(id).is_none() {
@@ -87,8 +85,13 @@ impl Object {
8785

8886
let mut trajectory = Trajectory::new();
8987

90-
for i in 0..point_count {
91-
physics_handler.update_objects(&mut objects);
88+
for i in 0..point_count * step {
89+
let time = physics_handler.get_timestep();
90+
physics_handler.update_objects(&mut objects, time);
91+
92+
if i % step != 0 {
93+
continue;
94+
}
9295

9396
let obj = objects.get(id);
9497

@@ -98,14 +101,7 @@ impl Object {
98101
}
99102

100103
let obj = obj.unwrap().clone();
101-
102-
if i % skip == 0 {
103-
trajectory.push(obj.position);
104-
}
105-
106-
if (trajectory.first().cloned().unwrap() - obj.position).length() > 1000.0 {
107-
return trajectory;
108-
}
104+
trajectory.push(obj.position);
109105
}
110106

111107
trajectory
@@ -196,47 +192,55 @@ impl ObjectPool {
196192
&self,
197193
physics_handler: &PhysicsHandler,
198194
point_count: u32,
199-
skip: u32,
195+
step: u32,
200196
) -> HashMap<usize, Trajectory> {
201-
let mut trajectories = HashMap::new();
197+
let mut ids: Vec<usize> = Vec::new();
198+
let mut objects = self.clone();
199+
let mut trajectories: HashMap<usize, Trajectory> = HashMap::new();
202200

203-
for obj in &self.objects {
204-
trajectories.insert(
205-
obj.id,
206-
obj.calculate_trajectory(self, physics_handler, point_count, skip),
207-
);
201+
for obj in objects.iter_mut() {
202+
ids.push(obj.id);
208203
}
209204

210-
trajectories
211-
}
212-
213-
pub fn calculate_trajectories_except(
214-
&self,
215-
id: usize,
216-
physics_handler: &PhysicsHandler,
217-
point_count: u32,
218-
skip: u32,
219-
) -> HashMap<usize, Trajectory> {
220-
let mut trajectories = HashMap::new();
205+
for i in 0..point_count * step {
206+
let time = physics_handler.get_timestep();
207+
physics_handler.update_objects(&mut objects, time);
221208

222-
for obj in &self.objects {
223-
if obj.id == id {
209+
if i % step != 0 {
224210
continue;
225211
}
226212

227-
trajectories.insert(
228-
obj.id,
229-
obj.calculate_trajectory(self, physics_handler, point_count, skip),
230-
);
213+
for id in ids.clone().iter() {
214+
if objects.iter().find(|o| o.id == *id).is_some() {
215+
continue;
216+
}
217+
218+
if let Some(traj) = trajectories.get_mut(id) {
219+
traj.end();
220+
}
221+
222+
ids.remove(ids.iter().position(|id| *id == *id).unwrap());
223+
}
224+
225+
for obj in objects.iter_mut() {
226+
if i % step != 0 {
227+
continue;
228+
}
229+
230+
trajectories
231+
.entry(obj.id)
232+
.or_insert(Trajectory::new())
233+
.push(obj.position);
234+
}
231235
}
232236

233237
trajectories
234238
}
235239

236240
pub fn draw_all(&self, renderer: &Renderer) {
237-
for obj in &self.objects {
241+
self.iter().for_each(|obj| {
238242
obj.draw(renderer);
239-
}
243+
});
240244
}
241245
}
242246

@@ -254,6 +258,7 @@ impl Clone for ObjectPool {
254258
}
255259
}
256260

261+
#[derive(Clone)]
257262
pub struct Trajectory {
258263
points: Vec<Vec3>,
259264
has_end: bool,
@@ -267,12 +272,14 @@ impl Trajectory {
267272
}
268273
}
269274

270-
pub fn push(&mut self, point: Vec3) {
275+
pub fn push(&mut self, point: Vec3) -> &mut Trajectory {
271276
self.points.push(point);
277+
self
272278
}
273279

274-
pub fn end(&mut self) {
280+
pub fn end(&mut self) -> &mut Trajectory {
275281
self.has_end = true;
282+
self
276283
}
277284

278285
pub fn len(&self) -> usize {

src/physics.rs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,30 @@ impl PhysicsHandler {
2020
pub fn update(&mut self, objects: &mut ObjectPool, dt: f32) {
2121
self.accumulator += dt;
2222
while self.accumulator > self.timestep {
23-
self.update_objects(objects);
24-
23+
self.update_objects(objects, self.timestep);
2524
self.accumulator -= self.timestep;
2625
}
2726
}
2827

29-
pub fn update_objects(&mut self, mut objects: &mut ObjectPool) {
28+
pub fn update_objects(&self, objects: &mut ObjectPool, time: f32) {
3029
let mut clone = objects.clone();
3130

3231
for obj in clone.iter_mut() {
33-
obj.velocity += self.get_obj_veloc(obj, objects);
32+
obj.add_velocity(self.get_obj_veloc(obj, objects, time));
3433
}
3534

3635
for obj in clone.iter_mut() {
37-
obj.update_pos();
36+
obj.update_pos(time);
3837
}
3938

40-
*objects = clone;
41-
42-
for obj in objects.clone().iter_mut() {
43-
self.handle_collisions(&mut objects, obj);
39+
for obj in objects.iter_mut() {
40+
self.handle_collisions(&mut clone, obj);
4441
}
42+
43+
*objects = clone;
4544
}
4645

47-
pub fn handle_collisions(&mut self, objects: &mut ObjectPool, object: &mut Object) {
46+
pub fn handle_collisions(&self, objects: &mut ObjectPool, object: &mut Object) {
4847
for other in objects
4948
.get_all_in_area(object.position, object.radius)
5049
.iter_mut()
@@ -84,14 +83,24 @@ impl PhysicsHandler {
8483
}
8584
}
8685

87-
pub fn get_obj_veloc(&self, object: &Object, objects: &ObjectPool) -> Vec3 {
88-
let mut force = Vec3::ZERO;
86+
pub fn get_obj_veloc(&self, object: &Object, objects: &ObjectPool, time: f32) -> Vec3 {
87+
let mut veloc = Vec3::ZERO;
8988

9089
for other in objects.iter() {
91-
force += self.get_grav_force(object.mass, other.mass, other.position - object.position);
90+
veloc += self.get_grav_veloc(other.mass, other.position - object.position, time);
91+
}
92+
93+
veloc
94+
}
95+
96+
pub fn get_grav_veloc(&self, m2: f32, dist: Vec3, time: f32) -> Vec3 {
97+
if dist.length_squared() == 0. {
98+
return Vec3::ZERO;
9299
}
93100

94-
Self::get_veloc(force, object.mass, self.timestep)
101+
let veloc = self.grav_const * m2 / dist.length_squared() * time;
102+
let dir = dist.normalize();
103+
dir * veloc
95104
}
96105

97106
pub fn get_grav_force(&self, m1: f32, m2: f32, dist: Vec3) -> Vec3 {
@@ -138,7 +147,7 @@ impl Default for PhysicsHandler {
138147
fn default() -> PhysicsHandler {
139148
PhysicsHandler {
140149
grav_const: 1.0,
141-
timestep: 0.01,
150+
timestep: 0.2,
142151
accumulator: 0.,
143152
}
144153
}

0 commit comments

Comments
 (0)