| 1 | module sim |
| 2 | |
| 3 | pub struct SimState { |
| 4 | pub mut: |
| 5 | position Vector3D |
| 6 | velocity Vector3D |
| 7 | accel Vector3D |
| 8 | } |
| 9 | |
| 10 | pub fn new_state(state SimState) SimState { |
| 11 | return SimState{ |
| 12 | ...state |
| 13 | } |
| 14 | } |
| 15 | |
| 16 | pub fn (mut state SimState) satisfy_rope_constraint(params SimParams) { |
| 17 | mut rope_vector := params.get_rope_vector(state) |
| 18 | rope_vector = rope_vector.scale(params.rope_length / rope_vector.norm()) |
| 19 | state.position = vector(z: params.rope_length) + rope_vector |
| 20 | } |
| 21 | |
| 22 | pub fn (mut state SimState) increment(delta_t f64, params SimParams) { |
| 23 | // 1. add up all forces |
| 24 | // 2. get an acceleration |
| 25 | // 3. add to velocity |
| 26 | // 4. ensure rope constraint is satisfied |
| 27 | |
| 28 | // sum up all forces |
| 29 | forces_sum := params.get_forces_sum(state) |
| 30 | |
| 31 | // get the acceleration |
| 32 | accel := forces_sum.scale(1.0 / params.bearing_mass) |
| 33 | state.accel = accel |
| 34 | |
| 35 | // update the velocity |
| 36 | state.velocity = state.velocity + accel.scale(delta_t) |
| 37 | |
| 38 | // update the position |
| 39 | state.position = state.position + state.velocity.scale(delta_t) |
| 40 | |
| 41 | // ensure the position satisfies rope constraint |
| 42 | state.satisfy_rope_constraint(params) |
| 43 | } |
| 44 | |
| 45 | pub fn (state SimState) done() bool { |
| 46 | return state.velocity.norm() < 0.05 && state.accel.norm() < 0.01 |
| 47 | } |
| 48 | |