Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public float[] PopulateArray1D(int sizeX, int sizeY)
- {
- // Try to use .TempJob allocation instead of persistant. Keeps unintentional memory leaks minimized.
- var unscaledArray = new NativeArray<float>(sizeX * sizeY, Allocator.TempJob);
- var scaledArray = new NativeArray<float>(sizeX * sizeY, Allocator.TempJob);
- var minQueue = new NativeQueue<float>(Allocator.TempJob);
- var maxQueue = new NativeQueue<float>(Allocator.TempJob);
- var min = new NativeArray<float>(1, Allocator.TempJob);
- var max = new NativeArray<float>(1, Allocator.TempJob);
- JobHandle handle = new MapChunkEvaluateJob
- {
- sizeX = sizeX,
- array = unscaledArray,
- Min = minQueue.AsParallelWriter(),
- Max = maxQueue.AsParallelWriter(),
- f = frequency
- // This inlines everything. It initializes the parallel threads and stops the main thread
- // until it's done.
- }.Schedule(unscaledArray.Length, 1);
- JobHandle handle2 = new ComputeMinMax
- {
- Mins = minQueue,
- Maxs = maxQueue,
- Min = min,
- Max = max
- }.Schedule(handle);
- handle2.Complete();
- new MapChunkNormalizeJob
- {
- unscaled_array = unscaledArray,
- scaled_array = scaledArray,
- myMin = min[0],
- myMax = max[0]
- }.Schedule(scaledArray.Length, 1, handle2).Complete();
- // This is if you really need the output array to be in a managed (regular) 2d array.
- // I personally would just return the collapsedArray and work with that.
- var outputArray = new float[sizeX * sizeY];
- outputArray = scaledArray.ToArray();
- // DO NOT FORGET TO DEALLOCATE THE NATIVE ARRAY WHEN YOU ARE DONE!!!!!!
- unscaledArray.Dispose();
- scaledArray.Dispose();
- minQueue.Dispose();
- maxQueue.Dispose();
- min.Dispose();
- max.Dispose();
- return outputArray;
- }
- [BurstCompile]
- private struct ComputeMinMax : IJob
- {
- public NativeQueue<float> Mins;
- public NativeQueue<float> Maxs;
- // Output
- public NativeArray<float> Min;
- public NativeArray<float> Max;
- public void Execute()
- {
- float min = float.MaxValue;
- while (this.Mins.TryDequeue(out var f))
- {
- if (f < min) min = f;
- }
- float max = float.MinValue;
- while (this.Maxs.TryDequeue(out var f))
- {
- if (f > max) max = f;
- }
- this.Min[0] = min;
- this.Max[0] = max;
- }
- }
- // Burst compile really important. Makes 1 second operations 10 milliseconds. It's amazing.
- [BurstCompile]
- public struct MapChunkNormalizeJob : IJobParallelFor
- {
- // This is the "collapsedArray", the 2d array collapsed into a 1d array.
- // The [WriteOnly] is not as nessisary as [ReadOnly] in jobs but it might help on the behind the scenes Unity optimization.
- [ReadOnly] public NativeArray<float> unscaled_array;
- [WriteOnly] public NativeArray<float> scaled_array;
- [ReadOnly] public float myMin;
- [ReadOnly] public float myMax;
- public void Execute(int index)
- {
- float min = myMin;
- float max = myMax;
- scaled_array[index] = (unscaled_array[index] - min) / (max - min);
- }
- }
- // Burst compile really important. Makes 1 second operations 10 milliseconds. It's amazing.
- [BurstCompile]
- public struct MapChunkEvaluateJob : IJobParallelFor
- {
- // This is needed in order to determine X and Y coordinates from index.
- [ReadOnly] public int sizeX;
- [ReadOnly] public float f;
- // This is the "collapsedArray", the 2d array collapsed into a 1d array.
- // The [WriteOnly] is not as nessisary as [ReadOnly] in jobs but it might help on the behind the scenes Unity optimization.
- [WriteOnly] public NativeArray<float> array;
- // Output
- public NativeQueue<float>.ParallelWriter Min;
- public NativeQueue<float>.ParallelWriter Max;
- public void Execute(int index)
- {
- float min = float.MaxValue;
- float max = float.MinValue;
- float amplitude = 1.0f;
- float sum = 0;
- float lacunarity = 1.25f;
- float frequency = f;
- float gain = 0.5f; // also persistence
- // Previously: Unity.Mathematics.noise.snoise(new Vector2(index, i));
- // Index = X value. i = Y value.
- // We can obtain these values from the index using sizeX
- // Use Unity.Mathematics.float2, it's optimized for Jobs.
- // I dont know if snoise needs a float2 or int2 can be used and you can skip the casting to int.
- for (int i = 0; i < 5; i++)
- {
- float x = (index % sizeX) * frequency;
- float y = (index / sizeX) * frequency;
- float value = Unity.Mathematics.noise.snoise(new Unity.Mathematics.float2(x, y));
- sum += value * amplitude;
- frequency *= lacunarity;
- amplitude *= gain;
- }
- if (sum > max) max = sum;
- if (sum < min) min = sum;
- this.Min.Enqueue(min);
- this.Max.Enqueue(max);
- array[index] = sum;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment