bool logic returning false when it seems it should not.

Godot Version

v4.6.2.stable.steam [71f334935]

Question

I’m trying to slice a mesh along a line. I have a function called slice_triangle which takes a PackedVector3Array of three points, and “slice points” which is a PackedVector3Array of two points which lie on the sides of the triangle. It returns an array of PackedVector3Arrays which represents the two or three triangles which result from splitting along the slice points. Here is the function as it is:

func _slice_triangle(t: PackedVector3Array, slice_points: PackedVector3Array) -> Array[PackedVector3Array]:
	#check for case where line directly intersects one of the tri points, therefore splitting into two
	var should_slice_in_two := false
	var matching_it = null
	var matching_is = null
	for p in t:
		if slice_points.has(p):
			should_slice_in_two = true
			matching_it = slice_points.find(p)
			matching_is = slice_points.find(p)
	if should_slice_in_two:
		assert(matching_it != null and matching_is != null)
		var other_is = 1 if matching_is == 0 else 0
		var other_it0 = wrap(matching_it + 1, 0, 2)
		var other_it1 = wrap(matching_it + 2, 0, 2)
		var nt0: PackedVector3Array = [slice_points[matching_is], slice_points[other_is], t[other_it0]]
		var nt1: PackedVector3Array = [slice_points[matching_is], t[other_it1], slice_points[other_is]]
		#nt0.reverse()
		#nt1.reverse()
		return [nt0, nt1]
	else:
		var nt0: PackedVector3Array = []
		var nt1: PackedVector3Array = []
		var nt2: PackedVector3Array = []
		var a = t[0]
		var b = t[1]
		var c = t[2]
		var x = slice_points[0]
		var y = slice_points[1]
		var abx_test = _is_point_on_line(x, a, b)
		var aby_test = _is_point_on_line(y, a, b)
		var acx_test = _is_point_on_line(x, a, c)
		var acy_test = _is_point_on_line(y, a, c)
		var bcx_test = _is_point_on_line(x, b, c)
		var bcy_test = _is_point_on_line(y, b, c)
		print([abx_test, aby_test, acx_test, acy_test, bcx_test, bcy_test])
		if abx_test and bcy_test:
			nt0 = [a, x, c]
			nt1 = [x, y, c]
			nt2 = [x, b, y]
		elif aby_test and bcx_test:
			nt0 = [a, y, c]
			nt1 = [y, x, c]
			nt2 = [y, b, x]
		elif abx_test and acy_test:
			nt0 = [y, x, b]
			nt1 = [y, b, c]
			nt2 = [a, x, y]
		elif aby_test and acx_test:
			nt0 = [x, y, b]
			nt1 = [x, b, c]
			nt2 = [a, y, x]
		elif bcx_test and acy_test:
			nt0 = [a, x, y]
			nt1 = [a, b, x]
			nt2 = [y, x, c]
		elif bcy_test and acx_test:
			nt0 = [a, y, x]
			nt1 = [a, b, y]
			nt2 = [x, y, c]
		assert(false, "One of these tests should've worked")
		return [nt0, nt1, nt2]

However, when I attempt to slice a sphere, apparently at random all of the tests at the bottom of the function fail, despite the fact that according to the debugging menu both abx_test and bcy_test are true (see proof below) and therefore the first test should succeed. Am I missing something here, or is this a bug in the engine? Please help! I have no inkling what the problem is.

Your last assert runs after the whole if statement without any guard clause, and you don’t return from the if statements anywhere, so this assert will always run and fail regardless of what happens in the if statement. You’d need to return from within the if statement if you want this assert to not run.

3 Likes