Skip to content

Instantly share code, notes, and snippets.

@N-Carter
Created May 14, 2012 23:21
Show Gist options
  • Save N-Carter/2698039 to your computer and use it in GitHub Desktop.
Save N-Carter/2698039 to your computer and use it in GitHub Desktop.
Spline mesh
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