Ejemplo n.º 1
0
        void PerformAction(MyVoxelMap voxelMap, MyvoxelImportAction action, MyMwcVoxelMaterialsEnum? voxelMaterial, ref bool changed)
        {
            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("PerformAction");

            //  Voxel map size must be multiple of grid size. Or, whole grid must fit exactly into X times into voxel map, without crossing border!
            MyCommonDebugUtils.AssertRelease((voxelMap.Size.X % VOXELS_IN_GRID_IN_ONE_DIRECTION) == 0);

            //  Voxel map size must be multiple of grid size. Or, whole grid must fit exactly into X times into voxel map, without crossing border!
            MyCommonDebugUtils.AssertRelease((voxelMap.Size.Z % VOXELS_IN_GRID_IN_ONE_DIRECTION) == 0);

            int gridsCountX = voxelMap.Size.X / VOXELS_IN_GRID_IN_ONE_DIRECTION;
            int gridsCountZ = voxelMap.Size.Z / VOXELS_IN_GRID_IN_ONE_DIRECTION;

            //  Space between two grid points in metres
            m_gridPointsSize = MyVoxelConstants.VOXEL_SIZE_IN_METRES / (float)GRID_POINTS_IN_ONE_VOXEL_IN_ONE_DIRECTION;
            m_gridPointsSizeHalf = m_gridPointsSize / 2.0f;

            //  Get min corner of the box
            MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(m_minCoord);

            //  Get max corner of the box
            MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(m_maxCoord);

            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            //  We are tracking which voxels were changed, so we can invalidate only needed cells in the cache
            MyMwcVector3Int minChanged = maxCorner;
            MyMwcVector3Int maxChanged = minCorner;

            bool contentChanged = false;

            for (int gridX = 0; gridX < gridsCountX; gridX++)
            {
                for (int gridZ = 0; gridZ < gridsCountZ; gridZ++)
                {
                    if (PerformGridAction(voxelMap, action, gridX, gridZ, ref minChanged, ref maxChanged, voxelMaterial, ref changed))
                    {
                        contentChanged = true;
                    }
                }
            }

            if (contentChanged)
            {
                //  Extend borders for cleaning, so it's one pixel on both sides
                minChanged.X -= 1;
                minChanged.Y -= 1;
                minChanged.Z -= 1;
                maxChanged.X += 1;
                maxChanged.Y += 1;
                maxChanged.Z += 1;
                voxelMap.FixVoxelCoord(ref minChanged);
                voxelMap.FixVoxelCoord(ref maxChanged);

                voxelMap.InvalidateCache(minChanged, maxChanged);
            }

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
        }
Ejemplo n.º 2
0
        public static void ChangeMaterialInBoxRelative(MyVoxelMap voxelMap, Vector3 relativeMin, Vector3 relativeMax, MyMwcVoxelMaterialsEnum material)
        {
            BoundingBox boundingBox = voxelMap.WorldAABB;

            //  Get min and max cell coordinate where camera bounding box can fit
            MyMwcVector3Int cellCoordMin = voxelMap.GetVoxelCoordinateFromMeters(boundingBox.Min);
            MyMwcVector3Int cellCoordMax = voxelMap.GetVoxelCoordinateFromMeters(boundingBox.Max);

            //  Fix min and max cell coordinates so they don't overlap the voxelmap
            voxelMap.FixVoxelCoord(ref cellCoordMin);
            voxelMap.FixVoxelCoord(ref cellCoordMax);

            cellCoordMin.X = (int)(cellCoordMax.X * relativeMin.X);
            cellCoordMin.Y = (int)(cellCoordMax.Y * relativeMin.Y);
            cellCoordMin.Z = (int)(cellCoordMax.Z * relativeMin.Z);

            cellCoordMax.X = (int)(cellCoordMax.X * relativeMax.X);
            cellCoordMax.Y = (int)(cellCoordMax.Y * relativeMax.Y);
            cellCoordMax.Z = (int)(cellCoordMax.Z * relativeMax.Z);

            MyMwcVector3Int cellCoord;

            for (cellCoord.X = cellCoordMin.X; cellCoord.X <= cellCoordMax.X; cellCoord.X++)
            {
                for (cellCoord.Y = cellCoordMin.Y; cellCoord.Y <= cellCoordMax.Y; cellCoord.Y++)
                {
                    for (cellCoord.Z = cellCoordMin.Z; cellCoord.Z <= cellCoordMax.Z; cellCoord.Z++)
                    {
                        voxelMap.SetVoxelMaterialAndIndestructibleContent(material, 0, ref cellCoord);
                    }
                }
            }

            voxelMap.InvalidateCache(cellCoordMin, cellCoordMax);
            voxelMap.CalcAverageDataCellMaterials();

            //MyVoxelMaps.RecalcVoxelMaps();
        }
Ejemplo n.º 3
0
        public static void FillEmpty(MyVoxelMap voxelMap)
        {
            float safeSize = 5; // Size in voxels to leave area empty on voxel map border
            var size = voxelMap.Size;
            for (int x = 0; x < size.X; x++)
            {
                for (int y = 0; y < size.Y; y++)
                {
                    for (int z = 0; z < size.Z; z++)
                    {
                        MyMwcVector3Int coords = new MyMwcVector3Int(x, y, z);

                        if (x <= safeSize || y <= safeSize || z <= safeSize || x >= size.X - safeSize - 1 || y >= size.Y - safeSize - 1 || z >= size.Z - safeSize - 1)
                        {
                            voxelMap.SetVoxelContent(0, ref coords);
                        }
                        else
                        {
                            voxelMap.SetVoxelContent(0, ref coords);
                        }
                    }
                }
            }
            voxelMap.InvalidateCache(new MyMwcVector3Int(0, 0, 0), size);
        }
Ejemplo n.º 4
0
        //  This is same as normal cut-out sphere, but cache is invalidated like in cut-out sphere fast(so that voxel cut-out will be immediately visible)
        public static void CutOutSphereInvalidateCache(MyVoxelMap voxelMap, BoundingSphere sphere, ref bool changed)
        {
            //  Get min corner of the explosion
            MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(new Vector3(
                sphere.Center.X - sphere.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES,
                sphere.Center.Y - sphere.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES,
                sphere.Center.Z - sphere.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES));

            //  Get max corner of the explosion
            MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(new Vector3(
                sphere.Center.X + sphere.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES,
                sphere.Center.Y + sphere.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES,
                sphere.Center.Z + sphere.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES));

            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            //  We are tracking which voxels were changed, so we can invalidate only needed cells in the cache
            MyMwcVector3Int minChanged = maxCorner;
            MyMwcVector3Int maxChanged = minCorner;

            int removedVoxelContent = 0;

            MyMwcVector3Int tempVoxelCoord;
            for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++)
            {
                for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++)
                {
                    for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++)
                    {
                        Vector3 voxelPosition = voxelMap.GetVoxelCenterPositionAbsolute(ref tempVoxelCoord);
                        float dist = (voxelPosition - sphere.Center).Length();
                        float diff = dist - sphere.Radius;

                        byte contentToRemove;
                        if (diff > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                        }
                        else if (diff < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_FULL;
                        }
                        else
                        {
                            //  This formula will work even if diff is positive or negative
                            contentToRemove = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - diff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                        }

                        int originalContent = voxelMap.GetVoxelContent(ref tempVoxelCoord);
                        if (originalContent > MyVoxelConstants.VOXEL_CONTENT_EMPTY && contentToRemove > MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                        {
                            changed = true;

                            int newVal = originalContent - contentToRemove;
                            if (newVal < MyVoxelConstants.VOXEL_CONTENT_EMPTY) newVal = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            voxelMap.SetVoxelContent((byte)newVal, ref tempVoxelCoord);

                            removedVoxelContent += originalContent - newVal;

                            if (tempVoxelCoord.X < minChanged.X) minChanged.X = tempVoxelCoord.X;
                            if (tempVoxelCoord.Y < minChanged.Y) minChanged.Y = tempVoxelCoord.Y;
                            if (tempVoxelCoord.Z < minChanged.Z) minChanged.Z = tempVoxelCoord.Z;
                            if (tempVoxelCoord.X > maxChanged.X) maxChanged.X = tempVoxelCoord.X;
                            if (tempVoxelCoord.Y > maxChanged.Y) maxChanged.Y = tempVoxelCoord.Y;
                            if (tempVoxelCoord.Z > maxChanged.Z) maxChanged.Z = tempVoxelCoord.Z;
                        }
                    }
                }
            }

            if (removedVoxelContent > 0)
            {
                //  Extend borders for cleaning, so it's one pixel on both sides
                minChanged.X -= 1;
                minChanged.Y -= 1;
                minChanged.Z -= 1;
                maxChanged.X += 1;
                maxChanged.Y += 1;
                maxChanged.Z += 1;
                voxelMap.FixVoxelCoord(ref minChanged);
                voxelMap.FixVoxelCoord(ref maxChanged);

                voxelMap.InvalidateCache(minChanged, maxChanged);
            }
        }
Ejemplo n.º 5
0
        //  Cut outs a sphere from voxel map (e.g. explosion in a voxel map). We modify only voxels inside the sphere - set them to full or partialy full.
        //  Other voxel are untouched. Sphere coordinates are in world space, not relative to voxel map and is in metres.
        //
        //  Method returns percent of how much voxels were removed by this explosion (value 0.0 means no voxels; value 1.0 means all voxels)
        //
        //  IMPORTANT:
        //  This is optimized version that uses cache for accessing voxels. But the cache has limits so it can be used only for not extremely large cut-outs.
        //  Non-optimized version is: CutOutSphere - but it doesn't mean it's slow... the difference is probably just 10-20%
        //
        //  Returns true if indestructible voxels has been hit (otherwise false)
        public static bool CutOutSphereFast(MyVoxelMap voxelMap, BoundingSphere explosion, out float voxelsCountInPercent, out MyMwcVoxelMaterialsEnum? voxelMaterial, bool isPlayerExplosion = false, float removeRatio = 1, Dictionary<MyMwcVoxelMaterialsEnum, int> exactCutOutMaterials = null)
        {
            explosion.Radius = System.Math.Min(explosion.Radius, MyExplosionsConstants.EXPLOSION_RADIUS_MAX);

            InvalidateCache = true; 

            voxelMaterial = null;

            MyMwcVoxelMaterialsEnum newVoxelMaterialTemp;
            byte tempminContentValueByte;
            MyMwcVector3Int exactCenterOfExplosion = voxelMap.GetVoxelCoordinateFromMeters(new Vector3(explosion.Center.X, explosion.Center.Y, explosion.Center.Z));
            voxelMap.FixVoxelCoord(ref exactCenterOfExplosion);
            voxelMap.GetMaterialAndIndestructibleContent(ref exactCenterOfExplosion, out newVoxelMaterialTemp, out tempminContentValueByte);
            if (voxelMaterial == null)
                voxelMaterial = newVoxelMaterialTemp;   //  We need to replace this only once


            int originalVoxelContentsSum = 0;       //  Sum of all voxel contents affected by this explosion before we extract any voxel. This value is increasing per every voxel, no matter if we realy extract it.
            int removedVoxelContentsSum = 0;        //  Sum of all voxel contents we removed by this explosion. This value increases only if we extract something from voxel map.

            //  Get min corner of the explosion
            MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(new Vector3(
                explosion.Center.X - explosion.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES,
                explosion.Center.Y - explosion.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES,
                explosion.Center.Z - explosion.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES));

            //  Get max corner of the explosion
            MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(new Vector3(
                explosion.Center.X + explosion.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES,
                explosion.Center.Y + explosion.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES,
                explosion.Center.Z + explosion.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES));

            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            MyMwcVector3Int cachedSubtract;
            cachedSubtract.X = minCorner.X - CACHED_BOUNDARY_IN_VOXELS;
            cachedSubtract.Y = minCorner.Y - CACHED_BOUNDARY_IN_VOXELS;
            cachedSubtract.Z = minCorner.Z - CACHED_BOUNDARY_IN_VOXELS;

            //  We are tracking which voxels were changed, so we can invalidate only needed cells in the cache
            MyMwcVector3Int minChanged = maxCorner;
            MyMwcVector3Int maxChanged = minCorner;

            MyMwcVector3Int tempVoxelCoord;
            bool indestructible = true;
            for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++)
            {
                for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++)
                {
                    for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++)
                    {
                        Vector3 voxelPosition = voxelMap.GetVoxelCenterPositionAbsolute(ref tempVoxelCoord);
                        float dist = (voxelPosition - explosion.Center).Length();
                        float diff = dist - explosion.Radius;

                        //  This number will tell us how much of this voxel we will remove (can be zero, can be full voxel, or between)
                        int contentToRemove;
                        if (diff > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                        }
                        else if (diff < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_FULL;
                        }
                        else
                        {
                            //  This formula will work even if diff is positive or negative
                            contentToRemove = (int)(MyVoxelConstants.VOXEL_ISO_LEVEL - diff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                        }

                        contentToRemove = (int)(contentToRemove * removeRatio);

                        //  Only if we have to remove something (e.g. voxels that are outside of the radius aren't affected, or voxels that are 
                        //  in cornes are always out of the radius, even if they are in bounding box)
                        if (contentToRemove > MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                        {

                            byte minContentValueByte;
                            MyMwcVoxelMaterialsEnum voxelMaterialTemp;
                            voxelMap.GetMaterialAndIndestructibleContent(ref tempVoxelCoord, out voxelMaterialTemp, out minContentValueByte);

                            int minContentValue = minContentValueByte;

                            if (minContentValue != MyVoxelConstants.VOXEL_CONTENT_FULL)
                            {
                                indestructible = false;
                            }

                            //  Alter only non-empty voxels (because we can't remove empty voxel...)
                            int originalContent = GetCachedVoxelContent(voxelMap, ref tempVoxelCoord, ref cachedSubtract);
                            if (originalContent > minContentValue)
                            {
                                //  IMPORTANT: When doing transformations on 'content' value, cast it to int always!!!
                                //  It's because you can easily forget that result will be negative and if you put negative into byte, it will
                                //  be overflown and you will be surprised by results!!

                                int newVal = originalContent - contentToRemove;
                                if (newVal < minContentValue) newVal = minContentValue;

                                voxelMap.SetVoxelContent((byte)newVal, ref tempVoxelCoord);
                                SetCachedVoxelContent(voxelMap, ref tempVoxelCoord, ref cachedSubtract, (byte)newVal);

                                //  Sum of all voxel contents affected by this explosion before we extract any voxel. This value is increasing per every voxel, no matter if we realy extract it.
                                originalVoxelContentsSum += originalContent;

                                //  Sum of all voxel contents we removed by this explosion. This value increases only if we extract something from voxel map.
                                removedVoxelContentsSum += originalContent - newVal;

                                if (exactCutOutMaterials != null)
                                {
                                    int oldValue = 0;
                                    exactCutOutMaterials.TryGetValue(voxelMaterialTemp, out oldValue);
                                    exactCutOutMaterials[voxelMaterialTemp] = oldValue + removedVoxelContentsSum;
                                }

                                if (tempVoxelCoord.X < minChanged.X) minChanged.X = tempVoxelCoord.X;
                                if (tempVoxelCoord.Y < minChanged.Y) minChanged.Y = tempVoxelCoord.Y;
                                if (tempVoxelCoord.Z < minChanged.Z) minChanged.Z = tempVoxelCoord.Z;
                                if (tempVoxelCoord.X > maxChanged.X) maxChanged.X = tempVoxelCoord.X;
                                if (tempVoxelCoord.Y > maxChanged.Y) maxChanged.Y = tempVoxelCoord.Y;
                                if (tempVoxelCoord.Z > maxChanged.Z) maxChanged.Z = tempVoxelCoord.Z;
                            }
                        }
                    }
                }
            }

            InvalidateCache = false;

            if (removedVoxelContentsSum > 0)
            {
                //  Extend borders for cleaning, so it's one pixel on both sides
                minChanged.X -= 1;
                minChanged.Y -= 1;
                minChanged.Z -= 1;
                maxChanged.X += 1;
                maxChanged.Y += 1;
                maxChanged.Z += 1;
                voxelMap.FixVoxelCoord(ref minChanged);
                voxelMap.FixVoxelCoord(ref maxChanged);

                //  Clear all small voxel that may have been created during explosion. They can be created even outside the range of
                //  explosion sphere, e.g. if you have three voxels in a row A, B, C, where A is 255, B is 60, and C is 255. During the
                //  explosion you change C to 0, so now we have 255, 60, 0. Than another explosion that will change A to 0, so we 
                //  will have 0, 60, 0. But B was always outside the range of the explosion. So this is why we need to do -1/+1 and remove
                //  B voxels too.
                RemoveSmallVoxelsUsingChachedVoxels(voxelMap, ref minCorner, ref maxCorner, ref cachedSubtract);

                //  Extend borders for invalidating the cache, so it's one pixel on both sides
                minChanged.X -= 1;
                minChanged.Y -= 1;
                minChanged.Z -= 1;
                maxChanged.X += 1;
                maxChanged.Y += 1;
                maxChanged.Z += 1;
                voxelMap.FixVoxelCoord(ref minChanged);
                voxelMap.FixVoxelCoord(ref maxChanged);

                //  Invalidate cache for voxels cells covered by explosion and some boundary voxels too
                voxelMap.InvalidateCache(minCorner, maxCorner);

                voxelMap.AddExplosion(explosion);
            }

            if (originalVoxelContentsSum > 0f)
            {
                voxelsCountInPercent = (float)removedVoxelContentsSum / (float)originalVoxelContentsSum;
            }
            else
            {
                voxelsCountInPercent = 0f;
            }

            return indestructible;
        }
Ejemplo n.º 6
0
        //  This is same as normal cut-out box, but cache is invalidated (so that voxel changes be immediately visible)
        public static void CutOutBoxInvalidateCache(MyVoxelMap voxelMap, BoundingBox box, ref bool changed)
        {
            //  Get min corner of the box
            MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(box.Min);

            //  Get max corner of the box
            MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(box.Max);

            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            //  We are tracking which voxels were changed, so we can invalidate only needed cells in the cache
            MyMwcVector3Int minChanged = maxCorner;
            MyMwcVector3Int maxChanged = minCorner;

            int removedVoxelContent = 0;

            MyMwcVector3Int tempVoxelCoord;
            for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++)
            {
                for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++)
                {
                    for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++)
                    {
                        Vector3 voxelPosition = voxelMap.GetVoxelCenterPositionAbsolute(ref tempVoxelCoord);
                        byte contentToRemove = MyVoxelConstants.VOXEL_CONTENT_FULL;

                        int originalContent = voxelMap.GetVoxelContent(ref tempVoxelCoord);
                        if (originalContent > MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                        {
                            changed = true;

                            int newVal = originalContent - contentToRemove;
                            if (newVal < MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                                newVal = MyVoxelConstants.VOXEL_CONTENT_EMPTY;

                            voxelMap.SetVoxelContent((byte)newVal, ref tempVoxelCoord);

                            removedVoxelContent += originalContent - newVal;

                            if (tempVoxelCoord.X < minChanged.X) minChanged.X = tempVoxelCoord.X;
                            if (tempVoxelCoord.Y < minChanged.Y) minChanged.Y = tempVoxelCoord.Y;
                            if (tempVoxelCoord.Z < minChanged.Z) minChanged.Z = tempVoxelCoord.Z;
                            if (tempVoxelCoord.X > maxChanged.X) maxChanged.X = tempVoxelCoord.X;
                            if (tempVoxelCoord.Y > maxChanged.Y) maxChanged.Y = tempVoxelCoord.Y;
                            if (tempVoxelCoord.Z > maxChanged.Z) maxChanged.Z = tempVoxelCoord.Z;
                        }
                    }
                }
            }

            if (removedVoxelContent > 0)
            {
                //  Extend borders for cleaning, so it's one pixel on both sides
                minChanged.X -= 1;
                minChanged.Y -= 1;
                minChanged.Z -= 1;
                maxChanged.X += 1;
                maxChanged.Y += 1;
                maxChanged.Z += 1;
                voxelMap.FixVoxelCoord(ref minChanged);
                voxelMap.FixVoxelCoord(ref maxChanged);

                voxelMap.InvalidateCache(minChanged, maxChanged);
            }
        }
Ejemplo n.º 7
0
        // This is same as normal CreateSphere method, but cache is invalidated (so that voxel changes be immediately visible)
        public static void CreateSphereInvalidateCache(MyVoxelMap voxelMap, BoundingSphere sphere, ref bool changed, MyMwcVoxelMaterialsEnum? material)
        {
            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MyVoxelGenerator.CreateSphereInvalidateCache");

            //  Get min corner of the explosion
            MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(new Vector3(
                sphere.Center.X - sphere.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES,
                sphere.Center.Y - sphere.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES,
                sphere.Center.Z - sphere.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES));

            //  Get max corner of the explosion
            MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(new Vector3(
                sphere.Center.X + sphere.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES,
                sphere.Center.Y + sphere.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES,
                sphere.Center.Z + sphere.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES));

            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            //  We are tracking which voxels were changed, so we can invalidate only needed cells in the cache
            MyMwcVector3Int minChanged = maxCorner;
            MyMwcVector3Int maxChanged = minCorner;

            bool sphereAdded = false;

            MyMwcVector3Int tempVoxelCoord;
            for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++)
            {
                for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++)
                {
                    for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++)
                    {
                        Vector3 voxelPosition = voxelMap.GetVoxelCenterPositionAbsolute(ref tempVoxelCoord);
                        float dist = (voxelPosition - sphere.Center).Length();
                        float diff = dist - sphere.Radius;

                        byte newContent;
                        if (diff > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            newContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                        }
                        else if (diff < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            newContent = MyVoxelConstants.VOXEL_CONTENT_FULL;
                        }
                        else
                        {
                            //  This formula will work even if diff is positive or negative
                            newContent = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - diff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                        }

                        byte originalContent = voxelMap.GetVoxelContent(ref tempVoxelCoord);

                        if (newContent > originalContent)
                        {
                            if (material.HasValue)
                            {
                                MyMwcVoxelMaterialsEnum originalMaterial;
                                byte originalIndestructibleContent;

                                voxelMap.GetMaterialAndIndestructibleContent(ref tempVoxelCoord, out originalMaterial, out originalIndestructibleContent);
                                voxelMap.SetVoxelMaterialAndIndestructibleContent(material.Value, originalIndestructibleContent, ref tempVoxelCoord);
                            }

                            changed = true;
                            voxelMap.SetVoxelContent(newContent, ref tempVoxelCoord);
                            sphereAdded = true;

                            if (tempVoxelCoord.X < minChanged.X) minChanged.X = tempVoxelCoord.X;
                            if (tempVoxelCoord.Y < minChanged.Y) minChanged.Y = tempVoxelCoord.Y;
                            if (tempVoxelCoord.Z < minChanged.Z) minChanged.Z = tempVoxelCoord.Z;
                            if (tempVoxelCoord.X > maxChanged.X) maxChanged.X = tempVoxelCoord.X;
                            if (tempVoxelCoord.Y > maxChanged.Y) maxChanged.Y = tempVoxelCoord.Y;
                            if (tempVoxelCoord.Z > maxChanged.Z) maxChanged.Z = tempVoxelCoord.Z;
                        }
                    }
                }
            }

            if (sphereAdded == true)
            {
                //  Extend borders for cleaning, so it's one pixel on both sides
                minChanged.X -= 1;
                minChanged.Y -= 1;
                minChanged.Z -= 1;
                maxChanged.X += 1;
                maxChanged.Y += 1;
                maxChanged.Z += 1;
                voxelMap.FixVoxelCoord(ref minChanged);
                voxelMap.FixVoxelCoord(ref maxChanged);

                voxelMap.InvalidateCache(minChanged, maxChanged);
            }

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
        }
Ejemplo n.º 8
0
        // This is same as normal CreateBox method, but cache is invalidated (so that voxel changes be immediately visible)
        public static void CreateBoxInvalidateCache(MyVoxelMap voxelMap, BoundingBox box, ref bool changed)
        {
            //  Get min corner of the box
            MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(box.Min);

            //  Get max corner of the box
            MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(box.Max);

            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            //  We are tracking which voxels were changed, so we can invalidate only needed cells in the cache
            MyMwcVector3Int minChanged = maxCorner;
            MyMwcVector3Int maxChanged = minCorner;

            bool sphereAdded = false;

            MyMwcVector3Int tempVoxelCoord;
            for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++)
            {
                for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++)
                {
                    for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++)
                    {
                        byte newContent = MyVoxelConstants.VOXEL_CONTENT_FULL;

                        byte originalContent = voxelMap.GetVoxelContent(ref tempVoxelCoord);

                        if (newContent > originalContent)
                        {
                            changed = true;
                            voxelMap.SetVoxelContent(newContent, ref tempVoxelCoord);
                            sphereAdded = true;

                            if (tempVoxelCoord.X < minChanged.X) minChanged.X = tempVoxelCoord.X;
                            if (tempVoxelCoord.Y < minChanged.Y) minChanged.Y = tempVoxelCoord.Y;
                            if (tempVoxelCoord.Z < minChanged.Z) minChanged.Z = tempVoxelCoord.Z;
                            if (tempVoxelCoord.X > maxChanged.X) maxChanged.X = tempVoxelCoord.X;
                            if (tempVoxelCoord.Y > maxChanged.Y) maxChanged.Y = tempVoxelCoord.Y;
                            if (tempVoxelCoord.Z > maxChanged.Z) maxChanged.Z = tempVoxelCoord.Z;
                        }
                    }
                }
            }

            if (sphereAdded == true)
            {
                //  Extend borders for cleaning, so it's one pixel on both sides
                minChanged.X -= 1;
                minChanged.Y -= 1;
                minChanged.Z -= 1;
                maxChanged.X += 1;
                maxChanged.Y += 1;
                maxChanged.Z += 1;
                voxelMap.FixVoxelCoord(ref minChanged);
                voxelMap.FixVoxelCoord(ref maxChanged);

                voxelMap.InvalidateCache(minChanged, maxChanged);
            }
        }
