// Copyright Epic Games, Inc. All Rights Reserved. #pragma once // These follow the corresponding C++ functions in PCGHelpers. uint ComputeSeed(uint A, uint B) { return ((A * 196314165U) + 907633515U) ^ ((B * 73148459U) + 453816763U); } uint ComputeSeed(uint A, uint B, uint C) { return ((A * 196314165U) + 907633515U) ^ ((B * 73148459U) + 453816763U) ^ ((C * 34731343U) + 453816743U); } uint ComputeSeedFromPosition(float3 InPosition) { const int3 PosInt = (int3)InPosition; const int Seed = ((PosInt.x * 196314165U) + 907633515U) ^ ((PosInt.y * 73148459U) + 453816763U) ^ ((PosInt.z * 34731343U) + 453816743U); return (uint)Seed; } // This follows the implementation in FRandomStream. float FRand(inout uint InOutSeed) { InOutSeed = (InOutSeed * 196314165U) + 907633515U; const float Result = asfloat(0x3F800000U | (InOutSeed >> 9)); return Result - 1.0f; } float3 CreateGrid2D(uint ElementIndex, uint NumPoints, uint NumRows, float3 Min, float3 Max) { if (NumRows == 0) { return Min; } const uint NumCols = ceil((0.f + NumPoints) / NumRows); if (NumCols == 0) { return Min; } const uint IndexX = ElementIndex / NumRows; const uint IndexY = ElementIndex - NumRows * IndexX; float3 Spacing = (Max - Min); if (NumCols > 1) { Spacing.x /= (NumCols - 1); } if (NumRows > 1) { Spacing.y /= (NumRows - 1); } float3 Position = Min; Position.x += IndexX * Spacing.x; Position.y += IndexY * Spacing.y; return Position; } float3 CreateGrid2D(uint ElementIndex, uint NumPoints, float3 Min, float3 Max) { if (NumPoints == 0) { return Min; } const uint NumRows = ceil(sqrt(NumPoints)); return CreateGrid2D(ElementIndex, NumPoints, NumRows, Min, Max); } float3 CreateGrid3D(uint ElementIndex, uint NumPoints, uint NumRows, uint NumCols, float3 Min, float3 Max) { if (NumRows == 0 || NumCols == 0) { return Min; } const uint NumLayers = ceil((0.f + NumPoints) / (NumRows * NumCols)); if (NumLayers == 0) { return Min; } uint3 Index; Index.x = ElementIndex % NumCols; Index.y = (ElementIndex / NumCols) % NumRows; Index.z = ElementIndex / (NumRows * NumCols); float3 Spacing = Max - Min; if (NumCols > 1) { Spacing.x /= (NumCols - 1); } if (NumRows > 1) { Spacing.y /= (NumRows - 1); } if (NumLayers > 1) { Spacing.z /= (NumLayers - 1); } return Min + Index * Spacing; } float3 CreateGrid3D(uint ElementIndex, uint NumPoints, float3 Min, float3 Max) { if (NumPoints == 0) { return Min; } const uint NumRows = round(pow(NumPoints, 1.f / 3.f)); const uint NumCols = NumRows; return CreateGrid3D(ElementIndex, NumPoints, NumRows, NumCols, Min, Max); }