Issues with buoyancy when applying it to a more complex mesh

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By fUNNY-fnaf

I’ve been working on a buoyancy script for Godot 4.0 and so far it works with simple squares, triangles etc. But, as soon as I try to apply to a more complex shape (a ship/boat in this case) it stops to work as intended.
Instead of following the waves, it keeps pointing up in the sky, as seen on the image…

Here’s my buoyancy code…

extends RigidBody3D

@export var float_force := 1.0;
@export var water_drag := 0.05;
@export var water_angular_drag := 0.05;
@export var air_drag := Vector3.ZERO;
@export var air_angular_drag := Vector3.ZERO;
@export var enable_torque := false;

@onready var gravity : float = ProjectSettings.get_setting("physics/3d/default_gravity") * self.gravity_scale;
@onready var probes = $probe_container.get_children();

var submerged := false;
var probes_submerged := 0;


func get_height(offset: Vector3, world_position: Vector3) -> float:
    var uv1_x = wrapf((world_position.x + offset.x) / Globals.NOISE_SCALE +    (Globals.TIME * Globals.WAVE_DIR_1.x) * Globals.TIME_SCALE, 0, 1);
    var uv1_y = wrapf((world_position.z + offset.z) / Globals.NOISE_SCALE + (Globals.TIME * Globals.WAVE_DIR_1.y) * Globals.TIME_SCALE, 0, 1);
    var uv2_x = wrapf((world_position.x + offset.x) / Globals.NOISE_SCALE + (Globals.TIME * Globals.WAVE_DIR_2.x) * Globals.TIME_SCALE, 0, 1);
    var uv2_y = wrapf((world_position.z + offset.z) / Globals.NOISE_SCALE + (Globals.TIME * Globals.WAVE_DIR_2.y) * Globals.TIME_SCALE, 0, 1);

    var pixel_pos1 = Vector2(uv1_x * Globals.WAVE.get_width(), uv1_y * Globals.WAVE.get_height());
    var pixel_pos2 = Vector2(uv2_x * Globals.WAVE.get_width(), uv2_y * Globals.WAVE.get_height());
    var pixel = lerp(Globals.WAVE.get_pixelv(pixel_pos1).r, Globals.WAVE.get_pixelv(pixel_pos2).r, 0.5);

    return pixel * Globals.HEIGHT_SCALE;


func _physics_process(delta):
    var vertex_distance = global_position.distance_to(Globals.OCEAN_POSITION);
    vertex_distance = clamp(vertex_distance, 0.0, 85.0);
    var vertex_distance_clamped = vertex_distance / 85.0;

    submerged = false;
    probes_submerged = 0;

    for p in probes:
            var water_height = get_height(Vector3.ZERO, p.global_position) * (1.0 - vertex_distance_clamped);
            var depth = water_height - p.global_position.y;
	
            if depth > 0:
                    probes_submerged+=1;
                    if (probes_submerged >= (len(probes) / 3) * 2):
                            submerged = true;
			
                    apply_force(Vector3.UP * float_force * gravity * depth, p.global_position - global_position);
                    if enable_torque: apply_torque(p.global_position - global_position);

func _integrate_forces(state: PhysicsDirectBodyState3D):
    if submerged:
            state.linear_velocity *= 1 - water_drag;
            state.angular_velocity *= 1 - water_angular_drag;
    else:
            state.linear_velocity *= Vector3.ONE + air_drag;
            state.angular_velocity *= Vector3.ONE + air_angular_drag;

Here’s the current parameters for the boat


If any more information is needed just ask, I’ll be more than happy to supply.
Thanks beforehand.