protected static bool TestVoxelPlacement(MySlimBlock block, ref MyGridPlacementSettings settings, bool dynamicMode)
        {
            var localAabb = BoundingBoxD.CreateInvalid();

            localAabb.Include(block.Min * block.CubeGrid.GridSize - block.CubeGrid.GridSize / 2);
            localAabb.Include(block.Max * block.CubeGrid.GridSize + block.CubeGrid.GridSize / 2);
            return(MyCubeGrid.TestVoxelPlacement(block.BlockDefinition, settings, dynamicMode, block.CubeGrid.WorldMatrix, localAabb));
        }
        protected static bool TestBlockPlacementArea(MySlimBlock block, ref MyGridPlacementSettings settings, bool dynamicMode)
        {
            var localAabb = BoundingBoxD.CreateInvalid();

            localAabb.Include(block.Min * block.CubeGrid.GridSize - block.CubeGrid.GridSize / 2);
            localAabb.Include(block.Max * block.CubeGrid.GridSize + block.CubeGrid.GridSize / 2);
            return(MyCubeGrid.TestBlockPlacementArea(block.BlockDefinition, block.Orientation, block.CubeGrid.WorldMatrix, ref settings, localAabb, dynamicMode, ignoredEntity: block.CubeGrid));
        }
 protected static bool TestBlockPlacementNoAABBInflate(MySlimBlock block, ref MyGridPlacementSettings settings, out MyCubeGrid touchingGrid)
 {
     return(MyCubeGrid.TestPlacementAreaCubeNoAABBInflate(block.CubeGrid, ref settings, block.Min, block.Max, block.Orientation, block.BlockDefinition, out touchingGrid, ignoredEntity: block.CubeGrid));
 }
        protected bool TestGridPlacementOnGrid(MyCubeGrid previewGrid, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid)
        {
            bool retval = true;

            Vector3I gridOffset = hitGrid.WorldToGridInteger(m_pastePosition);
            MatrixI  transform  = hitGrid.CalculateMergeTransform(previewGrid, gridOffset);

            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 && 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);
        }
        protected static bool TestBlockPlacementOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid)
        {
            Vector3I positionMin;

            Vector3I.Transform(ref block.Min, ref transform, out positionMin);
            Vector3I positionMax;

            Vector3I.Transform(ref block.Max, ref transform, out positionMax);
            Vector3I min = Vector3I.Min(positionMin, positionMax);
            Vector3I max = Vector3I.Max(positionMin, positionMax);

            Vector3I forward = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Forward));
            Vector3I up      = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Up));

            MyBlockOrientation blockOrientation = new MyBlockOrientation(Base6Directions.GetDirection(forward), Base6Directions.GetDirection(up));

            if (!hitGrid.CanAddCubes(min, max, blockOrientation, block.BlockDefinition))
            {
                return(false);
            }

            return(MyCubeGrid.TestPlacementAreaCube(hitGrid, ref settings, min, max, blockOrientation, block.BlockDefinition, ignoredEntity: hitGrid));
        }
        protected static bool CheckConnectivityOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid)
        {
            Vector3I position;
            Vector3I.Transform(ref block.Position, ref transform, out position);

            var forward = transform.GetDirection(block.Orientation.Forward);
            var up = transform.GetDirection(block.Orientation.Up);
            MyBlockOrientation blockOrientation = new MyBlockOrientation(forward, up);
            Quaternion rotation;
            blockOrientation.GetQuaternion(out rotation);
			var blockDefinition = block.BlockDefinition;
            return MyCubeGrid.CheckConnectivity(hitGrid, blockDefinition, blockDefinition.GetBuildProgressModelMountPoints(block.BuildLevelRatio), ref rotation, ref position);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Gets grids that are touching given grid. It's used for diciding if grids should be merged on later stage.
        /// </summary>
        /// <param name="grid">Grid to be tested.</param>
        /// <param name="settings">Settings used for the test.</param>
        private void GetTouchingGrids(MyCubeGrid grid, MyGridPlacementSettings settings)
        {
            m_touchingGrids.Clear();

            foreach (var block in grid.CubeBlocks)
            {
                if (block.FatBlock is MyCompoundCubeBlock)
                {
                    bool isTouching = false;
                    MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                    foreach (var blockInCompound in compoundBlock.GetBlocks())
                    {
                        MyCubeGrid touchingGridLocal = null;
                        MyCubeGrid.TestPlacementAreaCubeNoAABBInflate(blockInCompound.CubeGrid, ref settings, blockInCompound.Min, blockInCompound.Max, blockInCompound.Orientation,
                            blockInCompound.BlockDefinition, out touchingGridLocal, blockInCompound.CubeGrid);

                        if (touchingGridLocal == null) 
                            continue;

                        m_touchingGrids.Add(touchingGridLocal);
                        isTouching = true;
                        break;
                    }

                    if (isTouching)
                        break;
                }
                else
                {
                    MyCubeGrid touchingGridLocal = null;
                    MyCubeGrid.TestPlacementAreaCubeNoAABBInflate(block.CubeGrid, ref settings, block.Min, block.Max, block.Orientation,
                        block.BlockDefinition, out touchingGridLocal, block.CubeGrid);
                    
                    if (touchingGridLocal == null) 
                        continue;
                    
                    m_touchingGrids.Add(touchingGridLocal);
                    break;
                }
            }
        }
Exemplo n.º 8
0
        public static bool TestBlockPlacementArea(MyCubeBlockDefinition blockDefinition, MyBlockOrientation? blockOrientation, MatrixD worldMatrix, ref MyGridPlacementSettings settings, BoundingBoxD localAabb, bool dynamicBuildMode,
            MyEntity ignoredEntity = null, bool testVoxel = true)
        {
            ProfilerShort.Begin("TestStart");
            Vector3 halfExtents = localAabb.HalfExtents;
            halfExtents += settings.SearchHalfExtentsDeltaAbsolute; //this works for SE
            if (MyFakes.ENABLE_BLOCK_PLACING_IN_OCCUPIED_AREA)
                halfExtents -= new Vector3D(GRID_PLACING_AREA_FIX_VALUE);
            Vector3D translation = localAabb.TransformFast(ref worldMatrix).Center;
            Quaternion quaternion = Quaternion.CreateFromRotationMatrix(worldMatrix);
            quaternion.Normalize();
            ProfilerShort.End();

            ProfilerShort.Begin("VoxelOverlap");
            // copy settings so we wont override original one.
            MyGridPlacementSettings settingsCopy = settings;

            if (testVoxel && !TestVoxelPlacement(blockDefinition, settingsCopy, dynamicBuildMode, worldMatrix, localAabb))
                return false;

            ProfilerShort.End();

            ProfilerShort.Begin("Havok.GetPenetrationsBox");
            Debug.Assert(m_physicsBoxQueryList.Count == 0, "List not cleared");
            MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref quaternion, m_physicsBoxQueryList, MyPhysics.CollisionLayers.NoVoxelCollisionLayer);
            m_lastQueryBox.HalfExtents = halfExtents;
            m_lastQueryTransform = MatrixD.CreateFromQuaternion(quaternion);
            m_lastQueryTransform.Translation = translation;
            ProfilerShort.End();

            MyCubeGrid touchingGrid;
            return TestPlacementAreaInternal(null, ref settingsCopy, blockDefinition, blockOrientation, ref localAabb, ignoredEntity, ref worldMatrix, out touchingGrid, dynamicBuildMode: dynamicBuildMode);
        }
Exemplo n.º 9
0
 private static bool TestPlacementAreaInternal(MyCubeGrid targetGrid,
    ref MyGridPlacementSettings settings,
    MyCubeBlockDefinition blockDefinition,
    MyBlockOrientation? blockOrientation,
    ref BoundingBoxD localAabb,
    MyEntity ignoredEntity,
    ref MatrixD worldMatrix,
    out MyCubeGrid touchingGrid,
    bool dynamicBuildMode = false,
    bool ignoreFracturedPieces = false)
 {
     return TestPlacementAreaInternal(targetGrid, targetGrid != null ? targetGrid.IsStatic : !dynamicBuildMode,
         ref settings, blockDefinition, blockOrientation, ref localAabb, ignoredEntity, ref worldMatrix, out touchingGrid, dynamicBuildMode: dynamicBuildMode, ignoreFracturedPieces: ignoreFracturedPieces);
 }
Exemplo n.º 10
0
        private bool TestPlacement()
        {
            MyCubeGrid grid;
            MyGridPlacementSettings gridPlacementSettings;
            BoundingBoxD            xd;
            bool flag3;
            MyGridPlacementSettings settings4;
            bool flag1;
            bool flag = true;

            base.m_touchingGrids.Clear();
            int num = 0;

            goto TR_0047;
TR_000F:
            xd = grid.PositionComp.LocalAABB;
            MatrixD worldMatrixNormalizedInv = grid.PositionComp.WorldMatrixNormalizedInv;

            if (MySector.MainCamera != null)
            {
                Vector3D point = Vector3D.Transform(MySector.MainCamera.Position, worldMatrixNormalizedInv);
                flag = flag && (xd.Contains(point) != ContainmentType.Contains);
            }
            if (flag)
            {
                m_tmpCollisionPoints.Clear();
                MyCubeBuilder.PrepareCharacterCollisionPoints(m_tmpCollisionPoints);
                using (List <Vector3D> .Enumerator enumerator3 = m_tmpCollisionPoints.GetEnumerator())
                {
                    while (enumerator3.MoveNext())
                    {
                        Vector3D point = Vector3D.Transform(enumerator3.Current, worldMatrixNormalizedInv);
                        flag = flag && (xd.Contains(point) != ContainmentType.Contains);
                        if (!flag)
                        {
                            break;
                        }
                    }
                }
            }
            num++;
            goto TR_0047;
TR_001D:
            flag &= flag3;
            base.m_touchingGrids[num] = this.DetectTouchingGrid();
            goto TR_000F;
TR_0033:
            settings4 = base.m_settings.GetGridPlacementSettings(grid.GridSizeEnum, grid.IsStatic && !MyCubeBuilder.Static.DynamicMode);
            flag      = flag && MyCubeGrid.TestPlacementArea(grid, grid.IsStatic, ref settings4, grid.PositionComp.LocalAABB, false, null, true, true);
            goto TR_000F;
TR_0047:
            while (true)
            {
                if (num >= base.PreviewGrids.Count)
                {
                    return(flag);
                }
                grid = base.PreviewGrids[num];
                if (!Sandbox.Game.Entities.MyEntities.IsInsideWorld(grid.PositionComp.GetPosition()))
                {
                    return(false);
                }
                gridPlacementSettings = base.m_settings.GetGridPlacementSettings(grid.GridSizeEnum);
                base.m_touchingGrids.Add(null);
                if ((MySession.Static.SurvivalMode && !MyBlockBuilderBase.SpectatorIsBuilding) && !MySession.Static.CreativeToolsEnabled(Sync.MyId))
                {
                    if ((num == 0) && MyBlockBuilderBase.CameraControllerSpectator)
                    {
                        base.m_visible = false;
                        return(false);
                    }
                    if (((num == 0) && !MyCubeBuilder.Static.DynamicMode) && !MyCubeBuilderGizmo.DefaultGizmoCloseEnough(ref grid.PositionComp.WorldMatrixNormalizedInv, grid.PositionComp.LocalAABB, grid.GridSize, MyBlockBuilderBase.IntersectionDistance))
                    {
                        base.m_visible = false;
                        return(false);
                    }
                    if (!flag)
                    {
                        return(false);
                    }
                }
                if (!MyCubeBuilder.Static.DynamicMode)
                {
                    if (num != 0)
                    {
                        break;
                    }
                    if (!(base.m_hitEntity is MyCubeGrid))
                    {
                        break;
                    }
                    if (!base.IsSnapped)
                    {
                        break;
                    }
                    MyCubeGrid hitEntity = base.m_hitEntity as MyCubeGrid;
                    MyGridPlacementSettings gridPlacementSettings = base.m_settings.GetGridPlacementSettings(hitEntity.GridSizeEnum, hitEntity.IsStatic);
                    flag = ((hitEntity.GridSizeEnum != MyCubeSize.Large) || (grid.GridSizeEnum != MyCubeSize.Small)) ? (flag && base.TestGridPlacementOnGrid(grid, ref gridPlacementSettings, hitEntity)) : (flag && flag1);
                    base.m_touchingGrids.Clear();
                    base.m_touchingGrids.Add(hitEntity);
                }
                else
                {
                    MyGridPlacementSettings settings2 = (grid.GridSizeEnum == MyCubeSize.Large) ? base.m_settings.LargeGrid : base.m_settings.SmallGrid;
                    bool flag2 = false;
                    foreach (MySlimBlock block in grid.GetBlocks())
                    {
                        Vector3      min       = ((Vector3)(block.Min * base.PreviewGrids[num].GridSize)) - (Vector3.Half * base.PreviewGrids[num].GridSize);
                        Vector3      max       = (block.Max * base.PreviewGrids[num].GridSize) + (Vector3.Half * base.PreviewGrids[num].GridSize);
                        BoundingBoxD localAabb = new BoundingBoxD(min, max);
                        if (!flag2)
                        {
                            flag2 = TestVoxelPlacement(block, ref gridPlacementSettings, true);
                        }
                        flag = flag && MyCubeGrid.TestPlacementArea(grid, grid.IsStatic, ref settings2, localAabb, true, null, false, true);
                        if (!flag)
                        {
                            break;
                        }
                    }
                    flag &= flag2;
                }
                goto TR_000F;
            }
            if (num != 0)
            {
                goto TR_0033;
            }
            else if (!(base.m_hitEntity is MyVoxelMap))
            {
                goto TR_0033;
            }
            else
            {
                flag3 = false;
                using (HashSet <MySlimBlock> .Enumerator enumerator = grid.CubeBlocks.GetEnumerator())
                {
                    do
                    {
                        while (true)
                        {
                            if (enumerator.MoveNext())
                            {
                                MySlimBlock block3;
                                bool        flag4;
                                MySlimBlock current = enumerator.Current;
                                if (current.FatBlock is MyCompoundCubeBlock)
                                {
                                    using (List <MySlimBlock> .Enumerator enumerator2 = (current.FatBlock as MyCompoundCubeBlock).GetBlocks().GetEnumerator())
                                    {
                                        while (enumerator2.MoveNext())
                                        {
                                            if (!flag3)
                                            {
                                                flag1 = MyCubeGrid.TestPlacementArea(grid, ref gridPlacementSettings, grid.PositionComp.LocalAABB, false, null);
                                                flag3 = TestVoxelPlacement(block3, ref gridPlacementSettings, false);
                                            }
                                            flag = flag && flag4;
                                            if (!flag)
                                            {
                                                break;
                                            }
                                        }
                                        break;
                                    }
                                }
                                if (!flag3)
                                {
                                    flag4 = TestBlockPlacementArea(block3, ref gridPlacementSettings, false, false);
                                    flag3 = TestVoxelPlacement(current, ref gridPlacementSettings, false);
                                }
                                flag = flag && TestBlockPlacementArea(current, ref gridPlacementSettings, false, false);
                            }
                            else
                            {
                                goto TR_001D;
                            }
                            break;
                        }
                    }while (flag);
                }
            }
            goto TR_001D;
        }
        protected static bool CheckConnectivityOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid)
        {
            Vector3I position;

            Vector3I.Transform(ref block.Position, ref transform, out position);

            var forward = transform.GetDirection(block.Orientation.Forward);
            var up      = transform.GetDirection(block.Orientation.Up);
            MyBlockOrientation blockOrientation = new MyBlockOrientation(forward, up);
            Quaternion         rotation;

            blockOrientation.GetQuaternion(out rotation);
            var blockDefinition = block.BlockDefinition;

            return(MyCubeGrid.CheckConnectivity(hitGrid, blockDefinition, blockDefinition.GetBuildProgressModelMountPoints(block.BuildLevelRatio), ref rotation, ref position));
        }
 protected static bool TestBlockPlacementArea(MySlimBlock block, ref MyGridPlacementSettings settings, bool dynamicMode, bool testVoxel = true)
 {
     var localAabb = BoundingBoxD.CreateInvalid();
     localAabb.Include(block.Min * block.CubeGrid.GridSize - block.CubeGrid.GridSize / 2);
     localAabb.Include(block.Max * block.CubeGrid.GridSize + block.CubeGrid.GridSize / 2);
     return MyCubeGrid.TestBlockPlacementArea(block.BlockDefinition, block.Orientation, block.CubeGrid.WorldMatrix, ref settings, localAabb, dynamicMode, block.CubeGrid, testVoxel);
 }
