0

The system works great and manages to resolve all types of collisions except for when when a non static object slides of the corner of a static object. When that happens the object just fall through the static floor and intertwines itself.

In these examples the static object is the rectangle. Direct collision Sliding collision.

The code for the collision resolving looks like this.

!movable is the same as static

fn resolve_collision(
        line: [Entity; 2],
        closest_point: Vec2,
        point: &Entity,
        query: &mut Query<&mut MassPoint>,
        time: &Res<Time>,
    ) {
        let [mut a, mut b, mut point] = query.get_many_mut([line[0], line[1], *point]).unwrap();

        if !a.movable && !b.movable && !point.movable {
            return;
        }

        let average_line_mass = (a.mass + b.mass) / 2.0;

        let average_line_velocity = (a.velocity + b.velocity) / 2.0;

        //Skip the rest of the calculations if the line is immovable
        if !a.movable && !b.movable && point.movable {
            point.position = closest_point;

            let ((x, y), _) =
                calculate_new_velocities(&point, average_line_velocity, average_line_mass);

            point.position.x += x * time.delta_seconds();
            point.position.y += y * time.delta_seconds();

            return;
        }

        let line_move_multiplier = if point.movable {
            average_line_mass / (average_line_mass + point.mass)
        } else {
            1.0
        };

        //Account for the different masses
        let line_a_mass_move_multiplier = 1.0 + ((a.mass + b.mass) / 2.0);

        //Account for the closest point not being in the middle
        let line_a_slant_multiplier = 1.0 + a.position.distance(closest_point) / a.position.distance(b.position);

        //Average them for the final multiplier
        let a_move_multiplier = (line_a_mass_move_multiplier + line_a_slant_multiplier) / 2.0;

        //Where the points should meet
        let meet = point
            .position
            .lerp(closest_point, 1.0 - line_move_multiplier);

        //What the point needs to change by
        let point_change = meet - point.position;

        //What the line needs to change by
        let line_change = meet - closest_point;

        //What the start of the line needs to change by
        let line_a_change = line_change * a_move_multiplier;

        //What the end of the line needs to change by
        let line_b_change = line_change * (2.0 - a_move_multiplier);

        if point.movable {
            point.position += point_change;
        }

        a.position += line_a_change;

        b.position += line_b_change;


        //Update velocities
        ...
    }

Ive tried setting the variables manually and also been playing around with how they are calculated.

Viktor
  • 1
  • 1
  • 1

0 Answers0