Last active
August 29, 2015 14:17
-
-
Save ircnelson/d0759f6b4ae56e945d8f to your computer and use it in GitHub Desktop.
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 UnityEngine; | |
using System.Collections; | |
public class Level { | |
public Mesh mesh; | |
private bool drawDebugMesh; | |
private Path path; | |
private Face[] faces; | |
private int[] triangles; | |
private Vector3[] vertices; | |
private Vector2[] uvs; | |
public Level (int len, float startRadius, float maxRadius, float partLength, int sides, bool draw) { | |
float startTime = Time.realtimeSinceStartup; | |
drawDebugMesh = draw; | |
mesh = new Mesh (); | |
uvs = new Vector2[len * sides]; | |
path = new Path (len, startRadius, maxRadius, partLength, drawDebugMesh); | |
faces = GenerateFaces (path, sides, drawDebugMesh); | |
vertices = GenerateVertices (len, sides, faces); | |
triangles = GenerateTriangles (len, sides, vertices); | |
mesh.vertices = vertices; | |
mesh.triangles = triangles; | |
mesh.uv = uvs; | |
mesh.RecalculateNormals (); | |
mesh.Optimize (); | |
Debug.Log ((Time.realtimeSinceStartup - startTime) * 1000 + "ms for generating level"); | |
} | |
private Face[] GenerateFaces (Path p, int sides, bool drawDebugMesh) { | |
Face[] f = new Face[p.length]; | |
for (int n = 0; n < f.Length; n++) { | |
f[n] = new Face (p.radius[n], sides, p.centerPoints[n], p.centerPointNormals[n], p.faceRotation[n], drawDebugMesh); | |
if (n != 0 && drawDebugMesh) { | |
for (int i = 1; i < f[n].vertices.Length; i++) { | |
Debug.DrawLine (f[n].vertices[i], f[n - 1].vertices[i], Color.red, 600); | |
} | |
} | |
} | |
return f; | |
} | |
private Vector3[] GenerateVertices (int len, int sides, Face[] face) { | |
Vector3[] v = new Vector3[len * sides]; | |
for (int n = 0; n < face.Length; n++) { | |
for (int i = 0; i < sides; i++) { | |
v[n * (sides) + i] = face[n].vertices[i]; | |
} | |
} | |
return v; | |
} | |
private int[] GenerateTriangles (int len, int sides, Vector3[] verts) { | |
int[] tris = new int[verts.Length * 6]; | |
for (int n = 0; n < len - 1; n++) { | |
for (int i = 0; i < sides; i++) { | |
if (i != sides - 1) { | |
tris[n * (sides) * 6 + i * 6] = (n * sides) + i; | |
tris[n * (sides) * 6 + i * 6 + 1] = (n + 1) * sides + i; | |
tris[n * (sides) * 6 + i * 6 + 2] = (n + 1) * sides + 1 + i; | |
tris[n * (sides) * 6 + i * 6 + 3] = (n * sides) + i; | |
tris[n * (sides) * 6 + i * 6 + 4] = (n + 1) * sides + 1 + i; | |
tris[n * (sides) * 6 + i * 6 + 5] = (n * sides) + i + 1; | |
} else { | |
tris[n * (sides) * 6 + i * 6] = (n + 1) * sides - 1; | |
tris[n * (sides) * 6 + i * 6 + 1] = sides * (n + 1) + i; | |
tris[n * (sides) * 6 + i * 6 + 2] = sides * (n + 1); | |
tris[n * (sides) * 6 + i * 6 + 3] = (n + 1) * sides - 1; | |
tris[n * (sides) * 6 + i * 6 + 4] = sides * (n + 1); | |
tris[n * (sides) * 6 + i * 6 + 5] = n * sides; | |
} | |
} | |
} | |
return tris; | |
} | |
public struct Path { | |
public int length; // Length (in circles) of the tunnel | |
public float[] radius; // The radius of each circle | |
public Vector3[] centerPoints; // The center point of each circle | |
public Vector3[] centerPointNormals; // The normal of each circle | |
public Vector3[] faceRotation; | |
public Path (int len, float startRadius, float maxRadius, float partLength, bool drawDebugMesh) { | |
length = len; | |
radius = new float[length]; | |
centerPoints = new Vector3[length]; | |
centerPointNormals = new Vector3[length]; | |
faceRotation = new Vector3[length]; | |
radius[0] = startRadius; | |
centerPoints[0] = Vector3.zero; | |
faceRotation[0] = Vector3.zero; | |
for (int n = 1; n < length; n++) { | |
radius[n] = startRadius; | |
//radius[n] = radius[n - 1] + Random.Range (-0.5f, 0.5f); | |
faceRotation[n] = new Vector3 (faceRotation[n - 1].x + Random.Range (-0.2f, 0.2f), faceRotation[n - 1].y + Random.Range (-0.2f, 0.2f), 0); | |
centerPoints[n].x = partLength * Mathf.Sin (faceRotation[n].y) * Mathf.Cos (faceRotation[n].x) + centerPoints[n - 1].x; | |
centerPoints[n].y = partLength * Mathf.Cos (faceRotation[n].y) * Mathf.Sin (faceRotation[n].x) + centerPoints[n - 1].y; | |
centerPoints[n].z = partLength * Mathf.Cos (faceRotation[n].x) * Mathf.Cos (faceRotation[n].y) + centerPoints[n - 1].z; | |
if (drawDebugMesh) { | |
Debug.DrawLine (centerPoints[n - 1], centerPoints[n], Color.yellow, 600); | |
} | |
} | |
for (int n = 0; n < length - 1; n++) { | |
centerPointNormals[n] = centerPoints[n] - centerPoints[n + 1]; | |
} | |
} | |
} | |
public struct Face { | |
public Vector3[] vertices; | |
public Face (float r, int sides, Vector3 centerPoint, Vector3 centerPointNormal, Vector3 rotation, bool drawDebugMesh) { | |
vertices = new Vector3[sides]; | |
float angle = 2 * Mathf.PI / sides; | |
Vector3 normalized = centerPointNormal; | |
Vector3 ortho1 = Vector3.up; | |
Vector3 ortho2 = Vector3.right; | |
Vector3.OrthoNormalize(ref normalized, ref ortho1, ref ortho2); | |
for (int n = 0; n < sides; n++) { | |
//vertices[n].x = centerPoint.x + r * Mathf.Sin(n * angle); | |
//vertices[n].y = centerPoint.y + r * Mathf.Cos(n * angle); | |
//vertices[n].z = centerPoint.z; | |
vertices[n] = centerPoint + r * Mathf.Sin(n * angle) * ortho1 + r * Mathf.Cos(n * angle) * ortho2; | |
//vertices[n] = vertices[n] - Vector3.Dot (vertices[n] - centerPoint, normalized) * normalized; | |
if (n != 0 && drawDebugMesh) { | |
Debug.DrawLine (vertices[n], vertices[n - 1], Color.red, 600); | |
} | |
if (n == sides - 1 && drawDebugMesh) { | |
Debug.DrawLine (vertices[n], vertices[0], Color.red, 600); | |
} | |
} | |
} | |
} | |
} |
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 UnityEngine; | |
using System.Collections; | |
public class LevelController : MonoBehaviour { | |
public bool drawDebugMesh; | |
public Level currentLevel; | |
public int length; | |
public float startRadius; | |
public float maxRadius; | |
public float partLength; | |
public int sides; | |
[HideInInspector] public GameObject gameObj; | |
[HideInInspector] new public Transform transform; | |
void Start () { | |
gameObj = gameObject; | |
transform = gameObj.GetComponent<Transform> (); | |
if (length * sides >= 65000) { | |
length = (int)Mathf.Floor (65000 / sides); | |
} | |
currentLevel = new Level (length, startRadius, maxRadius, partLength, sides, drawDebugMesh); | |
transform.GetComponent<MeshFilter> ().mesh = currentLevel.mesh; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment