Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct VoxelData
- {
- StackArray8<float> data;
- }
- interface IVoxelDataStore
- {
- VoxelBounds voxelBounds { get; }
- int ParallelForEachCount { get; }
- bool TryGetCellData(int cellIndex, out VoxelData cellData);
- void StoreForEach<T>(int i, ref T voxelDataSource) where T : VoxelDataSource;
- }
- public struct HashMapVoxelDataStore : IVoxelDataStore
- {
- VoxelBounds voxelBounds;
- NativeParallelHashMap<int, VoxelData> data;
- public int ParallelForEachCount => (1 << startingSubdivisions) ^ 3;
- private int startingSubdivisions => 1;
- public bool TryGetCellData(int cellIndex, out VoxelData cellData)
- {
- return data.TryGetValue(int cellIndex, out cellData);
- }
- struct SubCell
- {
- public int3 min;
- public int3 max;
- }
- public void StoreForEach<T>(int i, ref T voxelDataSource) where T : VoxelDataSource
- {
- // for the recursive subdivision process to work, we would need to ensure the voxelBounds are a power of 2.
- // at the moment we sometimes add a skirt making the bounds +2 above a power of 2.
- // instead we need to use integer division to our advantage
- var mid = voxelBounds.cubeCount / 2;
- var min = mafs.ToBinaryInt3(i) * mid;
- var max = mafs.lerp(mid, voxelBounds.cubeCount, mafs.ToBinaryInt3(i));
- var stack = new NativeStack<SubCell>(voxelBounds.subdivs, Allocator.Temp);
- stack.Push(new SubCell(min, max));
- while (stack.Count > 0)
- {
- var subCell = stack.Pop();
- var diff = subCell.max - subCell.min;
- if (mafs.all(diff == 0))
- {
- var vd = new VoxelData();
- for (int j = 0; j < 8; j++)
- {
- var cnrIdx = voxelBounds.CubeToCornerIndex(subCell.min, j);
- var pos = voxelBounds.CornerIndexToPosition(cnrIdx);
- vd[i] = voxelDataSource.Sample(pos);
- }
- data.Add(subCell.min);
- continue;
- }
- var size = (subCell.max - subCell.min + 1) * voxelBounds.cellSize;
- var pos = voxelBounds.CubeIndexToPosition(subCell.min) + size / 2;
- var sample = voxelDataSource.Sample(pos);
- const float e = 0.0001f;
- var dx = (voxelDataSource.Sample(pos + new float3(e, 0, 0)) - sample) / e;
- var dy = (voxelDataSource.Sample(pos + new float3(0, e, 0)) - sample) / e;
- var dz = (voxelDataSource.Sample(pos + new float3(0, 0, e)) - sample) / e;
- var grad = new float3(dx, dy, dz);
- var distToSurface = mafs.abs(sample / grad);
- if (all(distToSurface / size) > 2) // 4x min distance should be a safe enough fudge factor
- {
- continue;
- }
- var half = diff / 2;
- mid = subCell.min + half;
- for (int j = 0; j < 8; j++)
- {
- var k = mafs.ToBinaryInt3(j);
- min = mafs.lerp(subCell.min, mid, k);
- max = mafs.lerp(mid, subCell.max, k);
- stack.Push(new SubCell(min, max));
- }
- }
- }
- }
- public struct GenerateVoxelDataJob<T, U> : IJobParallelFor
- where T : IVoxelDataStore
- where U : IVoxelDataSource
- {
- public T voxelDataStore;
- public U voxelDataSource;
- public void Execute(int i)
- {
- voxelDataStore.StoreForEach(i, ref voxelDataSource);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement