/// <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;
        }
        protected bool TrySnapToSurface(MyGridPlacementSettings.SnapMode snapMode)
        {
            if (m_closestHitDistSq < float.MaxValue)
            {
                Vector3 newDragPointPosition = m_hitPos;

                bool isAnyStatic = AnyCopiedGridIsStatic;
                if (isAnyStatic)
                {
                    m_pasteDirForward = Vector3.Forward;
                    m_pasteDirUp = Vector3.Up;
                }
                else if (m_hitNormal.Length() > 0.5)
                {
                    if (snapMode == MyGridPlacementSettings.SnapMode.OneFreeAxis)
                    {
                        m_pasteDirUp = m_hitNormal;

                        float dotUp = m_pasteDirUp.Dot(m_hitEntity.WorldMatrix.Up);
                        float dotFwd = m_pasteDirUp.Dot(m_hitEntity.WorldMatrix.Forward);
                        float dotRt = m_pasteDirUp.Dot(m_hitEntity.WorldMatrix.Right);
                        if (Math.Abs(dotUp) > Math.Abs(dotFwd))
                        {
                            if (Math.Abs(dotUp) > Math.Abs(dotRt))
                            {
                                m_pasteDirForward = Vector3.Normalize(m_hitEntity.WorldMatrix.Right - (dotRt * m_pasteDirUp));
                            }
                            else
                            {
                                m_pasteDirForward = Vector3.Normalize(m_hitEntity.WorldMatrix.Forward - (dotFwd * m_pasteDirUp));
                            }
                        }
                        else
                        {
                            if (Math.Abs(dotFwd) > Math.Abs(dotRt))
                            {
                                m_pasteDirForward = Vector3.Normalize(m_hitEntity.WorldMatrix.Up - (dotUp * m_pasteDirUp));
                            }
                            else
                            {
                                m_pasteDirForward = Vector3.Normalize(m_hitEntity.WorldMatrix.Forward - (dotFwd * m_pasteDirUp));
                            }
                        }
                    }
                    else if (snapMode == MyGridPlacementSettings.SnapMode.Base6Directions)
                    {
                        var hitGrid = m_hitEntity as MyCubeGrid;
                        if (hitGrid != null)
                        {
                            Matrix hitGridRotation = hitGrid.WorldMatrix.GetOrientation();
                            Matrix firstRotation = GetFirstGridOrientationMatrix();
                            Matrix newFirstRotation = Matrix.AlignRotationToAxes(ref firstRotation, ref hitGridRotation);
                            Matrix rotationDelta = Matrix.Invert(firstRotation) * newFirstRotation;

                            m_pasteDirForward = newFirstRotation.Forward;
                            m_pasteDirUp = newFirstRotation.Up;
                            m_pasteOrientationAngle = 0.0f;
                        }
                    }
                }

                Matrix newOrientation = GetFirstGridOrientationMatrix();
                Vector3 globalCenterDelta = Vector3.TransformNormal(m_dragPointToPositionLocal, newOrientation);

                m_pastePosition = newDragPointPosition + globalCenterDelta;

                if (MyDebugDrawSettings.DEBUG_DRAW_COPY_PASTE)
                {
                    MyRenderProxy.DebugDrawSphere(newDragPointPosition, 0.08f, Color.Red.ToVector3(), 1.0f, false);
                    MyRenderProxy.DebugDrawSphere(m_pastePosition, 0.08f, Color.Red.ToVector3(), 1.0f, false);
                }

                IsSnapped = true;
                return true;
            }
            IsSnapped = false;
            return false;
        }
 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);
 }
        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,
           bool testVoxels = true)
        {
            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;

            var worldAabb = localAabb.Transform(ref worldMatrix);

            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 voxelMap = entity as MyVoxelBase;
                if (voxelMap != null)
                {
                    overlappedVoxelMap = voxelMap;
                    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;
                }


                entityOverlap = true;
                break;
            }
            m_tmpResultList.Clear();
            m_physicsBoxQueryList.Clear();
            ProfilerShort.End();

            if (entityOverlap)
                return false;
            if (testVoxels)
                return TestVoxelOverlap(ref settings, ref localAabb, ref worldMatrix, ref worldAabb, ref overlappedVoxelMap, touchingStaticGrid);
            return true;
        }
        public static bool TestPlacementVoxelMapOverlap(
            MyVoxelBase voxelMap,
            ref MyGridPlacementSettings settings,
            ref BoundingBoxD localAabb,
            ref MatrixD worldMatrix,
            bool touchingStaticGrid = false)
        {
            ProfilerShort.Begin("TestPlacementVoxelMapOverlap");

            var worldAabb = localAabb.Transform(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.Penetration.MaxAllowed > 0;
                    break;
                case Outside:
                    testPassed = settings.Penetration.MinAllowed <= 0 || (settings.CanAnchorToStaticGrid && touchingStaticGrid);
                    break;
                default:
                    Debug.Fail("Invalid branch.");
                    break;
            }

            ProfilerShort.End();

            return testPassed;
        }
        public static bool TestBlockPlacementArea(MyCubeBlockDefinition blockDefinition, MyBlockOrientation? blockOrientation, MatrixD worldMatrix, ref MyGridPlacementSettings settings, BoundingBoxD localAabb, bool dynamicBuildMode,
            MyEntity ignoredEntity = null)
        {
            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.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(null, ref settings, blockDefinition, blockOrientation, ref localAabb, ignoredEntity, ref worldMatrix, out touchingGrid, dynamicBuildMode: dynamicBuildMode);
        }
        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.Transform(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 voxelMap = entity as MyVoxelBase;
                if (voxelMap != null)
                {
                    overlappedVoxelMap = voxelMap;
                    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;
            }

            ProfilerShort.Begin("TestVoxelOverlap");
            bool result = TestVoxelOverlap(ref settings, ref localAabb, ref worldMatrix, ref worldAabb, ref overlappedVoxelMap, touchingStaticGrid);
            ProfilerShort.End();

            return result;
        }
        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 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 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 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);
			var blockDefinition = block.BlockDefinition;
            return MyCubeGrid.CheckConnectivity(hitGrid, blockDefinition, blockDefinition.GetBuildProgressModelMountPoints(block.BuildLevelRatio), ref rotation, ref position);
        }
        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)
        {
            touchingGrid = null;

            if (blockDefinition != null && blockDefinition.UseModelIntersection)
            {
                var model = MyModels.GetModelOnlyData(blockDefinition.Model);
                if(model != null)
                    model.CheckLoadingErrors(blockDefinition.Context);

                if (model != null && model.HavokCollisionShapes != null)
                {
                    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.CharacterCollisionLayer);

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

            var worldMatrix = targetGrid != null ? targetGrid.WorldMatrix : MatrixD.Identity;
            return TestPlacementAreaInternal(targetGrid, ref settings, blockDefinition, blockOrientation, ref localAabb, ignoredEntity, ref worldMatrix, out touchingGrid);
        }
        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);
        }
        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)
        {
            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;

            var worldAabb = localAabb.Transform(ref worldMatrix);

            bool entityOverlap = false;
            MyVoxelBase overlappedVoxelMap = null;
            bool touchingStaticGrid = false;
            foreach (var rigidBody in m_physicsBoxQueryList)
            {
                var entity = rigidBody.GetEntity();
                if (entity == null)
                    continue;

                if (ignoredEntity != null && (entity == ignoredEntity || entity.GetTopMostParent() == ignoredEntity))
                    continue;

                var body = rigidBody.GetBody();
                if (body != null && body.IsPhantom)
                    continue;

                var voxelMap = entity as MyVoxelBase;
                if (voxelMap != null)
                {
                    overlappedVoxelMap = voxelMap;
                    continue;
                }

                var grid = entity as MyCubeGrid;
                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;

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


                entityOverlap = true;
                break;
            }
            m_tmpResultList.Clear();
            m_physicsBoxQueryList.Clear();
            ProfilerShort.End();

            if (entityOverlap)
                return false;

            return TestVoxelOverlap(ref settings, ref localAabb, ref worldMatrix, ref worldAabb, ref overlappedVoxelMap, touchingStaticGrid);
        }
        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);
        }
 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);
 }
        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);
        }
 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);
 }
 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);
 }
