Esempio n. 1
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);
            }
        }
Esempio n. 2
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;
        }
Esempio n. 3
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();
        }
Esempio n. 4
0
        //  Cut-outs a sphere from a voxel map.
        //  Generates inverse sphere in a voxel map (extract matters, create hole, etc - it's like explosion). We modify only voxels inside the sphere - set them to full or partialy full.
        //  Other voxel are untouched. Center is relative to voxel map (not world coordinates). Radius is in metres.
        //
        //  IMPORTANT:
        //  This is non-optimized version (faster one is CutOutSphereFast). But it doesn't mean this one is slow... the difference is probably just 10-20%
        public static void CutOutSphere(MyVoxelMap voxelMap, BoundingSphere sphere)
        {
            //  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);

            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)
                        {
                            int newVal = originalContent - contentToRemove;
                            if (newVal < MyVoxelConstants.VOXEL_CONTENT_EMPTY) newVal = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            voxelMap.SetVoxelContent((byte)newVal, ref tempVoxelCoord);
                        }

                    }
                }
            }
        }
Esempio n. 5
0
        //  Generates sphere in a voxel map. We modify only voxels inside the sphere - set them to full or partialy full.
        //  Other voxel are untouched. Center is relative to voxel map (not world coordinates). Radius is in metres.
        public static void CreateSphere(MyVoxelMap voxelMap, BoundingSphere sphere)
        {
            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MyVoxelGenerator.CreateSphere");

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

            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)
                        {
                            voxelMap.SetVoxelContent(newContent, ref tempVoxelCoord);
                        }
                    }
                }
            }

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
        }
Esempio 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);
            }
        }
Esempio n. 7
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
Esempio n. 8
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
Esempio n. 9
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();
        }