private IEnumerable <MutableFace> GetBackwardsFaces(MutableSolid solid, float epsilon = 0.001f) { var faces = solid.Faces.ToList(); var origin = GetOrigin(faces); return(faces.Where(x => x.Plane.OnPlane(origin, epsilon) > 0)); }
private void AddAdjacentPoint(MutableFace face, VertexPoint point, MutableSolid solid) { var s = point.MidpointStart.Position; var e = point.MidpointEnd.Position; foreach (var f in solid.Faces.Where(x => x != face)) { var vertList = f.Vertices.ToList(); foreach (var edge in f.GetEdges()) { if (edge.Start == s && edge.End == e) { var idx = vertList.FindIndex(x => x.Position.EquivalentTo(e)); f.Vertices.Insert(idx, new MutableVertex(point.Position)); return; } if (edge.Start == e && edge.End == s) { var idx = vertList.FindIndex(x => x.Position.EquivalentTo(s)); f.Vertices.Insert(idx, new MutableVertex(point.Position)); return; } } } }
private IEnumerable <MutableFace> GetCoplanarFaces(MutableSolid solid) { var faces = solid.Faces.ToList(); return(faces.Where(f1 => faces.Where(f2 => f2 != f1).Any(f2 => f2.Plane == f1.Plane))); }
private async Task Convert(BufferBuilder builder, MapDocument document, MutableSolid solid, ResourceCollector resourceCollector) { var displayFlags = document.Map.Data.GetOne <DisplayFlags>(); var hideNull = displayFlags?.HideNullTextures == true; var faces = solid.Faces.Where(x => x.Vertices.Count > 2).ToList(); // Pack the vertices like this [ f1v1 ... f1vn ] ... [ fnv1 ... fnvn ] var numVertices = (uint)faces.Sum(x => x.Vertices.Count); // Pack the indices like this [ solid1 ... solidn ] [ wireframe1 ... wireframe n ] var numSolidIndices = (uint)faces.Sum(x => (x.Vertices.Count - 2) * 3); var numWireframeIndices = numVertices * 2; var points = new VertexStandard[numVertices]; var indices = new uint[numSolidIndices + numWireframeIndices]; var tint = Color.FromArgb(128, 255, 128).ToVector4(); var tc = await document.Environment.GetTextureCollection(); var vi = 0u; var si = 0u; var wi = numSolidIndices; foreach (var face in faces) { var opacity = tc.GetOpacity(face.Texture.Name); var t = await tc.GetTextureItem(face.Texture.Name); var w = t?.Width ?? 0; var h = t?.Height ?? 0; var tintModifier = new Vector4(1, 1, 1, opacity); var offs = vi; var numFaceVerts = (uint)face.Vertices.Count; var textureCoords = face.GetTextureCoordinates(w, h).ToList(); var normal = face.Plane.Normal; for (var i = 0; i < face.Vertices.Count; i++) { var v = face.Vertices[i]; points[vi++] = new VertexStandard { Position = v.Position, Colour = Vector4.One, Normal = normal, Texture = new Vector2(textureCoords[i].Item2, textureCoords[i].Item3), Tint = tint * tintModifier, Flags = VertexFlags.None }; } // Triangles - [0 1 2] ... [0 n-1 n] for (uint i = 2; i < numFaceVerts; i++) { indices[si++] = offs; indices[si++] = offs + i - 1; indices[si++] = offs + i; } // Lines - [0 1] ... [n-1 n] [n 0] for (uint i = 0; i < numFaceVerts; i++) { indices[wi++] = offs + i; indices[wi++] = offs + (i == numFaceVerts - 1 ? 0 : i + 1); } } var groups = new List <BufferGroup>(); uint texOffset = 0; foreach (var f in faces) { var texInd = (uint)(f.Vertices.Count - 2) * 3; if (hideNull && tc.IsNullTexture(f.Texture.Name)) { texOffset += texInd; continue; } var opacity = tc.GetOpacity(f.Texture.Name); var t = await tc.GetTextureItem(f.Texture.Name); var transparent = opacity < 0.95f || t?.Flags.HasFlag(TextureFlags.Transparent) == true; var texture = t == null ? string.Empty : $"{document.Environment.ID}::{f.Texture.Name}"; groups.Add(transparent ? new BufferGroup(PipelineType.TexturedAlpha, CameraType.Perspective, f.Origin, texture, texOffset, texInd) : new BufferGroup(PipelineType.TexturedOpaque, CameraType.Perspective, texture, texOffset, texInd) ); texOffset += texInd; if (t != null) { resourceCollector.RequireTexture(t.Name); } } groups.Add(new BufferGroup(PipelineType.Wireframe, CameraType.Both, numSolidIndices, numWireframeIndices)); builder.Append(points, indices, groups); }