Skip to content

Instantly share code, notes, and snippets.

@Densyakun
Last active May 10, 2017 16:34
Show Gist options
  • Save Densyakun/564fadac7fdff34f7dd03873ee3c63d8 to your computer and use it in GitHub Desktop.
Save Densyakun/564fadac7fdff34f7dd03873ee3c63d8 to your computer and use it in GitHub Desktop.
[Unity] フラクタル地形の生成
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