I am attempting to filter out connections based on some Raycast checking to disable connections where there is an obstacle between the nodes.
Since I am using physics I am doing this by adding a main thread pass in the graph rule like this:
public override void Register(GridGraphRules rules)
{
rules.AddMainThreadPass(Pass.AfterConnections, FilterConnections);
}
my FilterConnections method is extracted almost entirely from Library/PackageCache/com.arongranberg.astar@4.3.82/Graphs/Grid/GridIterationUtilities.cs
with the removal of unsafe block and calls to some internal properties (those are recreated with hardcoded values) :
private void FilterConnections(GridGraphRules.Context context)
{
ulong connectionStride = 8;
ulong connectionMask = 0xFF;
var bounds = context.data.bounds;
var nodePositions = context.data.nodePositions;
var nodeConnections = context.data.nodeConnections;
var layeredDataLayout = context.data.layeredDataLayout;
int NoConnection = 0xFF;
var size = bounds.size;
Assert.IsTrue(nodeConnections.Length == size.x * size.y * size.z);
var neighbourOffsets = new int[8];
for (int i = 0; i < 8; i++) neighbourOffsets[i] = GridGraph.neighbourZOffsets[i] * size.x + GridGraph.neighbourXOffsets[i];
var layerStride = size.x * size.z;
int nodeIndex = 0;
for (int y = 0; y < size.y; y++) {
for (int z = 0; z < size.z; z++) {
for (int x = 0; x < size.x; x++, nodeIndex++) {
var conn = nodeConnections[nodeIndex];
if (layeredDataLayout) {
// Layered grid graph
for (int i = 0; i < 8; i++) {
var connectionValue = (int)((conn >> (int)(connectionStride*(ulong)i)) & connectionMask);
if (connectionValue != NoConnection && !IsValidConnection(nodePositions, nodeIndex, x, y, z, i, i + neighbourOffsets[i] + connectionValue*layerStride)) {
conn |= (ulong)NoConnection << (int)(connectionStride*(ulong)i);
}
}
} else {
// Normal grid graph
// Iterate through all connections on the node
for (int i = 0; i < 8; i++) {
if ((conn & (1UL << i)) != 0 && !IsValidConnection(nodePositions, nodeIndex, x, y, z, i, i + neighbourOffsets[i])) {
conn &= ~(1UL << i);
}
}
}
nodeConnections[nodeIndex] = conn;
}
}
}
}
but when the IsValidConnection method is called:
private bool IsValidConnection(NativeArray<Vector3> nodePositions, int dataIndex, int dataX, int dataLayer, int dataZ, int direction, int neighbourDataIndex)
{
var position = nodePositions[dataIndex];
if (neighbourDataIndex < 0 || nodePositions.Length <= neighbourDataIndex)
return false;
(...some more code)
}
I am getting the false in this if block. The neighbourDataIndex is less than 0 or it is a lot greater than nodePositions lenght.
My question is: Why? I am certain that I am doing something wrong, but since the code is mostly copied over from the library I am unable to find the reason. If I don’t try accessing nodePositions and simply return true or false it works as it should (either leaving connections as they were or disabling them all)
I am using a layer grid graph with 8 connections if that matters.