Can't slerp between two bases, non-normalized basis

Godot Version

4.4.1

Question

Hi, I’m trying to smoothly interpolate my characters rotation to a rotation I construct based on a given direction and the slope/tilt of the ground the character is currently on, however, everytime the final slerp is called godot throws this error, which doesnt crash the game but just doesnt implement any rotation.

I tried calling normalized and orthonormalized on all of the vectors and bases involved but it still throws the same error. I tried rounding the vectors to two decimals as well. Here is the function.
Edit: The error is caused by the final slerp at the end.

func turnCarTowards(target_direction: Vector3, delta) -> void:
	var target_basis

	#Constructing Desired Rotation from Target Direction and Ground Rotation
	if ground_ray.is_colliding():
			var new_up = ground_ray.get_collision_normal()
			var forward_flat = - flatten(target_direction).normalized
			var new_right = new_up.cross(forward_flat).normalized()
			var new_forward = new_right.cross(new_up).normalized()
		
			target_basis = Basis(new_right, new_up, -new_forward).orthonormalized()
				
	#This Implements constant turn speed by scaling step
    # shouldn't have anything to do with the error

	var target_quat = target_basis.get_rotation_quaternion()
	var quat = transform.basis.get_rotation_quaternion()

	var angle_to_turn = abs(quat.angle_to(target_quat))
	angle_to_turn = clampf(angle_to_turn, 0.01, angle_to_turn)

	var step_scale = slerp_rotation_breakpoint / angle_to_turn
	var step = delta * rotation_speed * step_scale
	step = clampf(step, step, 1.0)
	
	transform.basis = transform.basis.slerp(target_basis, step).orthonormalized()

Which of these is the line 137 the error message complains about?

the final line where I slerp between the objects basis and target_basis

Since I wasn’t able to figure out the bug, I decided to use quaternions instead of bases.

Bear in mind that this solution will likely only work with small angle changes which is enough for my purposes. I haven’t tested anything more extreme.

func turnCarTowards(target_point: Vector3, delta) -> void:
	var target_direction = directionTo(target_point)
	var angle_to_turn = facing_direction.angle_to(target_direction)
	angle_to_turn = max(angle_to_turn, 0.01)
	
	#This Maskes slerp turn at constant angular velocity
	var turn_step = calculateTurnStep(angle_to_turn, delta)

	var desired_quat = getDesiredQuat(target_direction)
	
	var new_quat = transform.basis.get_rotation_quaternion().slerp(desired_quat, turn_step)
	transform.basis = Basis(new_quat)

func calculateTurnStep(angle: float, delta) -> float:
	var step_scale = slerp_rotation_angle / angle
	var step = delta * rotation_speed * step_scale
	step = min(step, 1.0)
	return step

func getDesiredQuat(target_direction) -> Quaternion:
	var desired_yaw = atan2(target_direction.x, target_direction.z)
	var desired_yaw_quat = Quaternion(Vector3.UP, desired_yaw)
	var ground_quat = Quaternion(Vector3.UP, ground_ray.get_collision_normal())
	var desired_quat = ground_quat * desired_yaw_quat
	return desired_quat

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.