Exemplo n.º 13
0
        public BuildCheckResult CanBuild(MySlimBlock projectedBlock, bool checkHavokIntersections)
        {
            MyBlockOrientation blockOrientation = projectedBlock.Orientation;

            Matrix local;

            blockOrientation.GetMatrix(out local);
            var gridOrientation = (m_clipboard as MyGridClipboard).GetFirstGridOrientationMatrix();

            if (gridOrientation != Matrix.Identity)
            {
                var afterRotation = Matrix.Multiply(local, gridOrientation);
                blockOrientation = new MyBlockOrientation(ref afterRotation);
            }

            Quaternion blockOrientationQuat;

            blockOrientation.GetQuaternion(out blockOrientationQuat);

            Quaternion projQuat = Quaternion.Identity;

            Orientation.GetQuaternion(out projQuat);
            blockOrientationQuat = Quaternion.Multiply(projQuat, blockOrientationQuat);

            Vector3I projectedMin = CubeGrid.WorldToGridInteger(projectedBlock.CubeGrid.GridIntegerToWorld(projectedBlock.Min));
            Vector3I projectedMax = CubeGrid.WorldToGridInteger(projectedBlock.CubeGrid.GridIntegerToWorld(projectedBlock.Max));
            Vector3I blockPos     = CubeGrid.WorldToGridInteger(projectedBlock.CubeGrid.GridIntegerToWorld(projectedBlock.Position));

            Vector3I min = new Vector3I(Math.Min(projectedMin.X, projectedMax.X), Math.Min(projectedMin.Y, projectedMax.Y), Math.Min(projectedMin.Z, projectedMax.Z));
            Vector3I max = new Vector3I(Math.Max(projectedMin.X, projectedMax.X), Math.Max(projectedMin.Y, projectedMax.Y), Math.Max(projectedMin.Z, projectedMax.Z));

            projectedMin = min;
            projectedMax = max;

            if (!CubeGrid.CanAddCubes(projectedMin, projectedMax))
            {
                return(BuildCheckResult.IntersectedWithGrid);
            }

            MyGridPlacementSettings settings = new MyGridPlacementSettings();

            settings.Mode = MyGridPlacementSettings.SnapMode.OneFreeAxis;

            var  mountPoints = projectedBlock.BlockDefinition.GetBuildProgressModelMountPoints(1.0f);
            bool isConnected = MyCubeGrid.CheckConnectivity(this.CubeGrid, projectedBlock.BlockDefinition, mountPoints,
                                                            ref blockOrientationQuat, ref blockPos);

            if (isConnected)
            {
                if (CubeGrid.GetCubeBlock(blockPos) == null)
                {
                    if (checkHavokIntersections)
                    {
                        if (MyCubeGrid.TestPlacementAreaCube(CubeGrid, ref settings, projectedMin, projectedMax, blockOrientation, projectedBlock.BlockDefinition, CubeGrid))
                        {
                            return(BuildCheckResult.OK);
                        }
                        else
                        {
                            return(BuildCheckResult.IntersectedWithSomethingElse);
                        }
                    }
                    else
                    {
                        return(BuildCheckResult.OK);
                    }
                }
                else
                {
                    return(BuildCheckResult.AlreadyBuilt);
                }
            }
            else
            {
                return(BuildCheckResult.NotConnected);
            }
        }
 protected static bool TestBlockPlacementNoAABBInflate(MySlimBlock block, ref MyGridPlacementSettings settings, out MyCubeGrid touchingGrid)
 {
     return MyCubeGrid.TestPlacementAreaCubeNoAABBInflate(block.CubeGrid, ref settings, block.Min, block.Max, block.Orientation, block.BlockDefinition, out touchingGrid, ignoredEntity: block.CubeGrid);
 }
 protected static bool TestBlockPlacement(MySlimBlock block, ref MyGridPlacementSettings settings)
 {
     return MyCubeGrid.TestPlacementAreaCube(block.CubeGrid, ref settings, block.Min, block.Max, block.Orientation, block.BlockDefinition, ignoredEntity: block.CubeGrid);
 }
        protected static bool TestBlockPlacementOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid)
        {
            Vector3I positionMin;
            Vector3I.Transform(ref block.Min, ref transform, out positionMin);
            Vector3I positionMax;
            Vector3I.Transform(ref block.Max, ref transform, out positionMax);
            Vector3I min = Vector3I.Min(positionMin, positionMax);
            Vector3I max = Vector3I.Max(positionMin, positionMax);

            var forward = transform.GetDirection(block.Orientation.Forward);
            var up = transform.GetDirection(block.Orientation.Up);
            MyBlockOrientation blockOrientation = new MyBlockOrientation(forward, up);
            return hitGrid.CanPlaceBlock(min, max, blockOrientation, block.BlockDefinition, ref settings);
        }
        public static bool TestPlacementArea(MyCubeGrid targetGrid, ref MyGridPlacementSettings settings, BoundingBoxD localAabb, bool dynamicBuildMode, MyEntity ignoredEntity = null)
        {
            ProfilerShort.Begin("TestStart");
            var worldMatrix = targetGrid.WorldMatrix;

            Vector3 halfExtents = localAabb.HalfExtents;
            halfExtents += settings.SearchHalfExtentsDeltaAbsolute; //this works for SE
            if (MyFakes.ENABLE_BLOCK_PLACING_IN_OCCUPIED_AREA)
                halfExtents -= new Vector3D(GRID_PLACING_AREA_FIX_VALUE);
            Vector3D translation = localAabb.Transform(ref worldMatrix).Center;
            Quaternion quaternion = Quaternion.CreateFromRotationMatrix(worldMatrix);
            quaternion.Normalize();
            ProfilerShort.End();

            ProfilerShort.Begin("Havok.GetPenetrationsBox");
            Debug.Assert(m_physicsBoxQueryList.Count == 0, "List not cleared");
            MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref quaternion, m_physicsBoxQueryList, MyPhysics.CollisionLayers.CharacterCollisionLayer);
            m_lastQueryBox.HalfExtents = halfExtents;
            m_lastQueryTransform = MatrixD.CreateFromQuaternion(quaternion);
            m_lastQueryTransform.Translation = translation;
            ProfilerShort.End();

            MyCubeGrid touchingGrid;
            return TestPlacementAreaInternal(targetGrid, ref settings, null, null, ref localAabb, ignoredEntity, ref worldMatrix, out touchingGrid, dynamicBuildMode: dynamicBuildMode);
        }
        protected static bool TestBlockPlacementOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid)
        {
            Vector3I positionMin;

            Vector3I.Transform(ref block.Min, ref transform, out positionMin);
            Vector3I positionMax;

            Vector3I.Transform(ref block.Max, ref transform, out positionMax);
            Vector3I min = Vector3I.Min(positionMin, positionMax);
            Vector3I max = Vector3I.Max(positionMin, positionMax);

            var forward = transform.GetDirection(block.Orientation.Forward);
            var up      = transform.GetDirection(block.Orientation.Up);
            MyBlockOrientation blockOrientation = new MyBlockOrientation(forward, up);

            return(hitGrid.CanPlaceBlock(min, max, blockOrientation, block.BlockDefinition, ref settings));
        }
Exemplo n.º 19
0
        /// <summary>
        /// Checks if aabb is in voxel. If settings provided it will return false if penetration settings allow for it.
        /// </summary>
        /// <param name="worldMatrix">World matrix of the aabb.</param>
        /// <param name="localAabb">Local aabb</param>
        /// <param name="settings">Game settings</param>
        /// <returns></returns>
        public static bool IsAabbInsideVoxel(MatrixD worldMatrix, BoundingBoxD localAabb, MyGridPlacementSettings settings)
        {

            var worldAabb = localAabb.TransformFast(ref worldMatrix);

            List<MyVoxelBase> voxels = new List<MyVoxelBase>();
            MyGamePruningStructure.GetAllVoxelMapsInBox(ref worldAabb, voxels);

            foreach (MyVoxelBase voxel in voxels)
            {
                if (settings.VoxelPlacement.Value.PlacementMode != VoxelPlacementMode.Volumetric && voxel.IsAnyAabbCornerInside(ref worldMatrix, localAabb))
                    return true;

                if (settings.VoxelPlacement.Value.PlacementMode == VoxelPlacementMode.Volumetric && !TestPlacementVoxelMapPenetration(voxel, settings, ref localAabb, ref worldMatrix))
                    return true;
            }

            return false;
        }
Exemplo n.º 20
0
        private static void TestGridPlacement(ref MyGridPlacementSettings settings, ref MatrixD worldMatrix, ref MyCubeGrid touchingGrid, float gridSize, bool isStatic, ref BoundingBoxD localAABB, MyCubeBlockDefinition blockDefinition,
           MyBlockOrientation? blockOrientation, ref bool entityOverlap, ref bool touchingStaticGrid, MyCubeGrid grid)
        {
            var worldAabb = localAABB.TransformFast(ref worldMatrix);
            var invWorldMatrix = grid.PositionComp.WorldMatrixNormalizedInv;
            var otherLocalAabb = worldAabb.TransformFast(ref invWorldMatrix);

            Vector3D minToWorld = Vector3D.Transform(localAABB.Min, worldMatrix);
            Vector3D maxToWorld = Vector3D.Transform(localAABB.Max, worldMatrix);
            Vector3D tempMinLocal = Vector3D.Transform(minToWorld, invWorldMatrix);
            Vector3D tempMaxLocal = Vector3D.Transform(maxToWorld, invWorldMatrix);

            Vector3D otherMinLocal = Vector3D.Min(tempMinLocal, tempMaxLocal);
            Vector3D otherMaxLocal = Vector3D.Max(tempMinLocal, tempMaxLocal);

            var scaledMin = (otherMinLocal + gridSize / 2) / grid.GridSize;
            var scaledMax = (otherMaxLocal - gridSize / 2) / grid.GridSize;
            var tempMin = Vector3I.Round(scaledMin);
            var tempMax = Vector3I.Round(scaledMax);
            var min = Vector3I.Min(tempMin, tempMax);
            var max = Vector3I.Max(tempMin, tempMax);

            MyBlockOrientation? gridBlockOrientation = null;
            if (MyFakes.ENABLE_COMPOUND_BLOCKS && isStatic && grid.IsStatic && blockOrientation != null)
            {
                Matrix blockRotation;
                blockOrientation.Value.GetMatrix(out blockRotation);
                Matrix rotationInGrid = blockRotation * worldMatrix;
                rotationInGrid = rotationInGrid * invWorldMatrix;
                rotationInGrid.Translation = Vector3.Zero;

                Base6Directions.Direction forwardDir = Base6Directions.GetForward(ref rotationInGrid);
                Base6Directions.Direction upDir = Base6Directions.GetUp(ref rotationInGrid);
                if (Base6Directions.IsValidBlockOrientation(forwardDir, upDir))
                    gridBlockOrientation = new MyBlockOrientation(forwardDir, upDir);
            }

            if (!grid.CanAddCubes(min, max, gridBlockOrientation, blockDefinition))
            {
                entityOverlap = true;
                return;
            }

            if (settings.CanAnchorToStaticGrid && grid.IsTouchingAnyNeighbor(min, max))
            {
                touchingStaticGrid = true;
                if (touchingGrid == null)
                    touchingGrid = grid;
            }
        }
Exemplo n.º 21
0
        public static bool TestVoxelPlacement(MyCubeBlockDefinition blockDefinition, MyGridPlacementSettings settingsCopy, bool dynamicBuildMode, MatrixD worldMatrix, BoundingBoxD localAabb)
        {
            // Override Voxel penetration settings if block has definition of it.
            if (blockDefinition.VoxelPlacement != null)
            {
                settingsCopy.VoxelPlacement = dynamicBuildMode ? blockDefinition.VoxelPlacement.Value.DynamicMode : blockDefinition.VoxelPlacement.Value.StaticMode;
            }

            if (settingsCopy.VoxelPlacement.Value.PlacementMode == VoxelPlacementMode.None)
            {
                return false;
            }

            if (settingsCopy.VoxelPlacement.Value.PlacementMode != VoxelPlacementMode.Both)
            {
                bool result = IsAabbInsideVoxel(worldMatrix, localAabb, settingsCopy);

                if (settingsCopy.VoxelPlacement.Value.PlacementMode == VoxelPlacementMode.InVoxel)
                    result = !result;

                if (result)
            {
                    ProfilerShort.End();
                    return false;
                }
            }

            return true;
        }
