public void AddMesh(VectorPath path, float xOffset, float yOffset, Triangulator triangulator) { XOffset = xOffset; YOffset = yOffset; StartIndex = CurrentVertex; // Start triangulator (also clears VC): triangulator.Reset(); // Update triangulator vert offset: triangulator.VertexOffset = CurrentVertex; // Triangulator chain: FirstInContour = null; LastInContour = null; VectorPoint contourStart = path.FirstPathNode; VectorPoint current = contourStart; // Update acc: Triangulator = triangulator; CurrentAccuracy = TextureCameras.Accuracy; Winding = true; while (current != null) { if (current.IsClose || current.Next == null) { // Triangulate current listing: if (FirstInContour != null) { // Triangulate: int triangleCount = triangulator.VertexCount - 2; // Complete the triangulator chain: triangulator.Complete(FirstInContour, LastInContour); #if !TEXT_IS_CLOCKWISE // Text directionality: triangulator.FindWinding(); Winding = triangulator.Clockwise; #endif if (triangleCount > 0) { triangulator.Triangulate(Triangles, triangleCount, CurrentTriangle); CurrentTriangle += triangleCount * 3; } } FirstInContour = null; LastInContour = null; // Add the edges: VectorPoint edge = contourStart; // Reset: Moved = true; CloseBeforeThis = true; // Update acc: Triangulator = null; CurrentAccuracy = TextureCameras.Accuracy; while (edge != null) { if (edge.IsClose || edge.Next == null) { IsClosing = true; CloseX = edge.X; CloseY = edge.Y; } else { IsClosing = false; } if (edge.IsCurve || !edge.HasLine) { // Curves and moveto's edge.ComputeLinePoints(this); } else { if (TextureCameras.SD) { // Add the last point only: AddPoint(edge.X, edge.Y); } else { edge.ComputeLinePoints(this); } } if (IsClosing) { // End of this contour: break; } CloseBeforeThis = false; // Hop to the next one: edge = edge.Next; } // Clear VC: triangulator.VertexCount = 0; // Update triangulator vert offset: triangulator.VertexOffset = CurrentVertex; // Update start: contourStart = current.Next; // Restore acc/ triangulator: Triangulator = triangulator; CurrentAccuracy = TextureCameras.Accuracy; } else if (current.HasLine && current.IsCurve) { current.ComputeLinePoints(this); } else { AddPoint(current.X, current.Y); } // Hop to the next one: current = current.Next; } }
/// <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; } }