public void RenderOcean() { List <EPMPoint> oceanPoints = m_terrain.ExtractPoints_ByTypes(null, EPMPoint.GenerateTypesInt(false, EPMPoint.PointType.Ocean)); float height = (float)g_customData.seaLevel; for (int i = 0; i < oceanPoints.Count; i++) { oceanPoints[i].posY = height; } }
public static void SampleHeightByPoint(EPMBaseTerrain terrain, int pointNum, Vector2d radiusRange, EPMHeightSampler.CurveMode curve, EPMHeightSampler.CombineMode combine, double limitation) { List <EPMPoint> pointList = terrain.ExtractPoints_ByTypes(null, EPMPoint.GenerateTypesInt(true, EPMPoint.PointType.Ocean)); EPMPoint.HighestHeight = EPMPoint.LowestHeight = 0; for (int i = 0; i < pointNum; i++) { double radius = (double)terrain.RandomDouble(radiusRange.x, radiusRange.y); double height = (double)terrain.RandomDouble(-1f, 1f); Vector2d point = new Vector2d(terrain.RandomDouble(0, terrain.getXLength()), terrain.RandomDouble(0f, terrain.getZlength())); EPMHeightSampler.DistanceToPoint(height, point, radius, pointList, curve, combine, limitation); } }
public void TwistTerrain() { System.Random random = new System.Random(g_customData.twistSeed); List <EPMPoint> pointList = m_terrain.ExtractPoints_ByTypes(null, EPMPoint.GenerateTypesInt(true, EPMPoint.PointType.Ocean)); //If the Ocean Point is connected with OceanSide, it should be put into pointList!! List <EPMTriangle> tlist = m_terrain.ExtractTriangles_ByTypes(null, EPMPoint.GenerateTypesInt(false, EPMPoint.PointType.OceanSide)); Dictionary <int, EPMPoint> connectedOceanPoints = new Dictionary <int, EPMPoint>(); for (int i = 0; i < tlist.Count; i++) { List <EPMPoint> pl = tlist[i].g_pointList; for (int j = 0; j < pl.Count; j++) { if (pl[j].HasType(EPMPoint.PointType.Ocean)) { if (connectedOceanPoints.ContainsKey(pl[j].g_indexInList) == false) { connectedOceanPoints.Add(pl[j].g_indexInList, pl[j]); pointList.Add(pl[j]); } } } } for (int i = 0; i < g_customData.twistNum; i++) { double degree = random.NextDouble() * 2 * System.Math.PI; if (m_terrain.RandomInt(0, 2) % 2 == 0) { EPMPlaneTwister.SineExpander(pointList, new Vector2d(System.Math.Sin(degree), System.Math.Cos(degree)), 100, (float)g_customData.twistStrength); } else { EPMPlaneTwister.SineShifter(pointList, new Vector2d(System.Math.Sin(degree), System.Math.Cos(degree)), 100, (float)g_customData.twistStrength); } } }
public void SmoothRiver() { List <EPMPoint> plist = m_terrain.ExtractPoints_ByTypes(null, EPMPoint.GenerateTypesInt(false, EPMPoint.PointType.River)); for (int i = 0; i < plist.Count; i++) { plist[i].posY = -3; } for (int i = 0; i < g_customData.riverLists.Count; i++) { List <Vector2d> river = g_customData.riverLists[i]; for (int j = 1; j < river.Count; j++) { EPMHeightSampler.DirectionalDistance(0.5f, river[j] - river[j - 1], 100, plist, -1f); } } for (int i = 0; i < plist.Count; i++) { plist[i].ApplyHeight(); } }
public void RenderRiver() { List <EPMPoint> riverPoints = m_terrain.ExtractPoints_ByTypes(null, EPMPoint.GenerateTypesInt(false, EPMPoint.PointType.RiverSide, EPMPoint.PointType.River)); for (int k = 0; k < g_customData.riverLists.Count; k++) { List <Vector2d> river = g_customData.riverLists[k]; for (int i = 1; i < river.Count; i++) { EPMHeightSampler.DistanceToLine(5, river[i - 1], river[i], m_riverHalfWidth, riverPoints, EPMHeightSampler.CurveMode.CosineQuarter, EPMHeightSampler.CombineMode.SubtractWithLimitation, -3); if (i != river.Count - 1) { EPMHeightSampler.DistanceToPoint(5, river[i], m_riverHalfWidth, riverPoints, EPMHeightSampler.CurveMode.CosineQuarter, EPMHeightSampler.CombineMode.SubtractWithLimitation, -3); } } } for (int i = 0; i < riverPoints.Count; i++) { riverPoints[i].ApplyHeight(); } }
public void RenderHill() { List <EPMPoint> hillPoints = m_terrain.ExtractPoints_ByTypes(null, EPMPoint.GenerateTypesInt(false, EPMPoint.PointType.Hill)); for (int k = 0; k < g_customData.hillLists.Count; k++) { List <Vector2d> hill = g_customData.hillLists[k]; for (int i = 1; i < hill.Count; i++) { EPMHeightSampler.DistanceToLine(m_defaultHillHeight, hill[i - 1], hill[i], m_hillHalfWidth * 1.2f, hillPoints, EPMHeightSampler.CurveMode.CosineHalf); } } for (int i = 0; i < hillPoints.Count; i++) { hillPoints[i].ApplyHeight(); } for (int k = 0; k < g_customData.hillLists.Count; k++) { List <Vector2d> hill = g_customData.hillLists[k]; for (int i = 1; i < hill.Count; i++) { EPMHeightSampler.DirectionalDistance(m_terrain.RandomDouble(2f, 5f), hill[i] - hill[i - 1], 50f, hillPoints, m_defaultHillHeight * 1.5f, 2); } } List <EPMTriangle> hillTriangles = m_terrain.ExtractTriangles_ByVertex(hillPoints); for (int i = 0; i < hillTriangles.Count; i++) { if (hillTriangles[i].HasShapeType(EPMPoint.GetGroundEnums())) { hillTriangles[i].SetType(EPMPoint.PointType.Hill); } } }
public static void CheckAndSetTileTypeByNeighbor(EPMDelaunayTerrain terrain, EPMPoint.PointType checkType, EPMPoint.PointType neighborType, EPMPoint.PointType newTypeForPassCheck, EPMPoint.PointType newTypeForNotPassCheck, int minNeighborCount = 2, bool shareEdge = true, bool alsoSetPointsType = false) { CheckAndSetTileTypeByNeighbor(terrain, EPMPoint.GenerateTypesInt(false, checkType), EPMPoint.GenerateTypesInt(false, neighborType), newTypeForPassCheck, newTypeForNotPassCheck, true, minNeighborCount, shareEdge, alsoSetPointsType); }
public static void ExtractCenter(EPMDelaunayTerrain terrain, List <List <Vector2d> > pointList, EPMPoint.PointType oldType, EPMPoint.PointType newType, double halfWidth) { List <EPMTriangle> intersectList = new List <EPMTriangle>(); List <EPMTriangle> oldTypeList = terrain.ExtractTriangles_ByTypes(null, EPMPoint.GenerateTypesInt(false, oldType)); for (int i = 0; i < pointList.Count; i++) { List <Vector2d> lineSet = pointList[i]; for (int j = 0; j < lineSet.Count; j++) { intersectList.AddRange(terrain.ExtractTriangles_PointsInCircle(lineSet[j], halfWidth, 1, oldTypeList)); if (j >= 1) { Vector2d dir = lineSet[j] - lineSet[j - 1]; dir.Normalize(); Vector2d normal = new Vector2d(-dir.y, dir.x); intersectList.AddRange(terrain.ExtractTriangles_PointsInLineWithDistance(lineSet[j - 1] - dir * halfWidth, lineSet[j] + dir * halfWidth, halfWidth, 1, oldTypeList)); intersectList.AddRange(terrain.ExtractTriangles_IntersectLine(lineSet[j - 1] + normal * halfWidth - dir * halfWidth, lineSet[j] + normal * halfWidth + dir * halfWidth, oldTypeList)); intersectList.AddRange(terrain.ExtractTriangles_IntersectLine(lineSet[j - 1] - normal * halfWidth - dir * halfWidth, lineSet[j] - normal * halfWidth + dir * halfWidth, oldTypeList)); } } } for (int i = 0; i < intersectList.Count; i++) { EPMTriangle t = (EPMTriangle)intersectList[i]; t.g_pointList[0].g_type = newType; t.g_pointList[1].g_type = newType; t.g_pointList[2].g_type = newType; t.SetType(newType); } intersectList.Clear(); CheckAndSetTileTypeByNeighbor(terrain, oldType, newType, newType); }
public static void ExtractSide(EPMDelaunayTerrain terrain, EPMPoint.PointType oldType, EPMPoint.PointType sideType, double inLength = 2f) { List <EPMTriangle> list = terrain.ExtractTriangles_ByTypes(null, EPMPoint.GenerateTypesInt(false, oldType)); List <EPMPoint> allPoints = terrain.ExtractPoints_All(); List <EPMTriangle> sideList = new List <EPMTriangle>(); int groundEnum = EPMPoint.GetGroundEnums(); for (int i = 0; i < list.Count; i++) { EPMTriangle t = (EPMTriangle)list[i]; int count = 0; int ep1, ep2; ep1 = ep2 = 0; for (int j = 0; j < t.g_shareEdgeNeighbors.Count; j++) { //The edge has an ground tile neighbor. if (t.g_shareEdgeNeighbors[j].HasShapeType(groundEnum)) { count++; t.GetShareEdge((EPMTriangle)t.g_shareEdgeNeighbors[j], out ep1, out ep2); } } if (count == 1) { if (!t.g_visited) { sideList.Add(t); t.g_visited = true; } int ep3 = t.g_sortedIndexList[0]; if (ep3 == ep1 || ep3 == ep2) { ep3 = t.g_sortedIndexList[1]; } if (ep3 == ep1 || ep3 == ep2) { ep3 = t.g_sortedIndexList[2]; } Vector2d p1, p2, p3; p1 = allPoints[ep1].pos2d; p2 = allPoints[ep2].pos2d; p3 = allPoints[ep3].pos2d; Vector2d dir = p2 - p1; Vector2d normal = new Vector2d(-dir.y, dir.x); normal.Normalize(); if ((p3 - p1) * normal < 0) { normal = -normal; } for (int k = 0; k < t.g_shareEdgeNeighbors.Count; k++) { if (t.g_shareEdgeNeighbors[k].HasShapeType(oldType)) { EPMTriangle nei = (EPMTriangle)t.g_shareEdgeNeighbors[k]; if (nei.g_visited == false) { nei.g_visited = true; sideList.Add(nei); } for (int j = 0; j < nei.g_sharePointNeighbors.Count; j++) { EPMTriangle t2 = (EPMTriangle)nei.g_sharePointNeighbors[j]; if (t2.HasShapeType(oldType) && t2.g_visited == false) { Vector2d v2 = t2.g_pointList[0].pos2d; double dot = (v2 - p1) * normal; if (dot >= inLength) { continue; } v2 = t2.g_pointList[1].pos2d; dot = (v2 - p1) * normal; if (dot >= inLength) { continue; } v2 = t2.g_pointList[2].pos2d; dot = (v2 - p1) * normal; if (dot >= inLength) { continue; } t2.g_visited = true; sideList.Add((EPMTriangle)nei.g_sharePointNeighbors[j]); } } } } } } for (int i = 0; i < sideList.Count; i++) { sideList[i].SetType(sideType); } for (int i = 0; i < list.Count; i++) { EPMTriangle t = (EPMTriangle)list[i]; if (t.HasShapeType(sideType)) { continue; } bool finded = true; for (int j = 0; j < t.g_shareEdgeNeighbors.Count; j++) { if (t.g_shareEdgeNeighbors[j].HasShapeType(oldType)) { finded = false; break; } } if (finded) { t.SetType(sideType); } } for (int i = 0; i < list.Count; i++) { list[i].g_visited = false; } }
public void CreateMesh() { int rowSplit = g_customData.rowSplit; int columnSplit = g_customData.columnSplit; //First, delete the former created Mesh. for (int i = m_meshRoot.transform.childCount - 1; i >= 0; i--) { GameObject.DestroyImmediate(m_meshRoot.transform.GetChild(i).gameObject); } m_meshRoot.transform.DetachChildren(); //Split Mesh to smaller meshes. List <List <EPMTriangle> > submeshTriangleList = new List <List <EPMTriangle> >(); for (int i = 0; i < rowSplit * columnSplit; i++) { submeshTriangleList.Add(new List <EPMTriangle>()); } //Don't Draw Ocean, use an sea plane to replace it. List <EPMTriangle> triangleList = m_terrain.ExtractTriangles_ByTypes(null, EPMPoint.GenerateTypesInt(true, EPMPoint.PointType.Ocean)); for (int i = 0; i < triangleList.Count; i++) { EPMTriangle t = triangleList[i]; EPMPoint p1 = t.g_pointList[0]; //Check which submesh the point p1 falls in, than put the triangle into this submesh list. Vector2d v2 = p1.pos2d; int column = (int)((v2.x - m_terrain.g_startPoint.x) / m_terrain.getXLength() * columnSplit); if (column >= columnSplit) { column = columnSplit - 1; } int row = (int)((v2.y - m_terrain.g_startPoint.y) / m_terrain.getZlength() * rowSplit); if (row >= rowSplit) { row = rowSplit - 1; } submeshTriangleList[column + row * columnSplit].Add(t); } for (int i = 0; i < submeshTriangleList.Count; i++) { if (submeshTriangleList[i].Count == 0) { continue; } string name = (i / columnSplit).ToString() + "_" + (i % columnSplit).ToString(); CreateSubMesh(submeshTriangleList[i], name); } CreateSeaPlane((float)g_customData.seaLevel); }
public void RenderSingleGround(List <Vector2d> ground, EPMPoint.PointType type) { int groundEnums = EPMPoint.GetGroundEnums(); List <EPMPoint> plist = m_terrain.ExtractPoints_ByRegion(ground, null, groundEnums); for (int i = 0; i < plist.Count; i++) { plist[i].SetType(type); } List <EPMTriangle> triangleList = m_terrain.ExtractTriangles_ByVertex(plist); for (int i = 0; i < triangleList.Count; i++) { if (!triangleList[i].HasShapeType(groundEnums)) { continue; } triangleList[i].TryDetermineType(); } EPMPreDefinedTools.CheckAndSetTileTypeByNeighbor(m_terrain, EPMPoint.GetGroundEnums(), EPMPoint.GenerateTypesInt(false, type), type); }
public void RenderMountain() { List <EPMPoint> mountainPoints = m_terrain.ExtractPoints_ByTypes(null, EPMPoint.GenerateTypesInt(false, EPMPoint.PointType.Mountain)); List <EPMTriangle> mountainTriangles = m_terrain.ExtractTriangles_ByVertex(mountainPoints); for (int i = 0; i < mountainTriangles.Count; i++) { mountainTriangles[i].SetType(EPMPoint.PointType.Mountain); } for (int k = 0; k < g_customData.mountainLists.Count; k++) { List <Vector2d> mountain = g_customData.mountainLists[k]; for (int i = 0; i < mountain.Count; i++) { EPMHeightSampler.DistanceToPoint(m_terrain.RandomDouble(m_defaultMountainHeight / 2, m_defaultMountainHeight * 1.5f), mountain[i], m_mountainRadius * 1.5f, mountainPoints, EPMHeightSampler.CurveMode.ReverseLinear); } } for (int i = 0; i < mountainPoints.Count; i++) { mountainPoints[i].ApplyHeight(); } //find summit, the summit is the point that all its neighbors height is lower than it. List <EPMPoint> summitPoints = new List <EPMPoint>(); for (int i = 0; i < mountainPoints.Count; i++) { EPMPoint p = mountainPoints[i]; if (p.g_neighbors.Count <= 2) { continue; } bool summit = true; for (int j = 0; j < p.g_neighbors.Count; j++) { if (p.posY <= p.g_neighbors[j].posY) { summit = false; break; } } if (summit) { summitPoints.Add(p); } } for (int i = 0; i < summitPoints.Count; i++) { List <EPMTriangle> l = m_terrain.ExtractTriangles_PointsInCircle(summitPoints[i].pos2d, m_mountainRadius * m_terrain.RandomDouble(0.2f, 0.4f), 1, mountainTriangles); for (int j = 0; j < l.Count; j++) { l[j].SetType(EPMPoint.PointType.MountainSummit); } } }
public void SetIslandGround() { for (int i = 0; i < g_customData.islandLists.Count; i++) { List <Vector2d> island = g_customData.islandLists[i]; List <EPMPoint> points = m_terrain.ExtractPoints_ByRegion(island, null, EPMPoint.GenerateTypesInt(false, EPMPoint.PointType.Ocean)); for (int j = 0; j < points.Count; j++) { points[j].SetType(EPMPoint.PointType.Ground); } } }