Exemplo n.º 22
0
        public static bool TestPlacementVoxelMapOverlap(
            MyVoxelBase voxelMap,
            ref MyGridPlacementSettings settings,
            ref BoundingBoxD localAabb,
            ref MatrixD worldMatrix,
            bool touchingStaticGrid = false)
        {
            ProfilerShort.Begin("TestPlacementVoxelMapOverlap");

            var worldAabb = localAabb.TransformFast(ref worldMatrix);

            const int IntersectsOrInside = 1;
            const int Outside = 2;

            int overlapState = Outside;

            if (voxelMap == null)
                voxelMap = MySession.Static.VoxelMaps.GetVoxelMapWhoseBoundingBoxIntersectsBox(ref worldAabb, null);

            if (voxelMap != null && voxelMap.IsAnyAabbCornerInside(ref worldMatrix, localAabb))
            {
                overlapState = IntersectsOrInside;
            }

            bool testPassed = true;

            switch (overlapState)
            {
                case IntersectsOrInside:
                    testPassed = settings.VoxelPlacement.Value.PlacementMode == VoxelPlacementMode.Both;
                    break;
                case Outside:
                    testPassed = settings.VoxelPlacement.Value.PlacementMode == VoxelPlacementMode.OutsideVoxel || (settings.CanAnchorToStaticGrid && touchingStaticGrid);
                    break;
                default:
                    Debug.Fail("Invalid branch.");
                    break;
            }

            ProfilerShort.End();

            return testPassed;
        }
Exemplo n.º 23
0
        private static bool TestPlacementAreaInternalWithEntities(MyCubeGrid targetGrid,
         bool targetGridIsStatic,
         ref MyGridPlacementSettings settings,
         ref BoundingBoxD localAabb,
         MyEntity ignoredEntity,
         ref MatrixD worldMatrix,
         bool dynamicBuildMode = false)
        {
            ProfilerShort.Begin("TestPlacementAreaInternalWithEntities");

            MyCubeGrid touchingGrid = null;

            float gridSize = targetGrid.GridSize;
            bool isStatic = targetGridIsStatic;

            var worldAabb = localAabb.TransformFast(ref worldMatrix);

            bool entityOverlap = false;
            MyVoxelBase overlappedVoxelMap = null;
            bool touchingStaticGrid = false;
            foreach (var entity in m_tmpResultList)
            {
                if (ignoredEntity != null && (entity == ignoredEntity || entity.GetTopMostParent() == ignoredEntity))
                    continue;

                var body = entity.Physics;
                if (body == null)
                    continue;

                var grid = entity as MyCubeGrid;
                if (grid != null)
                {
                    // Small on large (or large on small) always possible
                    if (isStatic == grid.IsStatic && gridSize != grid.GridSize)
                        continue;

                    TestGridPlacement(ref settings, ref worldMatrix, ref touchingGrid, gridSize, isStatic, ref localAabb, null, null, ref entityOverlap, ref touchingStaticGrid, grid);

                    if (entityOverlap)
                    {
                        break;
                    }
                }
                else
                {
                    var character = entity as MyCharacter;
                    if (character != null && character.PositionComp.WorldAABB.Intersects(targetGrid.PositionComp.WorldAABB))
                    {
                        entityOverlap = true;
                        break;
                    }
                }
            }

            m_tmpResultList.Clear();
            ProfilerShort.End();

            if (entityOverlap)
                return false;

            if (targetGrid.IsStatic)
            {
                return true;
            }

            return true;
        }
        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;
        }
Exemplo n.º 25
0
        private static bool TestPlacementAreaInternal(MyCubeGrid targetGrid,
           bool targetGridIsStatic,
           ref MyGridPlacementSettings settings,
           MyCubeBlockDefinition blockDefinition,
           MyBlockOrientation? blockOrientation,
           ref BoundingBoxD localAabb,
           MyEntity ignoredEntity,
           ref MatrixD worldMatrix,
           out MyCubeGrid touchingGrid,
           bool dynamicBuildMode = false,
           bool ignoreFracturedPieces = false)
        {
            ProfilerShort.Begin("TestPlacementAreaInternal");

            touchingGrid = null;

            float gridSize = targetGrid != null ? targetGrid.GridSize : (blockDefinition != null ? MyDefinitionManager.Static.GetCubeSize(blockDefinition.CubeSize) : MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large));
            bool isStatic = targetGridIsStatic;

            bool entityOverlap = false;
            MyVoxelBase overlappedVoxelMap = null;
            bool touchingStaticGrid = false;
            foreach (var collison in m_physicsBoxQueryList)
            {
                var entity = collison.Body.GetEntity(0) as MyEntity;
                if (entity == null)
                    continue;

                if (ignoreFracturedPieces && (entity is MyFracturedPiece))
                    continue;

                if (entity.GetPhysicsBody().WeldInfo.Children.Count == 0 && ignoredEntity != null && (entity == ignoredEntity || entity.GetTopMostParent() == ignoredEntity))
                    continue;

                var body = entity.Physics;
                if (body != null && body.IsPhantom)
                    continue;

                var grid = entity as MyCubeGrid;
				if (grid == null)
				{
					var subPart = entity as MyEntitySubpart;
					if (subPart != null)
					{
						grid = subPart.GetTopMostParent() as MyCubeGrid;
					}
				}

                if(entity.GetPhysicsBody().WeldInfo.Children.Count > 0)
                {
                    if(entity != ignoredEntity)
                    {
                        //Vector4 min,max;
                        //entity.Physics.GetShape().GetLocalAABB(0.05f, out min, out max);
                        //MyOrientedBoundingBoxD obb = new MyOrientedBoundingBoxD(new BoundingBoxD(new Vector3D(min.X, min.Y, min.Z), new Vector3D(max.X, max.Y, max.Z)), entity.WorldMatrix);
                        //MyRenderProxy.DebugDrawOBB(obb, Color.Green, 0.5f, false, false);
                        //obb = new MyOrientedBoundingBoxD(new BoundingBoxD(-m_lastQueryBox.HalfExtents, m_lastQueryBox.HalfExtents), m_lastQueryTransform);
                        //MyRenderProxy.DebugDrawOBB(obb, Color.Red, 0.5f, false, false);
                        if (TestQueryIntersection(entity.GetPhysicsBody().GetShape(), entity.WorldMatrix))
                        {
                            entityOverlap = true;
                            if(touchingGrid == null)
                                touchingGrid = entity as MyCubeGrid;
                            break;
                        }
                    }

                    foreach(var child in entity.GetPhysicsBody().WeldInfo.Children)
                    {
                        if(child.Entity == ignoredEntity)
                            continue;
                        if(TestQueryIntersection(child.WeldedRigidBody.GetShape(), child.Entity.WorldMatrix))
                        {
                            if (touchingGrid == null)
                                touchingGrid = child.Entity as MyCubeGrid;
                            entityOverlap = true;
                            break;
                        }
                    }
                    if (entityOverlap)
                        break;
                    continue;
                }

                if (grid != null && ((isStatic && grid.IsStatic)
                    || (MyFakes.ENABLE_DYNAMIC_SMALL_GRID_MERGING && !isStatic && !grid.IsStatic && blockDefinition != null && blockDefinition.CubeSize == grid.GridSizeEnum)
                    || (/*MyFakes.ENABLE_BLOCK_PLACEMENT_ON_VOXEL &&*/ isStatic && grid.IsStatic && blockDefinition != null && blockDefinition.CubeSize == grid.GridSizeEnum)))
                {
                    // Small on large (or large on small) always possible
                    if (isStatic == grid.IsStatic && gridSize != grid.GridSize)
                        continue;

                    // first check if world orientation is correct.
                    if(!IsOrientationsAligned(grid.WorldMatrix, worldMatrix))
                    {
                        entityOverlap = true;
                        continue;
                    }

                    TestGridPlacement(ref settings, ref worldMatrix, ref touchingGrid, gridSize, isStatic, ref localAabb, blockDefinition, blockOrientation, ref entityOverlap, ref touchingStaticGrid, grid);
                    if (entityOverlap)
                    {
                        break;
                    }
                    continue;
                }

                //if (dynamicBuildMode)
                //{
                    entityOverlap = true;
                break;
                //}

            }
            m_tmpResultList.Clear();
            m_physicsBoxQueryList.Clear();
            ProfilerShort.End();

            if (entityOverlap)
                return false;

            return true;
        }
Exemplo n.º 26
0
 public static bool TestBlockPlacementArea(
     MyCubeGrid targetGrid,
     ref MyGridPlacementSettings settings,
     MyBlockOrientation blockOrientation,
     MyCubeBlockDefinition blockDefinition,
     ref Vector3D translation,
     ref Quaternion rotation,
     ref Vector3 halfExtents,
     ref BoundingBoxD localAabb,
     MyEntity ignoredEntity = null)
 {
     MyCubeGrid touchingGrid;
     return TestBlockPlacementArea(targetGrid, ref settings, blockOrientation, blockDefinition, ref translation, ref rotation, ref halfExtents, ref localAabb, out touchingGrid, ignoredEntity: ignoredEntity);
 }
Exemplo n.º 27
0
        private static bool TestPlacementVoxelMapPenetration(
            MyVoxelBase voxelMap, 
            MyGridPlacementSettings settings,
            ref BoundingBoxD localAabb,
            ref MatrixD worldMatrix,
            bool touchingStaticGrid = false)
        {
            ProfilerShort.Begin("TestPlacementVoxelMapPenetration");
            
            float penetrationRatio = 0f;
            float penetrationVolume = 0f;
            if (voxelMap != null)
            {
                MyTuple<float,float> penetrationInfo = voxelMap.GetVoxelContentInBoundingBox_Fast(localAabb, worldMatrix);
                penetrationVolume = (float)localAabb.Volume * penetrationInfo.Item2; // Currently not used but please leave as this data is there already and may be used in future
                penetrationRatio = penetrationInfo.Item2;
            }

            bool penetrationTestPassed = penetrationRatio <= settings.VoxelPlacement.Value.MaxAllowed &&
                (penetrationRatio >= settings.VoxelPlacement.Value.MinAllowed || (settings.CanAnchorToStaticGrid && touchingStaticGrid));


            //MyRenderProxy.DebugDrawText3D(worldMatrix.Translation, penetrationRatio.ToString(), Color.White, 1.0f, false);

            ProfilerShort.End();

            return penetrationTestPassed;
        }
Exemplo n.º 28
0
        public static bool TestBlockPlacementArea(
            MyCubeGrid targetGrid,
            ref MyGridPlacementSettings settings,
            MyBlockOrientation blockOrientation,
            MyCubeBlockDefinition blockDefinition,
            ref Vector3D translation,
            ref Quaternion rotation,
            ref Vector3 halfExtents,
            ref BoundingBoxD localAabb,
            out MyCubeGrid touchingGrid,
            MyEntity ignoredEntity = null,
            bool ignoreFracturedPieces = false)
        {
            touchingGrid = null;

            ProfilerShort.Begin("UseModelIntersection");
            if (blockDefinition != null && blockDefinition.UseModelIntersection)
            {
                var model = VRage.Game.Models.MyModels.GetModelOnlyData(blockDefinition.Model);
                if (model != null)
                {
                    bool newErrorFound;
                    model.CheckLoadingErrors(blockDefinition.Context, out newErrorFound);
                    if (newErrorFound)
                        MyDefinitionErrors.Add(blockDefinition.Context,
                            "There was error during loading of model, please check log file.", TErrorSeverity.Error);
                }

                if (model != null && model.HavokCollisionShapes != null)
                {
                    Matrix local;
                    blockOrientation.GetMatrix(out local);
                    Vector3 modelOffset;
                    Vector3.TransformNormal(ref blockDefinition.ModelOffset, ref local, out modelOffset);
                    translation += modelOffset;

                    int shapeCount = model.HavokCollisionShapes.Length;
                    HkShape[] shapes = new HkShape[shapeCount];
                    for (int q = 0; q < shapeCount; ++q)
                    {
                        shapes[q] = model.HavokCollisionShapes[q];
                    }

                    var shape = new HkListShape(shapes, shapeCount, HkReferencePolicy.None);

                    Quaternion q2 = Quaternion.CreateFromForwardUp(Base6Directions.GetVector(blockOrientation.Forward), Base6Directions.GetVector(blockOrientation.Up));
                    rotation = rotation * q2;
                    MyPhysics.GetPenetrationsShape(shape, ref translation, ref rotation, m_physicsBoxQueryList, MyPhysics.CollisionLayers.NoVoxelCollisionLayer);

                    shape.Base.RemoveReference();
                }
                else
                {
                    Debug.Assert(m_physicsBoxQueryList.Count == 0, "List not cleared");
                    MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref rotation, m_physicsBoxQueryList, MyPhysics.CollisionLayers.NoVoxelCollisionLayer);
                }
            }
            else
            {
                Debug.Assert(m_physicsBoxQueryList.Count == 0, "List not cleared");
                MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref rotation, m_physicsBoxQueryList, MyPhysics.CollisionLayers.NoVoxelCollisionLayer);
            }
            m_lastQueryBox.HalfExtents = halfExtents;
            m_lastQueryTransform = MatrixD.CreateFromQuaternion(rotation);
            m_lastQueryTransform.Translation = translation;

            var worldMatrix = targetGrid != null ? targetGrid.WorldMatrix : MatrixD.Identity;
            ProfilerShort.BeginNextBlock("TestPlacementAreaInternal");
            bool result = TestPlacementAreaInternal(targetGrid, ref settings, blockDefinition, blockOrientation, ref localAabb, ignoredEntity, ref worldMatrix, out touchingGrid, ignoreFracturedPieces: ignoreFracturedPieces);
            ProfilerShort.End();
            return result;
        }
Exemplo n.º 29
0
        public BuildCheckResult CanBuild(MySlimBlock projectedBlock, bool checkHavokIntersections)
        {
            MyBlockOrientation blockOrientation = projectedBlock.Orientation;
            
            //GR: For rotation take into account:
            //the projected block orientation
            Quaternion blockOrientationQuat;
            blockOrientation.GetQuaternion(out blockOrientationQuat);

            //GR: The projector block orientation (which is relative to the Cubegrid orientation)
            Quaternion projQuat = Quaternion.Identity;
            Orientation.GetQuaternion(out projQuat);
            blockOrientationQuat = Quaternion.Multiply(projQuat, blockOrientationQuat);

            //GR: The orienation settings of the projector
            //Take into account order of multiplication to review!
            blockOrientationQuat = Quaternion.Multiply(ProjectionRotationQuaternion, blockOrientationQuat);


            Vector3I projectedMin = CubeGrid.WorldToGridInteger(projectedBlock.CubeGrid.GridIntegerToWorld(projectedBlock.Min));
            Vector3I projectedMax = CubeGrid.WorldToGridInteger(projectedBlock.CubeGrid.GridIntegerToWorld(projectedBlock.Max));
            Vector3I blockPos = CubeGrid.WorldToGridInteger(projectedBlock.CubeGrid.GridIntegerToWorld(projectedBlock.Position));

            Vector3I min = new Vector3I(Math.Min(projectedMin.X, projectedMax.X), Math.Min(projectedMin.Y, projectedMax.Y), Math.Min(projectedMin.Z, projectedMax.Z));
            Vector3I max = new Vector3I(Math.Max(projectedMin.X, projectedMax.X), Math.Max(projectedMin.Y, projectedMax.Y), Math.Max(projectedMin.Z, projectedMax.Z));

            projectedMin = min;
            projectedMax = max;

            if (!CubeGrid.CanAddCubes(projectedMin, projectedMax))
            {
                return BuildCheckResult.IntersectedWithGrid;
            }

            MyGridPlacementSettings settings = new MyGridPlacementSettings();
            settings.SnapMode = SnapMode.OneFreeAxis;

			var mountPoints = projectedBlock.BlockDefinition.GetBuildProgressModelMountPoints(1.0f);
			bool isConnected = MyCubeGrid.CheckConnectivity(this.CubeGrid, projectedBlock.BlockDefinition, mountPoints,
															ref blockOrientationQuat, ref blockPos);
            if (isConnected)
            {
                if (CubeGrid.GetCubeBlock(blockPos) == null)
                {
                    if (checkHavokIntersections)
                    {
                        if (MyCubeGrid.TestPlacementAreaCube(CubeGrid, ref settings, projectedMin, projectedMax, blockOrientation, projectedBlock.BlockDefinition, CubeGrid))
                        {
                            return BuildCheckResult.OK;
                        }
                        else
                        {
                            return BuildCheckResult.IntersectedWithSomethingElse;
                        }
                    }
                    else
                    {
                        return BuildCheckResult.OK;
                    }
                }
                else
                {
                    return BuildCheckResult.AlreadyBuilt;
                }
            }
            else
            {
                return BuildCheckResult.NotConnected;
            }
        }
Exemplo n.º 30
0
 public static bool TestPlacementAreaCube(
     MyCubeGrid targetGrid,
     ref MyGridPlacementSettings settings,
     Vector3I min,
     Vector3I max,
     MyBlockOrientation blockOrientation,
     MyCubeBlockDefinition blockDefinition,
     MyEntity ignoredEntity = null,
     bool ignoreFracturedPieces = false)
 {
     MyCubeGrid touchingGrid = null;
     return TestPlacementAreaCube(targetGrid, ref settings, min, max, blockOrientation, blockDefinition, out touchingGrid, ignoredEntity: ignoredEntity, ignoreFracturedPieces: ignoreFracturedPieces);
 }
Exemplo n.º 31
0
        protected static bool CheckConnectivityOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid)
        {
            Vector3I position;

            Vector3I.Transform(ref block.Position, ref transform, out position);

            Vector3I           forward          = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Forward));
            Vector3I           up               = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Up));
            MyBlockOrientation blockOrientation = new MyBlockOrientation(Base6Directions.GetDirection(forward), Base6Directions.GetDirection(up));
            Quaternion         rotation;

            blockOrientation.GetQuaternion(out rotation);

            return(MyCubeGrid.CheckConnectivity(hitGrid, block.BlockDefinition, ref rotation, ref position));
        }
Exemplo n.º 32
0
        /// <summary>
        /// Test cube block placement area in grid.
        /// </summary>
        public static bool TestPlacementAreaCube(
            MyCubeGrid targetGrid,
            ref MyGridPlacementSettings settings,
            Vector3I min,
            Vector3I max,
            MyBlockOrientation blockOrientation,
            MyCubeBlockDefinition blockDefinition,
            out MyCubeGrid touchingGrid,
            MyEntity ignoredEntity = null,
            bool ignoreFracturedPieces = false)
        {
            touchingGrid = null;

            ProfilerShort.Begin("Math");
            var worldMatrix = targetGrid != null ? targetGrid.WorldMatrix : MatrixD.Identity;
            var gridSize = targetGrid != null ? targetGrid.GridSize : MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large);

            Vector3 halfExtents = ((max - min) * gridSize + gridSize) / 2;
            if (MyFakes.ENABLE_BLOCK_PLACING_IN_OCCUPIED_AREA)
                halfExtents -= new Vector3D(GRID_PLACING_AREA_FIX_VALUE);
            else
                halfExtents -= new Vector3(0.03f, 0.03f, 0.03f); //allows touching blocks like wheels
            var matrix = MatrixD.CreateTranslation((max + min) * 0.5f * gridSize) * worldMatrix;
            var localAabb = BoundingBoxD.CreateInvalid();
            localAabb.Include(min * gridSize - gridSize / 2);
            localAabb.Include(max * gridSize + gridSize / 2);

            Vector3D translation = matrix.Translation;
            Quaternion rotation = Quaternion.CreateFromRotationMatrix(matrix);

            ProfilerShort.BeginNextBlock("TestBlockPlacementArea");
            bool result = TestBlockPlacementArea(targetGrid, ref settings, blockOrientation, blockDefinition, ref translation, ref rotation, ref halfExtents, ref localAabb, out touchingGrid, ignoredEntity: ignoredEntity, 
                ignoreFracturedPieces: ignoreFracturedPieces);

            ProfilerShort.End();

            return result;
        }
Exemplo n.º 33
0
 protected static bool TestBlockPlacement(MySlimBlock block, ref MyGridPlacementSettings settings)
 {
     return(MyCubeGrid.TestPlacementAreaCube(block.CubeGrid, ref settings, block.Min, block.Max, block.Orientation, block.BlockDefinition, ignoredEntity: block.CubeGrid));
 }
Exemplo n.º 34
0
        public static bool TestPlacementAreaCubeNoAABBInflate(
            MyCubeGrid targetGrid,
            ref MyGridPlacementSettings settings,
            Vector3I min,
            Vector3I max,
            MyBlockOrientation blockOrientation,
            MyCubeBlockDefinition blockDefinition,
            out MyCubeGrid touchingGrid,
            MyEntity ignoredEntity = null)
        {
            touchingGrid = null;

            var worldMatrix = targetGrid != null ? targetGrid.WorldMatrix : MatrixD.Identity;
            var gridSize = targetGrid != null ? targetGrid.GridSize : MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large);

            Vector3 halfExtents = ((max - min) * gridSize + gridSize) / 2;
            var matrix = MatrixD.CreateTranslation((max + min) * 0.5f * gridSize) * worldMatrix;
            var localAabb = BoundingBoxD.CreateInvalid();
            localAabb.Include(min * gridSize - gridSize / 2);
            localAabb.Include(max * gridSize + gridSize / 2);

            Vector3D translation = matrix.Translation;
            Quaternion rotation = Quaternion.CreateFromRotationMatrix(matrix);

            return TestBlockPlacementArea(targetGrid, ref settings, blockOrientation, blockDefinition, ref translation, ref rotation, ref halfExtents, ref localAabb, out touchingGrid, ignoredEntity);
        }
Exemplo n.º 35
0
        //public static bool TestPlacementAreaWithEntities(MyCubeGrid targetGrid, bool targetGridIsStatic, ref MyGridPlacementSettings settings, BoundingBoxD localAabb, bool dynamicBuildMode, MyEntity ignoredEntity = null)
        //{
        //    ProfilerShort.Begin("Test start with entities");
        //    var worldMatrix = targetGrid.WorldMatrix;

        //    Vector3 halfExtents = localAabb.HalfExtents;
        //    halfExtents += settings.SearchHalfExtentsDeltaAbsolute; //this works for SE
        //    if (MyFakes.ENABLE_BLOCK_PLACING_IN_OCCUPIED_AREA)
        //        halfExtents -= new Vector3D(GRID_PLACING_AREA_FIX_VALUE);
        //    Vector3D translation = localAabb.Transform(ref worldMatrix).Center;
        //    Quaternion quaternion = Quaternion.CreateFromRotationMatrix(worldMatrix);
        //    quaternion.Normalize();
        //    ProfilerShort.End();

        //    ProfilerShort.Begin("get top most entities");

        //    m_tmpResultList.Clear();
        //    BoundingBoxD box = targetGrid.PositionComp.WorldAABB;
        //    MyGamePruningStructure.GetTopMostEntitiesInBox(ref box, m_tmpResultList);
        //    ProfilerShort.End();

        //    return TestPlacementAreaInternalWithEntities(targetGrid, targetGridIsStatic, ref settings, ref localAabb, ignoredEntity, ref worldMatrix, dynamicBuildMode: dynamicBuildMode);
        //}

        public static bool TestPlacementArea(MyCubeGrid targetGrid, bool targetGridIsStatic, ref MyGridPlacementSettings settings, BoundingBoxD localAabb, bool dynamicBuildMode, MyEntity ignoredEntity = null, bool testVoxel = true)
        {
            ProfilerShort.Begin("TestStart");
            var worldMatrix = targetGrid.WorldMatrix;

            Vector3 halfExtents = localAabb.HalfExtents;
            halfExtents += settings.SearchHalfExtentsDeltaAbsolute; //this works for SE
            if (MyFakes.ENABLE_BLOCK_PLACING_IN_OCCUPIED_AREA)
                halfExtents -= new Vector3D(GRID_PLACING_AREA_FIX_VALUE);
            Vector3D translation = localAabb.TransformFast(ref worldMatrix).Center;
            Quaternion quaternion = Quaternion.CreateFromRotationMatrix(worldMatrix);
            quaternion.Normalize();
            ProfilerShort.End();

            ProfilerShort.Begin("VoxelOverlap");

            if (testVoxel && settings.VoxelPlacement.Value.PlacementMode != VoxelPlacementMode.Both)
            {
                bool result = IsAabbInsideVoxel(worldMatrix, localAabb, settings);

                if (settings.VoxelPlacement.Value.PlacementMode == VoxelPlacementMode.InVoxel)
                    result = !result;

                if (result)
                {
                    ProfilerShort.End();
                    return false;
                }
            }

            ProfilerShort.End();

            ProfilerShort.Begin("Havok.GetPenetrationsBox");

            Debug.Assert(m_physicsBoxQueryList.Count == 0, "List not cleared");
            MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref quaternion, m_physicsBoxQueryList, MyPhysics.CollisionLayers.NoVoxelCollisionLayer);
            m_lastQueryBox.HalfExtents = halfExtents;
            m_lastQueryTransform = MatrixD.CreateFromQuaternion(quaternion);
            m_lastQueryTransform.Translation = translation;
            ProfilerShort.End();

            MyCubeGrid touchingGrid;
            return TestPlacementAreaInternal(targetGrid, targetGridIsStatic, ref settings, null, null, ref localAabb, ignoredEntity, ref worldMatrix, out touchingGrid, dynamicBuildMode);
        }
Exemplo n.º 36
0
        public BuildCheckResult CanBuild(MySlimBlock projectedBlock, bool checkHavokIntersections)
        {
            MyBlockOrientation blockOrientation = projectedBlock.Orientation;

            //GR: For rotation take into account:
            //the projected block orientation
            Quaternion blockOrientationQuat;

            blockOrientation.GetQuaternion(out blockOrientationQuat);

            //GR: The projector block orientation (which is relative to the Cubegrid orientation)
            Quaternion projQuat = Quaternion.Identity;

            Orientation.GetQuaternion(out projQuat);
            blockOrientationQuat = Quaternion.Multiply(projQuat, blockOrientationQuat);

            //GR: The orienation settings of the projector
            //Take into account order of multiplication to review!
            blockOrientationQuat = Quaternion.Multiply(ProjectionRotationQuaternion, blockOrientationQuat);


            Vector3I projectedMin = CubeGrid.WorldToGridInteger(projectedBlock.CubeGrid.GridIntegerToWorld(projectedBlock.Min));
            Vector3I projectedMax = CubeGrid.WorldToGridInteger(projectedBlock.CubeGrid.GridIntegerToWorld(projectedBlock.Max));
            Vector3I blockPos     = CubeGrid.WorldToGridInteger(projectedBlock.CubeGrid.GridIntegerToWorld(projectedBlock.Position));

            Vector3I min = new Vector3I(Math.Min(projectedMin.X, projectedMax.X), Math.Min(projectedMin.Y, projectedMax.Y), Math.Min(projectedMin.Z, projectedMax.Z));
            Vector3I max = new Vector3I(Math.Max(projectedMin.X, projectedMax.X), Math.Max(projectedMin.Y, projectedMax.Y), Math.Max(projectedMin.Z, projectedMax.Z));

            projectedMin = min;
            projectedMax = max;

            if (!CubeGrid.CanAddCubes(projectedMin, projectedMax))
            {
                return(BuildCheckResult.IntersectedWithGrid);
            }

            MyGridPlacementSettings settings = new MyGridPlacementSettings();

            settings.SnapMode = SnapMode.OneFreeAxis;

            var  mountPoints = projectedBlock.BlockDefinition.GetBuildProgressModelMountPoints(1.0f);
            bool isConnected = MyCubeGrid.CheckConnectivity(this.CubeGrid, projectedBlock.BlockDefinition, mountPoints,
                                                            ref blockOrientationQuat, ref blockPos);

            if (isConnected)
            {
                if (CubeGrid.GetCubeBlock(blockPos) == null)
                {
                    if (checkHavokIntersections)
                    {
                        if (MyCubeGrid.TestPlacementAreaCube(CubeGrid, ref settings, projectedMin, projectedMax, blockOrientation, projectedBlock.BlockDefinition, CubeGrid))
                        {
                            return(BuildCheckResult.OK);
                        }
                        else
                        {
                            return(BuildCheckResult.IntersectedWithSomethingElse);
                        }
                    }
                    else
                    {
                        return(BuildCheckResult.OK);
                    }
                }
                else
                {
                    return(BuildCheckResult.AlreadyBuilt);
                }
            }
            else
            {
                return(BuildCheckResult.NotConnected);
            }
        }