void RemoveTimeOutPoints() { List <CatmullRomPoint> toRemoveList = new List <CatmullRomPoint>(); for (var i = 0; i < catmullRomPointList.Count; i++) { CatmullRomPoint point = catmullRomPointList[i]; if (Time.realtimeSinceStartup - point.createTime > life_time) { toRemoveList.Add(point); } } for (var i = 0; i < toRemoveList.Count; i++) { CatmullRomPoint point = toRemoveList[i]; catmullRomPointList.Remove(point); } }
public CatmullRomSegment(CatmullRomPoint p0, CatmullRomPoint p1, CatmullRomPoint p2, CatmullRomPoint p3, int subSegmentNum) { this.p0 = p0; this.p1 = p1; this.p2 = p2; this.p3 = p3; this.subSegmentNum = subSegmentNum; length = 0; for (float i = 0; i < subSegmentNum; i++) { var point0 = GetPoint(i / subSegmentNum); var tangent0 = GetTangent(i / subSegmentNum); var createTime0 = Mathf.Lerp(p2.createTime, p3.createTime, i / subSegmentNum); var point1 = GetPoint((i + 1) / subSegmentNum); var tangent1 = GetTangent((i + 1) / subSegmentNum); var createTime1 = Mathf.Lerp(p2.createTime, p3.createTime, (i + 1) / subSegmentNum); var segment = new Segment(new Knot(point0, tangent0, createTime0), new Knot(point1, tangent1, createTime1)); subSegmentList.Add(segment); length += segment.length; } }
public CatmullRomSpline(CatmullRomPoint[] orgPoints, int subSegmentNum) { segment_num = orgPoints.Length - 1; //添加头尾顺延曲线方向的两个点 var list = new List <CatmullRomPoint>(orgPoints); var first = new CatmullRomPoint(2 * orgPoints[0].position - orgPoints[1].position, orgPoints[0].createTime); var last = new CatmullRomPoint( 2 * orgPoints[orgPoints.Length - 1].position - orgPoints[orgPoints.Length - 2].position, orgPoints[orgPoints.Length - 1].createTime); list.Insert(0, first); list.Add(last); this.orgPoints = list.ToArray(); length = 0; for (var i = 1; i <= this.orgPoints.Length - 3; i++) { segmentList.Add(new CatmullRomSegment(this.orgPoints[i - 1], this.orgPoints[i], this.orgPoints[i + 1], this.orgPoints[i + 2], subSegmentNum)); length += segmentList[segmentList.Count - 1].length; } }
void Update() { Vector3 currentPoint = this.transform.position; bool isNeedAddPoint = false; if (catmullRomPointList.Count < 2) { isNeedAddPoint = true; } else { float vertexDistance = (currentPoint - catmullRomPointList[catmullRomPointList.Count - 2].position).magnitude; if (vertexDistance > emissionDistance) { isNeedAddPoint = true; } } if (isNeedAddPoint) { catmullRomPoint = new CatmullRomPoint(currentPoint, Time.realtimeSinceStartup); catmullRomPointList.Add(catmullRomPoint); } else { catmullRomPoint = catmullRomPointList[catmullRomPointList.Count - 1]; catmullRomPoint.position = currentPoint; catmullRomPoint.createTime = Time.realtimeSinceStartup; } RemoveTimeOutPoints(); if (catmullRomPointList.Count < 2) { catmullRomMesh.Clear(); return; } CatmullRomPoint[] catmullRomPoints = catmullRomPointList.ToArray(); catmullRomPoints.Reverse(); spline = new CatmullRomSpline(catmullRomPoints, subdivision); newVerticeList.Clear(); newUVList.Clear(); newTriangleList.Clear(); //float splineLength = Mathf.Max(0, spline.GetLength()-0.1f); float splineLength = Mathf.Max(0, spline.length); int n = 0; bool isAngleDiffBig = false; //用于合并,当角度相差太大的时候,不进行合并 float eachAddDistance = 0.25f * width; //float eachAddDistance = 0.001f * width; for (float distance = 0; distance <= splineLength; distance = distance + eachAddDistance > splineLength ? splineLength : distance + eachAddDistance) { curPoint = spline.GetPointAtDistance(distance); curTangent = spline.GetTangentAtDistance(distance); Vector3 biNormal = CatmullRomSpline.ComputeBinormal(curTangent.position, normal); float timeSpan = Time.realtimeSinceStartup - curPoint.createTime; float lerpHeight = height; //合并相邻两个切线率相差不多的segment // if (n > 1) // { // float lastDistance = distance - width; // lastTangent = spline.GetTangentAtDistance(lastDistance); // float angle = Vector3.Angle(lastTangent.position, curTangent.position); // if (angle <= 0.5f) // { // if (!isAngleDiffBig) // { // for (int i = 0; i < 2; i++) // { // newVerticeList.RemoveLast(); // newUVList.RemoveLast(); // } // for (int i = 0; i < 6; i++) // newTriangleList.RemoveLast(); // n--; // } // else // isAngleDiffBig = false; // } // else // { // isAngleDiffBig = true; // } // } //需要添加epsilonAdd细小的offset,才能显示在mobile手机上,手机上刚好的在摄像机的nearClipPlane上是显示不出来的 Vector3 epsilonAdd = camera.transform.forward * epsilon; newVerticeList.Add(curPoint.position - (biNormal * (lerpHeight * 0.5f)) + epsilonAdd); newVerticeList.Add(curPoint.position + (biNormal * (lerpHeight * 0.5f)) + epsilonAdd); float lerp = 0; if (splineLength < width) //少于width的用正常lerp { lerp = distance / splineLength; } else //大于width的时候特殊处理 { if (distance <= 0.5f * width) //少于0.5f * width的部分占全图片的50% { lerp = 0.5f * (distance / (0.5f * width)); } else //线段的其他部分平分剩下图片的50% { lerp = 0.5f + 0.5f * ((distance - 0.5f * width) / (splineLength - 0.5f * width)); } } newUVList.Add(new Vector2(lerp, 0)); newUVList.Add(new Vector2(lerp, 1)); if (n > 0) { newTriangleList.Add((n * 2) - 2); newTriangleList.Add((n * 2) - 1); newTriangleList.Add(n * 2); newTriangleList.Add((n * 2) + 1); newTriangleList.Add(n * 2); newTriangleList.Add((n * 2) - 1); } if (distance >= splineLength - dd) { break; } if (distance == splineLength) { break; } n++; } catmullRomMesh.Clear(); catmullRomMesh.vertices = newVerticeList.ToArray(); catmullRomMesh.uv = newUVList.ToArray(); catmullRomMesh.triangles = newTriangleList.ToArray(); }