public static bool IsInVoxels(MySlimBlock block,bool checkForPhysics = true)
        {
            if (block.CubeGrid.Physics == null && checkForPhysics)
               return false;

            if (MyPerGameSettings.Destruction && block.CubeGrid.GridSizeEnum == MyCubeSize.Large)
                return block.CubeGrid.Physics.Shape.BlocksConnectedToWorld.Contains(block.Position);

            BoundingBoxD blockWorldAABB;
            block.GetWorldBoundingBox(out blockWorldAABB);

            m_tmpVoxelList.Clear();
            MyGamePruningStructure.GetAllVoxelMapsInBox(ref blockWorldAABB, m_tmpVoxelList);
            var cubeSize = block.CubeGrid.GridSize;
            BoundingBoxD localAAABB = new BoundingBoxD(cubeSize * ((Vector3D)block.Min - 0.5), cubeSize * ((Vector3D)block.Max + 0.5));
            var gridWorldMatrix = block.CubeGrid.WorldMatrix;
            foreach(var map in m_tmpVoxelList)
            {
                if (map.IsAnyAabbCornerInside(ref gridWorldMatrix, localAAABB))
                {
                    return true;
                }
            }
            return false;
        }
Пример #2
0
        private MyCubeGrid DetectTouchingGrid(MySlimBlock block)
        {
            if (MyCubeBuilder.Static.DynamicMode)
                return null;

            if (block == null)
                return null;

            if (block.FatBlock is MyCompoundCubeBlock)
            {
                foreach (var blockInCompound in (block.FatBlock as MyCompoundCubeBlock).GetBlocks())
                {
                    MyCubeGrid touchingGrid = DetectTouchingGrid(blockInCompound);
                    if (touchingGrid != null)
                        return touchingGrid;
                }

                return null;
            }

            ProfilerShort.Begin("MultiBlockClipboard: DetectMerge");

            float gridSize = block.CubeGrid.GridSize;
            BoundingBoxD aabb;
            block.GetWorldBoundingBox(out aabb);
            // Inflate by half cube, so it will intersect for sure when there's anything
            aabb.Inflate(gridSize / 2);

            m_tmpNearEntities.Clear();
            MyEntities.GetElementsInBox(ref aabb, m_tmpNearEntities);

            var mountPoints = block.BlockDefinition.GetBuildProgressModelMountPoints(block.BuildLevelRatio);

            try
            {
                for (int i = 0; i < m_tmpNearEntities.Count; i++)
                {
                    var grid = m_tmpNearEntities[i] as MyCubeGrid;
                    if (grid != null && grid != block.CubeGrid && grid.Physics != null && grid.Physics.Enabled && grid.IsStatic && grid.GridSizeEnum == block.CubeGrid.GridSizeEnum)
                    {
                        Vector3I gridOffset = grid.WorldToGridInteger(m_pastePosition);
                        if (!grid.CanMergeCubes(block.CubeGrid, gridOffset))
                            continue;

                        MatrixI transform = grid.CalculateMergeTransform(block.CubeGrid, gridOffset);
                        Base6Directions.Direction forward = transform.GetDirection(block.Orientation.Forward);
                        Base6Directions.Direction up = transform.GetDirection(block.Orientation.Up);
                        MyBlockOrientation newOrientation = new MyBlockOrientation(forward, up);
                        Quaternion newRotation;
                        newOrientation.GetQuaternion(out newRotation);
                        Vector3I newPosition = Vector3I.Transform(block.Position, transform);

                        if (!MyCubeGrid.CheckConnectivity(grid, block.BlockDefinition, mountPoints, ref newRotation, ref newPosition))
                            continue;

                        return grid;
                    }
                }
            }
            finally
            {
                m_tmpNearEntities.Clear();
                ProfilerShort.End();
            }

            return null;
        }