Exemple #20
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;

            bool canBuild = true;
            if (checkHavokIntersections)
            {
                canBuild = MyCubeGrid.TestPlacementAreaCube(CubeGrid, ref settings, projectedMin, projectedMax, blockOrientation, projectedBlock.BlockDefinition, CubeGrid);
            }

            bool isConnected = MyCubeGrid.CheckConnectivity(this.CubeGrid, projectedBlock.BlockDefinition, ref blockOrientationQuat, ref blockPos);

            if (!canBuild)
            {
                return BuildCheckResult.IntersectedWithSomethingElse;
            }
            else
            {
                if (isConnected)
                {
                    if (CubeGrid.GetCubeBlock(blockPos) == null)
                    {
                        return BuildCheckResult.OK;
                    }
                    else
                    {
                        return BuildCheckResult.AlreadyBuilt;
                    }
                }
            }

            return BuildCheckResult.NotConnected;
        }
        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.Transform(ref worldMatrix);
            var invWorldMatrix = grid.PositionComp.WorldMatrixNormalizedInv;
            var otherLocalAabb = worldAabb.Transform(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;
            }
        }
 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);
 }
        private static bool TestVoxelOverlap(ref MyGridPlacementSettings settings, ref BoundingBoxD localAabb, ref MatrixD worldMatrix, ref BoundingBoxD worldAabb, ref MyVoxelBase overlappedVoxelMap, bool touchingStaticGrid)
        {
            ProfilerShort.Begin("VoxelOverlap");
            try
            {
                if (MyFakes.GRID_IGNORE_VOXEL_OVERLAP) return true;

                if (MyFakes.ENABLE_VOXEL_MAP_AABB_CORNER_TEST)
                {
                    return TestPlacementVoxelMapOverlap(overlappedVoxelMap, ref settings, ref localAabb, ref worldMatrix, touchingStaticGrid: touchingStaticGrid);
                }
                else
                {
                    if (overlappedVoxelMap == null)
                    { // Havok only detects overlap with voxel map surface. This test will detect a voxel map even if we're fully inside it.

                        overlappedVoxelMap = MySession.Static.VoxelMaps.GetVoxelMapWhoseBoundingBoxIntersectsBox(ref worldAabb, null);
                        if (overlappedVoxelMap != null)
                        {
                            //We have just test, if aabb is not completelly inside voxelmap
                            if (!overlappedVoxelMap.IsOverlapOverThreshold(worldAabb))
                                overlappedVoxelMap = null;
                        }
                    }
                    return TestPlacementVoxelMapPenetration(overlappedVoxelMap, ref settings, ref localAabb, ref worldMatrix, touchingStaticGrid: touchingStaticGrid);
                }
            }
            finally
            {
                ProfilerShort.End();
            }
        }
        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)
                {
                    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.CharacterCollisionLayer);

                    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.CharacterCollisionLayer);
                }
            }
            else
            {
                Debug.Assert(m_physicsBoxQueryList.Count == 0, "List not cleared");
                MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref rotation, m_physicsBoxQueryList, MyPhysics.CollisionLayers.CharacterCollisionLayer);
            }
            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;
        }
        private static bool TestPlacementVoxelMapPenetration(
            MyVoxelBase voxelMap, 
            ref MyGridPlacementSettings settings,
            ref BoundingBoxD localAabb,
            ref MatrixD worldMatrix,
            bool touchingStaticGrid = false)
        {
            ProfilerShort.Begin("TestPlacementVoxelMapPenetration");
            var worldAabb = localAabb.Transform(ref worldMatrix);

            float penetrationAmountNormalized = 0f;
            float penetrationRatio = 0f;
            float penetrationVolume = 0f;
            if (voxelMap != null)
            {
                float unused;
                penetrationAmountNormalized = voxelMap.GetVoxelContentInBoundingBox_Obsolete(worldAabb, out unused);
                penetrationVolume = penetrationAmountNormalized * MyVoxelConstants.VOXEL_VOLUME_IN_METERS;
                penetrationRatio = penetrationVolume / (float)worldAabb.Volume;
            }

            bool penetrationTestPassed = true;
            switch (settings.Penetration.Unit)
            {
                case MyGridPlacementSettings.PenetrationUnitEnum.Absolute:
                    penetrationTestPassed = penetrationVolume <= settings.Penetration.MaxAllowed &&
                        (penetrationVolume >= settings.Penetration.MinAllowed || (settings.CanAnchorToStaticGrid && touchingStaticGrid));
                    break;

                case MyGridPlacementSettings.PenetrationUnitEnum.Ratio:
                    penetrationTestPassed = penetrationRatio <= settings.Penetration.MaxAllowed &&
                        (penetrationRatio >= settings.Penetration.MinAllowed || (settings.CanAnchorToStaticGrid && touchingStaticGrid));
                    break;

                default:
                    Debug.Fail("Invalid branch.");
                    break;
            }

            ProfilerShort.End();

            return penetrationTestPassed;
        }
        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)
        {
            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;

            var worldAabb = localAabb.Transform(ref worldMatrix);

            bool entityOverlap = false;
            MyVoxelBase overlappedVoxelMap = null;
            bool touchingStaticGrid = false;
            foreach (var rigidBody in m_physicsBoxQueryList)
            {
                var entity = rigidBody.GetEntity();
                if (entity == null)
                    continue;

                if (ignoredEntity != null && (entity == ignoredEntity || entity.GetTopMostParent() == ignoredEntity))
                    continue;

                var body = rigidBody.GetBody();
                if (body != null && body.IsPhantom)
                    continue;

                var voxelMap = entity as MyVoxelMap;
                if (voxelMap != null)
                {
                    overlappedVoxelMap = voxelMap;
                    continue;
                }

                var grid = entity as MyCubeGrid;
                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;

                    var invWorldMatrix = grid.PositionComp.WorldMatrixNormalizedInv;
                    var otherLocalAabb = worldAabb.Transform(ref invWorldMatrix);

					var scaledMin = otherLocalAabb.Min / grid.GridSize;
                    var scaledMax = otherLocalAabb.Max / grid.GridSize;
                    var min = Vector3I.Round(scaledMin);
                    var max = Vector3I.Round(scaledMax);

                    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;

                        gridBlockOrientation = new MyBlockOrientation(ref rotationInGrid);
                    }

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

                    if (settings.CanAnchorToStaticGrid && grid.IsTouchingAnyNeighbor(min, max))
                    {
                        touchingStaticGrid = true;
                        if (touchingGrid == null)
                            touchingGrid = grid;
                    }

                    continue;
                }


                entityOverlap = true;
                break;
            }
            m_physicsBoxQueryList.Clear();
            ProfilerShort.End();

            if (entityOverlap)
                return false;

            ProfilerShort.Begin("VoxelOverlap");
            if (overlappedVoxelMap == null)
            { // Havok only detects overlap with voxel map surface. This test will detect a voxel map even if we're fully inside it.
                //BoundingSphere sphere = new BoundingSphere(Vector3.Transform(targetGrid.LocalAABB.Center, worldMatrix), targetGrid.LocalAABB.Size.AbsMin() / 2.0f);
                //overlappedVoxelMap = MySession.Static.VoxelMaps.GetOverlappingWithSphere(ref sphere);
                overlappedVoxelMap = MySession.Static.VoxelMaps.GetVoxelMapWhoseBoundingBoxIntersectsBox(ref worldAabb, null);
                if (overlappedVoxelMap != null)
                {
                    float cellCount = 0;
                    var res = overlappedVoxelMap.GetVoxelContentInBoundingBox(worldAabb, out cellCount);
                    if (res < 0.01f)
                        overlappedVoxelMap = null;
                }
                //using (m_tmpResultList.GetClearToken())
                //{
                //    MyGamePruningStructure.GetAllEntitiesInBox(ref worldAabb, m_tmpResultList);

                //    foreach (var entity in m_tmpResultList)
                //    {
                //        MyVoxelMap voxelMap = entity as MyVoxelMap;
                //        if (voxelMap != null)
                //        {
                //            if (voxelMap.DoOverlapSphereTest((float)localAabb.Size.AbsMin() / 2.0f, worldAabb.Center))
                //            {
                //                overlappedVoxelMap = voxelMap;
                //                break;
                //            }
                //        }
                //    }
                //}
            }
            ProfilerShort.End();
            

            return TestPlacementVoxelMapPenetration(overlappedVoxelMap, ref settings, ref localAabb, ref worldMatrix, touchingStaticGrid: touchingStaticGrid);
        }