/// <summary> /// Loops through each voxel data point that is contained in <paramref name="dataChunk"/> AND in <paramref name="worldSpaceQuery"/>, and performs <paramref name="function"/> on it /// </summary> /// <param name="worldSpaceQuery">The query that determines whether or not a voxel data point is contained.</param> /// <param name="chunkCoordinate">The coordinate of <paramref name="dataChunk"/></param> /// <param name="dataChunk">The voxel datas of the chunk</param> /// <param name="function">The function that will be performed on each voxel data point. The arguments are as follows: 1) The world space position of the voxel data point, 2) The chunk space position of the voxel data point, 3) The index of the voxel data point inside of <paramref name="dataChunk"/>, 4) The value of the voxel data</param> public void ForEachVoxelDataInQueryInChunk(BoundsInt worldSpaceQuery, int3 chunkCoordinate, VoxelDataVolume <T> dataChunk, Action <int3, int3, int, T> function) { int3 chunkBoundsSize = VoxelWorld.WorldSettings.ChunkSize; int3 chunkWorldSpaceOrigin = chunkCoordinate * VoxelWorld.WorldSettings.ChunkSize; BoundsInt chunkWorldSpaceBounds = new BoundsInt(chunkWorldSpaceOrigin.ToVectorInt(), chunkBoundsSize.ToVectorInt()); BoundsInt intersectionVolume = IntersectionUtilities.GetIntersectionVolume(worldSpaceQuery, chunkWorldSpaceBounds); int3 intersectionVolumeMin = intersectionVolume.min.ToInt3(); int3 intersectionVolumeMax = intersectionVolume.max.ToInt3(); for (int voxelDataWorldPositionX = intersectionVolumeMin.x; voxelDataWorldPositionX <= intersectionVolumeMax.x; voxelDataWorldPositionX++) { for (int voxelDataWorldPositionY = intersectionVolumeMin.y; voxelDataWorldPositionY <= intersectionVolumeMax.y; voxelDataWorldPositionY++) { for (int voxelDataWorldPositionZ = intersectionVolumeMin.z; voxelDataWorldPositionZ <= intersectionVolumeMax.z; voxelDataWorldPositionZ++) { int3 voxelDataWorldPosition = new int3(voxelDataWorldPositionX, voxelDataWorldPositionY, voxelDataWorldPositionZ); int3 voxelDataLocalPosition = voxelDataWorldPosition - chunkWorldSpaceOrigin; int voxelDataIndex = IndexUtilities.XyzToIndex(voxelDataLocalPosition, chunkBoundsSize.x + 1, chunkBoundsSize.y + 1); if (dataChunk.TryGetVoxelData(voxelDataIndex, out T voxelData)) { function(voxelDataWorldPosition, voxelDataLocalPosition, voxelDataIndex, voxelData); } } } } }
/// <summary> /// Determines whether the specified index is within the current bounds of the <see cref="IDynamicIndexingBounds{TIndex}"/>. /// </summary> /// <typeparam name="TIndex">The type of the index.</typeparam> /// <param name="bounded">The bounds to check against.</param> /// <param name="index">The index to check.</param> /// <returns> /// <c>true</c> if the index is within current bounds; otherwise, <c>false</c>. /// </returns> public static bool IsIndexInCurrentBounds <TIndex>(this IDynamicIndexingBounds <TIndex> bounded, TIndex index) where TIndex : IIndex { Contracts.Requires.That(bounded != null); Contracts.Requires.That(index != null); Contracts.Requires.That(bounded.Rank == index.Rank); return(IndexUtilities.IsIn(index, bounded.CurrentLowerBounds, bounded.CurrentUpperBounds)); }
/// <summary> /// The execute method required for Unity's IJobParallelFor job type /// </summary> /// <param name="index">The iteration index provided by Unity's Job System</param> public void Execute(int index) { int3 worldPosition = IndexUtilities.IndexToXyz(index, OutputVoxelData.Width, OutputVoxelData.Height) + WorldPositionOffset; int worldPositionX = worldPosition.x; int worldPositionY = worldPosition.y; int worldPositionZ = worldPosition.z; float voxelData = CalculateVoxelData(worldPositionX, worldPositionY, worldPositionZ); OutputVoxelData.SetVoxelData(voxelData, index); }
/// <summary> /// Gets the index for point <paramref name="voxelDataLocalPosition"/> for this container. /// </summary> /// <param name="voxelDataLocalPosition">The voxel data position inside of this container to get the index for</param> /// <returns>The voxel data index for <paramref name="voxelDataLocalPosition"/></returns> public int GetIndex(int3 voxelDataLocalPosition) { return(IndexUtilities.XyzToIndex(voxelDataLocalPosition, Width, Height)); }
/// <summary> /// Gets the voxel data at <paramref name="x"/>, <paramref name="y"/>, <paramref name="z"/>. If the data doesn't exist at <paramref name="x"/>, <paramref name="y"/>, <paramref name="z"/>, an <see cref="IndexOutOfRangeException"/> will be thrown /// </summary> /// <param name="x">The x value of the voxel data location</param> /// <param name="y">The y value of the voxel data location</param> /// <param name="z">The z value of the voxel data location</param> /// <returns>The voxel data at <paramref name="x"/>, <paramref name="y"/>, <paramref name="z"/></returns> public T GetVoxelData(int x, int y, int z) { int index = IndexUtilities.XyzToIndex(x, y, z, Width, Height); return(GetVoxelData(index)); }
/// <summary> /// Tries to get the voxel data at <paramref name="x"/>, <paramref name="y"/>, <paramref name="z"/>. If the data exists at <paramref name="x"/>, <paramref name="y"/>, <paramref name="z"/>, true will be returned and <paramref name="voxelData"/> will be set to the value (range [0, 1]). If it doesn't exist, false will be returned and <paramref name="voxelData"/> will be set to 0. /// </summary> /// <param name="x">The x value of the voxel data location</param> /// <param name="y">The y value of the voxel data location</param> /// <param name="z">The z value of the voxel data location</param> /// <param name="voxelData">A voxel data in the range [0, 1] at <paramref name="x"/>, <paramref name="y"/>, <paramref name="z"/></param> /// <returns>Does a voxel data point exist at <paramref name="x"/>, <paramref name="y"/>, <paramref name="z"/></returns> public bool TryGetVoxelData(int x, int y, int z, out T voxelData) { int index = IndexUtilities.XyzToIndex(x, y, z, Width, Height); return(TryGetVoxelData(index, out voxelData)); }
/// <summary> /// Stores the <paramref name="voxelData"/> at <paramref name="x"/>, <paramref name="y"/>, <paramref name="z"/>. The <paramref name="voxelData"/> will be clamped to be in range [0, 1] /// </summary> /// <param name="voxelData">The new voxel data</param> /// <param name="x">The x value of the voxel data location</param> /// <param name="y">The y value of the voxel data location</param> /// <param name="z">The z value of the voxel data location</param> public void SetVoxelData(T voxelData, int x, int y, int z) { int index = IndexUtilities.XyzToIndex(x, y, z, Width, Height); SetVoxelData(voxelData, index); }
/// <summary> /// Stores the <paramref name="voxelData"/> at <paramref name="localPosition"/>. The <paramref name="voxelData"/> will be clamped to be in range [0, 1] /// </summary> /// <param name="voxelData">The new voxel data</param> /// <param name="localPosition">The location of that voxel data</param> public void SetVoxelData(T voxelData, int3 localPosition) { int index = IndexUtilities.XyzToIndex(localPosition, Width, Height); SetVoxelData(voxelData, index); }
/// <summary> /// Increases the voxel data at <paramref name="x"/>, <paramref name="y"/>, <paramref name="z"/> by <paramref name="increaseAmount"/>. If <paramref name="x"/>, <paramref name="y"/>, <paramref name="z"/> is out of <see cref="Size"/>, an <see cref="IndexOutOfRangeException"/> will be thrown. /// </summary> /// <param name="increaseAmount">How much the voxel data at <paramref name="x"/>, <paramref name="y"/>, <paramref name="z"/> should be increased by</param> /// <param name="x">The x value of the voxel data location</param> /// <param name="y">The y value of the voxel data location</param> /// <param name="z">The z value of the voxel data location</param> public void IncreaseVoxelData(float increaseAmount, int x, int y, int z) { int index = IndexUtilities.XyzToIndex(x, y, z, Width, Height); IncreaseVoxelData(increaseAmount, index); }
/// <summary> /// Increases the voxel data at <paramref name="localPosition"/> by <paramref name="increaseAmount"/>. If <paramref name="localPosition"/> is out of <see cref="Size"/>, an <see cref="IndexOutOfRangeException"/> will be thrown. /// </summary> /// <param name="increaseAmount">How much the voxel data at <paramref name="localPosition"/> should be increased by</param> /// <param name="localPosition">The local position of the voxel data to increase</param> public void IncreaseVoxelData(float increaseAmount, int3 localPosition) { int index = IndexUtilities.XyzToIndex(localPosition, Width, Height); IncreaseVoxelData(increaseAmount, index); }
public void TestXyzToIndex_Using_int3(int3 xyz, int expectedIndex, int width, int height) { int actualIndex = IndexUtilities.XyzToIndex(xyz, width, height); Assert.AreEqual(expectedIndex, actualIndex); }
/// <inheritdoc /> public bool IsIndexValid(TIndex index) => IndexUtilities.IsIn(index, this.LowerBounds, this.UpperBounds);
private static void TestIndexToXyz(int index, int expectedX, int expectedY, int expectedZ, int width, int height) { Assert.AreEqual(new int3(expectedX, expectedY, expectedZ), IndexUtilities.IndexToXyz(index, width, height)); }
private static void TestXyzToIndex_Using_int_xyz(int x, int y, int z, int expectedIndex, int width, int height) { int actualIndex = IndexUtilities.XyzToIndex(x, y, z, width, height); Assert.AreEqual(expectedIndex, actualIndex); }