Why does 3D freak out with upside-down normals and how can I fix this?

Godot Version

Godot 4.3

Question

Here is some code that I use to align the character in my game to walls/ceilings:

static func get_normal_alignment_quaternion(normal: Vector3) -> Quaternion:
	var quaternion := Quaternion(normal, Vector3.UP)
	if normal.distance_squared_to(Vector3.DOWN) < 0.0001 and DO_FIX_THAT_ISNT_ACTUALLY_A_FIX:
		quaternion = Quaternion(0, 0, 1, 0)
	return quaternion


static func align_to_normal(alignment: Vector3, normal: Vector3) -> Vector3:
	return alignment * get_normal_alignment_quaternion(normal)


static func align_basis_to_normal(basis: Basis, normal: Vector3) -> Basis:
	return basis * Basis(get_normal_alignment_quaternion(normal)).inverse()


static func misalign_from_normal(alignment: Vector3, normal: Vector3) -> Vector3:
	return alignment * get_normal_alignment_quaternion(normal).inverse()

I redid them today to attempt to fix the issue I’m having which is that these functions don’t work very well with surface normals that point downwards. For some reason, movement gets inverted from the transition of a wall to a ceiling. Here’s a video to demonstrate (warning: might induce motion sickness):

The “fix” I tried to add is to set the Quaternion to (0, 0, 1, 0) but as you can see, it only works across one axis. Why does 3D math not work well with upside-down normals and how can I mitigate this?

1 Like

Turns out the old code I used for aligning for normals was less janky than the new one and also I had a bit of scuffed level geometry. Oh well ¯\_(ツ)_/¯

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