Last active
May 10, 2017 16:34
-
-
Save Densyakun/564fadac7fdff34f7dd03873ee3c63d8 to your computer and use it in GitHub Desktop.
[Unity] フラクタル地形の生成
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using UnityEngine; | |
public class FractalTerrain | |
{ | |
//メッシュをコピー | |
public static Mesh mesh_copy (Mesh mesh) { | |
Mesh m = new Mesh (); | |
m.vertices = mesh.vertices; | |
m.uv = mesh.uv; | |
m.triangles = mesh.triangles; | |
recalc (m); | |
return m; | |
} | |
//法線等を再計算 | |
public static void recalc (Mesh mesh) { | |
mesh.RecalculateBounds (); | |
mesh.RecalculateNormals (); | |
} | |
//メッシュの細分化 | |
public static Mesh Subdivide_Half (Mesh mesh) | |
{ | |
Mesh m = mesh_copy (mesh); | |
List<Vector3> newverts = new List<Vector3> (m.vertices); | |
List<Vector2> newuv = new List<Vector2> (m.uv); | |
List<int> newtris = new List<int> (); | |
for (int c = 0; c <= m.triangles.Length - 3; c += 3) { | |
int vn0 = m.triangles [c]; | |
int vn1 = m.triangles [c + 1]; | |
int vn2 = m.triangles [c + 2]; | |
Vector2 vu0 = m.uv [vn0]; | |
Vector2 vu1 = m.uv [vn1]; | |
Vector2 vu2 = m.uv [vn2]; | |
newverts.Add ((m.vertices [vn0] + m.vertices [vn1]) / 2); | |
newverts.Add ((m.vertices [vn1] + m.vertices [vn2]) / 2); | |
newverts.Add ((m.vertices [vn2] + m.vertices [vn0]) / 2); | |
newuv.Add ((vu0 + vu1) / 2); | |
newuv.Add ((vu1 + vu2) / 2); | |
newuv.Add ((vu2 + vu0) / 2); | |
int _vn = newverts.Count - 3; | |
newtris.Add (vn0); | |
newtris.Add (_vn); | |
newtris.Add (_vn + 2); | |
newtris.Add (vn1); | |
newtris.Add (_vn + 1); | |
newtris.Add (_vn); | |
newtris.Add (vn2); | |
newtris.Add (_vn + 2); | |
newtris.Add (_vn + 1); | |
newtris.Add (_vn); | |
newtris.Add (_vn + 1); | |
newtris.Add (_vn + 2); | |
} | |
m.vertices = newverts.ToArray (); | |
m.uv = newuv.ToArray (); | |
m.triangles = newtris.ToArray (); | |
recalc (m); | |
return m; | |
} | |
//四角形の地形 | |
public static Mesh getQuadTerrain () { | |
Mesh mesh = new Mesh (); | |
mesh.vertices = new Vector3[]{ Vector3.zero, Vector3.forward, Vector3.right + Vector3.forward, Vector3.right }; | |
mesh.uv = new Vector2[]{ Vector2.zero, Vector2.up, Vector2.right + Vector2.up, Vector2.right }; | |
mesh.triangles = new int[]{ 0, 1, 2, 2, 3, 0 }; | |
recalc (mesh); | |
return mesh; | |
} | |
//三角形の地形 | |
public static Mesh getTriangleTerrain () { | |
Mesh mesh = new Mesh (); | |
mesh.vertices = new Vector3[]{ Vector3.zero, Vector3.forward, Vector3.right }; | |
mesh.uv = new Vector2[]{ Vector2.zero, Vector2.up, Vector2.right }; | |
mesh.triangles = new int[]{ 0, 1, 2 }; | |
recalc (mesh); | |
return mesh; | |
} | |
public static void setVert(Vector3[] verts, Vector3 target, Vector3 result) { | |
for (int a = 0; a < verts.Length; a++) { | |
if (verts [a] == target) { | |
verts [a] = result; | |
} | |
} | |
} | |
//中点変位法を使用したフラクタル地形 | |
public static Mesh getFractalTerrain (int fineness, float height) { | |
Mesh mesh = getQuadTerrain (); | |
//Mesh mesh = getTriangleTerrain (); | |
Vector3[] verts = mesh.vertices; | |
for (int a = 0; a < verts.Length; a++) { | |
verts [a].y = Random.Range (0f, height); | |
} | |
mesh.vertices = verts; | |
for (int a = 0; a < fineness; a++) { | |
int b = mesh.vertices.Length; | |
mesh = FractalTerrain.Subdivide_Half (mesh); | |
verts = mesh.vertices; | |
while (b < verts.Length) { | |
float c = height / 2 / (a + 1); | |
setVert (verts, verts [b], verts [b] + Vector3.up * Random.Range (-c, c)); | |
b++; | |
} | |
mesh.vertices = verts; | |
} | |
return mesh; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment