void Start() { Point2DCollection <Boolean> candidates = new Point2DCollection <Boolean>(); int readjusted_x = Mathf.RoundToInt(Constants.EXTENT.x / Constants.BALL_DIAMETER), readjusted_y = Mathf.RoundToInt(Constants.EXTENT.y / Constants.BALL_DIAMETER); for (int i = 0; i < readjusted_x; i++) { for (int j = 0; j < readjusted_y; j++) { candidates.put(new Vector2(i, j), true); } } points_per_level.Add(candidates); SemiSigmoid weighter = new SemiSigmoid(); int level = 0; Vector2 up = new Vector2(0, 1), across = new Vector2(1, 1), right = new Vector2(1, 0); float y_sep = Mathf.Pow(2.0f, -0.5f); while (candidates.count > 0) { float thresh = weighter.eval(UnityEngine.Random.value); // stability conditions candidates = candidates.filter_to_new_by_point((Vector2 v) => (System.Convert.ToInt32(candidates.has(v + up)) + System.Convert.ToInt32(candidates.has(v + across)) + System.Convert.ToInt32(candidates.has(v + right)) >= 2) && UnityEngine.Random.value < thresh && v.x < readjusted_x && v.y < readjusted_y); Debug.Log(candidates); Debug.Log(candidates.count); points_per_level.Add(candidates); } for (int i = 0; i < points_per_level.Count; i++) { points_per_level[i].pointed_iterate((Vector2 vec, Boolean v) => Instantiate(this.ball, (new Vector3(vec.x + 0.5f * i, vec.y + 0.5f * i, Constants.BALL_Z_OFFSET - i * y_sep)) * Constants.BALL_DIAMETER, Quaternion.identity)); } }
void Start() { Mesh M = new Mesh(); SemiSigmoid weighter = new SemiSigmoid(); int terrain_points = (int)(weighter.eval(Random.value) * Constants.MAX_POINTS); List <Vector3> vertices = new List <Vector3>(); Point2DCollection <int> vec2_vertices = new Point2DCollection <int>(); List <uint> colors = new List <uint>(); // vertices.Add(new Vector3(0.6626031f, 0.05119444f, 0.0f) * 10.0f); // vertices.Add(new Vector3(0.6618521f, 0.2226332f, 0.0f) * 10.0f); // vertices.Add(new Vector3(0.3871413f, 0.5442802f, 0.0f) * 10.0f); // vertices.Add(new Vector3(0.6093425f, 0.3753652f, 0.0f) * 10.0f); // vertices.Add(new Vector3(0.7540823f, 0.5187992f, 0.0f) * 10.0f); // for(int i=0; i<vertices.Count; i++) { // vec2_vertices.put(vertices[i], i); // colors.Add(0); // } for (int i = 0; i < terrain_points; i++) { float x = Random.value, y = Random.value; Vector3 vec = new Vector3(x * Constants.EXTENT.x, y * Constants.EXTENT.y, Mathf.PerlinNoise(x * Constants.PERLIN_SCALE, y * Constants.PERLIN_SCALE) * Constants.MAX_ELEVATION - Constants.MAX_ELEVATION / 2); Debug.Log(System.String.Format("{0}, {1}", vec.x, vec.y)); vertices.Add(vec); vec2_vertices.put(vec, i); colors.Add(0); } M.vertices = vertices.ToArray(); Debug.Log(vec2_vertices.M.Count); List <LineSegment> triangle_line_segments = new Delaunay.Voronoi(vec2_vertices.rezip(), colors, new Rect(0, 0, Constants.EXTENT.x, Constants.EXTENT.y)).DelaunayTriangulation(); Point2DCollection <Point2DCollection <bool> > adjs = new Point2DCollection <Point2DCollection <bool> >(); // second parameters of Point2DCollection not really all that useful anymore, because we're storing the index to the original array now anyways for (int i = 0; i < triangle_line_segments.Count; i++) { // Debug.Log(System.String.Format("{0}, {1}", triangle_line_segments[i].p0, triangle_line_segments[i].p1)); Vector2 src, dst; src = (Vector2)triangle_line_segments[i].p0; dst = (Vector2)triangle_line_segments[i].p1; if (adjs.get(src) == null) { Point2DCollection <bool> new_adj = new Point2DCollection <bool>(); new_adj.put(dst, true); adjs.put(src, new_adj); } else { adjs.get(src).put(dst, true); } if (adjs.get(dst) == null) { Point2DCollection <bool> new_adj = new Point2DCollection <bool>(); new_adj.put(src, true); adjs.put(dst, new_adj); } else { adjs.get(dst).put(src, true); } Debug.Log(System.String.Format("({0}, {1}) <-> ({2}, {3})", dst.x, dst.y, src.x, src.y)); Point2DCollection <bool> maybe_intersect = adjs.get(src).intersect_to_new(adjs.get(dst)); if (maybe_intersect.count > 0) { Debug.Log(System.String.Format("({0}, {1}), ({2}, {3}), ({4}, {5})", src.x, src.y, dst.x, dst.y, maybe_intersect.rezip()[0].x, maybe_intersect.rezip()[0].y)); int A = vec2_vertices.get(src), B = vec2_vertices.get(dst), C = vec2_vertices.get(maybe_intersect.rezip()[0]); if (this._is_clockwise(vertices[A], vertices[B], vertices[C])) { int[] triangle = { A, B, C }; this.triangles.AddRange(triangle); } else { int[] triangle = { A, C, B }; this.triangles.AddRange(triangle); } } } M.triangles = this.triangles.ToArray(); M.RecalculateNormals(); // M.Optimize(); GetComponent <MeshFilter>().mesh = M; MeshCollider collider = GetComponent <MeshCollider>(); collider.convex = false; collider.enabled = true; collider.sharedMesh = M; StringBuilder str_vertices = new StringBuilder(); for (int i = 0; i < this.triangles.Count; i++) { str_vertices.Append(System.String.Format(this.triangles[i].ToString())); } Debug.Log(str_vertices.ToString()); }