private void addCursorTransform() { knotNormals.Add(cursorTransform.up); knotBinormals.Add(cursorTransform.forward); knotTangents.Add(cursorTransform.right); knotRadius.Add(cursorTransform.GetComponent <ProcShape>().m_Radius); knotLengths.Add(spline.Length()); }
private void addCursorTransform() { knotNormals.Add(cursorTransform.up); knotBinormals.Add(cursorTransform.forward); knotTangents.Add(cursorTransform.right); knotLengths.Add(spline.Length()); ProcSection ps = cursorTransform.GetComponent <ProcSection>(); knotHeight.Add(ps.m_Height); knotWidth.Add(ps.m_Width); knotThickness.Add(ps.m_Thickness); }
public void BuildMeshTrail(Vector3 pos) { // Checks and update the spline path for cursor List <Knot> knots = splineSide.knots; Vector3 point = pos; knots[knots.Count - 1].position = point; knots[knots.Count - 2].position = point; if (Vector3.Distance(knots[knots.Count - 3].position, point) > trackLength && Vector3.Distance(knots[knots.Count - 4].position, point) > trackLength) // point exceeds length path travelled { // add knot and the normals at the point knots.Add(new Knot(point)); splineSide.Parametrize(); knotLengths.Add(splineSide.Length()); knotLengths.RemoveAt(0); CreateMeshTrail(0); // update mesh } }
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; }
private void addCursorTransform() { knotBinormals.Add(cursorTransform.forward * lineCursor.transform.localScale.z); knotLengths.Add(spline.Length()); }
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(); }
// create mesh for LINEAR extrusion public void CreateMeshTrail(Vector3 bn, float nValue, Vector3 normPos) { // throws out previous mesh if nValue is set List <Knot> knots = spline.knots; CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker(); meshBuilder = new MeshBuilder(); Vector3 position = new Vector3(0, 0, 0); // makes points based on the distance segments int begin = 0; int end = (int)(spline.Length() / trackLength); int offset = 5; int totalPoints = end - begin - offset; totalPoints *= 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) { meshBuilder = new MeshBuilder(); spline.PlaceMarker(marker, trackLength * offset); Vector3 diffSide = new Vector3(bn.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!"); } } Vector3 sidePos = Vector3.zero; // iterate through the entire path of the spline for (int j = 0; j < 2; ++j) { if (j == 1) { sidePos = bn; } 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; // build or update mesh if (nValue > -0.01f && nValue < 0.01f) { if (j >= 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, 0, reverse); } } else { Vector3 startPos = Vector3.zero; Vector3 endPos = normPos; if (j >= meshBuilder.Vertices.Count / totalPoints) { BuildQuadSpline(meshBuilder, position, normal, totalPoints, startPos, endPos, 0, reverse); } else { UpdateQuadSpline(meshBuilder, position, normal, totalPoints, startPos, endPos, i - offset, 0, 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 Vector3 startPos = Vector3.zero; Vector3 endPos = bn; 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); Vector3 startTangent = spline.GetTangent(marker); if (nValue < 0) { startTangent *= -1; } spline.PlaceMarker(marker, trackLength * (end - 1)); endPos = spline.GetPosition(marker); BuildQuadSpline(meshBuilder, Vector3.zero, startTangent, 4, startPos, endPos, p, reverse); BuildQuadSpline(meshBuilder, bn, startTangent, 4, startPos, endPos, p, reverse); BuildQuadSpline(meshBuilder, normPos, startTangent, 4, startPos, endPos, p, reverse); BuildQuadSpline(meshBuilder, normPos + bn, startTangent, 4, startPos, endPos, p, reverse); } filter.sharedMesh = meshBuilder.CreateMesh(); }