/// <summary> /// /// </summary> private void Awake() { _currentStack = _model.Stack; _currentGeneration = new CellStack[_genSize]; _population.Reset(); InitializeMatingPool(); }
// Converts the top cell to sand if certain criteria are met // This modifies terrain based on neighbor stacks // Thus it should only be called after all cell stacks are generated void AddSand(CellStack cellStack) { if (cellStack.Count() == terrain.waterLevel) { HexCoordinates[] neighbors = cellStack.coordinates.GetNeighbors(); for (int i = 0; i < 6; i++) { CellStack neighbor = GetCellStackFromWorldCoords(neighbors[i]); // The neighbor cell stack might not be in this chunk if (neighbor == null) { TerrainChunk neighborChunk = terrain.GetChunkFromWorldCoords(neighbors[i]); if (neighborChunk != null) { neighbor = neighborChunk.GetCellStackFromWorldCoords(neighbors[i]); } } if (neighbor != null) { if (neighbor.Count() < terrain.waterLevel) { cellStack.Pop(); cellStack.Push(CellType.Sand); break; } } } } }
/// <summary> /// /// </summary> private void Awake() { _currentStack = _model.Stack; _currentGenerationData = new CellStackData[_genSize]; _population.Reset(); InitializeMatingPool(); string filepath = Application.dataPath + "/00-DataOutput"; string dateAndTimeVar = System.DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss"); filepath += "/" + dateAndTimeVar; filePath = filepath; System.IO.Directory.CreateDirectory(filePath); //ONLY IF USING GENES FOR PARTIAL IMAGE SEEDS - synthesize 4 images from child genes - don't use this if you dont have genes for image textures if (_SeedFromGenes == true) { Texture2D texture1 = _seeds[_currentStack.DNA.GetGene(0)]; Texture2D texture2 = _seeds[_currentStack.DNA.GetGene(1)]; Texture2D texture3 = _seeds[_currentStack.DNA.GetGene(2)]; Texture2D texture4 = _seeds[_currentStack.DNA.GetGene(3)]; Texture2D combined = ImageSynthesizer.CombineFour(texture1, texture2, texture3, texture4, _currentStack.RowCount, _currentStack.ColumnCount); //place the synthesized image into the stack _currentStack.SetSeed(combined); //resets/initializes the model using the synthesized image _model.ResetModel(combined); //place the synthesized image into the stack _currentStack.SetSeed(combined); _analyser.ResetAnalysis(); } }
internal static void FlushAllData() { CellStacks = null; FloorCell = new CellStack.Cell(); CeilingCell = new CellStack.Cell(); CellStack.StaticReset(); }
public void RemoveCell(HexCoordinates coordinates) { CellStack stack = GetCellStackFromWorldCoords(coordinates); if (stack) { stack.Pop(); GenerateMeshes(); } }
/// <summary> /// /// </summary> private void Awake() { // create model _model = new CAModel2D(GetComponent <ICARule2D>(), _stack.RowCount, _stack.ColumnCount); _stack = Instantiate(_stack); // initialize model _initializer.Initialize(_model.CurrentState); }
public void AddTerrainObject(TerrainObjectType type, HexCoordinates coordinates) { //TODO this could be more efficient CellStack stack = GetCellStackFromWorldCoords(coordinates); if (type == TerrainObjectType.Tree) { AddTree(stack); } }
public static void Create() { if (CellStacks == null) { CellStacks = new CellStack[Graph.Nodes.Length]; for (int i = 0; i < CellStacks.Length; i++) { CellStacks[i] = new CellStack(); } } }
public CellStack GetCellStackFromChunkOffset(Vector2 coords) { CellStack stack = null; try { stack = cellStacks[(int)coords.x, (int)coords.y]; } catch (IndexOutOfRangeException e) { Debug.LogWarning("WARNING: Tried to access CellStack that is out of bounds"); } return(stack); }
public bool CanRemoveCell(HexCoordinates coordinates) { CellStack stack = GetCellStackFromWorldCoords(coordinates); if (stack) { return(stack.CanPop()); } else { return(false); } }
private void TouchCell(TerrainChunk chunk, HexCoordinates coords) { try { CellStack stack = chunk.GetCellStackFromWorldCoords(coords); ghostCellPrefab.SetActive(true); Vector3 ghostPosition = stack.coordinates.ToWorldPosition(terrain) + HexMetrics.ScaledHeightVector(terrain) * stack.Count(); ghostCellPrefab.transform.localPosition = ghostPosition; } catch (NullReferenceException e) { Debug.LogWarning("Trying to access null cellstack"); } }
public IEnumerator GenerationCoroutine() { vertices.Clear(); triangles.Clear(); submeshes = new List <int> [materials.Count()]; triangleIndex = 0; int rows = chunk.size; int columns = chunk.size; for (int z = 0, i = 0; z < rows; z++) { for (int x = 0; x < columns; x++) { CellStack stack = chunk.GetCellStackFromChunkOffset(new Vector2(x, z)); if (stack != null) { yield return(Ninja.JumpToUnity); GenerateStackMesh(x, z, stack); yield return(Ninja.JumpBack); } } } yield return(Ninja.JumpToUnity); terrainRenderMesh.Clear(); terrainRenderMesh.vertices = vertices.ToArray(); terrainRenderMesh.triangles = triangles.ToArray(); //Create a submesh for each material terrainRenderMesh.subMeshCount = submeshes.Count(); //Set material for each submesh meshRenderer.materials = materials; for (int i = 0; i < submeshes.Count(); i++) { if (submeshes[i] != null) { terrainRenderMesh.SetTriangles(submeshes[i], i); } } terrainRenderMesh.RecalculateNormals(); terrainRenderMesh.RecalculateBounds(); yield return(Ninja.JumpBack); }
public void RemoveTerrainObject(HexCoordinates coordinates) { //TODO this could be more efficient CellStack stack = GetCellStackFromWorldCoords(coordinates); if (stack) { Vector2Int index = stack.indexWithinChunk; TerrainObject obj = terrainObjects[index.x, index.y]; if (obj != null) { terrainObjects[index.x, index.y] = null; GameObject.Destroy(obj.gameObject); } } }
CellStack CreateCellStack(int x, int z, int height) { CellStack cellStack = ScriptableObject.CreateInstance <CellStack>(); HexCoordinates coords = HexCoordinates.FromOffsetCoordinates(x + (int)offsetOrigin.x, z + (int)offsetOrigin.y); Vector2Int indexWithinChunk = new Vector2Int(x % size, z % size); cellStack.Init(coords, indexWithinChunk); cellStack.Push(CellType.Bedrock); int numStoneTiles = (int)(height * terrain.stoneHeightPercentage); // Generate terrian based on stack height for (int i = 0; i < height; i++) { CellType newCell; if (height >= terrain.waterLevel - 1 && i == height - 1) { newCell = CellType.Grass; } else if (i < numStoneTiles) { newCell = CellType.Stone; } else { newCell = CellType.Dirt; } cellStack.Push(newCell); } if (showCoordinates && gridCanvas != null) { Vector3 position = cellStack.coordinates.ToChunkPosition(); position += HexMetrics.heightVector * (cellStack.Count() + 1); Text label = Instantiate <Text>(terrain.cellLabelPrefab); label.rectTransform.SetParent(gridCanvas.transform, false); label.rectTransform.anchoredPosition3D = new Vector3(position.x, position.z, -position.y); label.text = cellStack.coordinates.ToStringOnSeparateLines(); } return(cellStack); }
public void AddCell(CellType cell, HexCoordinates coords) { CellStack stack = GetCellStackFromWorldCoords(coords); if (stack) { // Only trees can be placed on top of grass // So if something else is placed on top of grass, turn the grass into dirt if (stack.Peek() == CellType.Grass) { stack.Pop(); stack.Push(CellType.Dirt); } stack.Push(cell); GenerateMeshes(); } }
// Adds a tree on top of stack if certain criteria are met void AddTree(CellStack cellStack) { if (cellStack.Count() > terrain.waterLevel && (cellStack.Peek() == CellType.Grass || cellStack.Peek() == CellType.Dirt)) { Vector2Int offset = cellStack.indexWithinChunk; Vector3 treePos = transform.position + new Vector3(offset.x * HexMetrics.innerRadius * 2 + offset.y % 2 * HexMetrics.innerRadius, transform.localPosition.y + HexMetrics.height * cellStack.Count(), offset.y * HexMetrics.outerRadius * 1.5f); // Randomly rotate the tree so it looks less uniform float rotation = UnityEngine.Random.Range(0, 359); Vector3 treeRot = new Vector3(0, rotation, 0); TerrainObject tree = GameObject.Instantiate(treePrefab); tree.Init(cellStack.coordinates, offset); tree.transform.SetParent(transform); tree.transform.position = treePos; tree.transform.rotation = Quaternion.Euler(treeRot); terrainObjects[offset.x, offset.y] = tree; } }
private static void ApplyDeltaField(Interface.Struct.GridDelta delta, Interface.Struct.GridDeltaBlock[] blocks, Action <CellStack, uint, byte> action) { if (blocks.Length != 0) { //Out.Log(Significance.Low, " Applying " + blocks.Length + " blocks..."); uint at = 0; foreach (var block in blocks) { for (int i = 0; i < block.repitition; i++) { uint stackIndex = (at % delta.nodeCount) + delta.nodeOffset; uint layer = at / delta.nodeCount; CellStack stack = CellStacks[stackIndex]; action(stack, layer, block.value); at++; } } Debug.Assert(at == delta.nodeCount * CellStack.LayersPerStack); } }
public IEnumerator GenerationCoroutine() { vertices.Clear(); triangles.Clear(); int rows = chunk.size; int columns = chunk.size; for (int z = 0, i = 0; z < rows; z++) { for (int x = 0; x < columns; x++) { CellStack stack = chunk.GetCellStackFromChunkOffset(new Vector2(x, z)); if (stack != null) { yield return(Ninja.JumpToUnity); GenerateStackMesh(x, z, stack); yield return(Ninja.JumpBack); } } } yield return(Ninja.JumpToUnity); terrainMesh.Clear(); terrainMesh.vertices = vertices.ToArray(); terrainMesh.triangles = triangles.ToArray(); terrainMesh.RecalculateNormals(); terrainMesh.RecalculateBounds(); meshCollider.sharedMesh = terrainMesh; yield return(Ninja.JumpBack); //navMeshSurface.BuildNavMesh(); }
public static void Create() { if (CellStacks == null) { CellStacks = new CellStack[Graph.Nodes.Length]; for (int i = 0; i < CellStacks.Length; i++) CellStacks[i] = new CellStack(); } }
internal static void BeginSession(float heightPerLayer, int numLayersPerStack) { CellStack.Setup(heightPerLayer, numLayersPerStack); }
/// <summary> /// Adds a stack to the current generation of stacks /// </summary> private void AddStackToGeneration(CellStack stack) { //add stack to current generation of stacks _currentGenerationData[_curCount] = stack.CopyData(); }
/// <summary> /// /// </summary> private void Update() { //check if stack is finished building //if build not complete, leave function if (_model.BuildComplete == false) { return; } //if stack building is complete, get fitness / update if (_model.BuildComplete == true) { //calculate fitness _analyser.Fitness(); //move the stack position var generations = _population.Population.Count + 1; Vector3 vector = new Vector3(1.5f * (_currentStack.RowCount) * (_curCount - 1), 0, 1.5f * (_currentStack.ColumnCount)); _currentStack.transform.localPosition = vector; _currentStack.transform.parent = gameObject.transform; //add stack to current generation AddStackToGeneration(_currentStack); _curCount++; //if count == popsize recalculate the mating pool if (_curCount == _genSize) { //add generation to the population history AddGenToPopulation(_currentGeneration); //run natural selection to generate breeding pool UpdateMatingPool(); //reset current population array _currentGeneration = new CellStack[_genSize]; //reset popcounter _curCount = 0; //move population Vector3 vec = new Vector3(0, 0, 1.5f * (_currentStack.ColumnCount)); foreach (var stack in _population.Population) { stack.transform.localPosition += vec; } } //breed new dna from mating pool IDNAF childdna = Breed(); //turn off/deactivate the stack _currentStack.gameObject.SetActive(false); Debug.Log("Generation: " + generations + ", Stack: " + _curCount + " | Fitness= " + _currentStack.Fitness); //reset the stack and insert new dna _currentStack = Instantiate(_stackPrefab); _currentStack.SetDNA(childdna); _model.SetStack(_currentStack); //synthesize 4 images from child gene Texture2D texture1 = _seeds[Mathf.RoundToInt(childdna.GetGene(0))]; Texture2D texture2 = _seeds[Mathf.RoundToInt(childdna.GetGene(1))]; Texture2D texture3 = _seeds[Mathf.RoundToInt(childdna.GetGene(2))]; Texture2D texture4 = _seeds[Mathf.RoundToInt(childdna.GetGene(3))]; Texture2D combined = ImageSynthesizer.CombineFour(texture1, texture2, texture3, texture4, _currentStack.RowCount, _currentStack.ColumnCount); //place the synthesized image into the stack _currentStack.SetSeed(combined); //resets/initializes the model using the synthesized image _model.ResetModel(combined); //_model.ResetModel(); //Debug.Log("I reseted the model"); } }
/// <summary> /// Adds a stack to the current generation of stacks /// </summary> private void AddStackToGeneration(CellStack stack) { //add stack to current generation of stacks _currentGeneration[_curCount] = stack; }
void GenerateStackMesh(int x, int z, CellStack stack) { int stackHeight = stack.Count(); Vector2 worldOffset = new Vector2(x + chunk.offsetOrigin.x, z + chunk.offsetOrigin.y); Vector3 center = HexCoordinates.FromOffsetCoordinates(x, z).ToChunkPosition(); center += new Vector3(0, transform.localPosition.y, 0); center += stackHeight * HexMetrics.heightVector; CellType top = stack.Peek(); HexCoordinates[] neighbors = stack.coordinates.GetNeighbors(); for (int i = 0; i < 6; i++) { //Generates the horizontal part of the terrain (top of the stack) AddTriangle( center, center + HexMetrics.corners[i], center + HexMetrics.corners[i + 1] ); //Generates the vertical part of the terrain (sides of the stack) CellStack neighbor = chunk.GetCellStackFromWorldCoords(neighbors[i]); //If we have a neighbor in this direction, check its height //If it is taller than us, ignore it (it will create the vertical wall) //If it is the same height as us, ignore it (we don't need a vertical wall) //If it is shorter than us, create a vertical wall down to its height if (neighbor != null) { int neighborHeight = neighbor.Count(); float wallHeight = (stackHeight - neighborHeight) * HexMetrics.heightVector.y; if (wallHeight > 0) { Vector3 wallHeightVector = new Vector3(0, wallHeight, 0); AddTriangle( center + HexMetrics.corners[i] - wallHeightVector, center + HexMetrics.corners[i + 1], center + HexMetrics.corners[i] ); AddTriangle( center + HexMetrics.corners[i] - wallHeightVector, center + HexMetrics.corners[i + 1] - wallHeightVector, center + HexMetrics.corners[i + 1] ); } } else { AddTriangle( center + HexMetrics.corners[i] - HexMetrics.heightVector * stackHeight, center + HexMetrics.corners[i + 1], center + HexMetrics.corners[i] ); AddTriangle( center + HexMetrics.corners[i] - HexMetrics.heightVector * stackHeight, center + HexMetrics.corners[i + 1] - HexMetrics.heightVector * stackHeight, center + HexMetrics.corners[i + 1] ); } } }
void GenerateStackMesh(int x, int z, CellStack stack) { int stackHeight = stack.Count(); Vector2 worldOffset = new Vector2(x + chunk.offsetOrigin.x, z + chunk.offsetOrigin.y); Vector3 center = HexCoordinates.FromOffsetCoordinates(x, z).ToChunkPosition(); center += new Vector3(0, transform.localPosition.y, 0); center += stackHeight * HexMetrics.heightVector; CellType topCell = stack.Peek(); Material topMaterial = getTopMaterial(topCell); List <int> topMaterialSubmesh = getSubmesh(topMaterial); //Generates the horizontal part of the terrain (top of the stack) for (int i = 0; i < 6; i++) { AddTriangleToMesh( center, center + HexMetrics.corners[i], center + HexMetrics.corners[i + 1] ); AddTriangleToSubmesh( topMaterialSubmesh, center, center + HexMetrics.corners[i], center + HexMetrics.corners[i + 1] ); } HexCoordinates[] neighbors = stack.coordinates.GetNeighbors(); Vector3 topCenter = center; //Generates the vertical part of the terrain (sides of the stack) for (int i = 0; i < 6; i++) { center = topCenter; //If we have a neighbor in this direction, check its height //If it is taller than us, ignore it (it will create the vertical wall) //If it is the same height as us, ignore it (we don't need a vertical wall) //If it is shorter than us, create a vertical wall down to its height CellStack neighbor = chunk.GetCellStackFromWorldCoords(neighbors[i]); int neighborHeight = 0; if (neighbor != null) { neighborHeight = neighbor.Count(); } for (int elevation = stackHeight; elevation > neighborHeight; elevation--) { CellType currentCell = stack.PeekAt(elevation - 1); Material sideMaterial = getSideMaterial(currentCell); List <int> sideMaterialSubmesh = getSubmesh(sideMaterial); AddTriangleToMesh( center + HexMetrics.corners[i] - HexMetrics.heightVector, center + HexMetrics.corners[i + 1], center + HexMetrics.corners[i] ); AddTriangleToSubmesh( sideMaterialSubmesh, center + HexMetrics.corners[i] - HexMetrics.heightVector, center + HexMetrics.corners[i + 1], center + HexMetrics.corners[i] ); AddTriangleToMesh( center + HexMetrics.corners[i] - HexMetrics.heightVector, center + HexMetrics.corners[i + 1] - HexMetrics.heightVector, center + HexMetrics.corners[i + 1] ); AddTriangleToSubmesh( sideMaterialSubmesh, center + HexMetrics.corners[i] - HexMetrics.heightVector, center + HexMetrics.corners[i + 1] - HexMetrics.heightVector, center + HexMetrics.corners[i + 1] ); center -= HexMetrics.heightVector; } } }
/// <summary> /// /// </summary> /// <param name="stack"></param> public void SetStack(CellStack stack) { _stack = stack; }