CelticCraft/Plugins/VoxelFree/Source/Voxel/Private/VoxelTools/VoxelMathLibrary.cpp

67 lines
No EOL
2.1 KiB
C++

// Copyright 2020 Phyronnaz
#include "VoxelTools/VoxelMathLibrary.h"
#include "VoxelUtilities/VoxelBaseUtilities.h"
FVector UVoxelMathLibrary::GetUnitVectorFromRandom(FVector2D Random)
{
// From Raytracing Gems, Chapter 16
// Compute radius r (branchless).
Random = 2 * Random - 1;
const float d = 1 - (FMath::Abs(Random.X) + FMath::Abs(Random.Y));
const float Radius = 1 - FMath::Abs(d);
// Compute phi in the first quadrant (branchless, except for the division-by-zero test),
// using sign(random) to map the result to the correct quadrant below
const float Phi = (Radius == 0) ? 0 : (PI / 4) * ((FMath::Abs(Random.Y) - FMath::Abs(Random.X)) / Radius + 1);
const float f = Radius * FMath::Sqrt(2 - Radius * Radius);
FVector Result;
Result.X = f * FMath::Sign(Random.X) * FMath::Cos(Phi);
Result.Y = f * FMath::Sign(Random.Y) * FMath::Sin(Phi);
Result.Z = FMath::Sign(d) * (1 - Radius * Radius);
ensure(Result.IsUnit());
return Result;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
FVoxelHaltonStream UVoxelMathLibrary::MakeHaltonStream(int32 InitialSeed)
{
return { InitialSeed, uint32(FMath::Abs(InitialSeed)) };
}
void UVoxelMathLibrary::ResetHaltonStream(const FVoxelHaltonStream& Stream)
{
Stream.Seed = Stream.InitialSeed;
}
float UVoxelMathLibrary::GetHalton1D(const FVoxelHaltonStream& Stream)
{
const float Value = FVoxelUtilities::Halton<2>(Stream.Seed);
Stream.Seed++;
return Value;
}
FVector2D UVoxelMathLibrary::GetHalton2D(const FVoxelHaltonStream& Stream)
{
FVector2D Value;
Value.X = FVoxelUtilities::Halton<2>(Stream.Seed);
Value.Y = FVoxelUtilities::Halton<3>(Stream.Seed);
Stream.Seed++;
return Value;
}
FVector UVoxelMathLibrary::GetHalton3D(const FVoxelHaltonStream& Stream)
{
FVector Value;
Value.X = FVoxelUtilities::Halton<2>(Stream.Seed);
Value.Y = FVoxelUtilities::Halton<3>(Stream.Seed);
Value.Z = FVoxelUtilities::Halton<5>(Stream.Seed);
Stream.Seed++;
return Value;
}