Example #1
0
        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;
                    }
                }
            }
        }
Example #3
0
        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)));
        }
Example #4
0
        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);
        }