Пример #1
0
        private static void UpdateMesh(CSGNode node, CSGNode root)
        {
            //if (node.Left != null) UpdateMesh(node.Left, node);
            //if (node.Right != null) UpdateMesh(node.Right, node);

            var processedNode = node;
            var processedMesh = node.cachedMesh;

            var inputPolygons    = processedMesh.Polygons;
            var insidePolygons   = new List <Polygon>(inputPolygons.Count);
            var outsidePolygons  = new List <Polygon>(inputPolygons.Count);
            var alignedPolygons  = new List <Polygon>(inputPolygons.Count);
            var reversedPolygons = new List <Polygon>(inputPolygons.Count);

            CSGCategorization.Categorize(processedNode,
                                         processedMesh,

                                         root,

                                         inputPolygons, // these are the polygons that are categorized

                                         insidePolygons,
                                         alignedPolygons,
                                         reversedPolygons,
                                         outsidePolygons
                                         );

            // Flag all non aligned polygons as being invisible, and store their categorizations
            // so we can use it if we instance this mesh.
            foreach (var polygon in insidePolygons)
            {
                polygon.Category = PolygonCategory.Inside;
                polygon.Visible  = false;
            }

            foreach (var polygon in outsidePolygons)
            {
                polygon.Category = PolygonCategory.Outside;
                polygon.Visible  = false;
            }

            foreach (var polygon in alignedPolygons)
            {
                polygon.Category = PolygonCategory.Aligned;
            }

            foreach (var polygon in reversedPolygons)
            {
                polygon.Category = PolygonCategory.ReverseAligned;
            }
        }
Пример #2
0
        // We cache our base meshes here
        public static ConcurrentDictionary <CSGNode, CSGMesh> ProcessCSGNodes(CSGNode root, IEnumerable <CSGNode> nodes)
        {
            var meshes    = new ConcurrentDictionary <CSGNode, CSGMesh>();
            var buildMesh =
                (Action <CSGNode>)
                delegate(CSGNode node)
            {
                CSGMesh mesh;

                if (node.cachedMesh == null)
                {
                    // If the node we're performing csg on is a brush, we simply create the geometry from the planes
                    // If the node is a more complicated node, we perform csg on it's child nodes and combine the
                    // meshes that are created.
                    // Note that right now we cache brushes per node, but we can improve on this by caching on
                    // node type instead. Since lots of nodes will have the same geometry in real life and only
                    // need to be created once. It won't help much in runtime performance considering they're
                    // cached anyway, but it'll save on memory usage.
                    if (node.NodeType != CSGNodeType.Brush)
                    {
                        var childNodes  = CSGUtility.FindChildBrushes(node, root.Transformation.Transform);
                        var brushMeshes = ProcessCSGNodes(node, childNodes);
                        mesh = CSGMesh.Combine(node.Translation, brushMeshes);
                    }
                    else
                    {
                        mesh = CSGMesh.CreateFromPlanes(node.Generator.GetPlanes(node.WorldTransformation));
                    }

                    // Cache the mesh
                    node.cachedMesh = mesh;
                }
                else
                {
                    mesh = node.cachedMesh;
                }

                // Clone the cached mesh so we can perform CSG on it.
                var clonedMesh = mesh;                                //.Clone();
                node.Bounds.Set(clonedMesh.Bounds);
                meshes[node] = clonedMesh;
            };

            var updateDelegate =
                (Action <KeyValuePair <CSGNode, CSGMesh> >)
                delegate(KeyValuePair <CSGNode, CSGMesh> item)
            {
                var processedNode = item.Key;
                var processedMesh = item.Value;

                var inputPolygons    = processedMesh.Polygons;
                var insidePolygons   = new List <Polygon>(inputPolygons.Count);
                var outsidePolygons  = new List <Polygon>(inputPolygons.Count);
                var alignedPolygons  = new List <Polygon>(inputPolygons.Count);
                var reversedPolygons = new List <Polygon>(inputPolygons.Count);

                CSGCategorization.Categorize(processedNode,
                                             processedMesh,

                                             root,

                                             inputPolygons,                                                             // these are the polygons that are categorized

                                             insidePolygons,
                                             alignedPolygons,
                                             reversedPolygons,
                                             outsidePolygons
                                             );

                // Flag all non aligned polygons as being invisible, and store their categorizations
                // so we can use it if we instance this mesh.
                foreach (var polygon in insidePolygons)
                {
                    polygon.Category = PolygonCategory.Inside;
                    polygon.Visible  = false;
                }

                foreach (var polygon in outsidePolygons)
                {
                    polygon.Category = PolygonCategory.Outside;
                    polygon.Visible  = false;
                }

                foreach (var polygon in alignedPolygons)
                {
                    polygon.Category = PolygonCategory.Aligned;
                }

                foreach (var polygon in reversedPolygons)
                {
                    polygon.Category = PolygonCategory.ReverseAligned;
                }
            };


            //
            // Here we run build the meshes and perform csg on them either in serial or parallel
            //


            foreach (var node in nodes)
            {
                buildMesh(node);
            }
            CSGUtility.UpdateBounds(root);
            foreach (var item in meshes)
            {
                updateDelegate(item);
            }

            //ProcessNode(root, root);
            //Parallel.ForEach(nodes, ProcessNode);

            //CSGUtility.UpdateBounds(root);
            //UpdateMesh(root, root);

            //Parallel.ForEach(meshes, updateDelegate);

            //*/
            return(meshes);
        }