Visual Scripting – Sorting things out

Before I am able to place vegetation on the terrain I need to know the slope angle at each point so I can determine whether it is too steep or what kind of plants i want to appear in those circumstances. I could get the tangent/normal data from the FRawMesh from last week however i that would require removing duplicates again which would be both slow and I could become a pain if they don’t match up after the sorting process. I decided to go the easier route and calculate them by sampling the adjacent points.

The first issue is that blueprints only support 1D arrays but i need to address elements with 2D Coordinates, To help with this i wrote a macro that uses the formula i = y * width + x which will do just that.

Sorting_2DindexingSorting_Indexing0

To test that it worked I set the cube at that index to a red material, sadly I do not have a screenshot of this but there were red cubes.

Sorting_ColouringTest

In the testing, the cubes at (0, 0) and (width, height) were in the correct positions in the array; however, due to the way I was removing the duplicate vertices, they were not all sorted causing some rows to be jumbled with the next. I changed the debug cube to also have a Text Renderer that I show the position in the array on.

Sorting_UnsortedDefaultOrder.PNG

My original instinct was to implement my own sorting algorithm in blueprint or C++, in theory i would be able to use the same indexing formula as my comparison for checking, however this would be very time consuming. Instead i found that TArray already has the function TArray::Sort() so I wrote a C++ function that would use it and return the sorted array.
Sorting_UsingSortFunction

TArray UMyFunctionLibrary::Sort(TArray points)
{
    // use TArray::Sort using my predicate to sort the array
    points.Sort(SortPredicate);
    return points;
}

// Function that TArray::Sort can use to compare FVectors
bool UMyFunctionLibrary::SortPredicate(const FVector & a, const FVector & b)
{
    if (a.Y < b.Y)
    {
        // if a's y is less we know it has to be before b
        return true;
    }
    else if (a.Y == b.Y && a.X < b.X)
    {
        // if they're at equal y, if a's x is less than b's x, true
        return true;
    }
    else
    {
        // else b is before a
        return false;
    }
}

It’s worth noting that for simplicity’s sake I used multiple if statements in my predicate function and not the more elegant formula. It is possible that using the formula could be faster but it was quicker to write and is more easily read when using this solution.

Sorting_sorted

Here you can see the successfully sorted array, ready for me to start calculating the slope data.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s