//sets all the points to points of a Vector3 array, as well as capping the ends. public void SetPoints(Vector3[] points, float radius, Color col) { if (points.Length < 2) { return; } vertices = new TubeVertex[points.Length + 2]; Vector3 v0offset = (points[0] - points[1]) * 0.01f; vertices[0] = new TubeVertex(v0offset + points[0], 0.0f, col); Vector3 v1offset = (points[points.Length - 1] - points[points.Length - 2]) * 0.01f; vertices[vertices.Length - 1] = new TubeVertex(v1offset + points[points.Length - 1], 0.0f, col); for (int p = 0; p < points.Length; p++) { vertices[p + 1] = new TubeVertex(points[p], radius, col); } /* * Debug.Log("vertices.Length = " + vertices.Length); * for (int i = 0; i < vertices.Length; i++) * { * Debug.Log( i + " " + vertices[i].point); * } */ }
public void Respline() { int ptCount = (int)(spline.EstimateLength() * pointDensity); vertices = new TubeVertex[ptCount + 1]; for (int i = 0; i <= ptCount; i++) { float t = (float)i / (float)ptCount; Vector3 pos = spline.GetPoint(t); float fade = Mathf.Clamp01(Vector3.Distance(pos, spline.GetPoint(0)) / endFadeLength); // fade tube at beginning fade *= Mathf.Clamp01(Vector3.Distance(pos, spline.GetPoint(1)) / endFadeLength); // and at end vertices[i] = new TubeVertex(transform.InverseTransformPoint(pos), 1f, Color.Lerp(Color.clear, Color.white, fade)); } }
///sets all the points to points of a Vector3 array, as well as capping the ends. public void SetPoints(Vector3[] pointsIn, float radius, Color col) { if (pointsIn.Length < 2) return; Vector3[] points = InvTransformPoints(pointsIn, transform); vertices = new TubeVertex[points.Length + 2]; Vector3 v0offset = (points[0] - points[1]) * 0.01f; vertices[0] = new TubeVertex(v0offset + points[0], 0.0f, col); Vector3 v1offset = (points[points.Length - 1] - points[points.Length - 2]) * 0.01f; vertices[vertices.Length - 1] = new TubeVertex(v1offset + points[points.Length - 1], 0.0f, col); for (int p = 0; p < points.Length; p++) { vertices[p + 1] = new TubeVertex(points[p], radius, col); } }
//sets all the points to points of a Vector3 array, as well as capping the ends. public void SetPoints(Vector3[] points, Color col) { if (points.Length < 2) { return; } vertices = new TubeVertex[points.Length + 2]; Vector3 v0offset = (points[0] - points[1]) * 0.01f; vertices[0] = new TubeVertex(v0offset + points[0], 0.0f, col); Vector3 v1offset = (points[points.Length - 1] - points[points.Length - 2]) * 0.01f; vertices[vertices.Length - 1] = new TubeVertex(v1offset + points[points.Length - 1], 0.0f, col); for (int p = 0; p < points.Length; p++) { vertices[p + 1] = new TubeVertex(points[p], tubeWidth.Evaluate((float)p / points.Length), col); } }
public void SetBinePoints(Vector3[] points, float[] radius, Color col) { if (points.Length < 2) { return; } vertices = new TubeVertex[points.Length + 2]; Vector3 v0offset = (points[0] - points[1]) * 0.01f; vertices[0] = new TubeVertex(v0offset + points[0], 0.0f, col); Vector3 v1offset = (points[points.Length - 1] - points[points.Length - 2]) * 0.01f; vertices[vertices.Length - 1] = new TubeVertex(v1offset + points[points.Length - 1], 0.0f, col); for (int p = 0; p < points.Length; p++) { vertices[p + 1] = new TubeVertex(points[p], radius[p], col); } }
public void SetPoints(List <Vector3> points, float radius, Color col) { if (points.Count < 2) { return; } vertices = new TubeVertex[points.Count + 2]; Vector3 v0offset = (points[0] - points[1]) * 0.01f; vertices[0] = new TubeVertex(v0offset + points[0], 0.0f, col); Vector3 v1offset = (points[points.Count - 1] - points[points.Count - 2]) * 0.01f; vertices[vertices.Length - 1] = new TubeVertex(v1offset + points[points.Count - 1], 0.0f, col); for (int p = 0; p < points.Count; p++) { vertices[p + 1] = new TubeVertex(points[p], radius, col); } }
//sets all the points to points of a Vector3 array, as well as capping the ends. public void SetPoints(Vector3[] points, float radius, Color col) { if (points.Length < 2) { // GetComponent<MeshFilter>().mesh.Clear(); return; } vertices = new TubeVertex[points.Length + 2]; Vector3 v0offset = (points[0] - points[1]) * 0.01f; vertices[0] = new TubeVertex(v0offset + points[0], 0.0f, col); Vector3 v1offset = (points[points.Length - 1] - points[points.Length - 2]) * 0.01f; vertices[vertices.Length - 1] = new TubeVertex(v1offset + points[points.Length - 1], 0.0f, col); for (int p = 0; p < points.Length; p++) { vertices[p + 1] = new TubeVertex(points[p], radius, col); } }
//sets all the points to points of a Vector3 array, as well as capping the ends. public void SetPoints(Vector3[] points, float radius, Color col) { if (points.Length < 2) { return; } vertices = new TubeVertex[points.Length + 2]; // создаем нулевую точку смещением от points[0] в направлении "наружу" Vector3 v0offset = (points[0] - points[1]) * 0.01f; vertices[0] = new TubeVertex(v0offset + points[0], 0.0f, col); // создаем последнюю точку смещением от points[Length - 1] в направлении "наружу" Vector3 v1offset = (points[points.Length - 1] - points[points.Length - 2]) * 0.01f; vertices[vertices.Length - 1] = new TubeVertex(v1offset + points[points.Length - 1], 0.0f, col); // остальные точки - это координаты шаров, их просто копируем for (int p = 0; p < points.Length; p++) { vertices[p + 1] = new TubeVertex(points[p], radius, col); } }
public void SetPoints(Vector3[] points, float radius, Color color1, Color color2, int sum, int prev) { if (points.Length < 2) { return; } vertices = new TubeVertex[points.Length + 2]; Vector3 v0offset = (points [0] - points [1]) * 0.01f; vertices [0] = new TubeVertex(v0offset + points [0], 0.0f, color1); Vector3 v1offset = (points [points.Length - 1] - points [points.Length - 2]) * 0.01f; vertices [vertices.Length - 1] = new TubeVertex(v1offset + points [points.Length - 1], 0.0f, color1); for (int p = 0; p < points.Length; p++) { float f = (float)p; vertices [p + 1] = new TubeVertex(points [p], radius, Color.Lerp(color1, color2, (f + prev) / sum)); } setUpMesh(points.Length); }
public static void GenerateMesh(List <TubeVertex> vertices, int dataIndex, bool Flat, bool Web, BrushType brushType, Vector2 ExtendsMultiplier, List <Vector3> meshVertices, List <Vector4> meshTangents, List <Vector3> meshNormals, List <Vector2> uvs, List <Color> colors, ref int[] indices, ref float length) { int additionalVertices = brushType == BrushType.Sphere ? 8 : 2; int actualVertexCount = vertices.Count + additionalVertices; List <int> tris = new List <int>(); float currentTotalLength = 0; Action <int, TubeVertex, TubeVertex, TubeVertex> addPointFunc = (int i, TubeVertex v, TubeVertex prev, TubeVertex next) => { var prevPoint = prev.point; var nextPoint = next.point; float dist = Vector3.Distance(prevPoint, v.point); currentTotalLength += dist; if (float.IsNaN(v.point.x) || float.IsNaN(v.point.z) || float.IsNaN(v.point.z)) { return; } meshVertices[i] = v.point; if (Flat) { meshNormals[i] = v.orientation * Vector3.up * Mathf.Clamp(ExtendsMultiplier.y * v.extends.y, 0, .005f); } else { meshNormals[i] = v.orientation * Vector3.up * ExtendsMultiplier.y * v.extends.y; } // Tangents for hermite interpolation Vector3 dir = 0.5f * (nextPoint - prevPoint); // Width of the line meshTangents[i] = new Vector4(dir.x, dir.y, dir.z, v.extends.x * ExtendsMultiplier.x); uvs[i] = new Vector2(dataIndex, currentTotalLength); colors[i] = v.color; if (i < actualVertexCount - 1) { tris.Add(i); tris.Add(i + 1); } if (Web && i < actualVertexCount - 7) { tris.Add(i); tris.Add(i + 7); } }; if (brushType == BrushType.Sphere) { TubeVertex firstAddVert = vertices[0]; var startPoint = vertices[0].point; firstAddVert.point -= firstAddVert.orientation * Vector3.forward * firstAddVert.extends.x * 0.5f; var endPoint = firstAddVert.point; Vector2 smallExtends = brushType == BrushType.Sphere ? firstAddVert.extends * 0.001f : firstAddVert.extends; var prevExtends = firstAddVert.extends; Func <float, float> t = (float v) => v; Func <float, float> height = (float v) => Mathf.Sqrt(1.0f - (1.0f - v) * (1.0f - v)); { firstAddVert.extends = firstAddVert.extends * 0.001f; var lastVert = firstAddVert; float interp = ((float)1.0f) / (0.5f * additionalVertices + 1); firstAddVert.extends = Vector2.Lerp(smallExtends, prevExtends, height(t(interp))); firstAddVert.point = Vector3.Lerp(endPoint, startPoint, t(interp)); var thisVert = firstAddVert; addPointFunc(0, lastVert, lastVert, thisVert); interp = ((float)2.0f) / (0.5f * additionalVertices + 1); firstAddVert.extends = Vector2.Lerp(smallExtends, prevExtends, height(t(interp))); firstAddVert.point = Vector3.Lerp(endPoint, startPoint, t(interp)); var nextVert = firstAddVert; for (int i = 1; i <= additionalVertices / 2; i++) { addPointFunc(i, thisVert, lastVert, nextVert); lastVert = thisVert; thisVert = nextVert; interp = ((float)i + 2) / (0.5f * additionalVertices + 1); nextVert.extends = Vector2.Lerp(smallExtends, prevExtends, height(t(interp))); nextVert.point = Vector3.Lerp(endPoint, startPoint, t(interp)); } firstAddVert = lastVert; } TubeVertex lastAddVert = vertices[vertices.Count - 1]; startPoint = lastAddVert.point; lastAddVert.point += lastAddVert.orientation * Vector3.forward * lastAddVert.extends.x * 0.5f; endPoint = lastAddVert.point; prevExtends = lastAddVert.extends; smallExtends = brushType == BrushType.Sphere ? lastAddVert.extends * 0.001f : lastAddVert.extends; lastAddVert.extends = Vector2.Lerp(prevExtends, smallExtends, 1.0f / (0.5f * additionalVertices)); lastAddVert.point = Vector3.Lerp(startPoint, endPoint, 1.0f / (0.5f * additionalVertices)); int firstIndex = additionalVertices / 2; for (int i = 1; i < vertices.Count - 1; i++) { addPointFunc(firstIndex + i, vertices[i], i == 1 ? firstAddVert : vertices[i - 1], i == vertices.Count - 2 ? lastAddVert : vertices[i + 1]); } { float interp = 0.0f / (0.5f * additionalVertices + 1); var lastVert = vertices[vertices.Count - 2]; lastAddVert.extends = Vector2.Lerp(prevExtends, smallExtends, 1.0f - height(1.0f - t(interp))); lastAddVert.point = Vector3.Lerp(startPoint, endPoint, t(interp)); var thisVert = lastAddVert; interp = 1.0f / (0.5f * additionalVertices + 1); lastAddVert.extends = Vector2.Lerp(prevExtends, smallExtends, 1.0f - height(1.0f - t(interp))); lastAddVert.point = Vector3.Lerp(startPoint, endPoint, t(interp)); var nextVert = lastAddVert; for (int i = actualVertexCount - additionalVertices / 2 - 1; i < actualVertexCount - 1; i++) { addPointFunc(i, thisVert, lastVert, nextVert); interp = 1.0f - ((float)actualVertexCount - i - 3) / (0.5f * additionalVertices + 1); lastVert = thisVert; thisVert = nextVert; nextVert.extends = Vector2.Lerp(prevExtends, smallExtends, 1.0f - height(1.0f - t(interp))); nextVert.point = Vector3.Lerp(startPoint, endPoint, t(interp)); } lastAddVert.extends = vertices[vertices.Count - 1].extends * 0.001f; lastAddVert.point = endPoint; addPointFunc(actualVertexCount - 1, lastAddVert, lastVert, lastAddVert); } } else { var firstPoint = vertices[0]; firstPoint.point -= firstPoint.orientation * Vector3.forward * firstPoint.extends.x * 0.5f; var nextPoint = firstPoint; firstPoint.extends *= 0.00001f; addPointFunc(0, firstPoint, firstPoint, nextPoint); addPointFunc(1, nextPoint, firstPoint, vertices[1]); var lastPoint = vertices[vertices.Count - 1]; lastPoint.point += lastPoint.orientation * Vector3.forward * lastPoint.extends.x * 0.5f; var closingPoint = lastPoint; closingPoint.extends *= 0.00001f; var lastAddedPoint = nextPoint; for (int i = 1; i < vertices.Count - 1; i++) { addPointFunc(i + 1, vertices[i], lastAddedPoint, i == vertices.Count - 2 ? lastPoint : vertices[i + 1]); lastAddedPoint = vertices[i]; } addPointFunc(vertices.Count, lastPoint, lastAddedPoint, closingPoint); addPointFunc(vertices.Count + 1, closingPoint, lastPoint, closingPoint); } indices = tris.ToArray(); length = currentTotalLength; }
void Reset() { vertices = new TubeVertex[2]; vertices[0] = new TubeVertex(Vector3.zero, 1.0f, Color.white); vertices[1] = new TubeVertex(new Vector3(1, 0, 0), 1.0f, Color.white); }
public void Reset() { vertices = new TubeVertex[2]; vertices[0] = new TubeVertex(Vector3.zero, 1.0f, Color.white); vertices[1] = new TubeVertex(Vector3.right, 1.0f, Color.white); }
public static Mesh CreateTube(Vector3[] positions, int crossSegments, Color color, float radius) { TubeVertex[] vertices = new TubeVertex[positions.Length]; for (int i = 0; i < positions.Length; i++) { TubeVertex v = new TubeVertex(positions[i], radius, color); vertices[i] = v; } Vector3[] crossPoints = new Vector3[crossSegments]; float theta = 2.0f * Mathf.PI / crossSegments; for (int c = 0; c < crossSegments; c++) { crossPoints[c] = new Vector3(Mathf.Cos(theta * c), Mathf.Sin(theta * c), 0); } Vector3[] meshVertices = new Vector3[vertices.Length * crossSegments]; Vector2[] uvs = new Vector2[vertices.Length * crossSegments]; Color[] colors = new Color[vertices.Length * crossSegments]; int[] tris = new int[vertices.Length * crossSegments * 6]; int[] lastVertices = new int[crossSegments]; int[] theseVertices = new int[crossSegments]; Quaternion rotation = Quaternion.identity; for (int p = 0; p < vertices.Length; p++) { if (p < vertices.Length - 1) { rotation = Quaternion.FromToRotation(Vector3.forward, vertices[p + 1].point - vertices[p].point); } for (int c = 0; c < crossSegments; c++) { int vertexIndex = p * crossSegments + c; meshVertices[vertexIndex] = vertices[p].point + rotation * crossPoints[c] * vertices[p].radius; uvs[vertexIndex] = new Vector2((0.0f + c) / crossSegments, (0.0f + p) / vertices.Length); colors[vertexIndex] = vertices[p].color; // print(c+" - vertex index "+(p*crossSegments+c) + " is " + meshVertices[p*crossSegments+c]); lastVertices[c] = theseVertices[c]; theseVertices[c] = p * crossSegments + c; } //make triangles if (p > 0) { for (int c = 0; c < crossSegments; c++) { int start = (p * crossSegments + c) * 6; tris[start] = lastVertices[c]; tris[start + 1] = lastVertices[(c + 1) % crossSegments]; tris[start + 2] = theseVertices[c]; tris[start + 3] = tris[start + 2]; tris[start + 4] = tris[start + 1]; tris[start + 5] = theseVertices[(c + 1) % crossSegments]; // print("Triangle: indexes("+tris[start]+", "+tris[start+1]+", "+tris[start+2]+"), ("+tris[start+3]+", "+tris[start+4]+", "+tris[start+5]+")"); } } } Mesh mesh = new Mesh(); mesh.vertices = meshVertices; mesh.triangles = tris; mesh.RecalculateNormals(); mesh.uv = uvs; return(mesh); }
//sets all the points to points of a Vector3 array, as well as capping the ends. public void SetPoints(Vector3[] points, float radius, Color col) { if (points.Length < 2) return; vertices = new TubeVertex[points.Length+2]; Vector3 v0offset = (points[0]-points[1])*0.01f; vertices[0] = new TubeVertex(v0offset+points[0], 0.0f, col); Vector3 v1offset = (points[points.Length-1] - points[points.Length-2])*0.01f; vertices[vertices.Length-1] = new TubeVertex(v1offset+points[points.Length-1], 0.0f, col); for (int p=0;p<points.Length;p++) { vertices[p+1] = new TubeVertex(points[p], radius, col); } }
void LateUpdate() { transform.position = Vector3.zero; transform.rotation = Quaternion.identity; GetComponent <Renderer>().enabled = vertices.Count <= 2 ? false : true; if (emit && emitTime != 0) { emitTime -= Time.deltaTime; if (emitTime == 0) { emitTime = -1; } if (emitTime < 0) { emit = false; } } // destroy if autodestruct. if (!emit && vertices.Count == 0 && autoDestruct) { Destroy(gameObject); } if (emit) { TubeVertex p = new TubeVertex(); p.point = target.position + target.TransformDirection(offset); p.timeCreated = Time.time; vertices.Add(p); } ArrayList remove = new ArrayList(); int i = 0; foreach (TubeVertex p in vertices) { // cull old points first if (Time.time - p.timeCreated > lifeTime) { remove.Add(p); } i++; } foreach (TubeVertex p in remove) { vertices.Remove(p); } remove.Clear(); if (vertices.Count > 1) { //draw tube for (int k = 0; k < vertices.Count; k++) { vertices[k].radius = radius.Evaluate((float)((float)(vertices.Count - 1 - k) / (float)(vertices.Count - 1))); } if (crossSegments != lastCrossSegments) { crossPoints = new Vector3[crossSegments]; float theta = 2.0f * Mathf.PI / crossSegments; for (int c = 0; c < crossSegments; c++) { crossPoints[c] = new Vector3(Mathf.Cos(theta * c), Mathf.Sin(theta * c), 0); } lastCrossSegments = crossSegments; } Vector3[] meshVertices = new Vector3[vertices.Count * crossSegments]; Vector2[] uvs = new Vector2[vertices.Count * crossSegments]; Color[] colors = new Color[vertices.Count * crossSegments]; int[] tris = new int[vertices.Count * crossSegments * 6]; int[] lastVertices = new int[crossSegments]; int[] theseVertices = new int[crossSegments]; Quaternion rotation = Quaternion.identity; for (int p = 0; p < vertices.Count; p++) { if (p < vertices.Count - 1) { rotation = Quaternion.FromToRotation(Vector3.forward, vertices[p + 1].point - vertices[p].point); } for (int c = 0; c < crossSegments; c++) { int vertexIndex = p * crossSegments + c; meshVertices[vertexIndex] = vertices[p].point + rotation * crossPoints[c] * vertices[p].radius; uvs[vertexIndex] = new Vector2((0f + c) / crossSegments, (1f + p) / vertices.Count); float overlifetime = (float)((float)(vertices.Count - 1 - p) / (float)(vertices.Count - 1)); Color color = colorOverLifeTime.Evaluate(overlifetime) * fadeBias; colors[vertexIndex] = color; //vertices[p].color; lastVertices[c] = theseVertices[c]; theseVertices[c] = p * crossSegments + c; } //make triangles if (p > 0) { for (int c = 0; c < crossSegments; c++) { int start = (p * crossSegments + c) * 6; tris[start] = lastVertices[c]; tris[start + 1] = lastVertices[(c + 1) % crossSegments]; tris[start + 2] = theseVertices[c]; tris[start + 3] = tris[start + 2]; tris[start + 4] = tris[start + 1]; tris[start + 5] = theseVertices[(c + 1) % crossSegments]; } } } Mesh mesh = GetComponent <MeshFilter>().mesh; if (!mesh) { mesh = new Mesh(); } mesh.Clear(); mesh.vertices = meshVertices; mesh.triangles = tris; mesh.colors = colors; mesh.RecalculateNormals(); mesh.uv = uvs; } }