Пример #3
0
        public static bool IsInVoxels(MySlimBlock block,bool checkForPhysics = true)
        {
            if (block.CubeGrid.Physics == null && checkForPhysics)
               return false;

            if (MyPerGameSettings.Destruction && block.CubeGrid.GridSizeEnum == Common.ObjectBuilders.MyCubeSize.Large)
                return block.CubeGrid.Physics.Shape.BlocksConnectedToWorld.Contains(block.Position);

            BoundingBoxD blockWorldAABB;
            block.GetWorldBoundingBox(out blockWorldAABB);

            var voxelMap = MySession.Static.VoxelMaps.GetVoxelMapWhoseBoundingBoxIntersectsBox(ref blockWorldAABB, null);
            if (voxelMap == null)
                return false;

            var cubeSize = block.CubeGrid.GridSize;
            BoundingBoxD localAAABB = new BoundingBoxD(cubeSize * ((Vector3D)block.Min - 0.5), cubeSize * ((Vector3D)block.Max + 0.5));
            var gridWorldMatrix = block.CubeGrid.WorldMatrix;

            return voxelMap.IsAnyAabbCornerInside(ref gridWorldMatrix, localAAABB);
        }
        private void MyCubeGridsOnBlockBuilt(MyCubeGrid myCubeGrid, MySlimBlock mySlimBlock)
        {
            if (mySlimBlock == null || !myCubeGrid.IsStatic) return;

            // Avoid multiple queues for compound block additions.
            var compound = myCubeGrid.GetCubeBlock(mySlimBlock.Min).FatBlock as MyCompoundCubeBlock;
            if (compound != null && mySlimBlock.FatBlock != compound) return;

            BoundingBoxD blockAabb;
            mySlimBlock.GetWorldBoundingBox(out blockAabb, true);
            m_cubeBlocksPending.Add(myCubeGrid, blockAabb);

            //Debug.Print("CubeGrid {0}: Block added at {1}.", myCubeGrid, mySlimBlock.Position);
        }
Пример #5
0
        /// <summary>
        /// Adds small/large block static connections and creates links. Returns true if the block connects to any other block.
        /// </summary>
        public bool AddBlockSmallToLargeConnection(MySlimBlock block)
        {
            if (!m_smallToLargeCheckEnabled)
            {
                return(true);
            }

            if (!block.CubeGrid.IsStatic || !block.CubeGrid.EnableSmallToLargeConnections || !block.CubeGrid.SmallToLargeConnectionsInitialized ||
                block.FatBlock == null || block.FatBlock.Components.Has <MyFractureComponentBase>())
            {
                return(false);
            }

            bool retval = false;

            if (block.FatBlock is MyCompoundCubeBlock)
            {
                MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                foreach (var blockInCompound in compoundBlock.GetBlocks())
                {
                    bool localRetVal = AddBlockSmallToLargeConnection(blockInCompound);
                    retval = retval || localRetVal;
                }
                return(retval);
            }

            MyCubeSize searchCubeSize = GetCubeSize(block) == MyCubeSize.Large ? MyCubeSize.Small : MyCubeSize.Large;

            GetSurroundingBlocksFromStaticGrids(block, searchCubeSize, m_tmpBlocks);

            if (m_tmpBlocks.Count == 0)
            {
                return(false);
            }

            float smallGridSize = MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Small);

            BoundingBoxD blockAabb;

            block.GetWorldBoundingBox(out blockAabb);
            blockAabb.Inflate(0.05);

            if (GetCubeSize(block) == MyCubeSize.Large)
            {
                foreach (var smallBlock in m_tmpBlocks)
                {
                    Debug.Assert(GetCubeSize(smallBlock.SlimBlock) == MyCubeSize.Small);

                    BoundingBoxD smallAabb;
                    smallBlock.SlimBlock.GetWorldBoundingBox(out smallAabb);

                    if (!smallAabb.Intersects(blockAabb))
                    {
                        continue;
                    }

                    if (SmallBlockConnectsToLarge(smallBlock.SlimBlock, ref smallAabb, block, ref blockAabb))
                    {
                        ConnectSmallToLargeBlock(smallBlock.SlimBlock, block);
                        retval = true;
                    }
                }
            }
            else
            {
                Debug.Assert(GetCubeSize(block) == MyCubeSize.Small);

                foreach (var largeBlock in m_tmpBlocks)
                {
                    Debug.Assert(GetCubeSize(largeBlock.SlimBlock) == MyCubeSize.Large);

                    BoundingBoxD largeAabb;
                    largeBlock.SlimBlock.GetWorldBoundingBox(out largeAabb);

                    if (!largeAabb.Intersects(blockAabb))
                    {
                        continue;
                    }

                    if (SmallBlockConnectsToLarge(block, ref blockAabb, largeBlock.SlimBlock, ref largeAabb))
                    {
                        ConnectSmallToLargeBlock(block, largeBlock.SlimBlock);
                        retval = true;
                    }
                }
            }

            return(retval);
        }
