Skip to content

Commit

Permalink
CellularAutomaton: Separated cells into a structure
Browse files Browse the repository at this point in the history
  • Loading branch information
BasmanovDaniil committed Jan 10, 2021
1 parent da27b2e commit 9e2af0c
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 43 deletions.
43 changes: 43 additions & 0 deletions Runtime/CellularAutomaton/Cells.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System;
using Unity.Collections;
using Random = UnityEngine.Random;

namespace ProceduralToolkit.CellularAutomata
{
public struct Cells : IDisposable
{
public NativeArray2D<bool> cells;
public NativeArray2D<bool> copy;

public Cells(CellularAutomaton.Config config)
{
cells = new NativeArray2D<bool>(config.width, config.height, Allocator.Persistent);
copy = new NativeArray2D<bool>(config.width, config.height, Allocator.Persistent);

FillWithNoise(config.startNoise);
}

public void Dispose()
{
if (cells.IsCreated)
{
cells.Dispose();
}
if (copy.IsCreated)
{
copy.Dispose();
}
}

public void FillWithNoise(float noise)
{
for (int y = 0; y < cells.LengthY; y++)
{
for (int x = 0; x < cells.LengthX; x++)
{
cells[x, y] = copy[x, y] = Random.value < noise;
}
}
}
}
}
11 changes: 11 additions & 0 deletions Runtime/CellularAutomaton/Cells.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 17 additions & 40 deletions Runtime/CellularAutomaton/CellularAutomaton.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using System;
using Unity.Collections;
using UnityEngine.Assertions;
using Random = UnityEngine.Random;

namespace ProceduralToolkit.CellularAutomata
{
/// <summary>
/// Generic cellular automaton for two-state rulesets
/// </summary>
public struct CellularAutomaton : IDisposable
public struct CellularAutomaton
{
[Serializable]
public struct Config
Expand All @@ -29,87 +28,65 @@ public struct Config
};
}

public NativeArray2D<bool> cells;
public NativeArray2D<bool> copy;
public Cells cells;
public Config config;
public int simulationSteps;

public CellularAutomaton(Config config, int simulationSteps = 1)
public CellularAutomaton(Cells cells, Config config, int simulationSteps = 1)
{
Assert.IsTrue(config.width > 0);
Assert.IsTrue(config.height > 0);

this.cells = cells;
this.config = config;
this.simulationSteps = simulationSteps;
cells = new NativeArray2D<bool>(config.width, config.height, Allocator.Persistent);
copy = new NativeArray2D<bool>(config.width, config.height, Allocator.Persistent);

FillWithNoise();
}

public void Dispose()
public CellularAutomaton(Config config, int simulationSteps = 1)
{
if (cells.IsCreated)
{
cells.Dispose();
}
if (copy.IsCreated)
{
copy.Dispose();
}
Assert.IsTrue(config.width > 0);
Assert.IsTrue(config.height > 0);

cells = new Cells(config);
this.config = config;
this.simulationSteps = simulationSteps;
}

public void Execute()
{
for (int i = 0; i < simulationSteps; i++)
{
PTUtils.Swap(ref cells, ref copy);
PTUtils.Swap(ref cells.cells, ref cells.copy);
for (int x = 0; x < config.width; x++)
{
for (int y = 0; y < config.height; y++)
{
int aliveCells = CountAliveNeighbourCells(x, y);

if (copy[x, y])
if (cells.copy[x, y])
{
cells[x, y] = config.ruleset.CanSurvive(aliveCells);
cells.cells[x, y] = config.ruleset.CanSurvive(aliveCells);
}
else
{
cells[x, y] = config.ruleset.CanSpawn(aliveCells);
cells.cells[x, y] = config.ruleset.CanSpawn(aliveCells);
}
}
}
}
}

public void FillWithNoise()
{
FillWithNoise(config.startNoise);
}

public void FillWithNoise(float noise)
{
for (int x = 0; x < config.width; x++)
{
for (int y = 0; y < config.height; y++)
{
cells[x, y] = copy[x, y] = Random.value < noise;
}
}
}

private int CountAliveNeighbourCells(int x, int y)
{
if (config.aliveBorders)
{
var visitor = new Visitor8Unbounded<CounterUnbounded>(new CounterUnbounded {array = copy});
var visitor = new Visitor8Unbounded<CounterUnbounded>(new CounterUnbounded {array = cells.copy});
visitor.Visit8Unbounded(x, y);
return visitor.action.count;
}
else
{
var visitor = new Visitor8<Counter>(copy.LengthX, copy.LengthY, new Counter {array = copy});
var visitor = new Visitor8<Counter>(cells.copy.LengthX, cells.copy.LengthY, new Counter {array = cells.copy});
visitor.Visit8(x, y);
return visitor.action.count;
}
Expand Down
6 changes: 3 additions & 3 deletions Samples/CellularAutomata/CellularAutomatonExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ private void Update()
{
for (int y = 0; y < config.height; y++)
{
pixels.SetXY(x, y, config.width, automaton.cells[x, y] ? aliveColor : deadColor);
pixels.SetXY(x, y, config.width, automaton.cells.cells[x, y] ? aliveColor : deadColor);
}
}

Expand All @@ -102,12 +102,12 @@ private void Update()

private void OnDestroy()
{
automaton.Dispose();
automaton.cells.Dispose();
}

private void Generate()
{
automaton.Dispose();
automaton.cells.Dispose();
automaton = new CellularAutomaton(config);

GeneratePalette();
Expand Down

0 comments on commit 9e2af0c

Please sign in to comment.