public Snapshot(JobHandle handle, VoxelChunk <TIndexer> chunk) { this.handle = handle; this.chunk = chunk; }
public RayCastResult(Vector3 pos, Vector3 sidePos, VoxelChunk <TIndexer> chunk) { this.pos = pos; this.sidePos = sidePos; this.chunk = chunk; }
public void ApplyGrid <TGridIndexer>(int x, int y, int z, NativeArray3D <Voxel, TGridIndexer> grid, bool propagatePadding, bool includePadding, VoxelEditConsumer <TIndexer> edits, bool writeToChunks = true, bool writeUnsetVoxels = false) where TGridIndexer : struct, IIndexer { int minX = Mathf.FloorToInt((float)x / ChunkSize); int minY = Mathf.FloorToInt((float)y / ChunkSize); int minZ = Mathf.FloorToInt((float)z / ChunkSize); int maxX = Mathf.FloorToInt((float)(x + grid.Length(0)) / ChunkSize); int maxY = Mathf.FloorToInt((float)(y + grid.Length(1)) / ChunkSize); int maxZ = Mathf.FloorToInt((float)(z + grid.Length(2)) / ChunkSize); var handles = new List <VoxelChunk <TIndexer> .FinalizeChange>(); var watch = System.Diagnostics.Stopwatch.StartNew(); if (edits != null) { var snapshots = new List <VoxelChunk <TIndexer> .Snapshot>(); //Include padding int minX2 = Mathf.FloorToInt((float)(x - 1) / ChunkSize); int minY2 = Mathf.FloorToInt((float)(y - 1) / ChunkSize); int minZ2 = Mathf.FloorToInt((float)(z - 1) / ChunkSize); int maxX2 = Mathf.FloorToInt((float)(x + grid.Length(0) + 1) / ChunkSize); int maxY2 = Mathf.FloorToInt((float)(y + grid.Length(1) + 1) / ChunkSize); int maxZ2 = Mathf.FloorToInt((float)(z + grid.Length(2) + 1) / ChunkSize); var snapshotChunks = new List <VoxelChunk <TIndexer> >(); for (int cx = minX2; cx <= maxX2; cx++) { for (int cy = minY2; cy <= maxY2; cy++) { for (int cz = minZ2; cz <= maxZ2; cz++) { ChunkPos chunkPos = ChunkPos.FromChunk(cx, cy, cz); chunks.TryGetValue(chunkPos, out VoxelChunk <TIndexer> chunk); if (chunk != null) { snapshots.Add(chunk.ScheduleSnapshot()); } else { snapshotChunks.Add(new VoxelChunk <TIndexer>(this, chunkPos, ChunkSize, IndexerFactory)); } } } } //Finalize clone jobs foreach (VoxelChunk <TIndexer> .Snapshot snapshot in snapshots) { snapshot.handle.Complete(); snapshotChunks.Add(snapshot.chunk); } //Produce edit edits(new VoxelEdit <TIndexer>(this, snapshotChunks)); } if (writeToChunks) { var changes = new List <VoxelChunk <TIndexer> .Change>(); //Schedule all jobs for (int cx = minX; cx <= maxX; cx++) { for (int cy = minY; cy <= maxY; cy++) { for (int cz = minZ; cz <= maxZ; cz++) { ChunkPos chunkPos = ChunkPos.FromChunk(cx, cy, cz); chunks.TryGetValue(chunkPos, out VoxelChunk <TIndexer> chunk); if (chunk == null) { chunks[chunkPos] = chunk = new VoxelChunk <TIndexer>(this, chunkPos, ChunkSize, IndexerFactory); } var gx = (cx - minX) * ChunkSize; var gy = (cy - minY) * ChunkSize; var gz = (cz - minZ) * ChunkSize; changes.Add(chunk.ScheduleGrid(0, 0, 0, gx, gy, gz, grid, propagatePadding, includePadding, writeUnsetVoxels)); } } } //Wait and finalize jobs foreach (var change in changes) { change.handle.Complete(); } //Finalize foreach (var change in changes) { change.finalize(); } } }
/// <summary> /// Applies the specified signed distance field function to the world. /// The SDF is applied in local space, i.e. 1 voxel = 1 unit on the signed distance field! /// </summary> /// <param name="pos">World position</param> /// <param name="rot">World rotation</param> /// <param name="sdf">Signed distance field function</param> /// <param name="material">Material to be added</param> /// <param name="replace">Whether only solid material should be replaced</param> /// <param name="edits">Consumes the voxel edit. Can be null if no voxel edits should be stored</param> public void ApplySdf <TSdf>(Vector3 pos, Quaternion rot, TSdf sdf, int material, bool replace, VoxelEditConsumer <TIndexer> edits) where TSdf : struct, ISdf { pos = TransformPointToLocalSpace(pos); rot = TransformQuatToLocalSpace(rot); Debug.Log("Apply sdf at: " + pos); var transformedSdf = new TransformSDF <TSdf>(Matrix4x4.TRS(pos, rot, Vector3.one), sdf); Vector3 minBound = transformedSdf.Min(); Vector3 maxBound = transformedSdf.Max(); int minX = Mathf.FloorToInt((float)minBound.x / ChunkSize); int minY = Mathf.FloorToInt((float)minBound.y / ChunkSize); int minZ = Mathf.FloorToInt((float)minBound.z / ChunkSize); int maxX = Mathf.FloorToInt((float)maxBound.x / ChunkSize); int maxY = Mathf.FloorToInt((float)maxBound.y / ChunkSize); int maxZ = Mathf.FloorToInt((float)maxBound.z / ChunkSize); var changes = new List <VoxelChunk <TIndexer> .Change>(); var watch = System.Diagnostics.Stopwatch.StartNew(); if (edits != null) { var snapshots = new List <VoxelChunk <TIndexer> .Snapshot>(); //Include padding int minX2 = Mathf.FloorToInt((float)(minBound.x - 1) / ChunkSize); int minY2 = Mathf.FloorToInt((float)(minBound.y - 1) / ChunkSize); int minZ2 = Mathf.FloorToInt((float)(minBound.z - 1) / ChunkSize); int maxX2 = Mathf.FloorToInt((float)(maxBound.x + 1) / ChunkSize); int maxY2 = Mathf.FloorToInt((float)(maxBound.y + 1) / ChunkSize); int maxZ2 = Mathf.FloorToInt((float)(maxBound.z + 1) / ChunkSize); var snapshotChunks = new List <VoxelChunk <TIndexer> >(); for (int cx = minX2; cx <= maxX2; cx++) { for (int cy = minY2; cy <= maxY2; cy++) { for (int cz = minZ2; cz <= maxZ2; cz++) { ChunkPos chunkPos = ChunkPos.FromChunk(cx, cy, cz); chunks.TryGetValue(chunkPos, out VoxelChunk <TIndexer> chunk); if (chunk != null) { snapshots.Add(chunk.ScheduleSnapshot()); } else { snapshotChunks.Add(new VoxelChunk <TIndexer>(this, chunkPos, ChunkSize, IndexerFactory)); } } } } //Finalize clone jobs foreach (VoxelChunk <TIndexer> .Snapshot snapshot in snapshots) { snapshot.handle.Complete(); snapshotChunks.Add(snapshot.chunk); } //Produce edit edits(new VoxelEdit <TIndexer>(this, snapshotChunks)); } //Schedule all jobs for (int cx = minX; cx <= maxX; cx++) { for (int cy = minY; cy <= maxY; cy++) { for (int cz = minZ; cz <= maxZ; cz++) { ChunkPos chunkPos = ChunkPos.FromChunk(cx, cy, cz); chunks.TryGetValue(chunkPos, out VoxelChunk <TIndexer> chunk); if (chunk == null) { chunks[chunkPos] = chunk = new VoxelChunk <TIndexer>(this, chunkPos, ChunkSize, IndexerFactory); } changes.Add(chunk.ScheduleSdf(-cx * ChunkSize, -cy * ChunkSize, -cz * ChunkSize, transformedSdf, material, replace)); } } } //Wait and finalize jobs foreach (var change in changes) { change.handle.Complete(); } //Finalize foreach (var change in changes) { change.finalize(); } watch.Stop(); string text = "Applied SDF to " + changes.Count + " voxel chunks in " + watch.ElapsedMilliseconds + "ms. Avg: " + (watch.ElapsedMilliseconds / (float)changes.Count) + "ms."; Debug.Log(text); }