Created
May 14, 2012 23:21
-
-
Save N-Carter/2698039 to your computer and use it in GitHub Desktop.
Spline mesh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections.Generic; | |
using System.Linq; | |
public class SplineMesh : MonoBehaviour | |
{ | |
[System.Serializable] | |
public class Node | |
{ | |
public Vector3 position; | |
public Node(Vector3 position) | |
{ | |
this.position = position; | |
} | |
} | |
public struct Segment | |
{ | |
public Node start; | |
public Node end; | |
public Segment(Node previous, Node next) | |
{ | |
this.start = previous; | |
this.end = next; | |
} | |
public Vector3 Direction {get {return end.position - start.position;}} | |
public Vector3 Normal {get {Vector3 direction = Direction.normalized; return new Vector3(-direction.y, direction.x, 0.0f);}} | |
} | |
[SerializeField] protected Node[] m_Nodes; | |
[SerializeField] protected int m_Divisions = 8; | |
[SerializeField] protected float m_Height = 1.0f; | |
[SerializeField] protected float m_Depth = 1.0f; | |
[SerializeField] protected float m_BaselineOffset = 1.0f; | |
[SerializeField] protected Vector2 m_UVTiling = Vector2.one; | |
[SerializeField] protected Vector2 m_UVOffset = Vector2.zero; | |
[SerializeField] protected bool m_LengthAffectsU = true; | |
public Node GetNode(int index) | |
{ | |
return m_Nodes[index]; | |
} | |
protected void Reset() | |
{ | |
m_Nodes = new Node[] {new Node(new Vector3(-1, 0, 0)), new Node(new Vector3(1, 0, 0))}; | |
} | |
#region Properties | |
public IEnumerable<Node> Nodes {get {return m_Nodes;}} | |
public IEnumerable<Segment> Segments | |
{ | |
get | |
{ | |
var previousNode = m_Nodes.First(); | |
foreach(var node in m_Nodes.Skip(1)) | |
{ | |
yield return new Segment(previousNode, node); | |
previousNode = node; | |
} | |
} | |
} | |
public IEnumerable<Node> Spline | |
{ | |
get | |
{ | |
if(m_Nodes.Length > 2) | |
yield return m_Nodes[0]; | |
Vector3 p2 = m_Nodes[0].position; | |
for(int nodeIndex = 1; nodeIndex < m_Nodes.Length - 1; ++nodeIndex) | |
{ | |
Vector3 previousNode = m_Nodes[nodeIndex - 1].position; | |
Vector3 thisNode = m_Nodes[nodeIndex + 0].position; | |
Vector3 nextNode = m_Nodes[nodeIndex + 1].position; | |
Vector3 p0 = (previousNode + thisNode) * 0.5f; | |
Vector3 p1 = thisNode; | |
p2 = (thisNode + nextNode) * 0.5f; | |
foreach(var vertex in QuadraticSplinePieceVertices(p0, p1, p2, m_Divisions)) | |
yield return new Node(vertex); | |
} | |
yield return new Node(p2); | |
yield return m_Nodes[m_Nodes.Length - 1]; | |
} | |
} | |
public static IEnumerable<Vector3> QuadraticSplinePieceVertices(Vector3 point0, Vector3 point1, Vector3 point2, int divisions) | |
{ | |
for(int i = 0; i < divisions; i++) | |
{ | |
float t = (float)i / divisions; | |
float oneMinusT = 1.0f - t; | |
yield return oneMinusT * oneMinusT * point0 + 2 * oneMinusT * t * point1 + t * t * point2; | |
} | |
} | |
public IEnumerable<Segment> SplineSegments | |
{ | |
get | |
{ | |
var spline = Spline; | |
var previousNode = spline.First(); | |
foreach(var node in spline.Skip(1)) | |
{ | |
// Debug.Log(string.Format("Segment {0} - {1}", previousNode.position, node.position)); | |
yield return new Segment(previousNode, node); | |
previousNode = node; | |
} | |
} | |
} | |
public int CountNodes {get {return (m_Nodes != null ? m_Nodes.Length : 0);}} | |
public int CountSplineDivisions | |
{ | |
get | |
{ | |
int numNodes = CountNodes; | |
return 2 + (numNodes > 2 ? 1 : 0) + (numNodes - 2) * m_Divisions; | |
} | |
} | |
// public float Height {get {return m_Height;}} | |
// public float Depth {get {return m_Depth;}} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment