示例#1
0
        public List <Segment> FindSegments(MyVoxelSegmentationType segmentationType = 2, int mergeIterations = 1)
        {
            this.m_segments.Clear();
            switch (segmentationType)
            {
            case MyVoxelSegmentationType.ExtraSimple:
                this.CreateSegmentsExtraSimple();
                break;

            case MyVoxelSegmentationType.Simple:
                this.CreateSegmentsSimple();
                break;

            case MyVoxelSegmentationType.Simple2:
                this.CreateSegmentsSimple2();
                break;

            default:
                this.CreateSegments(segmentationType == MyVoxelSegmentationType.Fast);
                this.m_segments.Sort(new SegmentSizeComparer());
                this.RemoveFullyContainedOptimized();
                this.ClipSegments();
                for (int i = 0; i < mergeIterations; i++)
                {
                    this.MergeSegments();
                }
                break;
            }
            return(this.m_segments);
        }
示例#2
0
 public void Collect(MyCubeGrid grid, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType, IDictionary <Vector3I, HkMassElement> massResults)
 {
     foreach (MySlimBlock block in grid.GetBlocks())
     {
         if (block.FatBlock is MyCompoundCubeBlock)
         {
             this.CollectCompoundBlock((MyCompoundCubeBlock)block.FatBlock, massResults);
             continue;
         }
         this.CollectBlock(block, block.BlockDefinition.PhysicsOption, massResults, true);
     }
     this.AddSegmentedParts(grid.GridSize, segmenter, segmentationType);
     this.m_tmpCubes.Clear();
 }
