Skip to content

Instantly share code, notes, and snippets.

@Kailang
Created February 21, 2019 09:22
Show Gist options
  • Save Kailang/dedcf93f673c26eea27994293cbb5ab5 to your computer and use it in GitHub Desktop.
Save Kailang/dedcf93f673c26eea27994293cbb5ab5 to your computer and use it in GitHub Desktop.
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