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); }