pub fn kinimatics_system(
    mut k_bods: Query<(&mut Kinimatics, &mut Transform, Option<&Engine>)>,
    time: Res<Time>,
) {
    // each element will have a corresponding entry in this list.
    let num_bods = k_bods.iter_mut().count();
    let mut all_forces: Vec<Vec<Vec3>> = Vec::new();
    all_forces.reserve(num_bods);

    // initialize a new vector for each k_bod
    for _ in 0..num_bods {
        all_forces.push(Vec::new());
    }

    let dt = time.delta_seconds();

    const GRAVITATIONAL_CONSTANT: f32 = 6.67430e-11;

    //  Calculate forces from gravity
    let mut entities: Vec<(Mut<Kinimatics>, Mut<Transform>, Option<&Engine>)> =
        k_bods.iter_mut().collect();

    for (i, q) in entities.iter().enumerate() {
        // NOTE do I need to do bounds checking here?
        entities
            .split_at(i + 1)
            .1
            .iter()
            .enumerate()
            .for_each(|(j, o)| {
                // calculate magnitude of the force
                let force_mag = GRAVITATIONAL_CONSTANT * (q.0.mass * o.0.mass)
                    / q.1.translation.distance_squared(o.1.translation);

                // calculate direction and magnitude of the forces for each object.
                let d1 = (o.1.translation - q.1.translation).normalize() * force_mag;
                let d2 = (q.1.translation - o.1.translation).normalize() * force_mag;

                // add these forces to a list of forces
                all_forces[i].push(d1);
                all_forces[i + j + 1].push(d2);
            });
    }

    // ## Calculate other forces and update kinimatics
    for (i, (kin, tran, engine)) in entities.iter_mut().enumerate() {
        // handle acceleration from ship engine
        if let Some(t) = engine {
            all_forces[i].push(
                tran.rotation.mul_vec3(Vec3::Y)
                    * match t.throttle {
                        Throttle::Fixed(true) => t.max_thrust,
                        Throttle::Fixed(false) => 0.0,
                        Throttle::Variable(amount) => amount * t.max_thrust,
                    },
            );
        }

        // add up forces, then apply them
        kin.acceleration = all_forces[i]
            .iter()
            .copied()
            .reduce(|acc, x| acc + x)
            .expect("0 forces")
            / kin.mass;

        kin.velocity = kin.velocity + kin.acceleration * dt;
        tran.translation = tran.translation + kin.velocity * dt;
    }
}
/// :SYSTEM: Iterates through all of the kinimatic entities, and simulates physics
/// on them, updating their transforms when it is done.
:SYSTEM: Iterates through all of the kinimatic entities, and simulates physics
on them, updating their transforms when it is done.
: SYSTEM : Iterates through all of the kinimatic entities and simulates physics on them updating their transforms when it is done .
pub fn kinimatics_system(
    mut k_bods: Query<(&mut Kinimatics, &mut Transform, Option<&Engine>)>,
    time: Res<Time>,
) {
    // each element will have a corresponding entry in this list.
    let num_bods = k_bods.iter_mut().count();
    let mut all_forces: Vec<Vec<Vec3>> = Vec::new();
    all_forces.reserve(num_bods);
    // initialize a new vector for each k_bod
    for _ in 0..num_bods {
        all_forces.push(Vec::new());
    }
    let dt = time.delta_seconds();
    const GRAVITATIONAL_CONSTANT: f32 = 6.67430e-11;
    //  Calculate forces from gravity
    let mut entities: Vec<(Mut<Kinimatics>, Mut<Transform>, Option<&Engine>)> =
        k_bods.iter_mut().collect();
    for (i, q) in entities.iter().enumerate() {
        // NOTE do I need to do bounds checking here?
        entities
            .split_at(i + 1)
            .1
            .iter()
            .enumerate()
            .for_each(|(j, o)| {
                // calculate magnitude of the force
                let force_mag = GRAVITATIONAL_CONSTANT * (q.0.mass * o.0.mass)
                    / q.1.translation.distance_squared(o.1.translation);
                // calculate direction and magnitude of the forces for each object.
                let d1 = (o.1.translation - q.1.translation).normalize() * force_mag;
                let d2 = (q.1.translation - o.1.translation).normalize() * force_mag;
                // add these forces to a list of forces
                all_forces[i].push(d1);
                all_forces[i + j + 1].push(d2);
            });
    }
    // ## Calculate other forces and update kinimatics
    for (i, (kin, tran, engine)) in entities.iter_mut().enumerate() {
        // handle acceleration from ship engine
        if let Some(t) = engine {
            all_forces[i].push(
                tran.rotation.mul_vec3(Vec3::Y)
                    * match t.throttle {
                        Throttle::Fixed(true) => t.max_thrust,
                        Throttle::Fixed(false) => 0.0,
                        Throttle::Variable(amount) => amount * t.max_thrust,
                    },
            );
        }
        // add up forces, then apply them
        kin.acceleration = all_forces[i]
            .iter()
            .copied()
            .reduce(|acc, x| acc + x)
            .expect("0 forces")
            / kin.mass;
        kin.velocity = kin.velocity + kin.acceleration * dt;
        tran.translation = tran.translation + kin.velocity * dt;
    }
}
pub fn kinimatics_system ( mut k_bods : Query < ( & mut Kinimatics , & mut Transform , Option < & Engine > ) > , time : Res < Time > , ) { // each element will have a corresponding entry in this list. let num_bods = k_bods . iter_mut ( ) . count ( ) ; let mut all_forces : Vec < Vec < Vec3 > > = Vec :: new ( ) ; all_forces . reserve ( num_bods ) ; // initialize a new vector for each k_bod for _ in 0 .. num_bods { all_forces . push ( Vec :: new ( ) ) ; } let dt = time . delta_seconds ( ) ; const GRAVITATIONAL_CONSTANT : f32 = 6.67430e-11 ; //  Calculate forces from gravity let mut entities : Vec < ( Mut < Kinimatics > , Mut < Transform > , Option < & Engine > ) > = k_bods . iter_mut ( ) . collect ( ) ; for ( i , q ) in entities . iter ( ) . enumerate ( ) { // NOTE do I need to do bounds checking here? entities . split_at ( i + 1 ) . 1 . iter ( ) . enumerate ( ) . for_each ( | ( j , o ) | { // calculate magnitude of the force let force_mag = GRAVITATIONAL_CONSTANT * ( q . 0 . mass * o . 0 . mass ) / q . 1 . translation . distance_squared ( o . 1 . translation ) ; // calculate direction and magnitude of the forces for each object. let d1 = ( o . 1 . translation - q . 1 . translation ) . normalize ( ) * force_mag ; let d2 = ( q . 1 . translation - o . 1 . translation ) . normalize ( ) * force_mag ; // add these forces to a list of forces all_forces [ i ] . push ( d1 ) ; all_forces [ i + j + 1 ] . push ( d2 ) ; } ) ; } // ## Calculate other forces and update kinimatics for ( i , ( kin , tran , engine ) ) in entities . iter_mut ( ) . enumerate ( ) { // handle acceleration from ship engine if let Some ( t ) = engine { all_forces [ i ] . push ( tran . rotation . mul_vec3 ( Vec3 :: Y ) * match t . throttle { Throttle :: Fixed ( true ) => t . max_thrust , Throttle :: Fixed ( false ) => 0.0 , Throttle :: Variable ( amount ) => amount * t . max_thrust , } , ) ; } // add up forces, then apply them kin . acceleration = all_forces [ i ] . iter ( ) . copied ( ) . reduce ( | acc , x | acc + x ) . expect ( " " ) / kin . mass ; kin . velocity = kin . velocity + kin . acceleration * dt ; tran . translation = tran . translation + kin . velocity * dt ; } }
:SYSTEM: Iterates through all of the kinimatic entities, and simulates physics
on them, updating their transforms when it is done.
: SYSTEM : Iterates through all of the kinimatic entities and simulates physics on them updating their transforms when it is done .
k_bods
Query<(&mut Kinimatics, &mut Transform, Option<&Engine>)>
time
Res<Time>
k_bods
Query<(&mut Kinimatics, &mut Transform, Option<&Engine>)>
time
Res<Time>