public void CancelTracking() { if (isRunning) { CancelInvoke(); if (knotLengths.Count >= 4) { List <Knot> knots = spline.knots; CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker(); // end cap splineTangent = spline.GetTangent(marker); BuildCap(meshBuilder, lastPosition, lastNormal, lastBinormal, lastTangent, lastRadius, true); BuildCap(meshBuilder, lastPosition, lastNormal, lastBinormal, lastTangent, lastRadius, false); // begin cap float beginDistance = knotLengths[3]; int begin = (int)(beginDistance / trackLength); spline.PlaceMarker(marker, beginDistance); BuildCap(meshBuilder, firstPosition, firstNormal, firstBinormal, firstTangent, firstRadius, true); BuildCap(meshBuilder, firstPosition, firstNormal, firstBinormal, firstTangent, firstRadius, false); //If the MeshFilter exists, attach the new mesh to it. //Assuming the GameObject also has a renderer attached, our new mesh will now be visible in the scene. if (filter != null) { Mesh mesh = meshBuilder.CreateMesh(); // center the mesh properly in 3D world filter.transform.localPosition = filter.transform.TransformPoint(mesh.bounds.center); var vertices = mesh.vertices; for (int i = 0; i < vertices.Length; ++i) { vertices[i] -= mesh.bounds.center; } mesh.vertices = vertices; mesh.RecalculateBounds(); // assigns mesh filter.sharedMesh = mesh; meshCollider.inflateMesh = true; meshCollider.sharedMesh = mesh; //if (FindObjectOfType<EdgeTool>() != null || FindObjectOfType<FaceTool>() != null || FindObjectOfType<HandleTool>() != null) GetComponent<MeshEditor>().GenerateHandles(); } } else { Destroy(filter.gameObject); } isRunning = false; first = true; } }
public bool PlaceMarker(CatmullRomSpline.Marker result, float distance, CatmullRomSpline.Marker from = null) { int nbSegments = this.NbSegments; if (nbSegments == 0) { return(false); } if (distance <= 0f) { result.segmentIndex = 0; result.subKnotAIndex = 0; result.subKnotBIndex = 1; result.lerpRatio = 0f; return(true); } if (distance >= this.Length()) { CatmullRomSpline.SubKnot[] segmentSubKnots = this.GetSegmentSubKnots(nbSegments - 1); result.segmentIndex = nbSegments - 1; result.subKnotAIndex = segmentSubKnots.Length - 2; result.subKnotBIndex = segmentSubKnots.Length - 1; result.lerpRatio = 1f; return(true); } int num = 0; int num2 = 1; if (from != null) { num = from.segmentIndex; } for (int i = num; i < nbSegments; i++) { if (distance <= this.GetSegmentDistanceFromStart(i)) { CatmullRomSpline.SubKnot[] segmentSubKnots = this.GetSegmentSubKnots(i); for (int j = num2; j < segmentSubKnots.Length; j++) { CatmullRomSpline.SubKnot subKnot = segmentSubKnots[j]; if (distance <= subKnot.distanceFromStart) { result.segmentIndex = i; result.subKnotAIndex = j - 1; result.subKnotBIndex = j; result.lerpRatio = 1f - (subKnot.distanceFromStart - distance) / (subKnot.distanceFromStart - segmentSubKnots[j - 1].distanceFromStart); break; } } break; } } return(true); }
public Vector3 GetTangent(CatmullRomSpline.Marker marker) { Vector3 zero = Vector3.zero; if (this.NbSegments == 0) { return(zero); } CatmullRomSpline.SubKnot[] segmentSubKnots = this.GetSegmentSubKnots(marker.segmentIndex); return(Vector3.Lerp(segmentSubKnots[marker.subKnotAIndex].tangent, segmentSubKnots[marker.subKnotBIndex].tangent, marker.lerpRatio)); }
public Vector3 FindTangentFromDistance(float distance) { Vector3 result = Vector3.zero; CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker(); bool flag = this.PlaceMarker(marker, distance, null); if (flag) { result = this.GetTangent(marker); } return(result); }
public void DebugDrawEquallySpacedDots() { Gizmos.color = Color.red; int num = 10 * this.NbSegments; float num2 = this.Length(); CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker(); this.PlaceMarker(marker, 0f, null); for (int i = 0; i <= num; i++) { this.MoveMarker(marker, (float)i * (num2 / (float)num)); Vector3 position = this.GetPosition(marker); Gizmos.DrawWireSphere(position, 0.025f); } }
//Build the mesh: public void BuildMesh() { List <Knot> knots = spline.knots; CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker(); int maxPoint = meshBuilder.Vertices.Count; float distance = 0; Vector3 position = new Vector3(0, 0, 0); Vector3 n = new Vector3(0, 0, 0); Vector3 bn = new Vector3(0, 0, 0); Vector3 t = new Vector3(0, 0, 0); float r = 0; for (int k = 0; k < 3; ++k) { int beginKnot = startKnot + k; int endKnot = startKnot + k + 1; float beginDistance = knotLengths[beginKnot]; float endDistance = knotLengths[endKnot]; int begin = (int)(beginDistance / trackLength); int end = (int)(endDistance / trackLength); float totalLength = endDistance - beginDistance; float nextDistance = end * trackLength; for (int i = begin; i < end; ++i) { if (i != 0 && beginKnot >= 3) { // place the marker at spline to get distance distance = trackLength * i; spline.PlaceMarker(marker, distance); // get the variable needed for the point on spline position = spline.GetPosition(marker); splineTangent = spline.GetTangent(marker); // finds transform for cursor at point in time n = Vector3.Lerp(knotNormals[endKnot], knotNormals[beginKnot], (endDistance - distance) / totalLength); bn = Vector3.Lerp(knotBinormals[endKnot], knotBinormals[beginKnot], (endDistance - distance) / totalLength); t = Vector3.Lerp(knotTangents[endKnot], knotTangents[beginKnot], (endDistance - distance) / totalLength); r = Mathf.Lerp(knotRadius[endKnot], knotRadius[beginKnot], (endDistance - distance) / totalLength); if (first) { first = false; firstPosition = position; firstNormal = n; firstBinormal = bn; firstTangent = t; firstRadius = r; } if (i * (m_RadialSegmentCount + 1) >= maxPoint) { BuildNewShape(position, n, bn, t, r, meshBuilder.Vertices.Count > 0); // add new vertices } else { BuildExistingShape(position, n, bn, t, r, i); // update vertices and normals*/ } } } } ++startKnot; lastPosition = position; lastNormal = n; lastBinormal = bn; lastTangent = t; lastRadius = r; //If the MeshFilter exists, attach the new mesh to it. //Assuming the GameObject also has a renderer attached, our new mesh will now be visible in the scene. if (filter != null) { filter.sharedMesh = meshBuilder.CreateMesh(); } }
private void RenderMesh() { if (advancedParameters.nbSegmentToParametrize == 0) { spline.Parametrize(); } else { spline.Parametrize(spline.NbSegments - advancedParameters.nbSegmentToParametrize, spline.NbSegments); } float length = Mathf.Max(spline.Length() - 0.1f, 0); int nbQuad = ((int)(1f / width * length)) + 1 - quadOffset; if (allocatedNbQuad < nbQuad) //allocate more memory for the mesh { Reallocate(nbQuad); length = Mathf.Max(spline.Length() - 0.1f, 0); nbQuad = ((int)(1f / width * length)) + 1 - quadOffset; } int startingQuad = lastStartingQuad; float lastDistance = startingQuad * width + quadOffset * width; maxInstanciedTriCount = System.Math.Max(maxInstanciedTriCount, (nbQuad - 1) * NbTriIndexPerQuad); Vector3 n = normal; if (dynamicNormalUpdate) { if (n == Vector3.zero) { n = (transform.position - Camera.main.transform.position).normalized; } for (int i = 0; i < normals.Length; i++) { normals[i] = n; } } CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker(); spline.PlaceMarker(marker, lastDistance); Vector3 lastPosition = spline.GetPosition(marker); Vector3 lastTangent = spline.GetTangent(marker); Vector3 lastBinormal = CatmullRomSpline.ComputeBinormal(lastTangent, n); int drawingEnd = meshDisposition == MeshDisposition.Fragmented ? nbQuad - 1 : nbQuad - 1; float startingDist = lastDistance; for (int i = startingQuad; i < drawingEnd; i++) { float distance = lastDistance + width; int firstVertexIndex = i * NbVertexPerQuad; int firstTriIndex = i * NbTriIndexPerQuad; spline.MoveMarker(marker, distance); Vector3 position = spline.GetPosition(marker); Vector3 tangent = spline.GetTangent(marker); Vector3 binormal = CatmullRomSpline.ComputeBinormal(tangent, n); float h = FadeMultiplier(lastDistance, length); float h2 = FadeMultiplier(distance, length); float rh = h * height, rh2 = h2 * height; if (fadeType == FadeType.Alpha || fadeType == FadeType.None) { rh = h > 0 ? height : 0; rh2 = h2 > 0 ? height : 0; } if (meshDisposition == MeshDisposition.Continuous) { vertices[firstVertexIndex] = transform.InverseTransformPoint(lastPosition - origin + (lastBinormal * (rh * 0.5f))); vertices[firstVertexIndex + 1] = transform.InverseTransformPoint(lastPosition - origin + (-lastBinormal * (rh * 0.5f))); vertices[firstVertexIndex + 2] = transform.InverseTransformPoint(position - origin + (binormal * (rh2 * 0.5f))); vertices[firstVertexIndex + 3] = transform.InverseTransformPoint(position - origin + (-binormal * (rh2 * 0.5f))); uv[firstVertexIndex] = new Vector2(lastDistance / height, 1); uv[firstVertexIndex + 1] = new Vector2(lastDistance / height, 0); uv[firstVertexIndex + 2] = new Vector2(distance / height, 1); uv[firstVertexIndex + 3] = new Vector2(distance / height, 0); } else { Vector3 pos = lastPosition + (lastTangent * width * -0.5f) - origin; vertices[firstVertexIndex] = transform.InverseTransformPoint(pos + (lastBinormal * (rh * 0.5f))); vertices[firstVertexIndex + 1] = transform.InverseTransformPoint(pos + (-lastBinormal * (rh * 0.5f))); vertices[firstVertexIndex + 2] = transform.InverseTransformPoint(pos + (lastTangent * width) + (lastBinormal * (rh * 0.5f))); vertices[firstVertexIndex + 3] = transform.InverseTransformPoint(pos + (lastTangent * width) + (-lastBinormal * (rh * 0.5f))); uv[firstVertexIndex] = new Vector2(0, 1); uv[firstVertexIndex + 1] = new Vector2(0, 0); uv[firstVertexIndex + 2] = new Vector2(1, 1); uv[firstVertexIndex + 3] = new Vector2(1, 0); } float relLength = length - startingDist; uv2[firstVertexIndex] = new Vector2((lastDistance - startingDist) / relLength, 1); uv2[firstVertexIndex + 1] = new Vector2((lastDistance - startingDist) / relLength, 0); uv2[firstVertexIndex + 2] = new Vector2((distance - startingDist) / relLength, 1); uv2[firstVertexIndex + 3] = new Vector2((distance - startingDist) / relLength, 0); triangles[firstTriIndex] = firstVertexIndex; triangles[firstTriIndex + 1] = firstVertexIndex + 1; triangles[firstTriIndex + 2] = firstVertexIndex + 2; triangles[firstTriIndex + 3] = firstVertexIndex + 2; triangles[firstTriIndex + 4] = firstVertexIndex + 1; triangles[firstTriIndex + 5] = firstVertexIndex + 3; colors[firstVertexIndex] = vertexColor; colors[firstVertexIndex + 1] = vertexColor; colors[firstVertexIndex + 2] = vertexColor; colors[firstVertexIndex + 3] = vertexColor; if (fadeType == FadeType.Alpha || fadeType == FadeType.Both) { colors[firstVertexIndex].a *= h; colors[firstVertexIndex + 1].a *= h; colors[firstVertexIndex + 2].a *= h2; colors[firstVertexIndex + 3].a *= h2; } lastPosition = position; lastTangent = tangent; lastBinormal = binormal; lastDistance = distance; } for (int i = (nbQuad - 1) * NbTriIndexPerQuad; i < maxInstanciedTriCount; i++) //clear a few tri ahead { triangles[i] = 0; } lastStartingQuad = advancedParameters.lengthToRedraw == 0 ? System.Math.Max(0, nbQuad - ((int)(maxLength / width) + 5)) : System.Math.Max(0, nbQuad - ((int)(advancedParameters.lengthToRedraw / width) + 5)); mesh.Clear(); mesh.vertices = vertices; mesh.uv = uv; mesh.uv2 = uv2; mesh.triangles = triangles; mesh.colors = colors; mesh.normals = normals; }
//Build the mesh: public void UpdateMesh() { List <Knot> knots = spline.knots; CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker(); int maxPoint = meshBuilder.Vertices.Count; Vector3 position = new Vector3(0, 0, 0); Vector3 lastPosition = new Vector3(0, 0, 0); Vector3 t = new Vector3(0, 0, 0); for (int k = 0; k < 3; ++k) { int beginKnot = startKnot + k; int endKnot = startKnot + k + 1; float beginDistance = knotLengths[beginKnot]; float endDistance = knotLengths[endKnot]; int begin = (int)(beginDistance / trackLength); int end = (int)(endDistance / trackLength); float totalLength = endDistance - beginDistance; spline.PlaceMarker(marker, trackLength * begin - 1); lastPosition = spline.GetPosition(marker); for (int i = begin; i < end; ++i) { // place the marker at spline to get distance float distance = trackLength * i; spline.PlaceMarker(marker, distance); // get the variable needed for the point on spline position = spline.GetPosition(marker); // finds transform for cursor at point in time Vector3 bn = Vector3.Lerp(knotBinormals[endKnot], knotBinormals[beginKnot], (endDistance - distance) / totalLength); // find via cross product Vector3 normal = Vector3.Cross(position - lastPosition, bn); Vector3 linePoint = bn * 0.5f; // find points for mesh vertices Vector3 point = position + linePoint; Vector3 point2 = position - linePoint; // build or update mesh if (i * 4 >= maxPoint) { BuildQuad(meshBuilder, point, point2, normal); } else { UpdateQuad(meshBuilder, point, point2, normal, i); } // gets last position lastPosition = position; } } ++startKnot; // creates mesh for filter and renderer CreateMesh(); }
public void CreateMeshTrail() { // creates a new mesh builder for generating mesh meshBuilder = new MeshBuilder(); // find the max count of control points int max = 0; for (int i = 0; i < lineList.Count; ++i) { if (max < lineList[i].Count) { max = lineList[i].Count; } } // redistribute points for lines with smaller number of control points for (int i = 0; i < lineList.Count; ++i) { // if line does not have enough control points if (max > lineList[i].Count) { List <Vector3> l = new List <Vector3>(); float frac1 = 0; float frac2 = 0; int index = 1; // add beginning point l.Add(lineList[i][0]); // interpolate between two points for (int j = 1; j < lineList[i].Count; ++j) { frac1 = (float)index / (max - 1); frac2 = (float)j / (lineList[i].Count - 1); // if the point is distributed between the 2 control point while (frac1 < frac2) { Vector3 diff = (lineList[i][j] - lineList[i][j - 1]); l.Add(lineList[i][j - 1] + diff * frac1); ++index; frac1 = (float)index / (max - 1); } // endpoint of the 2 control point l.Add(lineList[i][j]); ++index; } lineList[i] = l; } } if (smooth) // create smooth sections { List <Vector3> listA; CatmullRomSpline spline; splineList = new List <CatmullRomSpline>(); // generate the splines for (int j = 0; j < lineList[0].Count; ++j) // cycle the jth point of all lines { spline = new CatmullRomSpline(); for (int i = 0; i < lineList.Count; ++i) // cycle through all the lines { listA = lineList[i]; if (i == 0 || i == lineList.Count - 1) { for (int n = 0; n < 3; ++n) { spline.knots.Add(new Knot(listA[j])); } } else { spline.knots.Add(new Knot(listA[j])); } } spline.Parametrize(); splineList.Add(spline); } // find the maxlength for division float maxLength = -1; for (int i = 0; i < splineList.Count; ++i) { if (maxLength < splineList[i].Length()) { maxLength = splineList[i].Length(); } } float trackLength = 0.01f; int maxCount = (int)(maxLength / trackLength); int total = 0; int offset = 1; CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker(); // Render the trail, spline by spline Vector3 posA; Vector3 posB; Vector3 tangentA; Vector3 tangentB; // NOTE: Creates SEPARATE quad spline // Quad 0: spline 0 and spline 1 // Quad 1: spline 1 and spline 2 // Quad 2: spline 2 and spline 3 .. etc for (int i = 0; i < splineList.Count - 1; ++i) { CatmullRomSpline splineA = splineList[i]; CatmullRomSpline splineB = splineList[i + 1]; for (int j = offset; j < maxCount; ++j) { // grab positions and tangents splineA.PlaceMarker(marker, j * splineA.Length() / maxCount); posA = splineA.GetPosition(marker); tangentA = splineA.GetTangent(marker); splineB.PlaceMarker(marker, j * splineB.Length() / maxCount); posB = splineB.GetPosition(marker); tangentB = splineB.GetTangent(marker); // calculate the normals Vector3 normalA = Vector3.Cross((posA - posB), tangentA).normalized; Vector3 normalB = Vector3.Cross(tangentB, (posB - posA)).normalized; // build the splines BuildQuadSpline(meshBuilder, posA, posB, normalA, normalB, total, false); } // update offset for rendering separate quad splines total = meshBuilder.Vertices.Count; } } else // create smooth sections { List <Vector3> listA; List <Vector3> listB; int total = 0; for (int j = 0; j < lineList[0].Count - 1; ++j) { for (int i = 0; i < lineList.Count - 1; ++i) { listA = lineList[i]; listB = lineList[i + 1]; BuildQuad(meshBuilder, listA[j], listB[j], listA[j + 1], listB[j + 1], total); } total = meshBuilder.Vertices.Count; } } BuildMesh(); }
public void MoveMarker(CatmullRomSpline.Marker marker, float distance) { this.PlaceMarker(marker, distance, marker); }
//Build the mesh: public void BuildMesh() { CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker(); int maxPoint = meshBuilder.Vertices.Count; Vector3 position = new Vector3(0, 0, 0); Vector3 t = new Vector3(0, 0, 0); float width = 0; float height = 0; float thickness = 0; for (int k = 0; k < 3; ++k) { int beginKnot = startKnot + k; int endKnot = startKnot + k + 1; float beginDistance = knotLengths[beginKnot]; float endDistance = knotLengths[endKnot]; int begin = (int)(beginDistance / trackLength); int end = (int)(endDistance / trackLength); float totalLength = endDistance - beginDistance; for (int i = begin; i < end; ++i) { if (i != 0 && beginKnot >= 3) { // place the marker at spline to get distance float distance = trackLength * i; spline.PlaceMarker(marker, distance); // get the variable needed for the point on spline position = spline.GetPosition(marker); splineTangent = spline.GetTangent(marker); // finds transform for cursor at point in time Vector3 n = Vector3.Lerp(knotNormals[endKnot], knotNormals[beginKnot], (endDistance - distance) / totalLength); Vector3 bn = Vector3.Lerp(knotBinormals[endKnot], knotBinormals[beginKnot], (endDistance - distance) / totalLength); t = Vector3.Lerp(knotTangents[endKnot], knotTangents[beginKnot], (endDistance - distance) / totalLength); width = Mathf.Lerp(knotWidth[endKnot], knotWidth[beginKnot], (endDistance - distance) / totalLength); height = Mathf.Lerp(knotHeight[endKnot], knotHeight[beginKnot], (endDistance - distance) / totalLength); thickness = Mathf.Lerp(knotThickness[endKnot], knotThickness[beginKnot], (endDistance - distance) / totalLength); if (first) { first = false; firstPosition = position; firstNormal = n; firstBinormal = bn; firstTangent = t; firstWidth = width; firstHeight = height; firstThickness = thickness; } // setup shape for specified section SetupShape(n, bn, t, width, height, thickness); if (i * (shapePoints.Length) >= maxPoint) { BuildNewShape(position, meshBuilder.Vertices.Count > 0); // add new vertices } else { BuildExistingShape(position, i); // update vertices and normals*/ } } } } lastTangent = t; lastPosition = position; ++startKnot; //If the MeshFilter exists, attach the new mesh to it. //Assuming the GameObject also has a renderer attached, our new mesh will now be visible in the scene. if (filter != null) { filter.sharedMesh = meshBuilder.CreateMesh(); } }
private void RenderMesh() { if (this.advancedParameters.nbSegmentToParametrize == 0) { this.spline.Parametrize(); } else { this.spline.Parametrize(this.spline.NbSegments - this.advancedParameters.nbSegmentToParametrize, this.spline.NbSegments); } float num = Mathf.Max(this.spline.Length() - 0.1f, 0f); int num2 = (int)(1f / this.width * num) + 1 - this.quadOffset; if (this.allocatedNbQuad < num2) { this.Reallocate(num2); num = Mathf.Max(this.spline.Length() - 0.1f, 0f); num2 = (int)(1f / this.width * num) + 1 - this.quadOffset; } int num3 = this.lastStartingQuad; float num4 = (float)num3 * this.width + (float)this.quadOffset * this.width; this.maxInstanciedTriCount = Math.Max(this.maxInstanciedTriCount, (num2 - 1) * 6); CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker(); this.spline.PlaceMarker(marker, num4, null); Vector3 a = this.spline.GetPosition(marker); Vector3 vector = this.spline.GetTangent(marker); Vector3 a2 = CatmullRomSpline.ComputeBinormal(vector, this.normal); int num5 = (this.meshDisposition != SplineTrailRenderer.MeshDisposition.Fragmented) ? (num2 - 1) : (num2 - 1); int num6 = this.vertices.Length; int num7 = this.uv.Length; int num8 = this.triangles.Length; int num9 = this.colors.Length; for (int i = num3; i < num5; i++) { float num10 = num4 + this.width; int num11 = i * 4; int num12 = i * 6; this.spline.MoveMarker(marker, num10); Vector3 position = this.spline.GetPosition(marker); Vector3 tangent = this.spline.GetTangent(marker); Vector3 vector2 = CatmullRomSpline.ComputeBinormal(tangent, this.normal); float num13 = this.FadeMultiplier(num4, num); float num14 = this.FadeMultiplier(num10, num); float num15 = num13 * this.height; float num16 = num14 * this.height; if (this.fadeType == SplineTrailRenderer.FadeType.Alpha || this.fadeType == SplineTrailRenderer.FadeType.None) { num15 = ((num13 <= 0f) ? 0f : this.height); num16 = ((num14 <= 0f) ? 0f : this.height); } if (this.meshDisposition == SplineTrailRenderer.MeshDisposition.Continuous) { if (num6 > num11 + 4) { this.vertices[num11] = base.transform.InverseTransformPoint(a - this.origin + a2 * (num15 * 0.5f)); this.vertices[num11 + 1] = base.transform.InverseTransformPoint(a - this.origin + -a2 * (num15 * 0.5f)); this.vertices[num11 + 2] = base.transform.InverseTransformPoint(position - this.origin + vector2 * (num16 * 0.5f)); this.vertices[num11 + 3] = base.transform.InverseTransformPoint(position - this.origin + -vector2 * (num16 * 0.5f)); } if (num7 > num11 + 4) { this.uv[num11] = new Vector2(num4 / this.height, 1f); this.uv[num11 + 1] = new Vector2(num4 / this.height, 0f); this.uv[num11 + 2] = new Vector2(num10 / this.height, 1f); this.uv[num11 + 3] = new Vector2(num10 / this.height, 0f); } } else { Vector3 a3 = a + vector * this.width * -0.5f - this.origin; if (num6 > num11 + 4) { this.vertices[num11] = base.transform.InverseTransformPoint(a3 + a2 * (num15 * 0.5f)); this.vertices[num11 + 1] = base.transform.InverseTransformPoint(a3 + -a2 * (num15 * 0.5f)); this.vertices[num11 + 2] = base.transform.InverseTransformPoint(a3 + vector * this.width + a2 * (num15 * 0.5f)); this.vertices[num11 + 3] = base.transform.InverseTransformPoint(a3 + vector * this.width + -a2 * (num15 * 0.5f)); } if (num7 > num11 + 4) { this.uv[num11] = new Vector2(0f, 1f); this.uv[num11 + 1] = new Vector2(0f, 0f); this.uv[num11 + 2] = new Vector2(1f, 1f); this.uv[num11 + 3] = new Vector2(1f, 0f); } } if (num8 > num12 + 6) { this.triangles[num12] = num11; this.triangles[num12 + 1] = num11 + 1; this.triangles[num12 + 2] = num11 + 2; this.triangles[num12 + 3] = num11 + 2; this.triangles[num12 + 4] = num11 + 1; this.triangles[num12 + 5] = num11 + 3; } if (num9 > num11 + 4) { this.colors[num11] = this.vertexColor; this.colors[num11 + 1] = this.vertexColor; this.colors[num11 + 2] = this.vertexColor; this.colors[num11 + 3] = this.vertexColor; } if ((this.fadeType == SplineTrailRenderer.FadeType.Alpha || this.fadeType == SplineTrailRenderer.FadeType.Both) && num9 > num11 + 4) { Color[] expr_6F0_cp_0 = this.colors; int expr_6F0_cp_1 = num11; expr_6F0_cp_0[expr_6F0_cp_1].a = expr_6F0_cp_0[expr_6F0_cp_1].a * num13; Color[] expr_70D_cp_0 = this.colors; int expr_70D_cp_1 = num11 + 1; expr_70D_cp_0[expr_70D_cp_1].a = expr_70D_cp_0[expr_70D_cp_1].a * num13; Color[] expr_72A_cp_0 = this.colors; int expr_72A_cp_1 = num11 + 2; expr_72A_cp_0[expr_72A_cp_1].a = expr_72A_cp_0[expr_72A_cp_1].a * num14; Color[] expr_747_cp_0 = this.colors; int expr_747_cp_1 = num11 + 3; expr_747_cp_0[expr_747_cp_1].a = expr_747_cp_0[expr_747_cp_1].a * num14; } a = position; vector = tangent; a2 = vector2; num4 = num10; } for (int j = (num2 - 1) * 6; j < this.maxInstanciedTriCount; j++) { if (j < this.triangles.Length) { this.triangles[j] = 0; } } this.lastStartingQuad = ((this.advancedParameters.lengthToRedraw != 0f) ? Math.Max(0, num2 - ((int)(this.advancedParameters.lengthToRedraw / this.width) + 5)) : Math.Max(0, num2 - ((int)(this.maxLength / this.width) + 5))); this.mesh.Clear(); this.mesh.vertices = this.vertices; this.mesh.uv = this.uv; this.mesh.triangles = this.triangles; this.mesh.colors = this.colors; this.mesh.normals = this.normals; }
public void RenderMesh() { if (advancedParameters.nbSegmentToParametrize == 0) spline.Parametrize (); else spline.Parametrize (spline.NbSegments - advancedParameters.nbSegmentToParametrize, spline.NbSegments); float length = Mathf.Max (spline.Length () - 0.1f, 0); int nbQuad = ((int)(1f / width * length)) + 1 - quadOffset; if (allocatedNbQuad < nbQuad) { //allocate more memory for the mesh Reallocate (nbQuad); length = Mathf.Max (spline.Length () - 0.1f, 0); nbQuad = ((int)(1f / width * length)) + 1 - quadOffset; } int startingQuad = lastStartingQuad; float lastDistance = startingQuad * width + quadOffset * width; maxInstanciedTriCount = System.Math.Max (maxInstanciedTriCount, (nbQuad - 1) * NbTriIndexPerQuad); Vector3 n = normal; if (dynamicNormalUpdate) { if (n == Vector3.zero) { n = (transform.position - Camera.main.transform.position).normalized; } for (int i=0; i<normals.Length; i++) { normals [i] = n; } } CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker (); spline.PlaceMarker (marker, lastDistance); Vector3 lastPosition = spline.GetPosition (marker); Vector3 lastTangent = spline.GetTangent (marker); Vector3 lastBinormal = CatmullRomSpline.ComputeBinormal (lastTangent, n); int drawingEnd = meshDisposition == MeshDisposition.Fragmented ? nbQuad - 1 : nbQuad - 1; float startingDist = lastDistance; for (int i=startingQuad; i<drawingEnd; i++) { float distance = lastDistance + width; int firstVertexIndex = i * NbVertexPerQuad; int firstTriIndex = i * NbTriIndexPerQuad; spline.MoveMarker (marker, distance); Vector3 position = spline.GetPosition (marker); Vector3 tangent = spline.GetTangent (marker); Vector3 binormal = CatmullRomSpline.ComputeBinormal (tangent, n); float h = FadeMultiplier (lastDistance, length); float h2 = FadeMultiplier (distance, length); float rh = h * height, rh2 = h2 * height; if (fadeType == FadeType.Alpha || fadeType == FadeType.None) { rh = h > 0 ? height : 0; rh2 = h2 > 0 ? height : 0; } if (meshDisposition == MeshDisposition.Continuous) { vertices [firstVertexIndex] = transform.InverseTransformPoint (lastPosition - origin + (lastBinormal * (rh * 0.5f))); vertices [firstVertexIndex + 1] = transform.InverseTransformPoint (lastPosition - origin + (-lastBinormal * (rh * 0.5f))); vertices [firstVertexIndex + 2] = transform.InverseTransformPoint (position - origin + (binormal * (rh2 * 0.5f))); vertices [firstVertexIndex + 3] = transform.InverseTransformPoint (position - origin + (-binormal * (rh2 * 0.5f))); uv [firstVertexIndex] = new Vector2 (lastDistance / height, 1); uv [firstVertexIndex + 1] = new Vector2 (lastDistance / height, 0); uv [firstVertexIndex + 2] = new Vector2 (distance / height, 1); uv [firstVertexIndex + 3] = new Vector2 (distance / height, 0); } else { Vector3 pos = lastPosition + (lastTangent * width * -0.5f) - origin; vertices [firstVertexIndex] = transform.InverseTransformPoint (pos + (lastBinormal * (rh * 0.5f))); vertices [firstVertexIndex + 1] = transform.InverseTransformPoint (pos + (-lastBinormal * (rh * 0.5f))); vertices [firstVertexIndex + 2] = transform.InverseTransformPoint (pos + (lastTangent * width) + (lastBinormal * (rh * 0.5f))); vertices [firstVertexIndex + 3] = transform.InverseTransformPoint (pos + (lastTangent * width) + (-lastBinormal * (rh * 0.5f))); uv [firstVertexIndex] = new Vector2 (0, 1); uv [firstVertexIndex + 1] = new Vector2 (0, 0); uv [firstVertexIndex + 2] = new Vector2 (1, 1); uv [firstVertexIndex + 3] = new Vector2 (1, 0); } float relLength = length - startingDist; uv2 [firstVertexIndex] = new Vector2 ((lastDistance - startingDist) / relLength, 1); uv2 [firstVertexIndex + 1] = new Vector2 ((lastDistance - startingDist) / relLength, 0); uv2 [firstVertexIndex + 2] = new Vector2 ((distance - startingDist) / relLength, 1); uv2 [firstVertexIndex + 3] = new Vector2 ((distance - startingDist) / relLength, 0); triangles [firstTriIndex] = firstVertexIndex; triangles [firstTriIndex + 1] = firstVertexIndex + 1; triangles [firstTriIndex + 2] = firstVertexIndex + 2; triangles [firstTriIndex + 3] = firstVertexIndex + 2; triangles [firstTriIndex + 4] = firstVertexIndex + 1; triangles [firstTriIndex + 5] = firstVertexIndex + 3; colors [firstVertexIndex] = vertexColor; colors [firstVertexIndex + 1] = vertexColor; colors [firstVertexIndex + 2] = vertexColor; colors [firstVertexIndex + 3] = vertexColor; if (fadeType == FadeType.Alpha || fadeType == FadeType.Both) { colors [firstVertexIndex].a *= h; colors [firstVertexIndex + 1].a *= h; colors [firstVertexIndex + 2].a *= h2; colors [firstVertexIndex + 3].a *= h2; } lastPosition = position; lastTangent = tangent; lastBinormal = binormal; lastDistance = distance; } for (int i=(nbQuad-1)*NbTriIndexPerQuad; i<maxInstanciedTriCount; i++) //clear a few tri ahead triangles [i] = 0; lastStartingQuad = advancedParameters.lengthToRedraw == 0 ? System.Math.Max (0, nbQuad - ((int)(maxLength / width) + 5)) : System.Math.Max (0, nbQuad - ((int)(advancedParameters.lengthToRedraw / width) + 5)); mesh.Clear (); mesh.vertices = vertices; mesh.uv = uv; mesh.uv2 = uv2; mesh.triangles = triangles; mesh.colors = colors; mesh.normals = normals; }
// create mesh for curved extrusion public void CreateMeshTrail(float nValue) { // throws out previous mesh if nValue is set List <Knot> knots = spline.knots; CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker(); CatmullRomSpline.Marker markerSide = new CatmullRomSpline.Marker(); int maxPoint = meshBuilder.Vertices.Count; Vector3 position = new Vector3(0, 0, 0); Vector3 sidePos = new Vector3(0, 0, 0); Vector3 normPos = new Vector3(0, 0, 1f) * nValue; // makes points based on the distance segments int begin = 0; int end = (int)(spline.Length() / trackLength); int beginSide = (int)(knotLengths[0] / trackLength); int endSide = (int)(splineSide.Length() / trackLength); int offset = 5; int totalPoints = end - begin - offset; int totalPointsSide = (int)(splineSide.Length() / trackLength) - begin - offset; totalPoints *= 2; totalPointsSide *= 2; // IMPORTANT!!! : DEPENDS UPON THE CONSTRAINTS // calculates the normal in order to determine the render direction // place the marker at spline to get distance bool reverse = true; // Restarts rendering if a volume is being generated if (nValue <= -0.01f || nValue >= 0.01f) { beginSide = 0; meshBuilder = new MeshBuilder(); spline.PlaceMarker(marker, trackLength * offset); splineSide.PlaceMarker(markerSide, 0); Vector3 diffSide = splineSide.GetPosition(markerSide); splineSide.PlaceMarker(markerSide, trackLength * (endSide - 1)); diffSide -= splineSide.GetPosition(markerSide); diffSide = new Vector3(diffSide.x, 0, 0); print("Normal: " + normPos); print("Tangent: " + spline.GetTangent(marker)); print("Side: " + diffSide); print("Cross: " + Vector3.Cross(spline.GetTangent(marker), normPos)); reverse = (Vector3.Dot(Vector3.Cross(spline.GetTangent(marker), normPos), diffSide) > 0); if (reverse) { print("REVERSE!"); } else { print("FORWARD!"); } } beginSide = (offset > beginSide) ? offset : beginSide; // iterate through the entire path of the spline for (int j = beginSide; j < endSide; ++j) { // place the marker at spline to get distance splineSide.PlaceMarker(marker, trackLength * j); sidePos = splineSide.GetPosition(marker); Vector3 sideTangent = splineSide.GetTangent(marker); for (int i = begin + offset; i < end; ++i) { // place the marker at spline to get distance spline.PlaceMarker(marker, trackLength * i); // get the variable needed for the point on spline position = spline.GetPosition(marker) + sidePos; Vector3 tangent = spline.GetTangent(marker); Vector3 normal = normPos.normalized; // build or update mesh if (nValue > -0.01f && nValue < 0.01f) { if ((j - offset) >= meshBuilder.Vertices.Count / totalPoints) { BuildQuadSpline(meshBuilder, position, normal, totalPoints, Vector3.zero, Vector3.zero, 0, reverse); } else { UpdateQuadSpline(meshBuilder, position, normal, totalPoints, Vector3.zero, Vector3.zero, i - offset, j - offset, reverse); } } else { Vector3 startPos = Vector3.zero; Vector3 endPos = normPos; if ((j - offset) >= meshBuilder.Vertices.Count / totalPoints) { BuildQuadSpline(meshBuilder, position, normal, totalPoints, startPos, endPos, 0, reverse); } else { UpdateQuadSpline(meshBuilder, position, normal, totalPoints, startPos, endPos, i - offset, j - offset, reverse); } } } } // detect if there is a structure or not if (nValue <= -0.01f || nValue >= 0.01f) { int p = meshBuilder.Vertices.Count; // build sides out of the spline splineSide.PlaceMarker(marker, trackLength * offset); Vector3 startPos = splineSide.GetPosition(marker); splineSide.PlaceMarker(marker, trackLength * (endSide - 1)); Vector3 endPos = splineSide.GetPosition(marker); for (int j = 0; j < 2; ++j) { for (int i = begin + offset; i < end; ++i) { // place the marker at spline to get distance spline.PlaceMarker(marker, trackLength * i); // get the variable needed for the point on spline position = spline.GetPosition(marker); if (j == 1) { position += normPos; } Vector3 tangent = spline.GetTangent(marker); Vector3 normal = Vector3.Cross(tangent, normPos).normalized; BuildQuadSpline(meshBuilder, position, normal, totalPoints, endPos, startPos, p, reverse); } } p = meshBuilder.Vertices.Count; // build caps out of the side spline spline.PlaceMarker(marker, trackLength * offset); startPos = spline.GetPosition(marker); spline.PlaceMarker(marker, trackLength * (end - 1)); endPos = spline.GetPosition(marker); for (int j = 0; j < 2; ++j) { for (int i = begin + offset; i < endSide; ++i) { // place the marker at spline to get distance splineSide.PlaceMarker(marker, trackLength * i); // get the variable needed for the point on spline position = splineSide.GetPosition(marker); if (j == 1) { position += normPos; } Vector3 tangent = splineSide.GetTangent(marker); Vector3 normal = Vector3.Cross(tangent, normPos).normalized; BuildQuadSpline(meshBuilder, position, normal, totalPointsSide, startPos, endPos, p, reverse); } } } filter.sharedMesh = meshBuilder.CreateMesh(); }