Ejemplo n.º 9
0
        } //Create Cuboid


        public static void CutOutCuboid(MyVoxelMap voxelMap, MyCuboid cuboid, MyMwcVoxelMaterialsEnum? material)
        {
            BoundingBox aabb = cuboid.GetAABB();


            MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(aabb.Min - new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES));
            MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(aabb.Max + new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES));

            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            MyMwcVector3Int tempVoxelCoord;
            for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++)
            {
                for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++)
                {
                    for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++)
                    {
                        Vector3 position = voxelMap.GetVoxelCenterPositionAbsolute(ref tempVoxelCoord);
                        BoundingBox voxelAABB = new BoundingBox(position - new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF), position + new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF));

                        bool isInside = true;

                        for (int i = 0; i < cuboid.Sides.Length; i++)
                        {
                            MyPlane side = cuboid.Sides[i].Plane;
                            float distance = MyUtils.GetDistanceFromPointToPlane(ref position, ref side);
                            if (distance > 0)
                            {
                                isInside = false;
                                break;
                            }
                        }

                        float minDistance = float.MaxValue;

                        for (int i = 0; i < cuboid.Sides.Length; i++)
                        {
                            MyQuad quad = new MyQuad();
                            quad.Point0 = cuboid.Sides[i].Lines[0].From;
                            quad.Point1 = cuboid.Sides[i].Lines[1].From;
                            quad.Point2 = cuboid.Sides[i].Lines[3].From;
                            quad.Point3 = cuboid.Sides[i].Lines[2].From;

                            float distance = MyUtils.GetDistancePointToQuad(ref position, ref quad);
                            if (distance < minDistance)
                            {
                                minDistance = distance;
                            }
                        }


                        byte newContent = 0;


                        if (isInside)
                        {
                            if (minDistance > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                            {
                                newContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            }
                            else
                            {
                                //  This formula will work even if diff is positive or negative
                                //newContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                newContent = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - minDistance / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                //newContent = (byte)(MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - minDistance / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL));
                            }
                        }
                        else
                        {
                            if (minDistance > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                            {
                                newContent = MyVoxelConstants.VOXEL_CONTENT_FULL;
                            }
                            else
                            {
                                //newContent = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                //  This formula will work even if diff is positive or negative
                                //newContent = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - minDistance / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                newContent = (byte)(MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - minDistance / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL));
                            }
                        }

                        byte originalContent = voxelMap.GetVoxelContent(ref tempVoxelCoord);

                        if (newContent < originalContent)
                        {
                            voxelMap.SetVoxelContent(newContent, ref tempVoxelCoord);
                            if (material.HasValue)
                                voxelMap.SetVoxelMaterialAndIndestructibleContent(material.Value, 0, ref tempVoxelCoord);
                        }
                    }
                }
            }

            voxelMap.InvalidateCache(minCorner, maxCorner);
            voxelMap.CalcAverageDataCellMaterials();
        } //CutOut Cuboid
Ejemplo n.º 10
0
        } //CreateCylinder


        public static void CutOutCylinder(MyVoxelMap voxelMap, float radius1, float radius2, MyOrientedBoundingBox box, MyMwcVoxelMaterialsEnum? material, ref bool changed)
        {
            //box.HalfExtent x = radius1
            //box.HalfExtent y = length/2
            //box.HalfExtent z = radius2


            BoundingBox aabb = box.GetAABB();

            MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(aabb.Min - new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES));
            MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(aabb.Max + new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES));

            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            MyMwcVector3Int tempVoxelCoord;
            for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++)
            {
                for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++)
                {
                    for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++)
                    {
                        Vector3 position = voxelMap.GetVoxelCenterPositionAbsolute(ref tempVoxelCoord);

                        //BoundingBox voxelAABB = new BoundingBox(position - new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF), position + new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF));

                        byte newContent = 0;

                        // Transform the point into box-local space and check against
                        // our extents.
                        Quaternion qinv = Quaternion.Conjugate(box.Orientation);
                        Vector3 plocal = Vector3.Transform(position - box.Center, qinv);

                        //MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF 

                        float distY = 0;
                        int sY = System.Math.Sign(plocal.Y);

                        if (sY > 0)
                        {
                            distY = plocal.Y - box.HalfExtent.Y;
                        }
                        else
                        {
                            distY = plocal.Y + box.HalfExtent.Y;
                        }

                        float distRatio = 1;
                        distRatio = MathHelper.Clamp((plocal.Y + box.HalfExtent.Y) / (2 * box.HalfExtent.Y), 0, 1);

                        int contentY = -1;

                        if (sY > 0)
                        {
                            if (distY > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                            {
                                contentY = MyVoxelConstants.VOXEL_CONTENT_FULL;
                            }
                            else if (distY < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                            {
                                contentY = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            }
                            else
                            {
                                //  This formula will work even if diff is positive or negative
                                //contentY = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distY / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                contentY = MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distY / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                            }
                        }
                        else
                        {
                            if (distY < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                            {
                                contentY = MyVoxelConstants.VOXEL_CONTENT_FULL;
                            }
                            else if (distY > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                            {
                                contentY = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            }
                            else
                            {
                                //  This formula will work even if diff is positive or negative
                                //contentY = MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distY / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                contentY = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distY / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                            }
                        }


                        Matrix boxMatrix = Matrix.CreateFromQuaternion(box.Orientation);
                        Vector3 hY1 = box.Center + boxMatrix.Up * box.HalfExtent.Y;
                        Vector3 hY2 = box.Center + boxMatrix.Down * box.HalfExtent.Y;

                        float dist = MyUtils.GetPointLineDistance(ref hY1, ref hY2, ref position);
                        float diff = dist - MathHelper.Lerp(radius2, radius1, distRatio);
                        //float diff = dist - box.HalfExtent.Z;

                        byte newContent2;
                        if (diff > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            newContent2 = MyVoxelConstants.VOXEL_CONTENT_FULL;
                        }
                        else if (diff < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            newContent2 = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                        }
                        else
                        {
                            //  This formula will work even if diff is positive or negative
                            //newContent2 = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - diff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                            newContent2 = (byte)(MyVoxelConstants.VOXEL_CONTENT_FULL - (int)(MyVoxelConstants.VOXEL_ISO_LEVEL - diff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL));
                        }


                        newContent = (byte)System.Math.Max(contentY, newContent2);
                        //newContent = (byte)contentY; 

                        byte originalContent = voxelMap.GetVoxelContent(ref tempVoxelCoord);

                        if (newContent < originalContent)
                        {
                            voxelMap.SetVoxelContent(newContent, ref tempVoxelCoord);
                            if (material.HasValue)
                                voxelMap.SetVoxelMaterialAndIndestructibleContent(material.Value, 0, ref tempVoxelCoord);
                        }

                    }
                }
            }

            voxelMap.InvalidateCache(minCorner, maxCorner);
            voxelMap.CalcAverageDataCellMaterials();

        } //CutoutCylinder
Ejemplo n.º 11
0
        public static void CutOutOrientedBox(MyVoxelMap voxelMap, MyOrientedBoundingBox box, ref bool changed)
        {
            BoundingBox aabb = box.GetAABB();

            MyMwcVector3Int minCorner = voxelMap.GetVoxelCoordinateFromMeters(aabb.Min - new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES));
            MyMwcVector3Int maxCorner = voxelMap.GetVoxelCoordinateFromMeters(aabb.Max + new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES));

            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            System.Threading.Tasks.Parallel.For(minCorner.X, maxCorner.X, i =>
                {
                    System.Threading.Tasks.Parallel.For(minCorner.Y, maxCorner.Y, j =>
                        {
                            System.Threading.Tasks.Parallel.For(minCorner.Z, maxCorner.Z, k =>
                            {
                                MyMwcVector3Int tempVoxelCoord = new MyMwcVector3Int(i, j, k);
                                Vector3 position = voxelMap.GetVoxelCenterPositionAbsolute(ref tempVoxelCoord);
                                BoundingBox voxelAABB = new BoundingBox(position - new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF), position + new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF));

                                byte newContent = 0;
                                ContainmentType ct = box.Contains(ref voxelAABB);
                                if (ct == ContainmentType.Contains)
                                {
                                    newContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                }
                                else
                                    if (ct == ContainmentType.Disjoint)
                                    {
                                        newContent = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                    }
                                    else
                                    {

                                        // Transform the point into box-local space and check against
                                        // our extents.
                                        Quaternion qinv = Quaternion.Conjugate(box.Orientation);
                                        Vector3 plocal = Vector3.Transform(position - box.Center, qinv);

                                        //MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF 

                                        float distX = 0;
                                        float distY = 0;
                                        float distZ = 0;

                                        int sX = System.Math.Sign(plocal.X);
                                        int sY = System.Math.Sign(plocal.Y);
                                        int sZ = System.Math.Sign(plocal.Z);

                                        if (sX > 0)
                                        {
                                            distX = plocal.X - box.HalfExtent.X;
                                        }
                                        else
                                        {
                                            distX = plocal.X + box.HalfExtent.X;
                                        }

                                        if (sY > 0)
                                        {
                                            distY = plocal.Y - box.HalfExtent.Y;
                                        }
                                        else
                                        {
                                            distY = plocal.Y + box.HalfExtent.Y;
                                        }

                                        if (sZ > 0)
                                        {
                                            distZ = plocal.Z - box.HalfExtent.Z;
                                        }
                                        else
                                        {
                                            distZ = plocal.Z + box.HalfExtent.Z;
                                        }

                                        //float diff = (distX + distY + distZ) / 3;
                                        //float diff = (sX*sY*sZ) * System.Math.Min(System.Math.Min(distX,distY), distZ);

                                        int contentX;
                                        int contentY;
                                        int contentZ;

                                        if (sX < 0)
                                        {
                                            if (distX > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentX = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                            }
                                            else if (distX < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentX = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                            }
                                            else
                                            {
                                                //  This formula will work even if diff is positive or negative
                                                contentX = MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distX / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                            }
                                        }
                                        else
                                        {
                                            if (distX < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentX = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                            }
                                            else if (distX > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentX = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                            }
                                            else
                                            {
                                                //  This formula will work even if diff is positive or negative
                                                contentX = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distX / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                            }
                                        }



                                        if (sY < 0)
                                        {
                                            if (distY > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentY = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                            }
                                            else if (distY < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentY = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                            }
                                            else
                                            {
                                                //  This formula will work even if diff is positive or negative
                                                contentY = MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distY / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                            }
                                        }
                                        else
                                        {
                                            if (distY < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentY = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                            }
                                            else if (distY > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentY = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                            }
                                            else
                                            {
                                                //  This formula will work even if diff is positive or negative
                                                contentY = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distY / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                            }
                                        }


                                        if (sZ < 0)
                                        {
                                            if (distZ > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentZ = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                            }
                                            else if (distZ < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentZ = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                            }
                                            else
                                            {
                                                //  This formula will work even if diff is positive or negative
                                                contentZ = MyVoxelConstants.VOXEL_CONTENT_FULL - (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distZ / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                            }
                                        }
                                        else
                                        {
                                            if (distZ < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentZ = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                                            }
                                            else if (distZ > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                                            {
                                                contentZ = MyVoxelConstants.VOXEL_CONTENT_FULL;
                                            }
                                            else
                                            {
                                                //  This formula will work even if diff is positive or negative
                                                contentZ = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - distZ / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                                            }
                                        }

                                        //voxelMap.SetVoxelContent( (byte)((contentX + contentY + contentZ)/3.0f), ref tempVoxelCoord);
                                        newContent = (byte)(System.Math.Min(System.Math.Min(contentX, contentY), contentZ));
                                    }


                                byte originalContent = voxelMap.GetVoxelContent(ref tempVoxelCoord);

                                if (newContent < originalContent)
                                {
                                    voxelMap.SetVoxelContent(newContent, ref tempVoxelCoord, true);
                                    //changed = true;
                                }
                            });
                        });
                });

            /*
            for (tempVoxelCoord.X = minCorner.X; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++)
            {
                for (tempVoxelCoord.Y = minCorner.Y; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++)
                {
                    for (tempVoxelCoord.Z = minCorner.Z; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++)
                    {
                        
                       
                    }
                }
            }*/

            changed = true;
            voxelMap.InvalidateCache(minCorner, maxCorner);
            voxelMap.CalcAverageDataCellMaterials();
        }
        //  Create world using data received from server
        public void CreateWorldFromDataReceivedFromServer()
        {
            MyMwcLog.WriteLine("CreateWorldFromDataReceivedFromServer - START");

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("CreateWorldFromDataReceivedFromServer");

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MySession.BeforeLoad");
            MySession.Static.BeforeLoad(m_checkpoint);
            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            CreateWorldFromDataReceivedFromServer_LoadCheckpoint();
            
            bool canUseGenerator = m_sessionType.Value != MyMwcStartSessionRequestTypeEnum.EDITOR_SANDBOX && m_sessionType.Value != MyMwcStartSessionRequestTypeEnum.SANDBOX_OWN && MyFakes.ENABLE_GENERATED_ASTEROIDS;
            if (m_checkpoint.SectorObjectBuilder.FromGenerator && canUseGenerator) // When no sector on server, use procedural generator
            {
                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("ProceduralGenerator.Player");
                if (m_checkpoint.PlayerObjectBuilder == null)
                {
                    MyMwcObjectBuilder_SmallShip_Player playerShipObjectBuilder = CreatePlayerShip();
                    playerShipObjectBuilder.PositionAndOrientation.Position = Vector3.Zero;
                    playerShipObjectBuilder.PositionAndOrientation.Up = Vector3.Up;
                    playerShipObjectBuilder.PositionAndOrientation.Forward = Vector3.Forward;
                    m_checkpoint.PlayerObjectBuilder = new MyMwcObjectBuilder_Player(100f, 10000f, 0f, null, playerShipObjectBuilder, null);
                }
                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
            }

            UpdateSmallshipsOfferedByVendors(m_checkpoint);

            if (((m_checkpoint.SectorObjectBuilder.FromGenerator && MyFakes.ENABLE_GENERATED_ASTEROIDS) || canUseGenerator)) // When no sector on server, use procedural generator
            {
                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Generating sector");

                //Use objects from server and generate new items into them
                //m_checkpoint.SectorObjectBuilder.SectorObjects = new List<MyMwcObjectBuilder_Base>();

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Safe areas");

                if (m_checkpoint.SectorObjectBuilder.SectorObjects == null)
                {
                    m_checkpoint.SectorObjectBuilder.SectorObjects = new List<MyMwcObjectBuilder_Base>();
                }

                MyMwcLog.WriteLine("Adding safe areas");

                List<BoundingSphere> safeAreas = new List<BoundingSphere>();
                foreach (MyMwcObjectBuilder_Base objectBuilder in m_checkpoint.SectorObjectBuilder.SectorObjects)
                {
                    MyMwcObjectBuilder_DummyPoint dummyObjectBuilder = objectBuilder as MyMwcObjectBuilder_DummyPoint;
                    if (dummyObjectBuilder != null && dummyObjectBuilder.DummyFlags.HasFlag(MyDummyPointFlags.SAFE_AREA))
                    {
                        safeAreas.Add(new BoundingSphere(dummyObjectBuilder.PositionAndOrientation.Position, dummyObjectBuilder.Size.Length() / 2.0f));
                    }

                    MyMwcObjectBuilder_VoxelMap voxelObjectBuilder = objectBuilder as MyMwcObjectBuilder_VoxelMap;
                    if (voxelObjectBuilder != null)
                    {
                        MyMwcVector3Int sizeInVoxels = MyVoxelFiles.Get(voxelObjectBuilder.VoxelFile).SizeInVoxels;
                        Vector3 sizeInMeters = new Vector3(MyVoxelConstants.VOXEL_SIZE_IN_METRES * sizeInVoxels.X, MyVoxelConstants.VOXEL_SIZE_IN_METRES * sizeInVoxels.Y, MyVoxelConstants.VOXEL_SIZE_IN_METRES * sizeInVoxels.Z);
                        safeAreas.Add(new BoundingSphere(voxelObjectBuilder.PositionAndOrientation.Position, sizeInMeters.Length() / 2.0f));
                    }
                }
                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

                MyMwcLog.WriteLine("GenerateSector");
                MySolarSystemMapSectorData sectorData = GenerateSector(m_sectorIdentifier.Position, m_checkpoint.SectorObjectBuilder.SectorObjects, safeAreas, m_checkpoint.SectorObjectBuilder.SectorObjects.Count > 0);

                //MySolarSystemMapSectorData sectorData = GenerateSectorData();
                m_checkpoint.SectorObjectBuilder.AreaTemplate = sectorData.Area;
                m_checkpoint.SectorObjectBuilder.AreaMultiplier = sectorData.AreaInfluenceMultiplier;

                MySector.UseGenerator = true;

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
            }
            else if (!m_checkpoint.SectorObjectBuilder.AreaTemplate.HasValue)
            {
                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Generating sector area data");
                MySolarSystemMapSectorData sectorData = GenerateSectorData();
                m_checkpoint.SectorObjectBuilder.AreaTemplate = sectorData.Area;
                m_checkpoint.SectorObjectBuilder.AreaMultiplier = sectorData.AreaInfluenceMultiplier;
                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
            }

            MyMwcLog.WriteLine("CreateFromSectorObjectBuilder");
            CreateFromSectorObjectBuilder(m_checkpoint.SectorObjectBuilder);


            MyTrailerLoad.TrailerAnimation = null;

            //  If null, then loop above didn't contain player's ship
            MyCommonDebugUtils.AssertRelease(MySession.PlayerShip != null);

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Preload cockpit models");

            MySmallShip playerShip = MySession.PlayerShip;
            //  Pre-load player's cockpit interior models
            //  IMPORTANT: Only data and no vertex buffers, because this method is called from Update and not from Draw
            MyModels.GetModelOnlyData(MySession.PlayerShip.CockpitInteriorModelEnum);
            MyModels.GetModelOnlyData(MySession.PlayerShip.CockpitGlassModelEnum);
            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            //0002325: AI - Add friend bot to story and sandbox, he will be there by default.
            if (!IsEditorActive() && MyFakes.SPAWN_FRIENDS == true)
            {
                MySession.PlayerFriends.Clear();// when saving bots will be enabled please remove this
                if (MySession.PlayerFriends.Count == 0)
                {
                    MySmallShipBot bot = CreateFakeBot("Friend", MyMwcObjectBuilder_SmallShip_TypesEnum.GREISER, MySession.PlayerShip.WorldMatrix.Translation + new Vector3(0, 30, 30), 1f, MyMwcObjectBuilder_FactionEnum.Euroamerican);
                    MySession.PlayerFriends.Add(bot);
                    bot.Follow(MySession.PlayerShip);
                    bot.Save = false;

                    bot = CreateFakeBot("Friend", MyMwcObjectBuilder_SmallShip_TypesEnum.GREISER, MySession.PlayerShip.WorldMatrix.Translation + new Vector3(0, -30, 30), 1f, MyMwcObjectBuilder_FactionEnum.Euroamerican);
                    MySession.PlayerFriends.Add(bot);
                    bot.Follow(MySession.PlayerShip);
                    bot.Save = false;
                }
            }

            MyMwcLog.WriteLine("MySession.Static.AfterLoad");
            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("AfterLoad");
            MySession.Static.AfterLoad(m_checkpoint);
            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();


            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Side missions");
            // Side missions
            foreach (var dummy in MyEntities.GetEntities().OfType<MyDummyPoint>())
            {
                if ((dummy.DummyFlags & MyDummyPointFlags.SIDE_MISSION) != 0)
                {
                    MyMwcLog.WriteLine("Side missions");
                    // TODO: Choose random submission
                    var sideMission = new MySideMissionAssassination(new MyMissionBase.MyMissionLocation(m_checkpoint.CurrentSector.Position, dummy.EntityId.Value.NumericValue));
                    if (MyMissions.GetMissionByID(sideMission.ID) == null)
                    {
                        MyMissions.AddMission(sideMission);
                    }
                }
            }
            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            MyMwcLog.WriteLine("MySession.Static.Player.TravelEnter");
            //Unpacks player friends needed for mission script
            MySession.Static.Player.TravelEnter();

            if (MySession.Is25DSector)
                MyGlobalEvents.DisableAllGlobalEvents();
            else
                MyGlobalEvents.EnableAllGlobalEvents();

            // Init active mission
            System.Diagnostics.Debug.Assert(MyMissions.ActiveMission == null);

            MyMwcLog.WriteLine("Active mission load - START");
            if (GetGameType() == MyGuiScreenGamePlayType.GAME_STORY && (MyMultiplayerGameplay.Static == null || MyMultiplayerGameplay.Static.IsHost))
            {
                MyMwcLog.WriteLine("Starting story mission");

                if (m_checkpoint.ActiveMissionID != -1)
                {
                    MyMwcLog.WriteLine("ActiveMissionID: " + m_checkpoint.ActiveMissionID);

                    MyMission mission = MyMissions.GetMissionByID((MyMissionID)m_checkpoint.ActiveMissionID) as MyMission;
                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Load active mission");
                    if (mission.IsMainSector)
                    {
                        mission.InsertRequiredActors();
                    }
                    mission.Load();
                    MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                }
                else
                {
                    MyMwcLog.WriteLine("ActiveMissionID: none");

                    if (m_missionToStart.HasValue)
                    {
                        MyMission mission = MyMissions.GetMissionByID(m_missionToStart.Value) as MyMission;
                        MyScriptWrapper.DebugSetFactions(mission);
                        mission.Accept();

                        m_missionToStart = null;
                    }
                }
                MyMissions.RefreshAvailableMissions();

                if (m_travelReason == MyMwcTravelTypeEnum.SOLAR)
                {
                    if (MyMissions.ActiveMission == null || MyMissions.ActiveMission.MovePlayerToMadelynHangar)
                    {
                        if (MyMissionBase.IsPlayerShipNearMadelyn())
                        {
                            if (MyMissions.ActiveMission != null)
                                MyMissionBase.MovePlayerAndFriendsToHangar(MyMissions.ActiveMission.RequiredActors);
                            else
                                MyMissionBase.MovePlayerAndFriendsToHangar(new MyActorEnum[] { MyActorEnum.MARCUS, MyActorEnum.TARJA, MyActorEnum.VALENTIN });
                        }
                    }
                }


            }
            else if (GetGameType() == MyGuiScreenGamePlayType.GAME_SANDBOX)
            {
                MyMwcLog.WriteLine("Starting sandbox mission");
                MyMissions.StartSandboxMission(m_checkpoint.CurrentSector.Position);
            }
            MyMwcLog.WriteLine("Active mission load - END");

            MyEntities.UpdateAfterSimulation(); //Updates AABBs of objects

            if (MyMultiplayerGameplay.IsStory())
            {
                MyMultiplayerGameplay.MakeInventoryItemsTradeable(MySession.PlayerShip);
            }


            if (MyFakes.MWBUILDER)
            {
                MyVoxelMap voxelMap = null;

                if (MyVoxelMaps.GetVoxelMapsCount() == 0)
                {
                   // MyMwcObjectBuilder_VoxelMap voxelMapOb = new MyMwcObjectBuilder_VoxelMap(Vector3.Zero, MyMwcVoxelFilesEnum.Cube_512x512x512, MyMwcVoxelMaterialsEnum.Stone_01);
                   // voxelMap = (MyVoxelMap)MyEntities.CreateFromObjectBuilderAndAdd(null, voxelMapOb, Matrix.Identity);
                    voxelMap = new MyVoxelMap();
                    voxelMap.Init(Vector3.Zero, new MyMwcVector3Int(1024, 1024, 1024), MyMwcVoxelMaterialsEnum.Stone_01);

                    //MyVoxelImport.Fill(voxelMap);
                    MyVoxelImport.FillEmpty(voxelMap);

                    MyEntities.Add(voxelMap);

                    voxelMap.SetPosition(Vector3.Zero);
                 

                    MyVoxelGenerator.CreateSphere(voxelMap, new BoundingSphere(Vector3.Zero, 1024));
                    voxelMap.InvalidateCache(new MyMwcVector3Int(0, 0, 0), new MyMwcVector3Int(1024, 1024, 1024));
                    

                    MyVoxelMaps.RecalcVoxelMaps();

                    voxelMap.UpdateAABBHr();


                    voxelMap.SaveVoxelContents(Path.Combine(MyMinerGame.Static.RootDirectory, "VoxelMaps", MyVoxelFiles.ExportFile + ".vox"));

                    //MyVoxelGenerator.CutOutBoxRelative(voxelMap, new Vector3(0, 0.5f, 0), new Vector3(1, 1, 1));
                    /*
  MyVoxelGenerator.ChangeMaterialInBoxRelative(voxelMap, new Vector3(0, 0.49f, 0), new Vector3(1, 0.5f, 1), MyMwcVoxelMaterialsEnum.Uranite_01);
  MyVoxelGenerator.ChangeMaterialInBoxRelative(voxelMap, new Vector3(0, 0.2f, 0), new Vector3(1, 0.49f, 1), MyMwcVoxelMaterialsEnum.Nickel_01);
  MyVoxelGenerator.ChangeMaterialInBoxRelative(voxelMap, new Vector3(0, 0.0f, 0), new Vector3(1, 0.1f, 1), MyMwcVoxelMaterialsEnum.Lava_01);
                     */
                }
                else
                {
                    voxelMap = MyVoxelMaps.GetVoxelMaps()[0];

                    MyPhysics.physicsSystem.GravitationPoints.Clear();
                    MyPhysics.physicsSystem.GravitationPoints.Add(new Tuple<BoundingSphere,float>(new BoundingSphere(voxelMap.WorldAABB.GetCenter(), voxelMap.WorldAABB.Size().Length()), 2000));

                    
              //      voxelMap.Init(Vector3.Zero, new MyMwcVector3Int(1024, 1024, 1024), MyMwcVoxelMaterialsEnum.Stone_01);
              //      MyVoxelImport.Fill(voxelMap);
              //      MyVoxelGenerator.CutOutBoxRelative(voxelMap, new Vector3(0, 0.3f, 0), new Vector3(1, 1, 1));

              //      string name = Path.Combine(MyFileSystemUtils.GetApplicationUserDataFolder(), "VoxelMap_0_mikrogen.vox");
              //      voxelMap.SaveVoxelContents(name);
                      
              //      voxelMap.SetName("VoxelMap_0_mikrogen.vox");
              //      voxelMap.Init(null, Vector3.Zero, null);
                }
                    
                MySpectator.Position = voxelMap.WorldAABB.GetCenter();

                MyCamera.SetViewMatrix(MySpectator.GetViewMatrix());
            }

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            MyMwcLog.WriteLine("CreateWorldFromDataReceivedFromServer - END");
        }