Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- public class MeshBuilder : MonoBehaviour
- {
- public GameObject Slice;
- public List<Vector3> Points;
- public int Angle;
- public int TotalAngle;
- public int Length;
- public int TotalLength;
- public float UvMultiplier = 1.0f;
- private float _width = 1;
- private Vector3[] _vertices = new Vector3[] { };
- private Vector2[] _uv = new Vector2[] { };
- private Vector3[] _normals = new Vector3[] { };
- private int[] _indices = new int[] { };
- private Mesh _sliceMesh;
- private Dictionary<int, int> _indicesDictionary = new Dictionary<int, int>();
- private Dictionary<int, List<int>> _indicesOrigDictionary = new Dictionary<int, List<int>>();
- private void Start()
- {
- _sliceMesh = Slice.GetComponent<MeshFilter>().sharedMesh;
- _vertices = _sliceMesh.vertices;
- _uv = _sliceMesh.uv;
- _normals = _sliceMesh.normals;
- _indices = _sliceMesh.triangles;
- float lowestY = 0;
- float highestX = 0;
- float lowestX = 0;
- for (int i = 0; i < _vertices.Length; i++)
- {
- if (lowestY > _vertices[i].y)
- lowestY = _vertices[i].y;
- if (highestX < _vertices[i].x)
- highestX = _vertices[i].x;
- if (lowestX > _vertices[i].x)
- lowestX = _vertices[i].x;
- }
- _width = highestX - lowestX;
- if (Angle == 0)
- {
- Vector3 forward = new Vector3(Mathf.Cos((TotalAngle + 90) / 180.0f * Mathf.PI), 0, Mathf.Sin((TotalAngle + 90) / 180.0f * Mathf.PI));
- Vector3 right = Vector3.Cross(Vector3.up, forward);
- for (int i = 0; i < _vertices.Length; i++)
- {
- if (_vertices[i].z > 0)
- {
- _vertices[i] = right * _vertices[i].x + Points[1] + new Vector3(0, _vertices[i].y, 0);
- _uv[i].y = TotalLength / _width * UvMultiplier;
- _normals[i] = Quaternion.AngleAxis(-TotalAngle, Vector3.up) * _normals[i];
- }
- else
- {
- _vertices[i] = right * _vertices[i].x + Points[0] + new Vector3(0, _vertices[i].y, 0);
- _uv[i].y = (TotalLength - Length) / _width * UvMultiplier;
- _normals[i] = Quaternion.AngleAxis(-TotalAngle, Vector3.up) * _normals[i];
- }
- }
- }
- else
- {
- int slicePoints = 0;
- List<Vector3> slicePositions = new List<Vector3>();
- List<Vector3> sliceNormals = new List<Vector3>();
- List<Vector2> sliceUv = new List<Vector2>();
- //Points of Slice
- for (int j = 0; j < _vertices.Length; j++)
- {
- if (!(_vertices[j].z > 0))
- {
- slicePoints++;
- slicePositions.Add(_vertices[j]);
- sliceNormals.Add(_normals[j]);
- sliceUv.Add(_uv[j]);
- }
- }
- for (int i = 0; i < _indices.Length / 3; i++)
- {
- _indicesOrigDictionary[i] = new List<int>() { _indices[3 * i], _indices[3 * i + 1], _indices[3 * i + 2] };
- }
- CalculateDictionary(slicePositions);
- List<Vector2> newUv = new List<Vector2>();
- List<Vector3> newNormals = new List<Vector3>();
- List<Vector3> newVertices = new List<Vector3>();
- List<int> newIndices = new List<int>();
- Vector3 forward = new Vector3(Mathf.Cos((TotalAngle - Angle + 90) / 180.0f * Mathf.PI), 0, Mathf.Sin((TotalAngle - Angle + 90) / 180.0f * Mathf.PI));
- Vector3 right = Vector3.Cross(Vector3.up, forward);
- //Adding Begin point to the list
- for (int j = 0; j < slicePositions.Count; j++)
- {
- newVertices.Add(right * slicePositions[j].x + Points[0] + new Vector3(0, slicePositions[j].y, 0));
- newUv.Add(new Vector2(sliceUv[j].x, UvMultiplier*(TotalLength - Length) / _width));
- newNormals.Add(Quaternion.AngleAxis(-TotalAngle+Angle, Vector3.up) * sliceNormals[j]);
- }
- //adding all the next points to the list
- for (int i = 1; i < Points.Count - 1; i++)
- {
- Vector3 forward1 = Points[i] - Points[i - 1];
- Vector3 forward2 = Points[i + 1] - Points[i];
- Vector3 forwardAverage = (forward2 + forward1) / 2;
- Vector3 rightVec = Vector3.Cross(Vector3.up, forwardAverage);
- rightVec.Normalize();
- for (int j = 0; j < slicePositions.Count; j++)
- {
- newVertices.Add(rightVec * slicePositions[j].x + Points[i] + new Vector3(0, slicePositions[j].y, 0));
- newUv.Add(new Vector2(sliceUv[j].x, UvMultiplier * (TotalLength - Length + (Length / (Points.Count - 1.0f) * i)) / _width));
- newNormals.Add(Quaternion.AngleAxis(-TotalAngle + Angle/(Points.Count - 1)*(Points.Count - 1-i), Vector3.up) * sliceNormals[j]);
- }
- }
- //Adding End point to the list
- forward = new Vector3(Mathf.Cos((TotalAngle + 90) / 180.0f * Mathf.PI), 0, Mathf.Sin((TotalAngle + 90) / 180.0f * Mathf.PI));
- right = Vector3.Cross(Vector3.up, forward);
- for (int j = 0; j < slicePositions.Count; j++)
- {
- newVertices.Add(right * slicePositions[j].x + Points[Points.Count - 1] + new Vector3(0, slicePositions[j].y, 0));
- newUv.Add(new Vector2(sliceUv[j].x, UvMultiplier * TotalLength / _width));
- newNormals.Add(Quaternion.AngleAxis(-TotalAngle, Vector3.up) * sliceNormals[j]);
- }
- //Calculate indices
- for (int s = 0; s < Points.Count - 1; s++)
- {
- for (int i = 0; i < slicePoints / 2; i++)
- {
- newIndices.Add(_indicesDictionary[2 * i] + s * slicePoints);
- newIndices.Add(_indicesDictionary[2 * i + 1] + s * slicePoints);
- newIndices.Add(_indicesDictionary[2 * i + 1] + (1 + s) * slicePoints);
- newIndices.Add(_indicesDictionary[2 * i + 1] + (1 + s) * slicePoints);
- newIndices.Add(_indicesDictionary[2 * i] + (1 + s) * slicePoints);
- newIndices.Add(_indicesDictionary[2 * i] + s * slicePoints);
- }
- }
- _vertices = newVertices.ToArray();
- _normals = newNormals.ToArray();
- _uv = newUv.ToArray();
- _indices = newIndices.ToArray();
- }
- for (int i = 0; i < _vertices.Length; i++)
- {
- _vertices[i].y -= lowestY;
- _vertices[i].x -= transform.position.x;
- _vertices[i].z -= transform.position.z;
- }
- Mesh mesh = new Mesh();
- mesh.name = "TrackMesh";
- mesh.vertices = _vertices;
- mesh.normals = _normals;
- mesh.uv = _uv;
- mesh.triangles = _indices;
- mesh.RecalculateBounds();
- MeshFilter filter = GetComponent<MeshFilter>();
- MeshCollider meshCollider = GetComponent<MeshCollider>();
- if (filter != null)
- {
- filter.sharedMesh = mesh;
- }
- if (meshCollider != null)
- {
- meshCollider.sharedMesh = mesh;
- }
- }
- // Update is called once per frame
- void Update()
- {
- }
- private void CalculateDictionary(List<Vector3> slicePositions)
- {
- _indicesDictionary[0] = 0;
- _indicesDictionary[1] = 1;
- int lastIndex = 1;
- int count = 2;
- while (!_indicesDictionary.ContainsKey(slicePositions.Count - 1))
- {
- for (int i = 2; i < slicePositions.Count; i++)
- {
- if (slicePositions[i] == slicePositions[lastIndex] && lastIndex != i)
- {
- _indicesDictionary[count] = i;
- if (i % 2 == 0)
- {
- _indicesDictionary[count + 1] = i + 1;
- lastIndex = i + 1;
- }
- else
- {
- _indicesDictionary[count + 1] = i - 1;
- lastIndex = i - 1;
- }
- count += 2;
- break;
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement