Advertisement
ThomasDM

SplineMaker

Dec 7th, 2016
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.43 KB | None | 0 0
  1. using System;
  2. using UnityEngine;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Runtime.InteropServices;
  7. using UnityEngine.Rendering;
  8.  
  9. public class SplineMaker : MonoBehaviour
  10. {
  11.     private Vector3 _position = new Vector3(0,0,0);
  12.     private int _angle = 0;
  13.     private int _length = 0;
  14.     public bool ShowSpheres = false;
  15.     public bool ShowLine = true;
  16.     public bool ShowEditorLine = true;
  17.     public bool CustomLight = true;
  18.     private int _steps = 0;
  19.     public GameObject Slice;
  20.     public float UvMultiplier = 1.0f;
  21.     public List<Vector3> TransitionPoints = new List<Vector3>();
  22.     public List<Vector3> TransitionVectors = new List<Vector3>();
  23.  
  24.     // Use this for initialization
  25.     void Start()
  26.     {
  27.     }
  28.  
  29.     // Update is called once per frame
  30.     void Update()
  31.     {
  32.  
  33.     }
  34.  
  35.     public void BuildSpline(int length, int angle)
  36.     {
  37.         float angleRad = _angle / 180.0f * Mathf.PI;
  38.  
  39.         GameObject spline = new GameObject();
  40.         spline.name = "Spline";
  41.         spline.transform.position = _position;
  42.         SimpleSpline splineLine = spline.AddComponent<SimpleSpline>();
  43.  
  44.         splineLine.DrawSpheres = ShowSpheres;
  45.         splineLine.Parameters.StartPoint = _position;
  46.         splineLine.DrawLines = ShowEditorLine;
  47.         if (TransitionPoints.Count == 0)
  48.         {
  49.             TransitionPoints.Add(_position);
  50.             TransitionVectors.Add(new Vector3(Mathf.Cos((float)Mathf.PI / 2), 0, Mathf.Sin((float)Mathf.PI / 2)));
  51.         }
  52.  
  53.  
  54.         if (angle == 0)
  55.         {
  56.             spline.GetComponent<SimpleSpline>().Parameters.ControlPoint = _position + new Vector3(length / 2.0f * Mathf.Cos(angleRad + (float)Mathf.PI / 2), 0, length / 2.0f * Mathf.Sin(angleRad + (float)Mathf.PI / 2));
  57.             spline.GetComponent<SimpleSpline>().Parameters.EndPoint = _position + new Vector3(length * Mathf.Cos(angleRad + (float)Mathf.PI / 2), 0, length * Mathf.Sin(angleRad + (float)Mathf.PI / 2));
  58.             TransitionPoints.Add(spline.GetComponent<SimpleSpline>().Parameters.EndPoint);
  59.             TransitionVectors.Add(new Vector3(Mathf.Cos(angleRad + (float)Mathf.PI / 2), 0,
  60.                 Mathf.Sin(angleRad + (float)Mathf.PI / 2)));
  61.  
  62.         }
  63.         else
  64.         {
  65.  
  66.             float radius = Mathf.Abs((float)length / (angle / 180.0f * Mathf.PI));
  67.             if (angle > 0)
  68.             {
  69.                 spline.GetComponent<SimpleSpline>().Parameters.EndPoint =
  70.                     _position
  71.                     - new Vector3(radius * Mathf.Cos(angleRad), 0, radius * Mathf.Sin(angleRad))
  72.                     + new Vector3(radius * Mathf.Cos(angleRad + angle / 180.0f * Mathf.PI), 0, radius * Mathf.Sin(angleRad + angle / 180.0f * Mathf.PI));
  73.                 TransitionPoints.Add(spline.GetComponent<SimpleSpline>().Parameters.EndPoint);
  74.                 TransitionVectors.Add(new Vector3(Mathf.Cos(angleRad + (float)Mathf.PI / 2), 0,
  75.                         Mathf.Sin(angleRad + (float)Mathf.PI / 2)));
  76.  
  77.  
  78.                 spline.GetComponent<SimpleSpline>().Parameters.ControlPoint =
  79.                     ClosestPointOnTwoLines(spline.GetComponent<SimpleSpline>().Parameters.StartPoint,
  80.                         new Vector3(Mathf.Cos(angleRad + (float)Mathf.PI / 2), 0, Mathf.Sin(angleRad + (float)Mathf.PI / 2)),
  81.                         spline.GetComponent<SimpleSpline>().Parameters.EndPoint,
  82.                         new Vector3(Mathf.Cos((_angle + angle + 90) / 180.0f * Mathf.PI), 0, Mathf.Sin((_angle + angle + 90) / 180.0f * Mathf.PI)));
  83.             }
  84.             else
  85.             {
  86.                 spline.GetComponent<SimpleSpline>().Parameters.EndPoint =
  87.                    _position
  88.                    + new Vector3(radius * Mathf.Cos(angleRad), 0, radius * Mathf.Sin(angleRad))
  89.                    - new Vector3(radius * Mathf.Cos(angleRad + angle / 180.0f * Mathf.PI), 0, radius * Mathf.Sin(angleRad + angle / 180.0f * Mathf.PI));
  90.                 TransitionPoints.Add(spline.GetComponent<SimpleSpline>().Parameters.EndPoint);
  91.                 TransitionVectors.Add(new Vector3(Mathf.Cos(angleRad + (float)Mathf.PI / 2), 0,
  92.                      Mathf.Sin(angleRad + (float)Mathf.PI / 2)));
  93.  
  94.  
  95.                 spline.GetComponent<SimpleSpline>().Parameters.ControlPoint =
  96.                     ClosestPointOnTwoLines(spline.GetComponent<SimpleSpline>().Parameters.StartPoint,
  97.                         new Vector3(Mathf.Cos(angleRad + (float)Mathf.PI / 2), 0, Mathf.Sin(angleRad + (float)Mathf.PI / 2)),
  98.                         spline.GetComponent<SimpleSpline>().Parameters.EndPoint,
  99.                         new Vector3(Mathf.Cos((_angle + angle + 90) / 180.0f * Mathf.PI), 0, Mathf.Sin((_angle + angle + 90) / 180.0f * Mathf.PI)));
  100.             }
  101.         }
  102.         _angle += angle;
  103.         _length += length;
  104.         _steps = angle == 0 ? 2 : Mathf.Abs(angle) / 2;
  105.         spline.GetComponent<SimpleSpline>().InterpolationSteps = _steps;
  106.         List<Vector3> pointslist = spline.GetComponent<SimpleSpline>().CalculateSplinePoints();
  107.  
  108.         _position = spline.GetComponent<SimpleSpline>().Parameters.EndPoint;
  109.  
  110.  
  111.         if (ShowLine)
  112.         {
  113.             LineRenderer lineRenderer = spline.AddComponent<LineRenderer>();
  114.             lineRenderer.SetVertexCount(_steps);
  115.             for (int i = 0; i < _steps; i++)
  116.             {
  117.                 lineRenderer.SetPosition(i, spline.GetComponent<SimpleSpline>().SplinePoints[i]);
  118.             }
  119.             lineRenderer.material = new Material(Shader.Find("Particles/Alpha Blended"));
  120.             lineRenderer.useLightProbes = false;
  121.             lineRenderer.receiveShadows = false;
  122.         }
  123.  
  124.         else
  125.         {
  126.             spline.AddComponent<MeshRenderer>();
  127.             spline.GetComponent<MeshRenderer>().material = Slice.GetComponent<MeshRenderer>().sharedMaterial;       //Visualisation
  128.             //spline.GetComponent<MeshRenderer>().receiveShadows = false;
  129.             //spline.GetComponent<MeshRenderer>().shadowCastingMode = ShadowCastingMode.Off;
  130.  
  131.             spline.AddComponent<MeshFilter>();                                                           //Mesh itself
  132.  
  133.             MeshBuilder build = spline.AddComponent<MeshBuilder>();                                                 //Custom script which makes the Mesh
  134.             build.Slice = Slice;
  135.             build.UvMultiplier = UvMultiplier;
  136.             build.Points = pointslist;
  137.             build.Angle = angle;
  138.             build.TotalAngle = _angle;
  139.             build.Length = length;
  140.             build.TotalLength = _length;
  141.  
  142.             spline.AddComponent<MeshCollider>();   //Collision so you can drive on it
  143.             if (CustomLight)
  144.             {
  145.                 Vector3[] vertices = Slice.GetComponent<MeshFilter>().sharedMesh.vertices;
  146.                 float highestY = 0;
  147.                 float lowestY = 0;
  148.                 float highestX = 0;
  149.                 float lowestX = 0;
  150.  
  151.                 for (int i = 0; i < vertices.Length; i++)
  152.                 {
  153.                     if (lowestY > vertices[i].y)
  154.                         lowestY = vertices[i].y;
  155.                     if (highestY < vertices[i].y)
  156.                         highestY = vertices[i].y;
  157.                     if (highestX < vertices[i].x)
  158.                         highestX = vertices[i].x;
  159.                     if (lowestX > vertices[i].x)
  160.                         lowestX = vertices[i].x;
  161.                 }
  162.  
  163.                 float width = highestX - lowestX;
  164.                 float height = highestY - lowestY;
  165.  
  166.                 var lightComp = spline.AddComponent<MakeLight>();
  167.                 lightComp.Length = length;
  168.                 lightComp.Height = height;
  169.             }
  170.         }
  171.     }
  172.  
  173.     private Vector3 ClosestPointOnTwoLines(Vector3 linePoint1, Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2)
  174.     {
  175.         float a = Vector3.Dot(lineVec1, lineVec1);
  176.         float b = Vector3.Dot(lineVec1, lineVec2);
  177.         float e = Vector3.Dot(lineVec2, lineVec2);
  178.  
  179.         float d = a * e - b * b;
  180.  
  181.         //lines are not parallel
  182.         if (d != 0.0f)
  183.         {
  184.  
  185.             Vector3 r = linePoint1 - linePoint2;
  186.             float c = Vector3.Dot(lineVec1, r);
  187.             float f = Vector3.Dot(lineVec2, r);
  188.  
  189.             float s = (b * f - c * e) / d;
  190.  
  191.             return linePoint1 + lineVec1 * s;
  192.         }
  193.         else
  194.         {
  195.             Debug.Log("Failed to find a point");
  196.             return new Vector3(0, 0, 0);
  197.         }
  198.     }
  199. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement