Created
February 21, 2019 09:22
-
-
Save Kailang/dedcf93f673c26eea27994293cbb5ab5 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 System.Collections.Generic; | |
using UnityEngine; | |
public class LineGraph : MonoBehaviour { | |
class Point { | |
public int id; | |
public Vector3 pos; | |
} | |
readonly List<List<Point>> links = new List<List<Point>>(); | |
readonly List<Point> points = new List<Point>(); | |
public Mesh mesh; | |
public float a, b, c; | |
public float segmentLength; | |
public float ringUpAmount; | |
public float ringDownAmount; | |
public float ringHorizontalAmount; | |
public float swingHorizontalAmount; | |
public float swingSpeedScale; | |
readonly List<Vector3> verts = new List<Vector3>(); | |
readonly List<int> tris = new List<int>(); | |
readonly List<float> swing = new List<float>(); | |
float GetValue(float x) { | |
return a * x * x + b * x + c; | |
} | |
void OnEnable() { | |
mesh = GetComponent<MeshFilter>().mesh; | |
// AddPoint(new Vector3(0, 0, 0)); | |
// | |
// for (int i = 0; i < 200; i += 1) { | |
// AddPoint(new Vector3(10, 0, i * .5f)); | |
// CreateLink(0, i + 1); | |
// } | |
// RebuildMesh(); | |
} | |
public int AddPoint(Vector3 pos) { | |
int id = points.Count; | |
points.Add(new Point{id = id, pos = pos}); | |
links.Add(new List<Point>()); | |
swing.Add(Random.Range(0, 1000)); | |
return id; | |
} | |
public void DelinkPoint(int id) { | |
var ptr = points[id]; | |
foreach (var edges in links) { | |
edges.Remove(ptr); | |
} | |
links[id].Clear(); | |
RebuildMesh(); | |
} | |
public void CreateLink(int fromId, int toId) { | |
links[fromId].Add(points[toId]); | |
RebuildMesh(); | |
} | |
public void DeleteLink(int fromId, int toId) { | |
links[fromId].Remove(points[toId]); | |
RebuildMesh(); | |
} | |
void RebuildMesh() { | |
verts.Clear(); | |
tris.Clear(); | |
var ringUpShift = new Vector3(0, ringUpAmount, 0); | |
for (int i = 0, count = links.Count; i < count; i += 1) { | |
var start = points[i]; | |
foreach (var end in links[i]) { | |
var startPos = start.pos; | |
var endPos = end.pos; | |
var direction = endPos - startPos; | |
var ringRightShift = Vector3.Cross(direction, Vector3.up).normalized * ringHorizontalAmount; | |
var ringLeftShift = -ringRightShift; | |
ringRightShift.y -= ringDownAmount; | |
ringLeftShift.y -= ringDownAmount; | |
float length = Vector3.Distance(startPos, endPos); | |
int segments = (int)(length / segmentLength); | |
for (var j = 0; j <= segments; j += 1) { | |
float t = (float)j / segments; | |
var pos = startPos + direction * t; | |
pos.y += GetValue(t); | |
int vertStart = verts.Count - 3; | |
var up = pos + ringUpShift; | |
var right = pos + ringRightShift; | |
var left = pos + ringLeftShift; | |
verts.Add(up); | |
verts.Add(right); | |
verts.Add(left); | |
if (j > 0) { | |
tris.Add(vertStart + 0); tris.Add(vertStart + 4); tris.Add(vertStart + 3); | |
tris.Add(vertStart + 0); tris.Add(vertStart + 1); tris.Add(vertStart + 4); | |
tris.Add(vertStart + 1); tris.Add(vertStart + 2); tris.Add(vertStart + 5); | |
tris.Add(vertStart + 1); tris.Add(vertStart + 5); tris.Add(vertStart + 4); | |
tris.Add(vertStart + 2); tris.Add(vertStart + 3); tris.Add(vertStart + 5); | |
tris.Add(vertStart + 2); tris.Add(vertStart + 0); tris.Add(vertStart + 3); | |
} | |
} | |
} | |
} | |
mesh.vertices = verts.ToArray(); | |
mesh.triangles = tris.ToArray(); | |
mesh.RecalculateNormals(); | |
} | |
void RebuildVertices() { | |
verts.Clear(); | |
var ringUpShift = new Vector3(0, ringUpAmount, 0); | |
for (int i = 0, count = links.Count; i < count; i += 1) { | |
var start = points[i]; | |
foreach (var end in links[i]) { | |
float swingAmount = Mathf.Sin(swing[i] + swing[end.id]) * swingHorizontalAmount; | |
var startPos = start.pos; | |
var endPos = end.pos; | |
var direction = endPos - startPos; | |
var right = Vector3.Cross(direction, Vector3.up).normalized; | |
var swingRight = right * swingAmount; | |
var ringRightShift = right * ringHorizontalAmount; | |
var ringLeftShift = -ringRightShift; | |
ringRightShift.y -= ringDownAmount; | |
ringLeftShift.y -= ringDownAmount; | |
float length = Vector3.Distance(startPos, endPos); | |
int segments = (int)(length / segmentLength); | |
for (var j = 0; j <= segments; j += 1) { | |
float t = (float)j / segments; | |
var pos = startPos + direction * t; | |
pos.y += GetValue(t); | |
pos += swingRight * (-4 * t * t + 4 * t); | |
var u = pos + ringUpShift; | |
var r = pos + ringRightShift; | |
var l = pos + ringLeftShift; | |
verts.Add(u); | |
verts.Add(r); | |
verts.Add(l); | |
} | |
} | |
} | |
mesh.vertices = verts.ToArray(); | |
mesh.triangles = tris.ToArray(); | |
mesh.RecalculateNormals(); | |
} | |
void Update() { | |
for (int i = 0, count = swing.Count; i < count; i += 1) { | |
swing[i] += Time.deltaTime * swingSpeedScale; | |
} | |
RebuildVertices(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment