public void Returns_values_greater_than_zero() { WorleyNoise.CellData cell = testUtil.RandomCellData(cellWorley); WorleyNoise.PointData point = testUtil.RandomPointData(cellWorley); float sumOfAllValuesPoint = 0; float sumOfAllValuesCell = 0; sumOfAllValuesCell += cell.index.x; sumOfAllValuesCell += cell.index.y; sumOfAllValuesCell += cell.position.x; sumOfAllValuesCell += cell.position.z; sumOfAllValuesCell += cell.value; sumOfAllValuesPoint += point.distance2Edge; sumOfAllValuesPoint += point.distance; sumOfAllValuesPoint += point.currentCellValue; sumOfAllValuesPoint += point.adjacentCellValue; sumOfAllValuesPoint += point.currentCellPosition.x; sumOfAllValuesPoint += point.currentCellPosition.z; sumOfAllValuesPoint += point.adjacentCellPosition.x; sumOfAllValuesPoint += point.adjacentCellPosition.z; sumOfAllValuesPoint += point.currentCellIndex.x; sumOfAllValuesPoint += point.currentCellIndex.y; sumOfAllValuesPoint += point.adjacentCellIndex.x; sumOfAllValuesPoint += point.adjacentCellIndex.y; Assert.NotZero(sumOfAllValuesPoint, "Point"); Assert.NotZero(sumOfAllValuesCell, "Cell"); }
bool AdjacentInSameGroup(WorleyNoise.PointData point) { float currentCellGroup = cellSystem.GetCellGrouping(point.currentCellIndex); float adjacentCellGroup = cellSystem.GetCellGrouping(point.adjacentCellIndex); return(currentCellGroup == adjacentCellGroup); }
WorleyNoise.PointData GetPointData(float3 position) { WorleyNoise.PointData data = worley.GetPointData(position.x, position.z); data.pointWorldPosition = position; data.isSet = true; return(data); }
bool AdjacentIsSameHeight(WorleyNoise.PointData point) { float currentCellHeight = cellSystem.GetCellHeight(point.currentCellIndex); float adjacentCellHeight = cellSystem.GetCellHeight(point.adjacentCellIndex); return(currentCellHeight == adjacentCellHeight); }
float SmoothSlope(WorleyNoise.PointData point) { float currentHeight = cellSystem.GetCellHeight(point.currentCellIndex); float adjacentHeight = cellSystem.GetCellHeight(point.adjacentCellIndex); if (currentHeight == adjacentHeight) { return(currentHeight); } float halfway = (currentHeight + adjacentHeight) / 2; float currentHeightGroup = topologyUtil.CellHeightGroup(point.currentCellIndex); float adjacentHeightGroup = topologyUtil.CellHeightGroup(point.adjacentCellIndex); float difference = math.max(currentHeightGroup, adjacentHeightGroup) - math.min(currentHeightGroup, adjacentHeightGroup); int clampedDifference = (int)math.clamp(difference, 1, TerrainSettings.cellHeightLevelCount); float adjustedSlopeLength = TerrainSettings.slopeLength * clampedDifference; float interpolator; if (point.distance2Edge > adjustedSlopeLength / 2) { interpolator = math.smoothstep(0, adjustedSlopeLength, point.distance2Edge); } else { interpolator = math.unlerp(0, adjustedSlopeLength, point.distance2Edge); } return(math.lerp(halfway, currentHeight, math.clamp(interpolator, 0, 1))); }
float Lake(WorleyNoise.PointData point, bool sloped) { float cellHeight = sloped ? SmoothSlope(point) : cellSystem.GetCellHeight(point.currentCellIndex); float lakeDepth = math.clamp(point.distance2Edge - 0.3f, 0, 1) * (TerrainSettings.cellheightMultiplier * 3); return(cellHeight - lakeDepth); }
bool SectorIsPathable(DynamicBuffer <WorleyNoise.PointData> points, float grouping) { for (int i = 0; i < points.Length; i++) { WorleyNoise.PointData point = points[i]; if (PointIsOutsideGroup(point, grouping)) { continue; } if (AdjacentInSameGroup(point)) { continue; } if (AdjacentIsSameHeight(point)) { return(true); } if (AdjacentEdgeIsSlope(point)) { return(true); } } return(false); }
public bool EdgeIsSloped(WorleyNoise.PointData point) { int2 edge = point.adjacentCellIndex - point.currentCellIndex; SlopedSideDirections slopeSides = SlopedSide(point.currentCellValue, point.adjacentCellValue); return(slopeSides.a.Equals(edge) || slopeSides.b.Equals(edge)); }
public void Distances_do_not_equal_999999() { WorleyNoise.PointData point = testUtil.RandomPointData(cellWorley); bool notEqual = (point.distance2Edge != 999999 && point.distance != 999999); Assert.IsTrue(notEqual, "distance2Edge: " + point.distance2Edge + "\ndistance: " + point.distance); }
public void Cell_value_greater_than_zero_and_less_than_one() { for (int i = 0; i < 500; i++) { WorleyNoise.CellData cell = testUtil.RandomCellData(cellWorley); WorleyNoise.PointData point = testUtil.RandomPointData(cellWorley); Assert.Less(cell.value, 1, "Cell less than 1"); Assert.Greater(cell.value, 0, "Cell greater than 0"); Assert.Less(point.currentCellValue, 1, "Point less than 1"); Assert.Greater(point.currentCellValue, 0, "Point greater than 0"); } }
public void FloodFillCell() { NativeQueue <WorleyNoise.PointData> dataToCheck = new NativeQueue <WorleyNoise.PointData>(Allocator.Temp); WorleyNoise.PointData initialPointData = GetPointData(startCell.position); dataToCheck.Enqueue(initialPointData); float startCellGrouping = GetOrGenerateCellGrouping(startCell.index); initialPointData.cellGrouping = startCellGrouping; pointMatrix.AddItem(initialPointData, initialPointData.pointWorldPosition); while (dataToCheck.Count > 0) { DebugSystem.Count("Points flood filled"); WorleyNoise.PointData data = dataToCheck.Dequeue(); bool currentIsOutsideCell = GetOrGenerateCellGrouping(data.currentCellIndex) != startCellGrouping; for (int x = -1; x <= 1; x++) { for (int z = -1; z <= 1; z++) { float3 adjacentPosition = new float3(x, 0, z) + data.pointWorldPosition; WorleyNoise.PointData adjacentData = GetPointData(adjacentPosition); float grouping = GetOrGenerateCellGrouping(adjacentData.currentCellIndex); bool adjacentIsOutsideCell = grouping != startCellGrouping; if (pointMatrix.ItemIsSet(adjacentPosition) || (currentIsOutsideCell && adjacentIsOutsideCell)) { continue; } adjacentData.cellGrouping = grouping; dataToCheck.Enqueue(adjacentData); pointMatrix.AddItem(adjacentData, adjacentData.pointWorldPosition); } } } dataToCheck.Dispose(); }
void AddVertexDataForTriangle(Vertex a, Vertex b, Vertex c, WorleyNoise.PointData aWorley, WorleyNoise.PointData bWorley, WorleyNoise.PointData cWorley) { if (!CurrentCellIsOwner(aWorley, bWorley, cWorley)) { return; } float difference = LargestHeightDifference(a.vertex.y, b.vertex.y, c.vertex.y); float4 color = PointColor(difference); AddVertexData(a, color - new float4(aWorley.distance2Edge * 0.1)); AddVertexData(b, color - new float4(bWorley.distance2Edge * 0.1)); AddVertexData(c, color - new float4(cWorley.distance2Edge * 0.1)); AddIndicesForTriangle(); return; }
public void PointData_matches_CellData() { WorleyNoise.PointData randomPoint = testUtil.RandomPointData(cellWorley); WorleyNoise.CellData cell = cellWorley.GetCellData(randomPoint.currentCellIndex); Assert.IsTrue( randomPoint.currentCellPosition.Equals(cell.position), "Position\n" + "PointData: " + randomPoint.currentCellPosition + '\n' + "CellData: " + cell.position ); Assert.IsTrue( randomPoint.currentCellIndex.Equals(cell.index), "Index\n" + "PointData: " + randomPoint.currentCellIndex + '\n' + "CellData: " + cell.index ); Assert.IsTrue( randomPoint.currentCellValue.Equals(cell.value), "Value\n" + "PointData: " + randomPoint.currentCellValue + '\n' + "CellData: " + cell.value ); }
void DebugWorley() { if (playerSystem.player == null) { return; } float3 playerPosition = math.round(playerSystem.player.transform.position); WorleyNoise.PointData point = debugWorley.GetPointData(playerPosition.x, playerPosition.z); Text("distance2Edge", point.distance2Edge.ToString()); Text("group", topologyUtil.CellGrouping(point.currentCellIndex).ToString()); Text("cell index", point.currentCellIndex.ToString()); worleyCurrentMarker.transform.position = math.round(point.currentCellPosition) + new float3(0.5f, cellSystem.GetHeightAtPosition(point.currentCellPosition) + 1, 0.5f); worleyAdjacentMarker.transform.position = math.round(point.adjacentCellPosition) + new float3(0.5f, cellSystem.GetHeightAtPosition(point.adjacentCellPosition) + 1, 0.5f); }
bool CurrentCellIsOwner(WorleyNoise.PointData aWorley, WorleyNoise.PointData bWorley, WorleyNoise.PointData cWorley) { if (!aWorley.isSet || !bWorley.isSet || !cWorley.isSet) { return(false); } NativeArray <WorleyNoise.PointData> sortPoints = new NativeArray <WorleyNoise.PointData>(3, Allocator.Temp); sortPoints[0] = aWorley; sortPoints[1] = bWorley; sortPoints[2] = cWorley; sortPoints.Sort(); float ownerGrouping = sortPoints[0].cellGrouping; return(masterGrouping == ownerGrouping); }
public void Execute() { Entity waterEntity = commandBuffer.CreateEntity(waterEntityArchetype); commandBuffer.SetComponent <Translation>(waterEntity, new Translation { Value = new float3(matrix.root.x, 0, matrix.root.z) }); vertices = commandBuffer.AddBuffer <Vertex>(waterEntity); colors = commandBuffer.AddBuffer <VertColor>(waterEntity); triangles = commandBuffer.AddBuffer <Triangle>(waterEntity); int indexOffset = 0; for (int x = 0; x < matrix.width - 1; x++) { for (int z = 0; z < matrix.width - 1; z++) { int2 bl = new int2(x, z); int2 tl = new int2(x, z + 1); int2 tr = new int2(x + 1, z + 1); int2 br = new int2(x + 1, z); WorleyNoise.PointData blWorley = matrix.GetItem <WorleyNoise.PointData>(bl, worley, arrayUtil); WorleyNoise.PointData tlWorley = matrix.GetItem <WorleyNoise.PointData>(tl, worley, arrayUtil); WorleyNoise.PointData trWorley = matrix.GetItem <WorleyNoise.PointData>(tr, worley, arrayUtil); WorleyNoise.PointData brWorley = matrix.GetItem <WorleyNoise.PointData>(br, worley, arrayUtil); if (!blWorley.isSet || !tlWorley.isSet || !trWorley.isSet || !brWorley.isSet) { continue; } float waterHeight = topologyUtil.CellHeight(masterCell.index); float4 waterColor = new float4(0, 0.5f, 1, 0.5f); vertices.Add(new Vertex { vertex = new float3(bl.x, waterHeight - 1, bl.y) }); vertices.Add(new Vertex { vertex = new float3(tl.x, waterHeight - 1, tl.y) }); vertices.Add(new Vertex { vertex = new float3(tr.x, waterHeight - 1, tr.y) }); vertices.Add(new Vertex { vertex = new float3(br.x, waterHeight - 1, br.y) }); colors.Add(new VertColor { color = waterColor }); colors.Add(new VertColor { color = waterColor }); colors.Add(new VertColor { color = waterColor }); colors.Add(new VertColor { color = waterColor }); GetTriangleIndicesForQuad(indexOffset); indexOffset += 4; } } }
bool AdjacentEdgeIsSlope(WorleyNoise.PointData point) { return(topologyUtil.EdgeIsSloped(point)); }
void ScheduleTopologyJobs() { var commandBuffer = new EntityCommandBuffer(Allocator.TempJob); var chunks = topologyGroup.CreateArchetypeChunkArray(Allocator.TempJob); var entityType = GetArchetypeChunkEntityType(); var sectorTypeType = GetArchetypeChunkComponentType <SectorSystem.TypeComponent>(true); var worleyType = GetArchetypeChunkBufferType <WorleyNoise.PointData>(true); var sectorCellArrayType = GetArchetypeChunkBufferType <CellSystem.SectorCell>(true); var sectorAdjacentCellArrayType = GetArchetypeChunkBufferType <CellSystem.AdjacentCell>(true); for (int c = 0; c < chunks.Length; c++) { var chunk = chunks[c]; var entities = chunk.GetNativeArray(entityType); var sectorTypes = chunk.GetNativeArray(sectorTypeType); var worleyArrays = chunk.GetBufferAccessor(worleyType); var sectorCellArrays = chunk.GetBufferAccessor(sectorCellArrayType); var sectorAdjacentCellArrays = chunk.GetBufferAccessor(sectorAdjacentCellArrayType); for (int e = 0; e < entities.Length; e++) { Entity entity = entities[e]; SectorSystem.SectorTypes sectorType = sectorTypes[e].Value; DynamicBuffer <WorleyNoise.PointData> worley = worleyArrays[e]; DynamicBuffer <CellSystem.SectorCell> sectorCells = sectorCellArrays[e]; DynamicBuffer <CellSystem.AdjacentCell> sectorAdjacentCells = sectorAdjacentCellArrays[e]; DynamicBuffer <Height> topology = commandBuffer.AddBuffer <Height>(entity); topology.ResizeUninitialized(worley.Length); for (int i = 0; i < topology.Length; i++) { if (!worley[i].isSet) { continue; } float3 position = worley[i].pointWorldPosition; WorleyNoise.PointData point = worley[i]; Height pointHeight = new Height(); bool sloped = topologyUtil.EdgeIsSloped(point); if (sloped && !(sectorType == SectorSystem.SectorTypes.LAKE)) { pointHeight.height = SmoothSlope(point); } else if (sectorType == SectorSystem.SectorTypes.LAKE) { pointHeight.height = Lake(worley[i], sloped); } else { pointHeight.height = cellSystem.GetCellHeight(worley[i].currentCellIndex); } topology[i] = pointHeight; } } } commandBuffer.Playback(entityManager); commandBuffer.Dispose(); chunks.Dispose(); }
bool PointIsOutsideGroup(WorleyNoise.PointData point, float grouping) { return(!point.isSet || (cellSystem.GetCellGrouping(point.currentCellIndex) != grouping)); }
public void Execute() { masterGrouping = topologyUtil.CellGrouping(masterCell.index); vertices = commandBuffer.AddBuffer <Vertex>(sectorEntity); colors = commandBuffer.AddBuffer <VertColor>(sectorEntity); triangles = commandBuffer.AddBuffer <Triangle>(sectorEntity); for (int x = 0; x < matrix.width - 1; x++) { for (int z = 0; z < matrix.width - 1; z++) { int2 bl = new int2(x, z); int2 tl = new int2(x, z + 1); int2 tr = new int2(x + 1, z + 1); int2 br = new int2(x + 1, z); WorleyNoise.PointData blWorley = matrix.GetItem <WorleyNoise.PointData>(bl, worley, arrayUtil); WorleyNoise.PointData tlWorley = matrix.GetItem <WorleyNoise.PointData>(tl, worley, arrayUtil); WorleyNoise.PointData trWorley = matrix.GetItem <WorleyNoise.PointData>(tr, worley, arrayUtil); WorleyNoise.PointData brWorley = matrix.GetItem <WorleyNoise.PointData>(br, worley, arrayUtil); if (!blWorley.isSet || !tlWorley.isSet || !trWorley.isSet || !brWorley.isSet) { continue; } Vertex blVertex = GetVertex(bl); Vertex tlVertex = GetVertex(tl); Vertex trVertex = GetVertex(tr); Vertex brVertex = GetVertex(br); bool northWestToSouthEast = brVertex.vertex.y != tlVertex.vertex.y; bool sloped = (topologyUtil.EdgeIsSloped(blWorley) || topologyUtil.EdgeIsSloped(tlWorley) || topologyUtil.EdgeIsSloped(trWorley) || topologyUtil.EdgeIsSloped(brWorley)); bool flat = (blVertex.vertex.y == tlVertex.vertex.y && blVertex.vertex.y == trVertex.vertex.y && blVertex.vertex.y == brVertex.vertex.y); if (northWestToSouthEast) { if (sloped || flat) { AddVertexDataQuad(blVertex, tlVertex, trVertex, brVertex, blWorley, tlWorley, trWorley, brWorley); } else { AddVertexDataForTriangle(blVertex, tlVertex, trVertex, blWorley, tlWorley, trWorley); AddVertexDataForTriangle(blVertex, trVertex, brVertex, blWorley, trWorley, brWorley); } } else { if (sloped || flat) { AddVertexDataQuad(tlVertex, trVertex, brVertex, blVertex, tlWorley, trWorley, brWorley, blWorley); } else { AddVertexDataForTriangle(blVertex, tlVertex, brVertex, blWorley, tlWorley, brWorley); AddVertexDataForTriangle(tlVertex, trVertex, brVertex, tlWorley, trWorley, brWorley); } } } } }