Godot Version
Godot 4
Question
I am working on Bezier surfaces and I have an algorithm to merge adjacent patches so that their edge nodes are the same, to save work and keep landscapes seamless.
The following is the algorithm.
func MergeAdjacentPatches(OrgPatch):
var FreeList = []
var NewControlPointList = OrgPatch.ControlPointList.duplicate()
for i in OrgPatch.Friends.size():
if OrgPatch.HasFriends[i]:
if i == 0:
for j in 4:
FreeList.append(OrgPatch.ControlPointList[3][j])
NewControlPointList[3][j] = OrgPatch.Friends[i].ControlPointList[0][j]
elif i == 1:
for j in 4:
FreeList.append(OrgPatch.ControlPointList[j][3])
NewControlPointList[j][3] = OrgPatch.Friends[i].ControlPointList[j][0]
elif i == 2:
for j in 4:
FreeList.append(OrgPatch.ControlPointList[0][j])
NewControlPointList[0][j] = OrgPatch.Friends[i].ControlPointList[3][j]
elif i == 3:
for j in 4:
FreeList.append(OrgPatch.ControlPointList[j][0])
NewControlPointList[j][0] = OrgPatch.Friends[i].ControlPointList[j][3]
var forklift = []
for i in FreeList.size():
var append = true
var j = i + 1
while j < FreeList.size():
if FreeList[i] == FreeList[j]:
append = false
j += 1
if append:
forklift.append(FreeList[i])
for i in forklift:
i.free()
return NewControlPointList
Algorithm Details:
@tool
script
The Friends
Array contains a list of the adjacent patches, 0 is pos x, 1 is pos y, 2 is neg x, 3 is neg z. I have confirmed many times that this Array is correct.
The HasFriends
array indicates where the Friends
Array actually has friends, since the patch may not have friends in certain directions and I can’t for the life of me find a way to detect if a variable is an object or not without it throwing an error.
The Issue:
The issue I encounter is that when I have three patches in an L shape, and I add a fourth to turn it into a square the single control point shared by all four patches is freed. This is odd because it shouldn’t be possible. The free() function is only ever applied to control points owned by the new patch, and the shared control point is only ever actually added to the control points list of the new patch after the function has run its course. (When the returned “NewControlPointList” is applied). I’ve been stuck for forever, I literally have no clue how to fix this, any tips are greatly appreciated.
Things I have determined:
The node is getting freed as part of array i
, which just contains the filtered contents of FreeList
. This means the node is being added to FreeList
despite that seemingly being impossible.
Hypothesis:
Maybe it has something to do with the .duplicate
statement at the beginning?