Start with a single horizontal line segment. Repeat for a sufficiently large number of times { Repeat over each line segment in the scene { Find the midpoint of the line segment. Displace the midpoint in Y by a random amount. Reduce the range for random numbers. } }
void Generate1DMountain(Vector3 start, Vector3 end, int iterateTime, float roughless) { if (iterateTime > 0) { float rand = Random.Range(0f, 2.999f) * roughless; Vector3 mid = new Vector3(0.5f * start.x + 0.5f * end.x, 0.5f * start.y + 0.5f * end.y + rand, 0); --iterateTime; Generate1DMountain(start, mid, iterateTime, roughless * iterateTime * iterateTime * 0.01f); points.Add(mid); Generate1DMountain(mid, end, iterateTime, roughless * iterateTime * iterateTime * 0.01f); } }
float GetMidHeight(int i, int stride, Vector3[] points) { return 0.5f * (points[i - stride].y + points[i + stride].y); } Vector3[] Generater1DMoutainIterative(Vector3 start, Vector3 end, int iterateTime, float heightScale, float h) { int length = CalculateArrayLenght(iterateTime); Vector3[] points = new Vector3[length]; points[0] = start; points[length - 1] = end; float gap = Mathf.Abs(end.x - start.x) / length; //Debug.Log("gap: " + gap); for(int i=0; i< length; i++) { points[i] = new Vector3(start.x + i*gap, 0f, 0f); } float ratio, scale; ratio = (float)Mathf.Pow(2.0f, -h); scale = heightScale * ratio; int stride = length / 2; while(stride != 0) { for (int i = stride; i < length; i += stride) { points[i].y = scale * Random.Range(-4f, 4f) + GetMidHeight(i, stride, points); i += stride; } scale *= ratio; Debug.Log("Stride: " + stride); stride >>= 1; } // DumpAllPoint(points); return points; }
void OnDrawGizmos() { Gizmos.color = Color.red; for (int i = 0; i < newPoints.Length - 1; i++) { Gizmos.DrawLine(newPoints[i], newPoints[i + 1]); } }
结果
public class EdgeMidHashTable { List<Edge> edges; List<Node> midNodes; public EdgeMidHashTable() { edges = new List<Edge>(); midNodes = new List<Node>(); } public void Clear() { edges.Clear(); midNodes.Clear(); } public void Add(Edge edge, Node node) { edges.Add(edge); midNodes.Add(node); } public bool IsContainsEdge(Edge edge) { return edges.Contains(edge); } public Node GetEdgeMidNode(Edge edge) { int index = GetEdgeIndex(edge); return midNodes[index]; } int GetEdgeIndex(Edge edge) { for(int i = 0; i< edges.Count; i++) { if(edges[i].Equals(edge)) { return i; } } return -1; } } public class Edge { int startNodeIndex; int endNodeIndex; public EdgeLabel label; public Node StartNode; public Node EndNode; public Edge() { } public Edge(Node Start, Node End) { label = EdgeLabel.Neutral; startNodeIndex = Start.vertexIndex; StartNode = Start; endNodeIndex = End.vertexIndex; EndNode = End; } public override bool Equals(object other) { if(other == null) { return false; } Edge otherEdge = (Edge)other; if ((StartNode.vertexIndex == otherEdge.StartNode.vertexIndex && EndNode.vertexIndex == otherEdge.EndNode.vertexIndex) || (StartNode.vertexIndex == otherEdge.EndNode.vertexIndex && EndNode.vertexIndex == otherEdge.StartNode.vertexIndex)) { return true; } return false; } public Edge(Node Start, Node End, EdgeLabel _label) { label = _label; startNodeIndex = Start.vertexIndex; StartNode = Start; endNodeIndex = End.vertexIndex; EndNode = End; } public Vector3 GetEdgeCenter() { return (StartNode.position + EndNode.position) * 0.5f; } public override int GetHashCode() { return this.label.GetHashCode(); } } public class Node { public Vector3 position; public int vertexIndex = -1; public Node(Vector3 _pos) { position = _pos; } public override bool Equals(object other) { if (other == null) { return false; } Node otherNode = (Node)other; if (this.vertexIndex == otherNode.vertexIndex) { return true; } return false; } } public class Triange { public Node[] vertices = new Node[3]; public Triange(Vector3 Vertex0, Vector3 Vertex1, Vector3 Vertex2) { vertices[0] = new Node(Vertex0); vertices[1] = new Node(Vertex1); vertices[2] = new Node(Vertex2); } public Triange(Node node0, Node node1, Node node2) { vertices[0] = node0; vertices[1] = node1; vertices[2] = node2; } }
void SplitTriangle(Triange triangle, int recursiveTime) { Vector3 VertexPos0 = triangle.vertices[0].position; Vector3 VertexPos1 = triangle.vertices[1].position; Vector3 VertexPos2 = triangle.vertices[2].position; float RandomScale = Vector3.Distance(VertexPos0, VertexPos1); float rand0 = 0f; float rand1 = 0f; float rand2 = 0f; Node midNode0 = new Node(Vector3.zero); Node midNode1 = new Node(Vector3.zero); Node midNode2 = new Node(Vector3.zero); midNode0 = CalculateMidNode(RandomScale, triangle.vertices[0], triangle.vertices[1]); midNode1 = CalculateMidNode(RandomScale, triangle.vertices[1], triangle.vertices[2]); midNode2 = CalculateMidNode(RandomScale, triangle.vertices[0], triangle.vertices[2]); Triange triangle0 = new Triange(triangle.vertices[0], midNode0, midNode2); Triange triangle1 = new Triange(midNode0, triangle.vertices[1], midNode1); Triange triangle2 = new Triange(midNode2, midNode1, triangle.vertices[2]); Triange triangle3 = new Triange(midNode0, midNode1, midNode2); if(recursiveTime >0) { recursiveTime--; SplitTriangle2(triangle0, recursiveTime); SplitTriangle2(triangle1, recursiveTime); SplitTriangle2(triangle2, recursiveTime); SplitTriangle2(triangle3, recursiveTime); } else if(recursiveTime == 0) { FinalTriangleList.Add(triangle0); FinalTriangleList.Add(triangle1); FinalTriangleList.Add(triangle2); FinalTriangleList.Add(triangle3); } }
public void GenerateMesh() { meshVertices = new List<Vector3>(); meshTriangles = new List<int>(); for (int i = 0; i < nodes.Count; i++) { meshVertices.Add(nodes[i].position); } for (int i = 0; i < FinalTriangleList.Count; i++) { meshTriangles.Add(FinalTriangleList[i].vertices[0].vertexIndex); meshTriangles.Add(FinalTriangleList[i].vertices[1].vertexIndex); meshTriangles.Add(FinalTriangleList[i].vertices[2].vertexIndex); } Mesh mesh = new Mesh(); GetComponent<MeshFilter>().mesh = mesh; mesh.vertices = meshVertices.ToArray(); mesh.triangles = meshTriangles.ToArray(); mesh.RecalculateNormals(); }
public class SquigTriangle { public Edge[] edges = new Edge[3]; public SquigTriangle() { } public SquigTriangle(Edge edge0, Edge edge1, Edge edge2) { edges[0] = edge0; edges[1] = edge1; edges[2] = edge2; } public SquigTriangle(Node node0, Node node1, Node node2) { edges[0] = new Edge(node0, node1); edges[1] = new Edge(node1, node2); edges[2] = new Edge(node2, node0); } /// <summary> /// Construct by nodes and labels.label0 ->Edge(node0, node1); label1 -> Edge(node1, node2); label2 -> Edge(node2, node0) /// </summary> public SquigTriangle(Node node0, Node node1, Node node2, EdgeLabel label0, EdgeLabel label1, EdgeLabel label2) { edges[0] = new Edge(node0, node1, label0); edges[1] = new Edge(node1, node2, label1); edges[2] = new Edge(node2, node0, label2); } public int GetEnteryEdgeIndex() { for(int i = 0; i< 3; i++) { if(edges[i].label == EdgeLabel.Entry) { return i; } } return -1; } public int GetExitEdgeIndex() { for(int i = 0; i< 3; i++) { if (edges[i].label == EdgeLabel.Exit) { return i; } } return -1; } public bool IsNeutralTriangle() { return edges[0].label == EdgeLabel.Neutral && edges[1].label == EdgeLabel.Neutral; } /// <summary> /// Sort Triangle's vertices. /// </summary> public void Resort() { if (edges[0].label == EdgeLabel.Neutral && edges[1].label == EdgeLabel.Neutral) { return; } Node[] nodes = new Node[4]; for(int i = 0; i< 3; i++) { if(edges[i].label == EdgeLabel.Entry) { nodes[0] = edges[i].StartNode; nodes[1] = edges[i].EndNode; } if (edges[i].label == EdgeLabel.Exit) { nodes[2] = edges[i].StartNode; nodes[3] = edges[i].EndNode; } } if (nodes[0].vertexIndex == nodes[2].vertexIndex ) { //0->1->3 edges[0]= new Edge(nodes[0], nodes[1] , EdgeLabel.Entry); edges[1] = new Edge(nodes[1], nodes[3], EdgeLabel.Neutral); edges[2] = new Edge(nodes[3], nodes[0], EdgeLabel.Exit); } else if(nodes[0].vertexIndex == nodes[3].vertexIndex) { //0->1->2 edges[0] = new Edge(nodes[0], nodes[1], EdgeLabel.Entry); edges[1] = new Edge(nodes[1], nodes[2], EdgeLabel.Neutral); edges[2] = new Edge(nodes[2], nodes[0], EdgeLabel.Exit); } else if(nodes[1].vertexIndex == nodes[2].vertexIndex) { //1->0->3 edges[0] = new Edge(nodes[1], nodes[0], EdgeLabel.Entry); edges[1] = new Edge(nodes[0], nodes[3], EdgeLabel.Neutral); edges[2] = new Edge(nodes[3], nodes[1], EdgeLabel.Exit); } if(nodes[1].vertexIndex == nodes[3].vertexIndex) { //1->0->2 edges[0] = new Edge(nodes[1], nodes[0], EdgeLabel.Entry); edges[1] = new Edge(nodes[0], nodes[2], EdgeLabel.Neutral); edges[2] = new Edge(nodes[2], nodes[1], EdgeLabel.Exit); } } }
// / \ // /__0_\ // / \3 / \ // /_1_\/_2_\ SquigTriangle[] SubdivideSquigTriange(SquigTriangle triangle) { //When Come up with Neutral triangle(with three Neutral edge) if (triangle.edges[0].label == EdgeLabel.Neutral && triangle.edges[1].label == EdgeLabel.Neutral) { FinalTriangleList.Add(triangle); return new SquigTriangle[] { }; } Node OriginalNode0 = triangle.edges[0].StartNode; Node OriginalNode1 = triangle.edges[0].EndNode; Node OriginalNode2 = triangle.edges[1].EndNode; //Splite three edges to 6 small edge. //OriginEdge0 -> edge0 + edge3 //OriginEdge1 -> edge4 + edge7 //OriginEdge2 -> edge2 + edge8 Edge[] splitedEdges = new Edge[9]; SpliteEdge(triangle.edges[0], out splitedEdges[0], out splitedEdges[3]); SpliteEdge(triangle.edges[1], out splitedEdges[4], out splitedEdges[7]); SpliteEdge(triangle.edges[2], out splitedEdges[8],out splitedEdges[2]); SquigTriangle successor0 = new SquigTriangle(); SquigTriangle successor1 = new SquigTriangle(); SquigTriangle successor2 = new SquigTriangle(); SquigTriangle successor3 = new SquigTriangle(); //Construct remain edges. Four situation. Take Symmetry into consideration //Situation 1 if (splitedEdges[0].label == EdgeLabel.Entry && splitedEdges[2].label == EdgeLabel.Exit ) { successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeLabel.Entry, EdgeLabel.Neutral, EdgeLabel.Exit); successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral); successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2, EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral); successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral); } else if(splitedEdges[2].label == EdgeLabel.Entry && splitedEdges[0].label == EdgeLabel.Exit) { successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeLabel.Exit, EdgeLabel.Neutral, EdgeLabel.Entry); successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral); successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2, EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral); successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral); } //Situation 2 else if (splitedEdges[0].label == EdgeLabel.Entry && splitedEdges[8].label == EdgeLabel.Exit) { successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeLabel.Entry, EdgeLabel.Exit, EdgeLabel.Neutral); successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral); successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2, EdgeLabel.Entry, EdgeLabel.Neutral, EdgeLabel.Exit); successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeLabel.Exit, EdgeLabel.Entry, EdgeLabel.Neutral); } else if(splitedEdges[0].label == EdgeLabel.Exit && splitedEdges[8].label == EdgeLabel.Entry) { successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeLabel.Neutral, EdgeLabel.Exit, EdgeLabel.Entry); successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeLabel.Exit, EdgeLabel.Neutral, EdgeLabel.Entry); successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2, EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral); successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeLabel.Neutral, EdgeLabel.Entry, EdgeLabel.Exit); } //Situation 3 else if (splitedEdges[3].label == EdgeLabel.Entry && splitedEdges[2].label == EdgeLabel.Exit) { successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeLabel.Neutral, EdgeLabel.Entry, EdgeLabel.Exit); successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeLabel.Entry, EdgeLabel.Neutral, EdgeLabel.Exit); successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2, EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral); successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeLabel.Neutral, EdgeLabel.Exit, EdgeLabel.Entry); }else if(splitedEdges[3].label == EdgeLabel.Exit && splitedEdges[2].label == EdgeLabel.Entry) { successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeLabel.Exit, EdgeLabel.Entry, EdgeLabel.Neutral); successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral); successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2, EdgeLabel.Exit, EdgeLabel.Neutral, EdgeLabel.Entry); successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeLabel.Entry, EdgeLabel.Exit, EdgeLabel.Neutral); } //Situation 4 else if (splitedEdges[3].label == EdgeLabel.Entry && splitedEdges[8].label == EdgeLabel.Exit) { successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral); successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeLabel.Entry, EdgeLabel.Neutral, EdgeLabel.Exit); successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2, EdgeLabel.Entry, EdgeLabel.Neutral, EdgeLabel.Exit); successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeLabel.Exit, EdgeLabel.Neutral, EdgeLabel.Entry); } else if (splitedEdges[3].label == EdgeLabel.Exit && splitedEdges[8].label == EdgeLabel.Entry) { successor0 = new SquigTriangle(OriginalNode0, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeLabel.Neutral, EdgeLabel.Neutral, EdgeLabel.Neutral); successor1 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), OriginalNode1, EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeLabel.Exit, EdgeLabel.Neutral, EdgeLabel.Entry); successor2 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), OriginalNode2, EdgeLabel.Exit, EdgeLabel.Neutral, EdgeLabel.Entry); successor3 = new SquigTriangle(EdgeMidHashTable.GetEdgeMidNode(triangle.edges[1]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[2]), EdgeMidHashTable.GetEdgeMidNode(triangle.edges[0]), EdgeLabel.Entry, EdgeLabel.Neutral, EdgeLabel.Exit); } Node midNode0 = new Node(triangle.edges[0].GetEdgeCenter()); Node midNode1 = new Node(triangle.edges[1].GetEdgeCenter()); Node midNode2 = new Node(triangle.edges[2].GetEdgeCenter()); Edge edge0 = new Edge(OriginalNode0, midNode0); Edge edge1 = new Edge(midNode0, midNode2); Edge edge2 = new Edge(midNode2, OriginalNode0); Edge edge3 = new Edge(midNode0, OriginalNode1); Edge edge4 = new Edge(OriginalNode1, midNode1); Edge edge5 = new Edge(midNode1, midNode0); Edge edge6 = new Edge(midNode2, midNode1); Edge edge7 = new Edge(midNode1, OriginalNode2); Edge edge8 = new Edge(OriginalNode2, midNode2); successor0.Resort(); successor1.Resort(); successor2.Resort(); successor3.Resort(); if (!successor3.IsNeutralTriangle()) { CrossedEdge.Add(successor3.edges[successor3.GetEnteryEdgeIndex()]); CrossedEdge.Add(successor3.edges[successor3.GetExitEdgeIndex()]); } return new SquigTriangle[] { successor0, successor1, successor2, successor3 }; }
void SpliteEdge(Edge originalEdge, float roughness, out Edge subEdge0, out Edge subEdge1) { //float RandomScale = Vector3.Distance(originalEdge.StartNode.position, originalEdge.EndNode.position); float randomResult = roughness * Random.Range(-0.5f, 0.5f); float randomLowerBound = roughness * -0.5f; float altn = 0.0f; for (int i = 0; i < LowerRandomLimits.Count; i++) { altn += LowerRandomLimits[i]; } Node midNode = new Node(Vector3.zero); subEdge0 = new Edge(); subEdge1 = new Edge(); if (EdgeMidHashTable.IsContainsEdge(originalEdge)) { midNode = EdgeMidHashTable.GetEdgeMidNode(originalEdge); }else { switch (originalEdge.label) { //Entry-> Entry + Neutral case EdgeLabel.Entry: case EdgeLabel.Exit: midNode = new Node(0.5f * new Vector3(originalEdge.StartNode.position.x + originalEdge.EndNode.position.x, originalEdge.StartNode.position.y + originalEdge.EndNode.position.y, altn + randomLowerBound)); EdgeMidHashTable.Add(originalEdge, midNode); PushNode(midNode); break; case EdgeLabel.Neutral: midNode = new Node(0.5f * new Vector3(originalEdge.StartNode.position.x + originalEdge.EndNode.position.x, originalEdge.StartNode.position.y + originalEdge.EndNode.position.y, originalEdge.StartNode.position.z + originalEdge.EndNode.position.z /*+ altn*/ + randomResult)); EdgeMidHashTable.Add(originalEdge, midNode); PushNode(midNode); break; } } switch (originalEdge.label) { //Entry-> Entry + Neutral case EdgeLabel.Entry: //RiverCrossed from last triangle if (CrossedEdge.Contains(new Edge(originalEdge.StartNode, midNode))) { subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Entry); subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Neutral); } else if (CrossedEdge.Contains(new Edge(midNode, originalEdge.EndNode))) { subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Neutral); subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Entry); } //Source of River else { int rand = Random.Range(0, 10); if(rand >5) { subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Entry); subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Neutral); CrossedEdge.Add(subEdge0); }else { subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Neutral); subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Entry); CrossedEdge.Add(subEdge1); } } break; //Neutral-> Neutral + Neutral case EdgeLabel.Neutral: subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Neutral); subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Neutral); break; //Exit-> Exit + Neutral case EdgeLabel.Exit: if (CrossedEdge.Contains(new Edge(originalEdge.StartNode, midNode))) { subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Exit); subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Neutral); } else if (CrossedEdge.Contains(new Edge(midNode, originalEdge.EndNode))) { subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Neutral); subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Exit); } //End of River else { int rand = Random.Range(0, 10); if (rand > 5) { subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Exit); subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Neutral); CrossedEdge.Add(subEdge0); } else { subEdge0 = new Edge(originalEdge.StartNode, midNode, EdgeLabel.Neutral); subEdge1 = new Edge(midNode, originalEdge.EndNode, EdgeLabel.Exit); CrossedEdge.Add(subEdge1); } } break; } }
Marching cube
A Fractal Model of Mountains with Rivers
Generating RandomFractal Terrain
Simple2d Terrain With Midpoint Displacement