Пример #6
0
        private MyCubeGrid DetectTouchingGrid(MySlimBlock block)
        {
            if (MyCubeBuilder.Static.DynamicMode)
            {
                return(null);
            }

            if (block == null)
            {
                return(null);
            }

            if (block.FatBlock is MyCompoundCubeBlock)
            {
                foreach (var blockInCompound in (block.FatBlock as MyCompoundCubeBlock).GetBlocks())
                {
                    MyCubeGrid touchingGrid = DetectTouchingGrid(blockInCompound);
                    if (touchingGrid != null)
                    {
                        return(touchingGrid);
                    }
                }

                return(null);
            }

            ProfilerShort.Begin("MultiBlockClipboard: DetectMerge");

            float        gridSize = block.CubeGrid.GridSize;
            BoundingBoxD aabb;

            block.GetWorldBoundingBox(out aabb);
            // Inflate by half cube, so it will intersect for sure when there's anything
            aabb.Inflate(gridSize / 2);

            m_tmpNearEntities.Clear();
            MyEntities.GetElementsInBox(ref aabb, m_tmpNearEntities);

            var mountPoints = block.BlockDefinition.GetBuildProgressModelMountPoints(block.BuildLevelRatio);

            try
            {
                for (int i = 0; i < m_tmpNearEntities.Count; i++)
                {
                    var grid = m_tmpNearEntities[i] as MyCubeGrid;
                    if (grid != null && grid != block.CubeGrid && grid.Physics != null && grid.Physics.Enabled && grid.IsStatic && grid.GridSizeEnum == block.CubeGrid.GridSizeEnum)
                    {
                        Vector3I gridOffset = grid.WorldToGridInteger(m_pastePosition);
                        if (!grid.CanMergeCubes(block.CubeGrid, gridOffset))
                        {
                            continue;
                        }

                        MatrixI transform = grid.CalculateMergeTransform(block.CubeGrid, gridOffset);
                        Base6Directions.Direction forward        = transform.GetDirection(block.Orientation.Forward);
                        Base6Directions.Direction up             = transform.GetDirection(block.Orientation.Up);
                        MyBlockOrientation        newOrientation = new MyBlockOrientation(forward, up);
                        Quaternion newRotation;
                        newOrientation.GetQuaternion(out newRotation);
                        Vector3I newPosition = Vector3I.Transform(block.Position, transform);

                        if (!MyCubeGrid.CheckConnectivity(grid, block.BlockDefinition, mountPoints, ref newRotation, ref newPosition))
                        {
                            continue;
                        }

                        return(grid);
                    }
                }
            }
            finally
            {
                m_tmpNearEntities.Clear();
                ProfilerShort.End();
            }

            return(null);
        }
Пример #7
0
        private void grid_OnBlockRemoved(MySlimBlock block)
        {
            bool ignore = true;
            bool noEntry = false;
            bool meshFound = false;

            var existingBlock = m_grid.GetCubeBlock(block.Position);
            var compound = existingBlock == null ? null : existingBlock.FatBlock as MyCompoundCubeBlock;

            if (!(block.FatBlock is MyCompoundCubeBlock) && block.BlockDefinition.NavigationDefinition == null) return;

            // Ignore blocks without navigation info (i.e. decorations and such)
            if (compound == null)
            {
                Debug.Assert(existingBlock == null, "Removed a block from position, but there still is another block and it's not a compound!");

                ignore = false;
                if (existingBlock != null)
                {
                    if (block.BlockDefinition.NavigationDefinition.NoEntry)
                        noEntry = true;
                    else
                        meshFound = true;
                }
            }
            else
            {
                var blocks = compound.GetBlocks();

                if (blocks.Count != 0)
                {
                    foreach (var subBlock in blocks)
                    {
                        if (subBlock.BlockDefinition.NavigationDefinition == null) continue;
                        if (subBlock.BlockDefinition.NavigationDefinition.NoEntry || meshFound)
                        {
                            ignore = false;
                            noEntry = true;
                            break;
                        }
                        else
                        {
                            ignore = false;
                            meshFound = true;
                            block = subBlock;
                        }
                    }
                }
            }

            BoundingBoxD bbox;
            block.GetWorldBoundingBox(out bbox);
            bbox.Inflate(5.1f);

            //m_coordinator.RemoveGridNavmeshLinks(m_grid);
            m_coordinator.InvalidateVoxelsBBox(ref bbox);

            MarkBlockChanged(block);
            MyAIComponent.Static.Pathfinding.GridPathfinding.MarkHighLevelDirty();

            if (ignore)
            {
                RemoveBlock(block.Min, block.Max, eraseCubeSet: true);
                FixBlockFaces(block);
            }
            else if (noEntry)
            {
                RemoveBlock(block.Min, block.Max, eraseCubeSet: false);
            }
            else if (meshFound)
            {
                RemoveBlock(block.Min, block.Max, eraseCubeSet: true);
                AddBlock(block);
            }
            else
            {
                if (m_cubeSet.Contains(block.Position))
                {
                    RemoveBlock(block.Min, block.Max, eraseCubeSet: true);
                    FixBlockFaces(block);
                }
            }
        }
Пример #8
0
        private void OnBlockAddedInternal(MySlimBlock block)
        {
            var existingBlock = m_grid.GetCubeBlock(block.Position);
            var compound = existingBlock.FatBlock as MyCompoundCubeBlock;

            // Ignore blocks without navigation info (i.e. decorations and such)
            if (!(block.FatBlock is MyCompoundCubeBlock) && block.BlockDefinition.NavigationDefinition == null) return;

            bool noEntry = false;
            bool meshFound = false;
            if (compound != null)
            {
                var blocks = compound.GetBlocks();

                if (blocks.Count == 0) return;

                foreach (var subBlock in blocks)
                {
                    if (subBlock.BlockDefinition.NavigationDefinition == null) continue;
                    if (subBlock.BlockDefinition.NavigationDefinition.NoEntry || meshFound)
                    {
                        meshFound = false;
                        noEntry = true;
                        break;
                    }
                    else
                    {
                        block = subBlock;
                        meshFound = true;
                    }
                }
            }
            else
            {
                if (block.BlockDefinition.NavigationDefinition != null)
                {
                    if (block.BlockDefinition.NavigationDefinition.NoEntry)
                    {
                        meshFound = false;
                        noEntry = true;
                    }
                    else
                    {
                        meshFound = true;
                    }
                }
            }

            // Ignore compounds with blocks without navigation info
            if (!noEntry && !meshFound) return;

            if (noEntry)
            {
                if (m_cubeSet.Contains(block.Position))
                    RemoveBlock(block.Min, block.Max, true);

                Vector3I pos = default(Vector3I);
                for (pos.X = block.Min.X; pos.X <= block.Max.X; ++pos.X)
                {
                    for (pos.Y = block.Min.Y; pos.Y <= block.Max.Y; ++pos.Y)
                    {
                        pos.Z = block.Min.Z - 1;
                        if (m_cubeSet.Contains(ref pos))
                        {
                            EraseFaceTriangles(pos, Base6Directions.Direction.Backward);
                        }

                        pos.Z = block.Max.Z + 1;
                        if (m_cubeSet.Contains(ref pos))
                        {
                            EraseFaceTriangles(pos, Base6Directions.Direction.Forward);
                        }
                    }

                    for (pos.Z = block.Min.Z; pos.Z <= block.Max.Z; ++pos.Z)
                    {
                        pos.Y = block.Min.Y - 1;
                        if (m_cubeSet.Contains(ref pos))
                        {
                            EraseFaceTriangles(pos, Base6Directions.Direction.Up);
                        }

                        pos.Y = block.Max.Y + 1;
                        if (m_cubeSet.Contains(ref pos))
                        {
                            EraseFaceTriangles(pos, Base6Directions.Direction.Down);
                        }
                    }
                }

                for (pos.Y = block.Min.Y; pos.Y <= block.Max.Y; ++pos.Y)
                {
                    for (pos.Z = block.Min.Z; pos.Z <= block.Max.Z; ++pos.Z)
                    {
                        pos.X = block.Min.X - 1;
                        if (m_cubeSet.Contains(ref pos))
                        {
                            EraseFaceTriangles(pos, Base6Directions.Direction.Right);
                        }

                        pos.X = block.Max.X + 1;
                        if (m_cubeSet.Contains(ref pos))
                        {
                            EraseFaceTriangles(pos, Base6Directions.Direction.Left);
                        }
                    }
                }

                pos = block.Min;
                for (var it = new Vector3I.RangeIterator(ref pos, ref block.Max); it.IsValid(); it.GetNext(out pos))
                {
                    m_cubeSet.Add(pos);
                }
            }
            else
            {
                if (m_cubeSet.Contains(block.Position))
                {
                    RemoveBlock(block.Min, block.Max, eraseCubeSet: true);
                }
                AddBlock(block);
            }

            BoundingBoxD bbox;
            block.GetWorldBoundingBox(out bbox);
            bbox.Inflate(5.1f);

            m_coordinator.InvalidateVoxelsBBox(ref bbox);

            MarkBlockChanged(block);
        }