浏览代码

Merge pull request #285 from Unity-Technologies/poisson-disk-super-sampling

Poisson disk super sampling
/0.8.0.preview.4_staging
Aryan Mann 3 年前
当前提交
38657ba3
共有 1 个文件被更改,包括 71 次插入15 次删除
  1. 86
      com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Utilities/PoissonDiskSampling.cs

86
com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Utilities/PoissonDiskSampling.cs


/// <param name="minimumRadius">The minimum distance required between each sampled point</param>
/// <param name="seed">The random seed used to initialize the algorithm state</param>
/// <param name="samplingResolution">The number of potential points sampled around every valid point</param>
/// <param name="allocator">The allocator to use for the samples container</param>
/// <returns>The list of generated poisson points</returns>
public static NativeList<float2> GenerateSamples(
float width,

int samplingResolution = k_DefaultSamplingResolution)
int samplingResolution = k_DefaultSamplingResolution,
Allocator allocator = Allocator.TempJob)
{
if (width < 0)
throw new ArgumentException($"Width {width} cannot be negative");

if (samplingResolution <= 0)
throw new ArgumentException($"SamplingAttempts {samplingResolution} cannot be <= 0");
var samples = new NativeList<float2>(Allocator.TempJob);
new SampleJob
var superSampledPoints = new NativeList<float2>(allocator);
var sampleJob = new SampleJob
{
width = width + minimumRadius * 2,
height = height + minimumRadius * 2,
minimumRadius = minimumRadius,
seed = seed,
samplingResolution = samplingResolution,
samples = superSampledPoints
}.Schedule();
var croppedSamples = new NativeList<float2>(allocator);
new CropJob
seed = seed,
samplingResolution = samplingResolution,
samples = samples
}.Schedule().Complete();
return samples;
superSampledPoints = superSampledPoints.AsDeferredJobArray(),
croppedSamples = croppedSamples
}.Schedule(sampleJob).Complete();
superSampledPoints.Dispose();
return croppedSamples;
}
[BurstCompile]

}
}
/// <summary>
/// This job is for filtering out all super sampled Poisson points that are found outside of the originally
/// specified 2D region. This job will also shift the cropped points back to their original region.
/// </summary>
[BurstCompile]
struct CropJob : IJob
{
public float width;
public float height;
public float minimumRadius;
[ReadOnly] public NativeArray<float2> superSampledPoints;
public NativeList<float2> croppedSamples;
public void Execute()
{
var results = new NativeArray<bool>(
superSampledPoints.Length, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
// The comparisons operations made in this loop are done separately from the list-building loop
// so that burst can automatically generate vectorized assembly code for this portion of the job.
for (var i = 0; i < superSampledPoints.Length; i++)
{
var point = superSampledPoints[i];
results[i] = point.x >= minimumRadius && point.x <= width + minimumRadius
&& point.y >= minimumRadius && point.y <= height + minimumRadius;
}
// This list-building code is done separately from the filtering loop
// because it cannot be vectorized by burst.
for (var i = 0; i < superSampledPoints.Length; i++)
{
if (results[i])
croppedSamples.Add(superSampledPoints[i]);
}
// Remove the positional offset from the filtered-but-still-super-sampled points
var offset = new float2(minimumRadius, minimumRadius);
for (var i = 0; i < croppedSamples.Length; i++)
croppedSamples[i] -= offset;
results.Dispose();
}
}
// Algorithm sourced from Robert Bridson's paper "Fast Poisson Disk Sampling in Arbitrary Dimensions"
// https://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf
/// <summary>

// Calculate occupancy grid dimensions
var random = new Unity.Mathematics.Random(seed);
var cellSize = minimumRadius / math.sqrt(2);
var rows = Mathf.FloorToInt(height / cellSize);
var cols = Mathf.FloorToInt(width / cellSize);
var cellSize = minimumRadius / math.sqrt(2f);
var rows = Mathf.CeilToInt(height / cellSize);
var cols = Mathf.CeilToInt(width / cellSize);
var gridSize = rows * cols;
if (gridSize == 0)
return samples;

// This list will track all points that may still have space around them for generating new points
var activePoints = new NativeList<float2>(Allocator.Temp);
// Randomly place a seed point in a central location within the generation space to kick off the algorithm
var firstPoint = new float2(
random.NextFloat(0.4f, 0.6f) * width,
random.NextFloat(0.4f, 0.6f) * height);
// Randomly place a seed point to kick off the algorithm
var firstPoint = new float2(random.NextFloat(0f, width), random.NextFloat(0f, height));
samples.Add(firstPoint);
var firstPointCol = Mathf.FloorToInt(firstPoint.x / cellSize);
var firstPointRow = Mathf.FloorToInt(firstPoint.y / cellSize);

正在加载...
取消
保存