示例#3
0
        /// <summary>
        /// Creates segments from voxel data.
        /// </summary>
        /// <param name="filledVoxels">Positions on filled voxels (or one material).</param>
        /// <param name="mergeIterations">Number of post-process merge iterations, one should be always sufficient, algorithm works pretty well with 0 too.</param>
        /// <param name="fastMethod">Fast method is about 3x faster, but prefers longer boxes instead of cubic and generates about 5 - 10% more segments.</param>
        /// <returns>List of segments.</returns>
        public List <Segment> FindSegments(MyVoxelSegmentationType segmentationType = MyVoxelSegmentationType.Optimized, int mergeIterations = 1)
        {
            m_segments.Clear();
            switch (segmentationType)
            {
            case MyVoxelSegmentationType.Simple:
                ProfilerShort.Begin("Create segments");
                CreateSegmentsSimple();
                ProfilerShort.End();
                break;

            case MyVoxelSegmentationType.Simple2:
                ProfilerShort.Begin("Create segments");
                CreateSegmentsSimple2();
                ProfilerShort.End();
                break;

            case MyVoxelSegmentationType.ExtraSimple:
                ProfilerShort.Begin("Create simple segments");
                CreateSegmentsExtraSimple();
                ProfilerShort.End();
                break;

            default:
                ProfilerShort.Begin("Create segments");
                CreateSegments(segmentationType == MyVoxelSegmentationType.Fast);
                ProfilerShort.End();
                ProfilerShort.Begin("Sort segments");
                m_segments.Sort(new SegmentSizeComparer());
                ProfilerShort.End();
                ProfilerShort.Begin("Remove fully contained");
                RemoveFullyContainedOptimized();
                ProfilerShort.End();
                ProfilerShort.Begin("Clip segments");
                ClipSegments();
                ProfilerShort.End();

                ProfilerShort.Begin("Merge segments");
                for (int i = 0; i < mergeIterations; i++)
                {
                    MergeSegments();     // Very optional
                }
                ProfilerShort.End();
                break;
            }

            return(m_segments);
        }
        void AddSegmentedParts(float gridSize, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType)
        {
            if (segmenter != null)
            {
                int mergeIterations = segmentationType == MyVoxelSegmentationType.Optimized ? 1 : 0;
                //SegmenterBenchmark(collector, segmenter, mergeIterations);

                ProfilerShort.Begin("Prepare segmentation");
                segmenter.ClearInput();
                foreach (var cube in m_tmpCubes)
                {
                    segmenter.AddInput(cube);
                }
                ProfilerShort.End();

                ProfilerShort.Begin("Make segments");
                var segments = segmenter.FindSegments(segmentationType, mergeIterations);
                ProfilerShort.End();

                ProfilerShort.Begin("Add segments");
                foreach (var s in segments)
                {
                    Vector3 min = s.Min * gridSize - new Vector3(gridSize / 2.0f);
                    Vector3 max = s.Max * gridSize + new Vector3(gridSize / 2.0f);
                    AddBox(s.Min, s.Max, ref min, ref max);
                }
                ProfilerShort.End();
            }
            else
            {
                ProfilerShort.Begin("Add full cubes");
                foreach (var c in m_tmpCubes)
                {
                    Vector3 min = c * gridSize - new Vector3(gridSize / 2.0f);
                    Vector3 max = c * gridSize + new Vector3(gridSize / 2.0f);
                    AddBox(c, c, ref min, ref max);
                }
                ProfilerShort.End();
            }
        }
        public void Collect(MyCubeGrid grid, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType, IDictionary <Vector3I, HkMassElement> massResults)
        {
            foreach (var block in grid.GetBlocks())
            {
                if (block.FatBlock is MyCompoundCubeBlock)
                {
                    CollectCompoundBlock((MyCompoundCubeBlock)block.FatBlock, massResults);
                    Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap!");
                }
                else
                {
                    CollectBlock(block, block.BlockDefinition.PhysicsOption, massResults);
                    Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap!");
                }
            }

            AddSegmentedParts(grid.GridSize, segmenter, segmentationType);
            m_tmpCubes.Clear();

            Debug.Assert(Shapes.Count > 0, "Shape count cannot be zero");
            Debug.Assert(massResults == null || massResults.Count > 0, "No mass elements, something is wrong!");
        }
        /// <summary>
        /// Intended for quite small refreshes (few blocks).
        /// Collect is faster for large refresh.
        /// Removes also dirty mass elements.
        /// </summary>
        public void CollectArea(MyCubeGrid grid, HashSet <Vector3I> dirtyBlocks, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType, IDictionary <Vector3I, HkMassElement> massResults)
        {
            ProfilerShort.Begin("Remove dirty");
            foreach (var pos in dirtyBlocks)
            {
                if (massResults != null)
                {
                    massResults.Remove(pos);
                }

                var block = grid.GetCubeBlock(pos);
                if (block != null)
                {
                    m_tmpRefreshSet.Add(block);
                }
            }
            ProfilerShort.End();

            ProfilerShort.Begin("Add new");
            foreach (var block in m_tmpRefreshSet)
            {
                if (block.FatBlock is MyCompoundCubeBlock)
                {
                    ProfilerShort.Begin("Collect compound");
                    CollectCompoundBlock((MyCompoundCubeBlock)block.FatBlock, massResults);
                    //Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap!");
                    ProfilerShort.End();
                }
                else
                {
                    ProfilerShort.Begin("Collect block");
                    CollectBlock(block, block.BlockDefinition.PhysicsOption, massResults);
                    //Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap!");
                    ProfilerShort.End();
                }
            }
            ProfilerShort.End();

            ProfilerShort.Begin("IsValidTest");
            Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap! Uncomment upper asserts to find what block caused this");
            ProfilerShort.End();

            ProfilerShort.Begin("Add segments");
            AddSegmentedParts(grid.GridSize, segmenter, segmentationType);
            ProfilerShort.End();

            m_tmpCubes.Clear();
            m_tmpRefreshSet.Clear(); // Clear is required, we certainly don't want to hold last reference to blocks
        }
示例#7
0
 public void CollectArea(MyCubeGrid grid, HashSet <Vector3I> dirtyBlocks, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType, IDictionary <Vector3I, HkMassElement> massResults)
 {
     using (MyUtils.ReuseCollection <MySlimBlock>(ref this.m_tmpRefreshSet))
     {
         foreach (Vector3I vectori in dirtyBlocks)
         {
             if (massResults != null)
             {
                 massResults.Remove(vectori);
             }
             MySlimBlock cubeBlock = grid.GetCubeBlock(vectori);
             if (cubeBlock != null)
             {
                 this.m_tmpRefreshSet.Add(cubeBlock);
             }
         }
         foreach (MySlimBlock block2 in this.m_tmpRefreshSet)
         {
             this.CollectBlock(block2, block2.BlockDefinition.PhysicsOption, massResults, true);
         }
         this.AddSegmentedParts(grid.GridSize, segmenter, segmentationType);
         this.m_tmpCubes.Clear();
     }
 }
示例#8
0
        private unsafe void AddSegmentedParts(float gridSize, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType)
        {
            int     num    = (int)Math.Floor((double)(40f / gridSize));
            Vector3 vector = new Vector3(gridSize * 0.5f);

            if (segmenter != null)
            {
                int mergeIterations = (segmentationType == MyVoxelSegmentationType.Optimized) ? 1 : 0;
                segmenter.ClearInput();
                foreach (Vector3I vectori3 in this.m_tmpCubes)
                {
                    segmenter.AddInput(vectori3);
                }
                foreach (MyVoxelSegmentation.Segment segment in segmenter.FindSegments(segmentationType, mergeIterations))
                {
                    Vector3I vectori;
                    vectori.X = segment.Min.X;
                    while (vectori.X <= segment.Max.X)
                    {
                        vectori.Y = segment.Min.Y;
                        while (true)
                        {
                            if (vectori.Y > segment.Max.Y)
                            {
                                int *numPtr3 = (int *)ref vectori.X;
                                numPtr3[0] += num;
                                break;
                            }
                            vectori.Z = segment.Min.Z;
                            while (true)
                            {
                                if (vectori.Z > segment.Max.Z)
                                {
                                    int *numPtr2 = (int *)ref vectori.Y;
                                    numPtr2[0] += num;
                                    break;
                                }
                                Vector3I maxPos = Vector3I.Min((Vector3I)((vectori + num) - 1), segment.Max);
                                Vector3  min    = ((Vector3)(vectori * gridSize)) - vector;
                                Vector3  max    = (maxPos * gridSize) + vector;
                                this.AddBox(vectori, maxPos, ref min, ref max);
                                int *numPtr1 = (int *)ref vectori.Z;
                                numPtr1[0] += num;
                            }
                        }
                    }
                }
            }
            else
            {
                foreach (Vector3I vectori4 in this.m_tmpCubes)
                {
                    Vector3 min = ((Vector3)(vectori4 * gridSize)) - vector;
                    Vector3 max = (vectori4 * gridSize) + vector;
                    this.AddBox(vectori4, vectori4, ref min, ref max);
                }
            }
        }
        public void Collect(MyCubeGrid grid, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType, IDictionary<Vector3I, HkMassElement> massResults)
        {
            foreach (var block in grid.GetBlocks())
            {
                if (block.FatBlock is MyCompoundCubeBlock)
                {
                    CollectCompoundBlock((MyCompoundCubeBlock)block.FatBlock, massResults);
                    Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap!");
                }
                else
                {
                    CollectBlock(block, block.BlockDefinition.PhysicsOption, massResults);
                    Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap!");
                }
            }

            AddSegmentedParts(grid.GridSize, segmenter, segmentationType);
            m_tmpCubes.Clear();

            Debug.Assert(Shapes.Count > 0, "Shape count cannot be zero");
            Debug.Assert(massResults == null || massResults.Count > 0, "No mass elements, something is wrong!");
        }
        void AddSegmentedParts(float gridSize, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType)
        {
            if (segmenter != null)
            {
                int mergeIterations = segmentationType == MyVoxelSegmentationType.Optimized ? 1 : 0;
                //SegmenterBenchmark(collector, segmenter, mergeIterations);

                ProfilerShort.Begin("Prepare segmentation");
                segmenter.ClearInput();
                foreach (var cube in m_tmpCubes)
                {
                    segmenter.AddInput(cube);
                }
                ProfilerShort.End();

                ProfilerShort.Begin("Make segments");
                var segments = segmenter.FindSegments(segmentationType, mergeIterations);
                ProfilerShort.End();

                ProfilerShort.Begin("Add segments");
                foreach (var s in segments)
                {
                    Vector3 min = s.Min * gridSize - new Vector3(gridSize / 2.0f);
                    Vector3 max = s.Max * gridSize + new Vector3(gridSize / 2.0f);
                    AddBox(s.Min, s.Max, ref min, ref max);
                }
                ProfilerShort.End();
            }
            else
            {
                ProfilerShort.Begin("Add full cubes");
                foreach (var c in m_tmpCubes)
                {
                    Vector3 min = c * gridSize - new Vector3(gridSize / 2.0f);
                    Vector3 max = c * gridSize + new Vector3(gridSize / 2.0f);
                    AddBox(c, c, ref min, ref max);
                }
                ProfilerShort.End();
            }
        }
        /// <summary>
        /// Intended for quite small refreshes (few blocks).
        /// Collect is faster for large refresh.
        /// Removes also dirty mass elements.
        /// </summary>
        public void CollectArea(MyCubeGrid grid, HashSet<Vector3I> dirtyBlocks, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType, IDictionary<Vector3I, HkMassElement> massResults)
        {
            ProfilerShort.Begin("Remove dirty");
            foreach (var pos in dirtyBlocks)
            {
                if(massResults != null)
                    massResults.Remove(pos);

                var block = grid.GetCubeBlock(pos);
                if (block != null)
                {
                    m_tmpRefreshSet.Add(block);
                }
            }
            ProfilerShort.End();

            ProfilerShort.Begin("Add new");
            foreach (var block in m_tmpRefreshSet)
            {
                if (block.FatBlock is MyCompoundCubeBlock)
                {
                    ProfilerShort.Begin("Collect compound");
                    CollectCompoundBlock((MyCompoundCubeBlock)block.FatBlock, massResults);
                    //Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap!");
                    ProfilerShort.End();
                }
                else
                {
                    ProfilerShort.Begin("Collect block");
                    CollectBlock(block, block.BlockDefinition.PhysicsOption, massResults);
                    //Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap!");
                    ProfilerShort.End();
                }
            }
            ProfilerShort.End();

            ProfilerShort.Begin("IsValidTest");
            Debug.Assert(IsValid(), "Overlapping shapes detected, block shapes cannot overlap! Uncomment upper asserts to find what block caused this");
            ProfilerShort.End();

            ProfilerShort.Begin("Add segments");
            AddSegmentedParts(grid.GridSize, segmenter, segmentationType);
            ProfilerShort.End();

            m_tmpCubes.Clear();
            m_tmpRefreshSet.Clear(); // Clear is required, we certainly don't want to hold last reference to blocks
        }
        void AddSegmentedParts(float gridSize, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType)
        {
            int maxExCubes = (int)Math.Floor(MAX_BOX_EXTENT/gridSize);
            Vector3 gridSizeHalf = new Vector3(gridSize*0.5f);
            if (segmenter != null)
            {
                int mergeIterations = segmentationType == MyVoxelSegmentationType.Optimized ? 1 : 0;
                //SegmenterBenchmark(collector, segmenter, mergeIterations);

                ProfilerShort.Begin("Prepare segmentation");
                segmenter.ClearInput();
                foreach (var cube in m_tmpCubes)
                {
                    segmenter.AddInput(cube);
                }
                ProfilerShort.End();

                ProfilerShort.Begin("Make segments");
                var segments = segmenter.FindSegments(segmentationType, mergeIterations);
                ProfilerShort.End();

                ProfilerShort.Begin("Add segments");
                Vector3I it;
                Vector3I maxI;
                foreach (var s in segments)
                {
                    for (it.X = s.Min.X; it.X <= s.Max.X; it.X += maxExCubes)
                    {
                        for (it.Y = s.Min.Y; it.Y <= s.Max.Y; it.Y += maxExCubes)
                            for (it.Z = s.Min.Z; it.Z <= s.Max.Z; it.Z += maxExCubes)
                            {
                                maxI = Vector3I.Min(it + maxExCubes - 1, s.Max);
                                Vector3 min = it * gridSize - gridSizeHalf;
                                Vector3 max = maxI * gridSize + gridSizeHalf;
                                AddBox(it, maxI, ref min, ref max);
                }
                    }
                }

                //foreach (var s in segments)
                //{
                //    Vector3 min = s.Min * gridSize - gridSizeHalf;
                //    Vector3 max = s.Max * gridSize + gridSizeHalf;
                //    AddBox(s.Min, s.Max, ref min, ref max);
                //}
                ProfilerShort.End();
            }
            else
            {
                ProfilerShort.Begin("Add full cubes");
                foreach (var c in m_tmpCubes)
                {
                    Vector3 min = c * gridSize - gridSizeHalf;
                    Vector3 max = c * gridSize + gridSizeHalf;
                    AddBox(c, c, ref min, ref max);
                }
                ProfilerShort.End();
            }
        }
