예제 #1
0
        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]);
        }
예제 #2
0
        public MeshSelection(IMeshSelection source)
            : this()
        {
            for (int i = 0; i < source.Count; i++)
            {
                this.Add(source[i]);
            }

            this.IsClosed = source.IsClosed;
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
        }