Advertisement
ThomasDM

MeshBuilder

Dec 7th, 2016
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.64 KB | None | 0 0
  1. using System;
  2. using UnityEngine;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6.  
  7. public class MeshBuilder : MonoBehaviour
  8. {
  9.     public GameObject Slice;
  10.     public List<Vector3> Points;
  11.     public int Angle;
  12.     public int TotalAngle;
  13.     public int Length;
  14.     public int TotalLength;
  15.     public float UvMultiplier = 1.0f;
  16.  
  17.     private float _width = 1;
  18.     private Vector3[] _vertices = new Vector3[] { };
  19.     private Vector2[] _uv = new Vector2[] { };
  20.     private Vector3[] _normals = new Vector3[] { };
  21.     private int[] _indices = new int[] { };
  22.     private Mesh _sliceMesh;
  23.     private Dictionary<int, int> _indicesDictionary = new Dictionary<int, int>();
  24.     private Dictionary<int, List<int>> _indicesOrigDictionary = new Dictionary<int, List<int>>();
  25.  
  26.     private void Start()
  27.     {
  28.         _sliceMesh = Slice.GetComponent<MeshFilter>().sharedMesh;
  29.  
  30.         _vertices = _sliceMesh.vertices;
  31.         _uv = _sliceMesh.uv;
  32.         _normals = _sliceMesh.normals;
  33.         _indices = _sliceMesh.triangles;
  34.  
  35.         float lowestY = 0;
  36.         float highestX = 0;
  37.         float lowestX = 0;
  38.  
  39.         for (int i = 0; i < _vertices.Length; i++)
  40.         {
  41.             if (lowestY > _vertices[i].y)
  42.                 lowestY = _vertices[i].y;
  43.             if (highestX < _vertices[i].x)
  44.                 highestX = _vertices[i].x;
  45.             if (lowestX > _vertices[i].x)
  46.                 lowestX = _vertices[i].x;
  47.         }
  48.  
  49.         _width = highestX - lowestX;
  50.  
  51.         if (Angle == 0)
  52.         {
  53.             Vector3 forward = new Vector3(Mathf.Cos((TotalAngle + 90) / 180.0f * Mathf.PI), 0, Mathf.Sin((TotalAngle + 90) / 180.0f * Mathf.PI));
  54.             Vector3 right = Vector3.Cross(Vector3.up, forward);
  55.  
  56.             for (int i = 0; i < _vertices.Length; i++)
  57.             {
  58.                 if (_vertices[i].z > 0)
  59.                 {
  60.                     _vertices[i] = right * _vertices[i].x + Points[1] + new Vector3(0, _vertices[i].y, 0);
  61.                     _uv[i].y = TotalLength / _width * UvMultiplier;
  62.                     _normals[i] = Quaternion.AngleAxis(-TotalAngle, Vector3.up) * _normals[i];
  63.                 }
  64.                 else
  65.                 {
  66.                     _vertices[i] = right * _vertices[i].x + Points[0] + new Vector3(0, _vertices[i].y, 0);
  67.                     _uv[i].y = (TotalLength - Length) / _width * UvMultiplier;
  68.                     _normals[i] = Quaternion.AngleAxis(-TotalAngle, Vector3.up) * _normals[i];
  69.                 }
  70.  
  71.             }
  72.         }
  73.         else
  74.         {
  75.             int slicePoints = 0;
  76.  
  77.             List<Vector3> slicePositions = new List<Vector3>();
  78.             List<Vector3> sliceNormals = new List<Vector3>();
  79.             List<Vector2> sliceUv = new List<Vector2>();
  80.  
  81.             //Points of Slice
  82.             for (int j = 0; j < _vertices.Length; j++)
  83.             {
  84.                 if (!(_vertices[j].z > 0))
  85.                 {
  86.                     slicePoints++;
  87.                     slicePositions.Add(_vertices[j]);
  88.                     sliceNormals.Add(_normals[j]);
  89.                     sliceUv.Add(_uv[j]);
  90.                 }
  91.             }
  92.  
  93.             for (int i = 0; i < _indices.Length / 3; i++)
  94.             {
  95.                 _indicesOrigDictionary[i] = new List<int>() { _indices[3 * i], _indices[3 * i + 1], _indices[3 * i + 2] };
  96.             }
  97.             CalculateDictionary(slicePositions);
  98.  
  99.             List<Vector2> newUv = new List<Vector2>();
  100.             List<Vector3> newNormals = new List<Vector3>();
  101.             List<Vector3> newVertices = new List<Vector3>();
  102.             List<int> newIndices = new List<int>();
  103.  
  104.             Vector3 forward = new Vector3(Mathf.Cos((TotalAngle - Angle + 90) / 180.0f * Mathf.PI), 0, Mathf.Sin((TotalAngle - Angle + 90) / 180.0f * Mathf.PI));
  105.             Vector3 right = Vector3.Cross(Vector3.up, forward);
  106.  
  107.             //Adding Begin point to the list
  108.             for (int j = 0; j < slicePositions.Count; j++)
  109.             {
  110.                 newVertices.Add(right * slicePositions[j].x + Points[0] + new Vector3(0, slicePositions[j].y, 0));
  111.                 newUv.Add(new Vector2(sliceUv[j].x, UvMultiplier*(TotalLength - Length) / _width));
  112.                 newNormals.Add(Quaternion.AngleAxis(-TotalAngle+Angle, Vector3.up) * sliceNormals[j]);
  113.             }
  114.  
  115.             //adding all the next points to the list
  116.             for (int i = 1; i < Points.Count - 1; i++)
  117.             {
  118.                 Vector3 forward1 = Points[i] - Points[i - 1];
  119.                 Vector3 forward2 = Points[i + 1] - Points[i];
  120.                 Vector3 forwardAverage = (forward2 + forward1) / 2;
  121.                 Vector3 rightVec = Vector3.Cross(Vector3.up, forwardAverage);
  122.                 rightVec.Normalize();
  123.  
  124.  
  125.                 for (int j = 0; j < slicePositions.Count; j++)
  126.                 {
  127.                     newVertices.Add(rightVec * slicePositions[j].x + Points[i] + new Vector3(0, slicePositions[j].y, 0));
  128.                     newUv.Add(new Vector2(sliceUv[j].x, UvMultiplier * (TotalLength - Length + (Length / (Points.Count - 1.0f) * i)) / _width));
  129.                     newNormals.Add(Quaternion.AngleAxis(-TotalAngle + Angle/(Points.Count - 1)*(Points.Count - 1-i), Vector3.up) * sliceNormals[j]);
  130.                 }
  131.             }
  132.  
  133.             //Adding End point to the list
  134.             forward = new Vector3(Mathf.Cos((TotalAngle + 90) / 180.0f * Mathf.PI), 0, Mathf.Sin((TotalAngle + 90) / 180.0f * Mathf.PI));
  135.             right = Vector3.Cross(Vector3.up, forward);
  136.  
  137.             for (int j = 0; j < slicePositions.Count; j++)
  138.             {
  139.                 newVertices.Add(right * slicePositions[j].x + Points[Points.Count - 1] + new Vector3(0, slicePositions[j].y, 0));
  140.                 newUv.Add(new Vector2(sliceUv[j].x, UvMultiplier * TotalLength / _width));
  141.                 newNormals.Add(Quaternion.AngleAxis(-TotalAngle, Vector3.up) * sliceNormals[j]);
  142.             }
  143.  
  144.             //Calculate indices
  145.             for (int s = 0; s < Points.Count - 1; s++)
  146.             {
  147.                 for (int i = 0; i < slicePoints / 2; i++)
  148.                 {
  149.                     newIndices.Add(_indicesDictionary[2 * i] + s * slicePoints);
  150.                     newIndices.Add(_indicesDictionary[2 * i + 1] + s * slicePoints);
  151.                     newIndices.Add(_indicesDictionary[2 * i + 1] + (1 + s) * slicePoints);
  152.                     newIndices.Add(_indicesDictionary[2 * i + 1] + (1 + s) * slicePoints);
  153.                     newIndices.Add(_indicesDictionary[2 * i] + (1 + s) * slicePoints);
  154.                     newIndices.Add(_indicesDictionary[2 * i] + s * slicePoints);
  155.                 }
  156.             }
  157.  
  158.             _vertices = newVertices.ToArray();
  159.             _normals = newNormals.ToArray();
  160.             _uv = newUv.ToArray();
  161.             _indices = newIndices.ToArray();
  162.         }
  163.  
  164.         for (int i = 0; i < _vertices.Length; i++)
  165.         {
  166.             _vertices[i].y -= lowestY;
  167.             _vertices[i].x -= transform.position.x;
  168.             _vertices[i].z -= transform.position.z;
  169.         }
  170.  
  171.         Mesh mesh = new Mesh();
  172.         mesh.name = "TrackMesh";
  173.         mesh.vertices = _vertices;
  174.         mesh.normals = _normals;
  175.         mesh.uv = _uv;
  176.         mesh.triangles = _indices;
  177.         mesh.RecalculateBounds();
  178.  
  179.         MeshFilter filter = GetComponent<MeshFilter>();
  180.         MeshCollider meshCollider = GetComponent<MeshCollider>();
  181.  
  182.         if (filter != null)
  183.         {
  184.             filter.sharedMesh = mesh;
  185.         }
  186.         if (meshCollider != null)
  187.         {
  188.             meshCollider.sharedMesh = mesh;
  189.         }
  190.     }
  191.  
  192.     // Update is called once per frame
  193.     void Update()
  194.     {
  195.  
  196.     }
  197.  
  198.     private void CalculateDictionary(List<Vector3> slicePositions)
  199.     {
  200.         _indicesDictionary[0] = 0;
  201.         _indicesDictionary[1] = 1;
  202.         int lastIndex = 1;
  203.         int count = 2;
  204.  
  205.         while (!_indicesDictionary.ContainsKey(slicePositions.Count - 1))
  206.         {
  207.             for (int i = 2; i < slicePositions.Count; i++)
  208.             {
  209.                 if (slicePositions[i] == slicePositions[lastIndex] && lastIndex != i)
  210.                 {
  211.                     _indicesDictionary[count] = i;
  212.  
  213.                     if (i % 2 == 0)
  214.                     {
  215.                         _indicesDictionary[count + 1] = i + 1;
  216.                         lastIndex = i + 1;
  217.                     }
  218.                     else
  219.                     {
  220.                         _indicesDictionary[count + 1] = i - 1;
  221.                         lastIndex = i - 1;
  222.                     }
  223.  
  224.                     count += 2;
  225.  
  226.                     break;
  227.                 }
  228.             }
  229.         }
  230.     }
  231. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement