public static void ExtrudeToCenter(this IMeshBuilder meshBuilder, IMeshSelection meshSelection) { var p = Vector3.zero; for (int i = 0; i < meshSelection.Count; i++) { p += meshBuilder.Vertices[meshSelection[i]]; } p = p / meshSelection.Count; meshBuilder.Vertices.Add(p); meshBuilder.UVs.Add(Vector2.zero); // meshBuilder.Colors.Add(new Color(1f, 1f, 1f, 1f)); for (int i = 0; i < meshSelection.Count - 1; i++) { var i1 = meshSelection[i]; var i2 = meshBuilder.Vertices.Count - 1; var i3 = meshSelection[i + 1]; meshBuilder.AddTriangle(i1, i2, i3); } // Add the final face. meshBuilder.AddTriangle(meshBuilder.Vertices.Count - 2, meshBuilder.Vertices.Count - 1, meshSelection[0]); }
public MeshSelection(IMeshSelection source) : this() { for (int i = 0; i < source.Count; i++) { this.Add(source[i]); } this.IsClosed = source.IsClosed; }
public static void ExtrudeSection( this IMeshBuilder meshBuilder, IMeshSelection currentSelection, int sectionStart, int sectionEnd, Func <int, Vector3, Vector3> extrudeTranslationFunc) { var sectionSelection = currentSelection.SelectRange(sectionStart, sectionEnd); sectionSelection = meshBuilder.ExtrudeEdge( sectionSelection, extrudeTranslationFunc); var origStart = currentSelection.GetAtVirtualIndex(sectionStart); var origEnd = currentSelection.GetAtVirtualIndex(sectionEnd); for (int i = 0; i < sectionSelection.Count; i++) { var currentSelectionIndex = (sectionStart + i).Wrap(currentSelection.Count - 1); currentSelection[currentSelectionIndex] = sectionSelection[i]; } // If the section selection covers the entire current selection, we don't need to // insert any indices to maintain the link back to the current selection. if (origStart == sectionEnd) { return; } if (sectionStart <= sectionEnd) { currentSelection.Insert(origEnd, sectionEnd + 1); currentSelection.Insert(origStart, sectionStart); } else { currentSelection.Insert(origStart, sectionStart); currentSelection.Insert(origEnd, sectionEnd + 1); } }
public static IMeshSelection ExtrudeEdge( this IMeshBuilder meshBuilder, IMeshSelection edge, Func <int, Vector3, Vector3> extrudeTranslationFunc) { Log.Trace("Will extrude edge {0}. Total vertices in mesh = {1}", edge, meshBuilder.Vertices.Count); var lowerEdge = new MeshSelection(edge); var extrudedEdge = new MeshSelection(); // Check if we're dealing with a closed selection loop. var isClosed = lowerEdge.IsClosed; if (isClosed) { Log.Trace("The edge has the same start and end point {0}", lowerEdge[0]); } // Extrude new vertices from the current source vertices. for (int i = 0; i < lowerEdge.Count; i++) { var extrudeIdx = lowerEdge[i]; var p = meshBuilder.Vertices[extrudeIdx]; Log.Trace("extrudeIdx = {0}", extrudeIdx); // TODO: Need to skip duplicate indexes when the start/end range is wrapped. var translation = extrudeTranslationFunc(i, p); var newVertexIdx = meshBuilder.AddVertex(p + translation); extrudedEdge.Add(newVertexIdx); // TODO: This currently assumes the normal won't be changed by the translation. Need fix // support rotation as well. meshBuilder.Normals.Add(meshBuilder.Normals[extrudeIdx]); } if (isClosed) { extrudedEdge.Add(extrudedEdge[0]); } Log.Trace("Building {0} quads", edge.Count); Assert.AreEqual(lowerEdge.Count, extrudedEdge.Count, "Number of extruded indices should match the number of lower indices"); Log.Trace("lowerEdge = {0}", lowerEdge); Log.Trace("extrudedEdge = {0}", extrudedEdge); // Build quads between the start vertices and the extruded vertices, using the virtual // selection which includes the closing vertex index. for (int i = 0; i < lowerEdge.VirtualCount - 1; i++) { var bl = lowerEdge.GetAtVirtualIndex(i); var tl = extrudedEdge.GetAtVirtualIndex(i); var tr = extrudedEdge.GetAtVirtualIndex(i + 1); var br = lowerEdge.GetAtVirtualIndex(i + 1); Log.Trace("Building quad: verts=[{0},{1},{2},{3}], indices=[{4},{5},{6},{7}]", meshBuilder.Vertices[bl], meshBuilder.Vertices[tl], meshBuilder.Vertices[tr], meshBuilder.Vertices[br], bl, tl, tr, br); meshBuilder.AddTriangle(bl, tl, br); meshBuilder.AddTriangle(br, tl, tr); } return(extrudedEdge); }