Last active
August 29, 2015 13:57
-
-
Save onedayitwillmake/9532364 to your computer and use it in GitHub Desktop.
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
/// Creating a dynamic 3D ribbon which moves towards a changing position each frame | |
/// Author Mario Gonzalez | |
using UnityEngine; | |
using System.Collections; | |
using System.Text; | |
public class RibbonMeshNotSharedVertices { | |
private Mesh mesh; | |
// Mesh Components | |
private Vector3[] vertices; | |
private Vector3[] normals; | |
private Vector2[] uvs; | |
private int[] triangles; | |
// Mesh properties | |
private float width; | |
private int len; | |
private int _index = 0; | |
// Bookkeeping | |
private Vector3 v0; // Store last two vertices | |
private Vector3 v1; | |
private Vector3 n0; // Store last two normals | |
private Vector3 n1; | |
private bool firstCall = true; | |
private Vector3 unitLeft; | |
private Vector3 unitRight; | |
private bool useFlippedNormals; | |
public Transform _quadTransform; | |
public RibbonMeshNotSharedVertices( GameObject aContainer, int aLength, float aWidth, bool shouldUseFlippedNormals ) { | |
// Set properties of the ribbon | |
len = aLength; | |
width = aWidth; | |
useFlippedNormals = shouldUseFlippedNormals; | |
// Create arrays for each of our properties | |
vertices = new Vector3[ len * 4 ]; | |
triangles = new int[ len * 6 ]; | |
normals = new Vector3[ len * 4]; | |
uvs = new Vector2[ len * 4]; | |
mesh = new Mesh(); | |
aContainer.GetComponent<MeshFilter>().mesh = mesh; | |
_quadTransform = new GameObject().transform; | |
_quadTransform.parent = aContainer.GetComponent<Transform>(); | |
unitLeft = new Vector3( width*0.5f, 0, width*0.5f ); | |
unitRight = new Vector3( -width*0.5f, 0, width*0.5f ); | |
} | |
private float angle = 1f; | |
public void CreateQuad( Vector3 target, float aWidth, float lookAtSpeed, float chaseSpeed ) { | |
if( aWidth != width ) { | |
width = aWidth; | |
unitLeft = new Vector3( width*0.5f, 0, width*0.5f ); | |
unitRight = new Vector3( -width*0.5f, 0, width*0.5f ); | |
} | |
// Move towards target | |
Vector3 newPosition = Vector3.Lerp(_quadTransform.position, target , Time.deltaTime * chaseSpeed); | |
Vector3 relativePosition = _quadTransform.position - newPosition; | |
// Ignore if position change is insignificant | |
float sqrLen = relativePosition.sqrMagnitude; | |
float min = 0.0001f; | |
if( sqrLen < min*min ) return; | |
//Smooth lookat - target | |
Quaternion rotation = Quaternion.LookRotation(relativePosition, Vector3.up ); | |
_quadTransform.rotation = Quaternion.Slerp(_quadTransform.rotation, rotation, Time.deltaTime * lookAtSpeed ) ; | |
_quadTransform.transform.position = newPosition; | |
// Slight extra rotation just to make it appear more 'ribbon like' as it moves | |
angle += 1f; | |
//_quadTransform.RotateAround( Vector3.up, angle ); | |
// Rotate the unitLeft and unitRight positions | |
Vector3 toTheLeft = _quadTransform.rotation * unitLeft; | |
Vector3 toTheRight = _quadTransform.rotation * unitRight; | |
////////////////////////// | |
// SET THE INDICES // | |
////////////////////////// | |
// Wrap the if past the length | |
if( _index >= len ) { // Wrap | |
_index = 0; | |
} | |
int _v_index = _index * 4; // Vertex array index - 4 points per quad, so increment by 4 | |
int _t_index = _index * 6; // Triangle array index - Three points per triangle, so incriment by two triangles | |
////////////////////////// | |
// CREATE FOUR VERTICES // | |
////////////////////////// | |
// For the first call, create v0 and v1 explicitely | |
// For proceeding calls, set the first two verts of this quad to the last two of the prev quad | |
if( firstCall ) { | |
vertices[ _v_index + 0] = _quadTransform.TransformPoint( toTheLeft ); | |
vertices[ _v_index + 1] = _quadTransform.TransformPoint( toTheRight ); | |
} else { | |
vertices[ _v_index + 0] = v0; | |
vertices[ _v_index + 1] = v1; | |
} | |
// If using flipped normals - wind the triangles in reverse order | |
if( useFlippedNormals ) { | |
v0 = vertices[ _v_index + 2] = _quadTransform.TransformPoint( toTheLeft ); | |
v1 = vertices[ _v_index + 3] = _quadTransform.TransformPoint( toTheRight ); | |
} else { | |
v0 = vertices[ _v_index + 2] = _quadTransform.TransformPoint( toTheRight ); | |
v1 = vertices[ _v_index + 3] = _quadTransform.TransformPoint( toTheLeft ); | |
} | |
// Create the normals all pointing outward | |
if( firstCall ) { | |
normals[ _v_index + 0 ] = Vector3.Cross( vertices[_v_index + 1] - vertices[_v_index + 0], vertices[_v_index + 2] - vertices[_v_index + 0]).normalized; | |
normals[ _v_index + 1 ] = Vector3.Cross( vertices[_v_index + 1] - vertices[_v_index + 0], vertices[_v_index + 2] - vertices[_v_index + 0]).normalized; | |
} else { // The normals for the second triangles are shared from the previous | |
normals[ _v_index + 0 ] = n0; | |
normals[ _v_index + 1 ] = n1; | |
} | |
n0 = normals[ _v_index + 2 ] = Vector3.Cross( vertices[_v_index + 2] - vertices[_v_index + 1], vertices[_v_index + 3] - vertices[_v_index + 1]).normalized; | |
n1 = normals[ _v_index + 3 ] = Vector3.Cross( vertices[_v_index + 2] - vertices[_v_index + 1], vertices[_v_index + 3] - vertices[_v_index + 1]).normalized; | |
// Create UV's at each corner | |
uvs[ _v_index + 0] = new Vector2(0, 1); | |
uvs[ _v_index + 1] = new Vector2(1, 1); | |
uvs[ _v_index + 2] = new Vector2(0, 0); | |
uvs[ _v_index + 3] = new Vector2(1, 0); | |
// Create two triangles pointing using the vertices array index positions | |
// 0 | |
triangles[ _t_index + 0] = _v_index + 0; | |
triangles[ _t_index + 1] = _v_index + 2; | |
triangles[ _t_index + 2] = _v_index + 1; | |
// 1 | |
triangles[ _t_index + 3] = _v_index + 2; | |
triangles[ _t_index + 4] = _v_index + 3; | |
triangles[ _t_index + 5] = _v_index + 1; | |
mesh.vertices = vertices; | |
mesh.triangles = triangles; | |
mesh.normals = normals; | |
mesh.uv = uvs; | |
// mesh.RecalculateNormals(); | |
_index += 1; | |
firstCall = false; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment