//Copies the vertices from one mesh onto another //This helps reduce loading time by preventing thousands of floating point operations from having to be recalculated in identical meshes public IEnumerator CopyMesh(int w, int h, MeshController mC, GameSettings s, MapMesh other) { width = w; height = h; if (width != other.GetWidth()) { //The algorithm breaks if the widths are different so thinner chunks are built normally yield return(Build(w, h, mC, s)); } else { //Initializes necessary variables settings = s; meshController = mC; int numVerts = CalculateVertices(w, h); int numTris = TriArrayCalculator(w, h); InitializeMeshData(numVerts, numTris); //Copies the variables from the reference mesh yield return(CopyVariables(other)); CreateMesh(); yield return(CreateTexture()); yield return(null); } }
public void Build(Map map, float cellSz, float wallH) { CellSize = cellSz; MapBuilder mb = new MapBuilder(map, cellSz, wallH); MapMesh mapMesh = mb.Build(); Mesh floor = CreateMesh(mapMesh.Floor); Mesh ceil = CreateMesh(mapMesh.Ceil); Mesh walls = CreateMesh(mapMesh.Walls); transform.Find("Floor").GetComponent <MeshFilter>().sharedMesh = floor; transform.Find("Ceiling").GetComponent <MeshFilter>().sharedMesh = ceil; transform.Find("Walls").GetComponent <MeshFilter>().sharedMesh = walls; //Mesh mesh = new Mesh(); //mesh.vertices = new Vector3[3] //{ // new Vector3(0,0,0), // new Vector3(0,0,1), // new Vector3(1,0,0) //}; //mesh.triangles = new int[3] //{ // 0,1,2 //}; //mesh.RecalculateNormals(); //GetComponent<MeshFilter>().sharedMesh = mesh; }
void BuildWorld() { CalculateContinentTerritory(); int tile = MapMetrics.Tile; MapMesh.regionIndex = regionIndex; MapMesh.regions = regions; for (int i = 0; i < h; i += tile) { for (int j = 0; j < w; j += tile) { MapMesh mapMesh = Instantiate(mapMeshPrefab); MapMeshes.Add(mapMesh); mapMesh.TriangulateMap(j, i); mapMesh.transform.localPosition = Vector3.zero; } } SetProvNames(); SetTowns(); foreach (var state in states) { state.Text = Instantiate(Text); state.Text.layer = 8; state.SetName(); state.SetNameStatus(true); Region cap = state.Capital; cap.Corona = Instantiate(CoronaPrefab, cap.Town.transform); cap.Corona.transform.localPosition = Vector3.up * 0.8f; } for (int i = 0; i < regions.Count; i++) { regions[i].UpdateBorder(); } regionMap = MapMetrics.map = new Texture2D(w, h, TextureFormat.RGBA32, false); MapMetrics.provincemap = new Texture2D(w, h, TextureFormat.RGBA32, false, false); occupationMap = MapMetrics.occupemap = new Texture2D(w, h, TextureFormat.RGBA32, false); regionMap.filterMode = FilterMode.Point; occupationMap.filterMode = FilterMode.Point; MapMetrics.UpdateColorMap(); MapMetrics.UpdateOccupedMap(); MapMetrics.UpdateProvincesMap(); System.IO.File.WriteAllBytes("DasIst.png", regionMap.EncodeToPNG()); terrainMat.SetTexture("_OccupeMap", MapMetrics.occupemap); terrainMat.SetColor("_Select", Color.white); Shader.SetGlobalTexture("_StateColor", MapMetrics.map); Shader.SetGlobalTexture("_ProvincesColor", MapMetrics.provincemap); Shader.SetGlobalVector("_NoiseConst", new Vector4(MapMetrics.noiseScale, MapMetrics.cellPerturbStrength, 0, 0)); Shader.SetGlobalTexture("_SplatMap", MapMetrics.GetSplatMap()); Shader.SetGlobalVector("_Size", new Vector4(1f / w, 1f / h, w, h)); Shader.SetGlobalTexture("_HeightMap", MapMetrics.GetHeightMap); Shader.SetGlobalTexture("_Noise", MapMetrics.noise); Shader.SetGlobalFloat("_MaxHeight", MapMetrics.MaxHeight); Shader.SetGlobalFloat("_SeaLevel", MapMetrics.SeaLevel); }
public MapBuilder(Map map, float cellSz, float wallHeight) { this.map = map; this.cellSz2 = cellSz * 0.5f; this.wallHeight = wallHeight; this.mapMesh = new MapMesh(); }
public void Start() { Res.LoadMats(); this.map = new Map(new Vector2Int(40, 40)); MapMesh mapMesh = new MapMesh(this.map); foreach (KeyValuePair <TerrainType, MeshData> kv in mapMesh.meshes) { MeshData meshData = kv.Value; // It's just easier to read, you don't need to do this. TerrainType terrainType = kv.Key; // It's just easier to read, you don't need to do this. GameObject go = new GameObject("Mesh for " + terrainType.ToString()); go.transform.SetParent(this.transform); // In our TerrainType enum Water=0, Dirt=1, Grass=2, Rocks=3 // We always want to draw Rocks over Grass, Grass over Dirt, Dirt over Water // So we can just use the negative integer value as the Z position for the GameObject. go.transform.localPosition = new Vector3(0, 0, -(int)terrainType); // Add a mesh filter and set the mesh to our mesh. MeshFilter mf = go.AddComponent <MeshFilter>(); mf.mesh = meshData.mesh; MeshRenderer mr = go.AddComponent <MeshRenderer>(); mr.material = Res.mats[terrainType.ToString()]; } this.ready = true; }
public override void OnInspectorGUI() { base.OnInspectorGUI(); MapMesh obj = (MapMesh)target; if (GUILayout.Button("ReGenerate")) { obj.ReGenerate(); } }
public IEnumerator BuildMap(GameSettings s) { //Initializing Variables settings = s; int maxHeight = ChunkParams.maxHeight; int maxWidth = ChunkParams.maxWidth; int wChunks = (int)Mathf.Ceil(settings.width / (float)maxWidth); int hChunks = (int)Mathf.Ceil(settings.height / (float)maxHeight); chunks = new GameObject[hChunks][]; MapMesh baseMesh = null; //Loops through and creates each mesh chunk one at a time for (int bH = 0; bH < hChunks; bH++) { int locHeight = GetChunkSize(bH, settings.height, maxHeight); float zPos = bH * maxHeight * HexParams.heightDistance; chunks[bH] = new GameObject[wChunks]; for (int bW = 0; bW < wChunks; bW++) { float xPos = bW * maxWidth * HexParams.shortDiameter; Vector3 pos = new Vector3(xPos, 0.0f, zPos); int locWidth = GetChunkSize(bW, settings.width, maxWidth); chunks[bH][bW] = (GameObject)Instantiate(chunkPrefab, pos, Quaternion.identity); if (bW == 0 && bH == 0) { baseMesh = chunks[bH][bW].GetComponent <MapMesh>(); yield return(baseMesh.Build(locWidth, locHeight, this, settings)); } else { yield return(chunks[bH][bW].GetComponent <MapMesh>().CopyMesh(locWidth, locHeight, this, settings, baseMesh)); } } } //Makes the chunks visible for (int bH = 0; bH < hChunks; bH++) { for (int bW = 0; bW < wChunks; bW++) { chunks[bH][bW].GetComponent <MeshCollider>().enabled = true; chunks[bH][bW].GetComponent <MeshRenderer>().enabled = true; } yield return(null); } yield return(null); }
// Start is called before the first frame update void Start() { Speed = speed; mesh = GetComponent <MapMesh>(); mapValues = mesh.mapValues; NewRule(); sideRuleSet.Set(mapValues, enviroment, transform); StartCoroutine(sideRuleSet.MakeAll()); MakeSideObjects(); if (gameOver != null) { gameOver.continueGame += Continue; } }
public void drawMap() { float heightSeed = Random.Range(0, 100); MeshGenerator meshGenerator = new MeshGenerator(this.getHexSize(), map, polygonDensity, riverDensity, heightSeed, elevatedHeightmap, mountainHeightmap, rivers); MapMesh mapMesh = meshGenerator.generateMapMesh(); this.GetComponent <MeshFilter>().mesh = mesh = mapMesh.landMesh; this.GetComponent <MeshCollider>().sharedMesh = this.GetComponent <MeshFilter>().mesh; this.lakes.GetComponent <MeshFilter>().mesh = mapMesh.innerWaterMesh; this.ocean.GetComponent <MeshFilter>().mesh = mapMesh.oceanMesh; generateTrees(heightSeed); }
public void CreateMapCells() { gridCanvas = GetComponentInChildren <Canvas>(); mapMesh = GetComponentInChildren <MapMesh>(); cells = new MapCell[height * width]; for (int z = 0, i = 0; z < height; ++z) { for (int x = 0; x < width; ++x) { CreateCell(x, z, i++); } } mapMesh.Triangulate(cells); }
public MapMesh generateMapMesh() { List <List <Vector2> > riverPoints = this.generateRiverPoints(); TriangleNet.Mesh mapTriangulation = this.triangulateMap(map, riverPoints); MapMesh terrain = this.generateTerrain(map, riverPoints, mapTriangulation); List <Color32> terrainColors = getTerrainColours(terrain.landMesh.vertices); Debug.Log(terrainColors.Count); Debug.Log(terrain.landMesh.vertices.Length); Debug.Log(terrain.innerWaterMesh.vertices.Length); Debug.Log(terrain.oceanMesh.vertices.Length); terrain.landMesh.colors32 = terrainColors.ToArray(); return(terrain); }
void CreateTerrain() { TerrainMaskArray = new Texture2DArray(w, h, 4, TerrainMask[0].format, TerrainMask[0].mipmapCount > 0); TerrainNormalMaskArray = new Texture2DArray(w, h, 4, TerrainNormalMask[0].format, TerrainNormalMask[0].mipmapCount > 0); for (int i = 0; i < 4; i++) { for (int j = 0; j < TerrainMask[i].mipmapCount; j++) { Graphics.CopyTexture(TerrainMask[i], 0, j, TerrainMaskArray, i, j); Graphics.CopyTexture(TerrainNormalMask[i], 0, j, TerrainNormalMaskArray, i, j); } } TerrainMaskArray.Apply(); TerrainNormalMaskArray.Apply(); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int t = terrainIndexes[i * w + j] & 31; if (t == (int)TerrainType.ForestLeaf || t == (int)TerrainType.ForestSpire) { GameObject tree = Instantiate(terrainItem[t - (int)TerrainType.ForestLeaf], Trees); tree.transform.position = MapMetrics.GetCellPosition(i, j); } } } foreach (var list in River) { GameObject r = MapMesh.AddRiver(list); r.transform.SetParent(WorldBorders.transform); r.GetComponent <MeshRenderer>().sharedMaterial = riverMat; } terrainMat.SetTexture("_TerrainNormTex", TerrainNormalMaskArray); terrainMat.SetTexture("_TerrainTex", TerrainMaskArray); }
//Copies variables from a reference mesh to avoid performing thousands of redundant floating point operation IEnumerator CopyVariables(MapMesh other) { int[][][][] otherVertMap = other.GetVertMap(); Vector3[] otherVerts = other.GetVerts(); Vector2[] otheruvs = other.GetUVs(); Vector3[] otherNormals = other.GetNormals(); int[] otherTris = other.GetTris(); //Assigns each variable in N time for (int i = 0; i < verts.Length; i++) { verts[i] = otherVerts[i]; uvs[i] = otheruvs[i]; normals[i] = otherNormals[i]; } for (int i = 0; i < tris.Length; i++) { tris[i] = otherTris[i]; } for (int sH = 0; sH < height; sH++) { for (int sW = 0; sW < width; sW++) { for (int w = 0; w < VertParams.longHeight; w++) { for (int h = 0; h < vertMap[sH][sW][w].Length; h++) { vertMap[sH][sW][w][h] = otherVertMap[sH][sW][w][h]; } } } } yield return(null); }
public void CreateMapView(DungeonMap dungeonMap) { Vector3 parentPosition; parentPosition.x = 0; parentPosition.y = 0; parentPosition.z = 0; GameObject mapParent = new GameObject("Map Mesh"); mapParent.transform.position = parentPosition; mapParent.transform.parent = this.transform; GameObject segmentParent = new GameObject("Segment Mesh"); segmentParent.transform.position = parentPosition; segmentParent.transform.parent = this.transform; GameObject segmentTemplateParent = new GameObject("Segment Template Mesh"); segmentParent.transform.position = parentPosition; segmentParent.transform.parent = this.transform; for (int y = 0; y < dungeonMap.SegmentHeight; y++) { for (int x = 0; x < dungeonMap.SegmentWidth; x++) { Vector3 childPosition; childPosition.x = x * MapConstants.MapSegmentWidth; childPosition.y = y * -MapConstants.MapSegmentHeight; childPosition.z = 0; MapMesh mesh = Instantiate <MapMesh>(mapMeshPrefab); mesh.name = "Map X_" + x + " Y_" + y + " ID_" + dungeonMap.segments[x, y].ID; mesh.transform.parent = mapParent.transform; mesh.transform.position = parentPosition; mesh.CreateMapMesh(childPosition, dungeonMap.CreateSegmentMap(x, y)); childPosition.z = -0.1f; MapMesh mesh2 = Instantiate <MapMesh>(mapMeshPrefab); mesh2.name = "Segment X_" + x + " Y_" + y + " ID_" + dungeonMap.segments[x, y].ID; mesh2.transform.parent = segmentParent.transform; mesh2.transform.position = parentPosition; mesh2.CreateSegmentComponentMesh(childPosition, dungeonMap.segments[x, y]); if (dungeonMap.segments[x, y].template.ThemeID != 0) { Vector3 templatePosition = new Vector3(childPosition.x + MapSegment.SegmentCellWidthHeight / 2f, childPosition.y - MapSegment.SegmentCellWidthHeight / 2f, -0.2f); SpriteRenderer sprite1 = Instantiate <SpriteRenderer>(segmentTemplatePrefab); sprite1.name = "Segment Template X_" + x + " Y_" + y + " ID_" + dungeonMap.segments[x, y].ID; sprite1.transform.parent = segmentTemplateParent.transform; sprite1.transform.position = templatePosition; sprite1.sprite = Resources.Load <Sprite>("Art/Theme1/" + dungeonMap.segments[x, y].template.Image); sprite1.transform.rotation = Quaternion.Euler(Vector3.forward * SegmentTemplate.GetTemplateSpriteRotation(dungeonMap.segments[x, y].template, dungeonMap.segments[x, y].ID)); } CreateMapSegmentTextOverlay(childPosition, dungeonMap.segments[x, y].ID); } } }
public MapMesh generateTerrain(Map map, List <List <Vector2> > riverPoints, TriangleNet.Mesh mapTriangulation) { MapMesh terrain = new MapMesh(); List <Vector3> landVertices = new List <Vector3>(); List <Vector3> oceanVertices = new List <Vector3>(); List <Vector3> innerWaterVertices = new List <Vector3>(); Dictionary <Vector2, float> mapVerticesHeights = new Dictionary <Vector2, float>(); foreach (Triangle triangle in mapTriangulation.Triangles) { List <MapVertex> mapVertices = triangle.vertices .Select(vertex => vertex is MapVertex ? (MapVertex)vertex : convertToMapVertex(vertex)) .Reverse() .ToList(); List <Vector3> underWaterShifts = new List <Vector3>(new Vector3[3]); List <bool> needsShoreAdjustments = new List <bool>(new bool[3]); if (mapVertices.Any(mapVertice => mapVertice.hex == null)) { for (int i = 0; i < mapVertices.Count; i++) { if (mapVertices[i].hex != null) { needsShoreAdjustments[i] = true; } } } MapVertex shoreMapVertex = mapVertices.FirstOrDefault(mapVertex => mapVertex.hex != null && (mapVertex.hex.biome == null || mapVertex.hex.biome.name != "Fresh lake")); if (shoreMapVertex != null) { Vector2 shoreCenter = HexMathHelper.hexToWorldCoords(new Vector2(shoreMapVertex.hex.x, shoreMapVertex.hex.y), this.hexSize); //if shore triangle push it underwater to create shore slope for (int i = 0; i < mapVertices.Count; i++) { if (mapVertices[i].hex == null) { underWaterShifts[i] = (new Vector2((float)mapVertices[i].x, (float)mapVertices[i].y) - shoreCenter).normalized * 0.3f; underWaterShifts[i] += new Vector3(0, 0, 0.03f); } } } List <Vector3> triangleVertices = new List <Vector3>(); for (int i = 0; i < mapVertices.Count; i++) { float height = TerrainHelper.getHeight(heightSeed, mapVertices[i], this.hexSize, elevatedHeightmap, mountainHeightmap); Vector3 newVertex = mapVertices[i].toVector3() + underWaterShifts[i] + new Vector3(0, 0, height); if (!mapVerticesHeights.ContainsKey(newVertex) && needsShoreAdjustments[i]) { newVertex.z = Random.Range(0.08f, 0.13f); mapVerticesHeights[newVertex] = newVertex.z; } if (mapVertices[i].isRiver && (mapVertices[i].hex == null || !mapVertices[i].hex.hasTag(RiverHelper.FRESH_LAKE_TAG))) { newVertex += TerrainHelper.getRiverHeightAdjustment(newVertex); } triangleVertices.Add(newVertex); } if (mapVertices.All(mapVertex => mapVertex.hex == null)) { oceanVertices.AddRange(triangleVertices); } else if (mapVertices.All(mapVertex => mapVertex.isRiver)) { innerWaterVertices.AddRange(triangleVertices); } else if (mapVertices.All(mapVertex => mapVertex.hex != null && mapVertex.hex.hasTag(RiverHelper.FRESH_LAKE_TAG))) { innerWaterVertices.AddRange(triangleVertices); } else { landVertices.AddRange(triangleVertices); } } //smooth shore for (int i = 0; i < landVertices.Count; i++) { Vector3 vertex = landVertices[i]; if (mapVerticesHeights.ContainsKey(vertex)) { vertex.z = mapVerticesHeights[landVertices[i]]; landVertices[i] = vertex; } } terrain.landMesh = this.createMesh("Land", landVertices); terrain.oceanMesh = this.createMesh("Ocean", oceanVertices); terrain.innerWaterMesh = this.createMesh("Lakes and Rivers", innerWaterVertices); return(terrain); }