protected bool TestGridPlacementOnGrid(MyCubeGrid previewGrid, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid)
        {
            Debug.Assert(previewGrid.GridSizeEnum == hitGrid.GridSizeEnum);

            bool retval = true;

            Vector3I gridOffset = hitGrid.WorldToGridInteger(previewGrid.PositionComp.WorldMatrix.Translation);
            MatrixI  transform  = hitGrid.CalculateMergeTransform(previewGrid, gridOffset);

            Matrix localPreviewMatrix = transform.GetFloatMatrix();

            localPreviewMatrix.Translation *= previewGrid.GridSize;

            if (MyDebugDrawSettings.DEBUG_DRAW_COPY_PASTE)
            {
                MyRenderProxy.DebugDrawText2D(new Vector2(0.0f, 60.0f), "First grid offset: " + gridOffset.ToString(), Color.Red, 1.0f);
            }

            retval = retval && MyCubeBuilder.CheckValidBlocksRotation(localPreviewMatrix, previewGrid);
            retval = retval && hitGrid.GridSizeEnum == previewGrid.GridSizeEnum && hitGrid.CanMergeCubes(previewGrid, gridOffset);
            retval = retval && MyCubeGrid.CheckMergeConnectivity(hitGrid, previewGrid, gridOffset);

            // Check if any block connects to hit grid
            if (retval)
            {
                bool connected = false;

                foreach (var block in previewGrid.CubeBlocks)
                {
                    if (block.FatBlock is MyCompoundCubeBlock)
                    {
                        MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                        foreach (var blockInCompound in compoundBlock.GetBlocks())
                        {
                            connected |= CheckConnectivityOnGrid(blockInCompound, ref transform, ref settings, hitGrid);
                            if (connected)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        connected |= CheckConnectivityOnGrid(block, ref transform, ref settings, hitGrid);
                    }

                    if (connected)
                    {
                        break;
                    }
                }

                retval &= connected;
            }

            if (retval)
            {
                foreach (var block in previewGrid.CubeBlocks)
                {
                    if (block.FatBlock is MyCompoundCubeBlock)
                    {
                        MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                        foreach (var blockInCompound in compoundBlock.GetBlocks())
                        {
                            retval = retval && TestBlockPlacementOnGrid(blockInCompound, ref transform, ref settings, hitGrid);
                            if (!retval)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        retval = retval && TestBlockPlacementOnGrid(block, ref transform, ref settings, hitGrid);
                    }

                    if (!retval)
                    {
                        break;
                    }
                }
            }

            return(retval);
        }
        private new bool TestPlacement()
        {
            bool retval = true;

            m_touchingGrids.Clear();

            for (int i = 0; i < PreviewGrids.Count; ++i)
            {
                var grid = PreviewGrids[i];

                m_touchingGrids.Add(null);

                if (MyCubeBuilder.Static.DynamicMode)
                {
                    if (!m_dynamicBuildAllowed)
                    {
                        var settings = m_settings.GetGridPlacementSettings(grid.GridSizeEnum, false);

                        BoundingBoxD localAabb   = (BoundingBoxD)grid.PositionComp.LocalAABB;
                        MatrixD      worldMatrix = grid.WorldMatrix;

                        if (MyFakes.ENABLE_VOXEL_MAP_AABB_CORNER_TEST)
                        {
                            retval = retval && MyCubeGrid.TestPlacementVoxelMapOverlap(null, ref settings, ref localAabb, ref worldMatrix);
                        }

                        retval = retval && MyCubeGrid.TestPlacementArea(grid, false, ref settings, localAabb, true);

                        if (!retval)
                        {
                            break;
                        }

                        //foreach (var block in grid.GetBlocks())
                        //{
                        //    Vector3 minLocal = block.Min * PreviewGrids[i].GridSize - Vector3.Half * PreviewGrids[i].GridSize;
                        //    Vector3 maxLocal = block.Max * PreviewGrids[i].GridSize + Vector3.Half * PreviewGrids[i].GridSize;
                        //    BoundingBoxD aabbLocal = new BoundingBoxD(minLocal, maxLocal);
                        //    retval &= MyCubeGrid.TestPlacementArea(grid, false, ref settings, aabbLocal, true);
                        //    if (!retval)
                        //        break;
                        //}
                    }
                }
                else
                { //not dynamic building mode
                    if (i == 0 && m_hitEntity is MyCubeGrid && IsSnapped && SnapMode == SnapMode.Base6Directions)
                    {
                        var settings = grid.GridSizeEnum == MyCubeSize.Large ? MyCubeBuilder.CubeBuilderDefinition.BuildingSettings.LargeStaticGrid : MyCubeBuilder.CubeBuilderDefinition.BuildingSettings.SmallStaticGrid;

                        var hitGrid = m_hitEntity as MyCubeGrid;

                        if (hitGrid.GridSizeEnum == MyCubeSize.Small && grid.GridSizeEnum == MyCubeSize.Large)
                        {
                            retval = false;
                            break;
                        }

                        bool smallOnLargeGrid = hitGrid.GridSizeEnum == MyCubeSize.Large && grid.GridSizeEnum == MyCubeSize.Small;

                        if (MyFakes.ENABLE_STATIC_SMALL_GRID_ON_LARGE /*&& grid.IsStatic*/ && smallOnLargeGrid)
                        {
                            if (!hitGrid.IsStatic)
                            {
                                retval = false;
                                break;
                            }

                            foreach (var block in grid.CubeBlocks)
                            {
                                if (block.FatBlock is MyCompoundCubeBlock)
                                {
                                    MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                                    foreach (var blockInCompound in compoundBlock.GetBlocks())
                                    {
                                        retval = retval && TestBlockPlacement(blockInCompound, ref settings);
                                        if (!retval)
                                        {
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    retval = retval && TestBlockPlacement(block, ref settings);
                                }

                                if (!retval)
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            retval = retval && TestGridPlacementOnGrid(grid, ref settings, hitGrid);
                        }
                    }
                    else
                    {
                        // Check with grid settings
                        {
                            MyCubeGrid touchingGrid = null;
                            var        settings     = i == 0 ? (grid.GridSizeEnum == MyCubeSize.Large ? MyCubeBuilder.CubeBuilderDefinition.BuildingSettings.LargeStaticGrid : MyCubeBuilder.CubeBuilderDefinition.BuildingSettings.SmallStaticGrid)
                                : MyCubeBuilder.CubeBuilderDefinition.BuildingSettings.GetGridPlacementSettings(grid.GridSizeEnum);

                            if (grid.IsStatic)
                            {
                                if (i == 0)
                                {
                                    Matrix orientation = grid.WorldMatrix.GetOrientation();
                                    retval = retval && MyCubeBuilder.CheckValidBlocksRotation(orientation, grid);
                                }

                                foreach (var block in grid.CubeBlocks)
                                {
                                    if (block.FatBlock is MyCompoundCubeBlock)
                                    {
                                        MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                                        foreach (var blockInCompound in compoundBlock.GetBlocks())
                                        {
                                            MyCubeGrid touchingGridLocal = null;
                                            retval = retval && TestBlockPlacementNoAABBInflate(blockInCompound, ref settings, out touchingGridLocal);

                                            if (retval && touchingGridLocal != null && touchingGrid == null)
                                            {
                                                touchingGrid = touchingGridLocal;
                                            }

                                            if (!retval)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        MyCubeGrid touchingGridLocal = null;
                                        retval = retval && TestBlockPlacementNoAABBInflate(block, ref settings, out touchingGridLocal);

                                        if (retval && touchingGridLocal != null && touchingGrid == null)
                                        {
                                            touchingGrid = touchingGridLocal;
                                        }
                                    }

                                    if (!retval)
                                    {
                                        break;
                                    }
                                }

                                if (retval && touchingGrid != null)
                                {
                                    m_touchingGrids[i] = touchingGrid;
                                }
                            }
                            else
                            {
                                foreach (var block in grid.CubeBlocks)
                                {
                                    Vector3      minLocal  = block.Min * PreviewGrids[i].GridSize - Vector3.Half * PreviewGrids[i].GridSize;
                                    Vector3      maxLocal  = block.Max * PreviewGrids[i].GridSize + Vector3.Half * PreviewGrids[i].GridSize;
                                    BoundingBoxD aabbLocal = new BoundingBoxD(minLocal, maxLocal);
                                    retval = retval && MyCubeGrid.TestPlacementArea(grid, grid.IsStatic, ref settings, aabbLocal, false);

                                    if (!retval)
                                    {
                                        break;
                                    }
                                }

                                m_touchingGrids[i] = null;
                            }
                        }

                        // Check connectivity with touching grid
                        if (retval && m_touchingGrids[i] != null)
                        {
                            var settings = grid.GridSizeEnum == MyCubeSize.Large ? MyCubeBuilder.CubeBuilderDefinition.BuildingSettings.LargeStaticGrid : MyCubeBuilder.CubeBuilderDefinition.BuildingSettings.SmallStaticGrid;
                            retval = retval && TestGridPlacementOnGrid(grid, ref settings, m_touchingGrids[i]);
                        }

                        // Check with paste settings only first grid
                        {
                            if (retval && i == 0)
                            {
                                bool smallStaticGrid = grid.GridSizeEnum == MyCubeSize.Small && grid.IsStatic;
                                if (smallStaticGrid || !grid.IsStatic)
                                {
                                    var  settings    = i == 0 ? m_settings.GetGridPlacementSettings(grid.GridSizeEnum, false) : MyCubeBuilder.CubeBuilderDefinition.BuildingSettings.SmallStaticGrid;
                                    bool localRetVal = true;

                                    foreach (var block in grid.CubeBlocks)
                                    {
                                        Vector3      minLocal       = block.Min * PreviewGrids[i].GridSize - Vector3.Half * PreviewGrids[i].GridSize;
                                        Vector3      maxLocal       = block.Max * PreviewGrids[i].GridSize + Vector3.Half * PreviewGrids[i].GridSize;
                                        BoundingBoxD blockLocalAABB = new BoundingBoxD(minLocal, maxLocal);

                                        localRetVal = localRetVal && MyCubeGrid.TestPlacementArea(grid, false, ref settings, blockLocalAABB, false);
                                        if (!localRetVal)
                                        {
                                            break;
                                        }
                                    }

                                    retval &= !localRetVal;
                                }
                                else if (m_touchingGrids[i] == null)
                                {
                                    var settings = m_settings.GetGridPlacementSettings(grid.GridSizeEnum, i == 0 ? true : grid.IsStatic);

                                    MyCubeGrid touchingGridLocal = null;

                                    bool localRetVal = false;
                                    foreach (var block in grid.CubeBlocks)
                                    {
                                        if (block.FatBlock is MyCompoundCubeBlock)
                                        {
                                            MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                                            foreach (var blockInCompound in compoundBlock.GetBlocks())
                                            {
                                                localRetVal |= TestBlockPlacementNoAABBInflate(blockInCompound, ref settings, out touchingGridLocal);
                                                if (localRetVal)
                                                {
                                                    break;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            localRetVal |= TestBlockPlacementNoAABBInflate(block, ref settings, out touchingGridLocal);
                                        }

                                        if (localRetVal)
                                        {
                                            break;
                                        }
                                    }

                                    retval &= localRetVal;
                                }
                            }
                        }
                    }
                }

                BoundingBoxD aabb = (BoundingBoxD)grid.PositionComp.LocalAABB;
                MatrixD      invGridWorlMatrix = grid.PositionComp.WorldMatrixNormalizedInv;

                // Character collisions.
                if (MySector.MainCamera != null)
                {
                    Vector3D cameraPos = Vector3D.Transform(MySector.MainCamera.Position, invGridWorlMatrix);
                    retval = retval && aabb.Contains(cameraPos) != ContainmentType.Contains;
                }

                if (retval)
                {
                    m_tmpCollisionPoints.Clear();
                    MyCubeBuilder.PrepareCharacterCollisionPoints(m_tmpCollisionPoints);
                    foreach (var pt in m_tmpCollisionPoints)
                    {
                        Vector3D ptLocal = Vector3D.Transform(pt, invGridWorlMatrix);
                        retval = retval && aabb.Contains(ptLocal) != ContainmentType.Contains;
                        if (!retval)
                        {
                            break;
                        }
                    }
                }

                if (!retval)
                {
                    break;
                }
            }

            return(retval);
        }