Example #1
0
        public static CSGMesh Combine(Vector3 offset, IDictionary<CSGNode, CSGMesh> brushMeshes)
        {
            var planeLookup = new Dictionary<Plane, short>();
            var vertexLookup = new Dictionary<Vector3, short>();

            var planes = new List<Plane>();
            var polygons = new List<Polygon>();
            var edges = new List<HalfEdge>();
            var vertices = new List<Vector3>();

            var bounds = new AABB();

            bounds.Clear();
            int edgeIndex = 0;
            int polygonIndex = 0;
            foreach (var item in brushMeshes)
            {
                var node = item.Key;
                var translation = Vector3.Subtract(node.Translation, offset);
                var mesh = item.Value;
                foreach (var edge in mesh.Edges)
                {
                    short vertexIndex;
                    var vertex = Vector3.Add(mesh.Vertices[edge.VertexIndex], translation);
                    if (!vertexLookup.TryGetValue(vertex, out vertexIndex))
                    {
                        vertexIndex = (short)vertices.Count;
                        vertices.Add(vertex);
                        vertexLookup.Add(vertex, vertexIndex);
                    }

                    var newEdge = new HalfEdge();
                    newEdge.VertexIndex = vertexIndex;
                    newEdge.NextIndex = (short)(edge.NextIndex + edgeIndex);
                    newEdge.TwinIndex = (short)(edge.TwinIndex + edgeIndex);
                    newEdge.PolygonIndex = (short)(edge.PolygonIndex + polygonIndex);

                    edges.Add(newEdge);
                }

                foreach (var polygon in mesh.Polygons)
                {
                    if (polygon.FirstIndex == -1)
                        continue;
                    short planeIndex;
                    var plane = mesh.Planes[polygon.PlaneIndex];
                    if (!planeLookup.TryGetValue(plane, out planeIndex))
                    {
                        planeIndex = (short)planes.Count;
                        planes.Add(plane);
                        planeLookup.Add(plane, planeIndex);
                    }

                    var newPolygon = new Polygon();
                    newPolygon.PlaneIndex = planeIndex;
                    newPolygon.FirstIndex = (short)(polygon.FirstIndex + edgeIndex);
                    newPolygon.Category = polygon.Category;
                    newPolygon.Visible = polygon.Visible;
                    newPolygon.Bounds.Set(polygon.Bounds, translation);

                    polygons.Add(newPolygon);

                    if (newPolygon.Visible)
                    {
                        var first = edges[newPolygon.FirstIndex];
                        var iterator = first;
                        do
                        {
                            bounds.Add(vertices[iterator.VertexIndex]);
                            iterator = edges[iterator.NextIndex];
                        } while (iterator != first);
                    }
                }
                edgeIndex = edges.Count;
                polygonIndex = polygons.Count;
            }
            return new CSGMesh(planes.ToArray(), polygons, edges, vertices, bounds);
        }
Example #2
0
        // Combines multiple meshes into one
        #region Combine
        public static CSGMesh Combine(Vector3 offset, IDictionary <CSGNode, CSGMesh> brushMeshes)
        {
            var planeLookup  = new Dictionary <Plane, short>();
            var vertexLookup = new Dictionary <Vector3, short>();

            var planes   = new List <Plane>();
            var polygons = new List <Polygon>();
            var edges    = new List <HalfEdge>();
            var vertices = new List <Vector3>();

            var bounds = new AABB();

            bounds.Clear();
            int edgeIndex    = 0;
            int polygonIndex = 0;

            foreach (var item in brushMeshes)
            {
                var node        = item.Key;
                var translation = Vector3.Subtract(node.Translation, offset);
                var mesh        = item.Value;
                foreach (var edge in mesh.Edges)
                {
                    short vertexIndex;
                    var   vertex = Vector3.Add(mesh.Vertices[edge.VertexIndex], translation);
                    if (!vertexLookup.TryGetValue(vertex, out vertexIndex))
                    {
                        vertexIndex = (short)vertices.Count;
                        vertices.Add(vertex);
                        vertexLookup.Add(vertex, vertexIndex);
                    }

                    var newEdge = new HalfEdge();
                    newEdge.VertexIndex  = vertexIndex;
                    newEdge.NextIndex    = (short)(edge.NextIndex + edgeIndex);
                    newEdge.TwinIndex    = (short)(edge.TwinIndex + edgeIndex);
                    newEdge.PolygonIndex = (short)(edge.PolygonIndex + polygonIndex);

                    edges.Add(newEdge);
                }

                foreach (var polygon in mesh.Polygons)
                {
                    if (polygon.FirstIndex == -1)
                    {
                        continue;
                    }
                    short planeIndex;
                    var   plane = mesh.Planes[polygon.PlaneIndex];
                    if (!planeLookup.TryGetValue(plane, out planeIndex))
                    {
                        planeIndex = (short)planes.Count;
                        planes.Add(plane);
                        planeLookup.Add(plane, planeIndex);
                    }

                    var newPolygon = new Polygon();
                    newPolygon.PlaneIndex = planeIndex;
                    newPolygon.FirstIndex = (short)(polygon.FirstIndex + edgeIndex);
                    newPolygon.Category   = polygon.Category;
                    newPolygon.Visible    = polygon.Visible;
                    newPolygon.Bounds.Set(polygon.Bounds, translation);

                    polygons.Add(newPolygon);

                    if (newPolygon.Visible)
                    {
                        var first    = edges[newPolygon.FirstIndex];
                        var iterator = first;
                        do
                        {
                            bounds.Add(vertices[iterator.VertexIndex]);
                            iterator = edges[iterator.NextIndex];
                        } while (iterator != first);
                    }
                }
                edgeIndex    = edges.Count;
                polygonIndex = polygons.Count;
            }
            return(new CSGMesh(planes.ToArray(), polygons, edges, vertices, bounds));
        }