示例#13
0
        void AddSegmentedParts(float gridSize, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType)
        {
            int     maxExCubes   = (int)Math.Floor(MAX_BOX_EXTENT / gridSize);
            Vector3 gridSizeHalf = new Vector3(gridSize * 0.5f);

            if (segmenter != null)
            {
                int mergeIterations = segmentationType == MyVoxelSegmentationType.Optimized ? 1 : 0;
                //SegmenterBenchmark(collector, segmenter, mergeIterations);

                ProfilerShort.Begin("Prepare segmentation");
                segmenter.ClearInput();
                foreach (var cube in m_tmpCubes)
                {
                    segmenter.AddInput(cube);
                }
                ProfilerShort.End();

                ProfilerShort.Begin("Make segments");
                var segments = segmenter.FindSegments(segmentationType, mergeIterations);
                ProfilerShort.End();

                ProfilerShort.Begin("Add segments");
                Vector3I it;
                Vector3I maxI;
                foreach (var s in segments)
                {
                    for (it.X = s.Min.X; it.X <= s.Max.X; it.X += maxExCubes)
                    {
                        for (it.Y = s.Min.Y; it.Y <= s.Max.Y; it.Y += maxExCubes)
                        {
                            for (it.Z = s.Min.Z; it.Z <= s.Max.Z; it.Z += maxExCubes)
                            {
                                maxI = Vector3I.Min(it + maxExCubes - 1, s.Max);
                                Vector3 min = it * gridSize - gridSizeHalf;
                                Vector3 max = maxI * gridSize + gridSizeHalf;
                                AddBox(it, maxI, ref min, ref max);
                            }
                        }
                    }
                }

                //foreach (var s in segments)
                //{
                //    Vector3 min = s.Min * gridSize - gridSizeHalf;
                //    Vector3 max = s.Max * gridSize + gridSizeHalf;
                //    AddBox(s.Min, s.Max, ref min, ref max);
                //}
                ProfilerShort.End();
            }
            else
            {
                ProfilerShort.Begin("Add full cubes");
                foreach (var c in m_tmpCubes)
                {
                    Vector3 min = c * gridSize - gridSizeHalf;
                    Vector3 max = c * gridSize + gridSizeHalf;
                    AddBox(c, c, ref min, ref max);
                }
                ProfilerShort.End();
            }
        }