Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- [RequireComponent (typeof (MeshFilter), typeof (MeshRenderer))]
- public class Line3d : MonoBehaviour
- {
- private struct Point
- {
- public Vector3 position;
- public Vector3 normal;
- public bool newLine;
- public Point (Vector3 pos, Vector3 norm, bool nLine)
- {
- position = pos;
- normal = norm;
- newLine = nLine;
- }
- }
- private struct Pair <T1, T2>
- {
- public T1 first;
- public T2 second;
- public Pair (T1 a, T2 b)
- {
- first = a;
- second = b;
- }
- }
- private MeshFilter meshFilter;
- private Mesh mesh;
- private List<Point> points;
- private int lastBuildPointCount;
- public float normalOffset = 0.01f;
- public float minDistance = 0.5f; // min distance between 2 points
- public float defaultWidth = 0.1f;
- public bool autoRebuild = true;
- private void Start ()
- {
- Reset ();
- }
- private void Update ()
- {
- if (autoRebuild && lastBuildPointCount != points.Count)
- Rebuild ();
- }
- private void Rebuild ()
- {
- List<List<Pair<Vector3, Vector3>>> linePoints = new List<List<Pair<Vector3, Vector3>>> ();
- List<Pair<Vector3, Vector3>> temp = null;
- for (int i = 0; i < points.Count; i++)
- {
- Point p = points[i];
- if (p.newLine)
- temp = new List<Pair<Vector3, Vector3>> ();
- temp.Add (new Pair<Vector3, Vector3> (p.position, p.normal));
- if (i == points.Count - 1 || points[i + 1].newLine)
- linePoints.Add (temp);
- }
- List<Vector3> vertices = new List<Vector3> ();
- List<Vector3> normals = new List<Vector3> ();
- List<Vector2> uv = new List<Vector2> ();
- List<int> tris = new List<int> ();
- Vector3 position, normal, direction, vertex;
- int _i = 0;
- for (int line = 0; line < linePoints.Count; line++)
- {
- temp = linePoints[line];
- for (int i = 0; temp.Count > 1 && i < temp.Count; i++)
- {
- position = temp[i].first;
- normal = temp[i].second;
- if (i == 0)
- direction = (temp[i + 1].first - position).normalized;
- else if (i == temp.Count - 1)
- direction = (position - temp[i - 1].first).normalized;
- else
- {
- Vector3
- dir1 = (position - temp[i - 1].first).normalized,
- dir2 = (temp[i + 1].first - position).normalized;
- direction = (dir1 + dir2) / 2;
- normal = normal.normalized * defaultWidth / 2;
- float width = 1f / Mathf.Cos (Vector3.Angle (dir1, dir2) / 2 * Mathf.Deg2Rad);
- normal *= width * width;
- }
- vertex = Vector3.Cross (normal, direction);
- vertices.Add (position + vertex);
- vertices.Add (position - vertex);
- normals.Add (normal);
- normals.Add (normal);
- uv.Add (new Vector2 (0, i));
- uv.Add (new Vector2 (1, i));
- if (i < points.Count - 1)
- {
- tris.Add (_i + i * 2);
- tris.Add (_i + i * 2 + 1);
- tris.Add (_i + i * 2 + 3);
- tris.Add (_i + i * 2 + 3);
- tris.Add (_i + i * 2 + 2);
- tris.Add (_i + i * 2);
- }
- }
- _i += temp.Count * 2 - 2;
- }
- mesh.vertices = vertices.ToArray ();
- mesh.normals = normals.ToArray ();
- mesh.uv = uv.ToArray ();
- mesh.triangles = tris.ToArray ();
- mesh.RecalculateBounds ();
- }
- public void Reset ()
- {
- meshFilter = GetComponent<MeshFilter> ();
- mesh = new Mesh ();
- meshFilter.mesh = mesh;
- points = new List<Point> ();
- lastBuildPointCount = 0;
- }
- public void AddPoint (Vector3 position, Vector3 normal)
- {
- AddPoint (position, normal, defaultWidth, false);
- }
- public void AddPoint (Vector3 position, Vector3 normal, float width)
- {
- AddPoint (position, normal, width, false);
- }
- public void AddPoint (Vector3 position, Vector3 normal, bool newLine)
- {
- AddPoint (position, normal, defaultWidth, newLine);
- }
- public void AddPoint (Vector3 position, Vector3 normal, float width, bool newLine)
- {
- if (normal.sqrMagnitude != 1)
- normal.Normalize ();
- position += normal * normalOffset;
- normal *= (width / 2);
- if (newLine && points.Count > 0 && points[points.Count - 1].newLine)
- points[points.Count - 1] = new Point (position, normal, true);
- else if (newLine)
- points.Add (new Point (position, normal, true));
- else if (
- points.Count > 1 &&
- !points[points.Count - 1].newLine &&
- (points[points.Count - 2].position - points[points.Count - 1].position).sqrMagnitude < minDistance * minDistance)
- {
- points[points.Count - 1] = new Point (position, normal, false);
- lastBuildPointCount--;
- }
- else
- points.Add (new Point (position, normal, false));
- }
- public void ForceRebuild ()
- {
- lastBuildPointCount = 0;
- Rebuild ();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement