// Adds vertices to a specified bevel (corner) based on number of bevelSegments void AddBevelVerts(ref Knot cur, Vector3 pos, float startAngle, float stopAngle, GeometryBasis gb, Color32 c) { float midAngle = (startAngle + stopAngle) / 2; Vector3 bevelOrigin = pos + Mathf.Sign(Mathf.Cos(midAngle * Mathf.Deg2Rad)) * gb.widthVectorToBevel + Mathf.Sign(Mathf.Sin(midAngle * Mathf.Deg2Rad)) * gb.thicknessVectorToBevel; // Distance between outer and inset edges float rtInsetOuterDist = (gb.widthVectorToEdge - gb.widthVectorToBevel).magnitude; float upInsetOuterDist = (gb.thicknessVectorToEdge - gb.thicknessVectorToBevel).magnitude; for (int i = 0; i < m_bevelVerts; i++) { float dt = 1f / (m_bevelVerts - 1); // in BevelVerts = 1 case, cannot place a vert at startAngle and stopAngle, // so opt for a single vert (angle-wise) equally between them. float t = (m_bevelVerts == 1) ? (.5f) : (i * dt); Vector3 offset = EllipseOffset(gb.nCrossSectionTangentWidth, rtInsetOuterDist, gb.nCrossSectionTangentThickness, upInsetOuterDist, Mathf.Lerp(startAngle, stopAngle, t)); AppendVertSquare(ref cur, bevelOrigin + offset, c); } }
void AddRingVerts(ref Knot cur, Vector3 pos, GeometryBasis gb) { Color32 c1 = m_Color; Color32 c2 = m_Color; if (m_debugShowSurfaceOrientation) { c1 = Color.blue; c2 = Color.red; } AddBevelVerts(ref cur, pos, 360f, 270f, gb, c1); AddBevelVerts(ref cur, pos, 270f, 180f, gb, c1); AddBevelVerts(ref cur, pos, 180f, 90f, gb, c2); AddBevelVerts(ref cur, pos, 90f, 0f, gb, c2); }
void AddEndCapVerts(ref Knot cur, Vector3 pos, GeometryBasis gb) { AppendVertSquare( ref cur, pos + gb.widthVectorToBevel - gb.thicknessVectorToBevel + gb.capNormalOffset, m_Color); AppendVertSquare( ref cur, pos - gb.widthVectorToBevel - gb.thicknessVectorToBevel + gb.capNormalOffset, m_Color); AppendVertSquare( ref cur, pos - gb.widthVectorToBevel + gb.thicknessVectorToBevel + gb.capNormalOffset, m_Color); AppendVertSquare( ref cur, pos + gb.widthVectorToBevel + gb.thicknessVectorToBevel + gb.capNormalOffset, m_Color); }
void OnChanged_MakeGeometry(int iKnot0) { m_Color.a = m_transparency; Knot prev = m_knots[iKnot0 - 1]; for (int iKnot = iKnot0; iKnot < m_knots.Count; ++iKnot) { Knot cur = m_knots[iKnot]; cur.iTri = prev.iTri + prev.nTri; cur.iVert = (ushort)(prev.iVert + prev.nVert); if (cur.HasGeometry) { cur.nVert = cur.nTri = 0; GeometryBasis curBasis = new GeometryBasis(cur, this); bool isStart = !prev.HasGeometry; bool isEnd = IsPenultimate(iKnot); bool isFlip = AlignmentParityReverses(ref cur, ref prev); // Stroke starting, see CASE 1 if (isStart) { int startCap = 0; int ring0 = startCap + kNumCapVerts; // Add a start cap at the prev knot's pos AddStartCapVerts(ref cur, prev.smoothedPos, curBasis); AddStartCapTris(ref cur, startCap); // Add a ring at the prev knot's pos AddRingVerts(ref cur, prev.smoothedPos, curBasis); AddCapToRingTris(ref cur, ring0, startCap); // Add a ring at the cur knot's pos AddRingVerts(ref cur, cur.smoothedPos, curBasis); AddMiddleRingTris(ref cur, ring0); // Stroke starting and ending, see CASE 2 if (isEnd) { int ring1 = ring0 + m_vertsPerRing; int endCap = ring1 + m_vertsPerRing; // Add an end cap at the cur knot's pos AddEndCapVerts(ref cur, cur.smoothedPos, curBasis); AddCapToRingTris(ref cur, ring1, endCap); AddEndCapTris(ref cur, endCap); } } else { // !start int sharedRing = 0; // Add a ring at the prev knot's pos, albeit virutally (by rewinding to last ring) cur.iVert -= (ushort)m_vertsPerRing; cur.nVert += (ushort)m_vertsPerRing; // Stroke continuing and flipping, see CASE 5 if (isFlip) { GeometryBasis prevBasisCurStrokeTangent = new GeometryBasis( prev, this, manuallySetStrokeTangent: curBasis.nStrokeTangent); // Close off end-face of approaching segment AddRingFaceTris(ref cur, sharedRing, true); // Add a degenerate ring at the prev knot's pos in the cur orientation AddRingVerts(ref cur, prev.smoothedPos, prevBasisCurStrokeTangent); int ring0 = sharedRing + m_vertsPerRing; // Add a ring at the cur knot's pos in the cur orientation (a normal ring) AddRingVerts(ref cur, cur.smoothedPos, curBasis); AddMiddleRingTris(ref cur, ring0); // Stroke ending, see CASE 6 if (isEnd) { int ring1 = ring0 + m_vertsPerRing; int endCap = ring1 + m_vertsPerRing; // Add an end cap at the cur knot's pos AddEndCapVerts(ref cur, cur.smoothedPos, curBasis); AddCapToRingTris(ref cur, ring1, endCap); AddEndCapTris(ref cur, endCap); } // Stroke continuing, see CASE 3 } else { // !flip // Add a ring at the cur knot's pos AddRingVerts(ref cur, cur.smoothedPos, curBasis); AddMiddleRingTris(ref cur, sharedRing); // Stroke ending, see CASE 4 if (isEnd) { int ring0 = sharedRing + m_vertsPerRing; int endCap = ring0 + m_vertsPerRing; // Add an end cap at the cur knot's pos AddEndCapVerts(ref cur, cur.smoothedPos, curBasis); AddCapToRingTris(ref cur, ring0, endCap); AddEndCapTris(ref cur, endCap); } } } } m_knots[iKnot] = cur; prev = cur; } }