Advertisement
artemisart

Line3d WIP

Apr 24th, 2013
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.61 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5.  
  6. [RequireComponent (typeof (MeshFilter), typeof (MeshRenderer))]
  7. public class Line3d : MonoBehaviour
  8. {
  9.     private struct Point
  10.     {
  11.         public Vector3 position;
  12.         public Vector3 normal;
  13.         public bool newLine;
  14.        
  15.         public Point (Vector3 pos, Vector3 norm, bool nLine)
  16.         {
  17.             position = pos;
  18.             normal = norm;
  19.             newLine = nLine;
  20.         }
  21.     }
  22.    
  23.     private struct Pair <T1, T2>
  24.     {
  25.         public T1 first;
  26.         public T2 second;
  27.        
  28.         public Pair (T1 a, T2 b)
  29.         {
  30.             first = a;
  31.             second = b;
  32.         }
  33.     }
  34.    
  35.     private MeshFilter meshFilter;
  36.     private Mesh mesh;
  37.     private List<Point> points;
  38.     private int lastBuildPointCount;
  39.    
  40.     public float normalOffset = 0.01f;
  41.     public float minDistance = 0.5f; // min distance between 2 points
  42.     public float defaultWidth = 0.1f;
  43.     public bool autoRebuild = true;
  44.    
  45.     private void Start ()
  46.     {
  47.         Reset ();
  48.     }
  49.    
  50.     private void Update ()
  51.     {
  52.         if (autoRebuild && lastBuildPointCount != points.Count)
  53.             Rebuild ();
  54.     }
  55.    
  56.     private void Rebuild ()
  57.     {
  58.        
  59.         List<List<Pair<Vector3, Vector3>>> linePoints = new List<List<Pair<Vector3, Vector3>>> ();
  60.         List<Pair<Vector3, Vector3>> temp = null;
  61.        
  62.         for (int i = 0; i < points.Count; i++)
  63.         {
  64.             Point p = points[i];
  65.             if (p.newLine)
  66.                 temp = new List<Pair<Vector3, Vector3>> ();
  67.             temp.Add (new Pair<Vector3, Vector3> (p.position, p.normal));
  68.             if (i == points.Count - 1 || points[i + 1].newLine)
  69.                 linePoints.Add (temp);
  70.         }
  71.        
  72.         List<Vector3> vertices = new List<Vector3> ();
  73.         List<Vector3> normals = new List<Vector3> ();
  74.         List<Vector2> uv = new List<Vector2> ();
  75.         List<int> tris = new List<int> ();
  76.         Vector3 position, normal, direction, vertex;
  77.        
  78.         int _i = 0;
  79.         for (int line = 0; line < linePoints.Count; line++)
  80.         {
  81.             temp = linePoints[line];
  82.             for (int i = 0; temp.Count > 1 && i < temp.Count; i++)
  83.             {
  84.                 position = temp[i].first;
  85.                 normal = temp[i].second;
  86.                 if (i == 0)
  87.                     direction = (temp[i + 1].first - position).normalized;
  88.                 else if (i == temp.Count - 1)
  89.                     direction = (position - temp[i - 1].first).normalized;
  90.                 else
  91.                 {
  92.                     Vector3
  93.                         dir1 = (position - temp[i - 1].first).normalized,
  94.                         dir2 = (temp[i + 1].first - position).normalized;
  95.                     direction = (dir1 + dir2) / 2;
  96.                     normal = normal.normalized * defaultWidth / 2;
  97.                     float width = 1f / Mathf.Cos (Vector3.Angle (dir1, dir2) / 2 * Mathf.Deg2Rad);
  98.                     normal *= width * width;
  99.                 }
  100.                 vertex = Vector3.Cross (normal, direction);
  101.                
  102.                 vertices.Add (position + vertex);
  103.                 vertices.Add (position - vertex);
  104.                
  105.                 normals.Add (normal);
  106.                 normals.Add (normal);
  107.                
  108.                 uv.Add (new Vector2 (0, i));
  109.                 uv.Add (new Vector2 (1, i));
  110.                
  111.                 if (i < points.Count - 1)
  112.                 {
  113.                     tris.Add (_i + i * 2);
  114.                     tris.Add (_i + i * 2 + 1);
  115.                     tris.Add (_i + i * 2 + 3);
  116.                    
  117.                     tris.Add (_i + i * 2 + 3);
  118.                     tris.Add (_i + i * 2 + 2);
  119.                     tris.Add (_i + i * 2);
  120.                 }
  121.             }
  122.             _i += temp.Count * 2 - 2;
  123.         }
  124.        
  125.         mesh.vertices = vertices.ToArray ();
  126.         mesh.normals = normals.ToArray ();
  127.         mesh.uv = uv.ToArray ();
  128.         mesh.triangles = tris.ToArray ();
  129.         mesh.RecalculateBounds ();
  130.     }
  131.    
  132.     public void Reset ()
  133.     {
  134.         meshFilter = GetComponent<MeshFilter> ();
  135.         mesh = new Mesh ();
  136.         meshFilter.mesh = mesh;
  137.         points = new List<Point> ();
  138.         lastBuildPointCount = 0;
  139.     }
  140.    
  141.     public void AddPoint (Vector3 position, Vector3 normal)
  142.     {
  143.         AddPoint (position, normal, defaultWidth, false);
  144.     }
  145.    
  146.     public void AddPoint (Vector3 position, Vector3 normal, float width)
  147.     {
  148.         AddPoint (position, normal, width, false);
  149.     }
  150.    
  151.     public void AddPoint (Vector3 position, Vector3 normal, bool newLine)
  152.     {
  153.         AddPoint (position, normal, defaultWidth, newLine);
  154.     }
  155.    
  156.     public void AddPoint (Vector3 position, Vector3 normal, float width, bool newLine)
  157.     {
  158.         if (normal.sqrMagnitude != 1)
  159.             normal.Normalize ();
  160.         position += normal * normalOffset;
  161.         normal *= (width / 2);
  162.        
  163.         if (newLine && points.Count > 0 && points[points.Count - 1].newLine)
  164.             points[points.Count - 1] = new Point (position, normal, true);
  165.         else if (newLine)
  166.             points.Add (new Point (position, normal, true));
  167.         else if (
  168.             points.Count > 1 &&
  169.             !points[points.Count - 1].newLine &&
  170.             (points[points.Count - 2].position - points[points.Count - 1].position).sqrMagnitude < minDistance * minDistance)
  171.         {
  172.             points[points.Count - 1] = new Point (position, normal, false);
  173.             lastBuildPointCount--;
  174.         }
  175.         else
  176.             points.Add (new Point (position, normal, false));
  177.     }
  178.    
  179.     public void ForceRebuild ()
  180.     {
  181.         lastBuildPointCount = 0;
  182.         Rebuild ();
  183.     }
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement