/// <summary>Get the verts/ tris/ uv of this in 3D.</summary> public void GetExtrude(Text3D text, int vertIndex, int triIndex, int vertCount, int triCount, float scale, ref float left, ref float top) { // What's the curve accuracy? float accuracy = TextExtrude.CurveAccuracy; if (Characters == null) { return; } // Create a triangulator - it will "select" a letter one at a time: Triangulator triangulator = new Triangulator(text.Vertices, 0, 0); triangulator.Clockwise = TextExtrude.Inverse; for (int c = 0; c < Characters.Length; c++) { Glyph character = Characters[c]; if (character == null || character.Space) { continue; } if (character.Width == 0f) { character.RecalculateMeta(); } if (Kerning != null) { left += Kerning[c] * FontSize; } int frontIndex = vertIndex; // The set of first nodes - these essentially identify where contours start. 0 is always present if there is at least one contour. List <int> firstNodes = new List <int>(); // Compute the vertices: character.GetVertices(text.Vertices, text.Normals, accuracy, left, -top, scale, ref vertIndex, firstNodes); // Duplicate and offset: int count = vertIndex - frontIndex; if (count == 0) { // Ignore continue; } // Future note: // - VectorPath.HoleSort seems to sort letters like i too. // - This results in a count of 1 (we're expecting 2) // - For each contour (foreach firstNodes), triangulate individually. // - Ensure the triangle count matches too. May need to move firstNodes set. // Select these verts in the triangulator: triangulator.Select(frontIndex, count); // Dupe the verts: for (int v = 0; v < count; v++) { Vector3 vert = text.Vertices[frontIndex + v]; vert.z = Extrude; text.Vertices[vertIndex + v] = vert; text.Normals[vertIndex + v] = new Vector3(0f, 0f, 1f); text.Normals[frontIndex + v] = new Vector3(0f, 0f, -1f); } // How many tri's in this char? (single face only) int charTris = count - 2; // Perform triangulation of the front face: triangulator.Triangulate(text.Triangles, charTris, triIndex); // Seek: int triIndexCount = charTris * 3; triIndex += triIndexCount; // Duplicate the results for the back face and invert them: for (int t = 0; t < charTris; t++) { text.Triangles[triIndex] = count + text.Triangles[triIndex - triIndexCount]; triIndex++; // Last two are inverted as the back face looks the other way: text.Triangles[triIndex] = count + text.Triangles[triIndex - triIndexCount + 1]; triIndex++; text.Triangles[triIndex] = count + text.Triangles[triIndex - triIndexCount - 1]; triIndex++; } // Time for the sides! // How many contours? int contourCount = firstNodes.Count; // Get the current first: int currentFirst = firstNodes[0]; int contourIndex = 1; // Get the "next" first: int nextFirst; if (contourCount > 1) { nextFirst = firstNodes[1]; } else { nextFirst = -1; } // Get the back face vertex indices: int backIndex = vertIndex; // For each edge.. for (int i = 0; i < count; i++) { // Get the next index: int next = i + 1; if (next == count || next == nextFirst) { // Loop back instead: next = currentFirst; // Advance to the next one: currentFirst = nextFirst; contourIndex++; // Update nextFirst too: if (contourIndex < contourCount) { nextFirst = firstNodes[contourIndex]; } else { nextFirst = -1; } } // Add two triangles from front face -> back face: text.Triangles[triIndex] = frontIndex + i; triIndex++; text.Triangles[triIndex] = backIndex + i; triIndex++; text.Triangles[triIndex] = backIndex + next; triIndex++; text.Triangles[triIndex] = frontIndex + next; triIndex++; text.Triangles[triIndex] = frontIndex + i; triIndex++; text.Triangles[triIndex] = backIndex + next; triIndex++; } // Seek vert index over the backface: vertIndex += count; // Move left along: left += (character.AdvanceWidth * FontSize) + LetterSpacing; } }