Skip to content

Instantly share code, notes, and snippets.

@Bradshaw
Created December 17, 2019 13:38
Show Gist options
  • Save Bradshaw/346baca61d129ce8267d65a890edb04c to your computer and use it in GitHub Desktop.
Save Bradshaw/346baca61d129ce8267d65a890edb04c to your computer and use it in GitHub Desktop.
Kinda broken tube renderer thing
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class TubeRenderer : MonoBehaviour {
public List<Vector3> positions;
public int positionCount {
set {
if (positions==null){
positions = new List<Vector3>();
}
if (value!=positions.Count){
dirty = true;
}
if (value<=0){
positions = new List<Vector3>();
return;
}
while (positions.Count<value){
positions.Add(Vector3.zero);
}
while (positions.Count>value){
positions.RemoveAt(positions.Count - 1);
}
}
get {
return positions.Count;
}
}
public int vertices;
MeshFilter filter;
MeshRenderer meshRenderer;
public float widthMultiplier;
public AnimationCurve WidthCurve;
public bool invert;
public bool lazyMode = true;
bool dirty = true;
void Awake(){
//int rlen = Random.Range(4, 30);
positions = new List<Vector3>();
filter = GetComponent<MeshFilter>();
meshRenderer = GetComponent<MeshRenderer>();
}
void OnDisable(){
meshRenderer.enabled = false;
}
void OnEnable(){
meshRenderer.enabled = true;
}
public void ForceUpdate(){
dirty = true;
}
void LateUpdate(){
if (dirty) {
dirty = false;
Mesh mesh = filter.mesh;
mesh.MarkDynamic();
mesh.Clear();
List<Vector3> verts = new List<Vector3>();
List<int> tris = new List<int>();
float ang = 360f / vertices;
for (int i = 0; i < positions.Count; i++)
{
Vector3 p = transform.InverseTransformPoint(positions[i]);
Vector3 d;
if (i == 0 && i < positions.Count - 1)
{
Vector3 pn = transform.InverseTransformPoint(positions[i]);
d = (pn - p).normalized;
}
else if (i > 0 && i == positions.Count - 1)
{
Vector3 pp = transform.InverseTransformPoint(positions[i - 1]);
d = (p - pp).normalized;
}
else if (i > 0 && i < positions.Count - 1)
{
Vector3 pn = transform.InverseTransformPoint(positions[i]);
Vector3 pp = transform.InverseTransformPoint(positions[i - 1]);
d = (pn - pp).normalized;
}
else
{
break;
}
Vector3 w = Vector3.Cross(d, Vector3.up);
for (int j = 0; j < vertices; j++)
{
float t = ((float)i / (float)positions.Count) * WidthCurve.keys[WidthCurve.length - 1].time;
verts.Add(p + Quaternion.AngleAxis(ang * j, d) * w * widthMultiplier * WidthCurve.Evaluate(t));
}
}
for (int seg = 0; seg < positions.Count - 1; seg++)
{
int s1 = seg * vertices;
int s2 = (seg + 1) * vertices;
for (int ver = 0; ver < vertices; ver++)
{
int p0 = s1 + ver;
int p1 = s2 + ver;
int p2 = s2 + ((ver + 1) % vertices);
int p3 = s1 + ((ver + 1) % vertices);
tris.Add(p0);
tris.Add(invert ? p1 : p2);
tris.Add(invert ? p2 : p1);
tris.Add(p0);
tris.Add(invert ? p2 : p3);
tris.Add(invert ? p3 : p2);
}
}
mesh.SetVertices(verts);
mesh.SetTriangles(tris, 0, true);
mesh.RecalculateBounds();
mesh.RecalculateNormals();
mesh.RecalculateTangents();
filter.mesh = mesh;
}
if (!lazyMode){
dirty = true;
}
}
public void SetPosition(int index, Vector3 v3){
Vector3 ov3 = positions[index];
if (ov3 == v3){
return;
}
positions[index] = v3;
dirty = true;
}
public void InsertPosition(Vector3 v3){
positions.Insert(0, v3);
positions.RemoveAt(positions.Count - 1);
dirty = true;
}
public void SetPositions(Vector3[] v3s){
if (v3s.Length == positions.Count){
bool itsTheSameThingLol = true;
for (int i = 0; i < v3s.Length; i++){
if (v3s[i]!=positions[i]){
itsTheSameThingLol = true;
break;
}
}
if (itsTheSameThingLol){
return;
}
}
positions = new List<Vector3>(v3s);
dirty = true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment