Esempio n. 1
0
        public static void PaintInShape(
            MyVoxelMap voxelMap,
            MyShape shape,
            byte materialIdx,
            bool updateSync = false)
        {
            Profiler.Begin("MyVoxelGenerator::PaintInShape()");

            if (voxelMap == null)
            {
                return;
            }

            if (updateSync && Sync.IsServer)
            {
                shape.SendPaintRequest(voxelMap.SyncObject, materialIdx);
            }

            Vector3I minCorner = voxelMap.GetVoxelCoordinateFromMeters(shape.GetMin());
            Vector3I maxCorner = voxelMap.GetVoxelCoordinateFromMeters(shape.GetMax());

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

            m_cache.Resize(ref minCorner, ref maxCorner);
            voxelMap.Storage.ReadRange(m_cache, false, true, MyVoxelGeometry.GetLodIndex(MyLodTypeEnum.LOD0), ref minCorner, ref maxCorner);

            Vector3I 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++)
                    {
                        var relPos = tempVoxelCoord - minCorner;
                        m_cache.Material(ref relPos, materialIdx); // set material
                    }
                }
            }

            Profiler.End();
        }
Esempio n. 2
0
        public static void CutOutShape(
            MyVoxelMap voxelMap,
            MyShape shape,
            out float voxelsCountInPercent,
            out MyVoxelMaterialDefinition voxelMaterial,
            float removeRatio = 1,
            Dictionary <MyVoxelMaterialDefinition, int> exactCutOutMaterials = null,
            bool updateSync = true,
            bool onlyCheck  = false)
        {
            Profiler.Begin("MyVoxelGenerator::CutOutShape()");

            if (updateSync && Sync.IsServer)
            {
                shape.SendCutOutRequest(voxelMap.SyncObject, removeRatio);
            }

            int originalSum = 0;
            int removedSum  = 0;

            Vector3I minCorner = voxelMap.GetVoxelCoordinateFromMeters(shape.GetMin());
            Vector3I maxCorner = voxelMap.GetVoxelCoordinateFromMeters(shape.GetMax());

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

            var cacheMin = minCorner - 1;
            var cacheMax = maxCorner + 1;

            voxelMap.FixVoxelCoord(ref cacheMin);
            voxelMap.FixVoxelCoord(ref cacheMax);
            m_cache.Resize(ref cacheMin, ref cacheMax);
            voxelMap.Storage.ReadRange(m_cache, true, true, MyVoxelGeometry.GetLodIndex(MyLodTypeEnum.LOD0), ref cacheMin, ref cacheMax);

            {
                Vector3I exactCenter = voxelMap.GetVoxelCoordinateFromMeters(shape.GetCenter());
                exactCenter  -= cacheMin;
                exactCenter   = Vector3I.Clamp(exactCenter, Vector3I.Zero, m_cache.Size3D - 1);
                voxelMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref exactCenter));
            }

            Vector3I 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++)
                    {
                        var relPos   = tempVoxelCoord - cacheMin; // get original amount
                        var original = m_cache.Content(ref relPos);

                        if (original == MyVoxelConstants.VOXEL_CONTENT_EMPTY) // if there is nothing to remove
                        {
                            continue;
                        }

                        var vpos   = voxelMap.GetVoxelPositionAbsolute(ref tempVoxelCoord);
                        var volume = shape.GetVolume(ref vpos);

                        if (volume == 0f) // if there is no intersection
                        {
                            continue;
                        }

                        var maxRemove = (int)(volume * MyVoxelConstants.VOXEL_CONTENT_FULL);
                        var voxelMat  = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref relPos));
                        var toRemove  = (int)(maxRemove * removeRatio * voxelMat.DamageRatio);
                        if (voxelMap.Storage is MyCellStorage)
                        {
                            if (toRemove < MyCellStorage.Quantizer.GetMinimumQuantizableValue())
                            {
                                toRemove = MyCellStorage.Quantizer.GetMinimumQuantizableValue();
                            }
                        }
                        var newVal  = MathHelper.Clamp(original - toRemove, 0, maxRemove);
                        var removed = Math.Abs(original - newVal);

                        if (!onlyCheck)
                        {
                            m_cache.Content(ref relPos, (byte)newVal);
                        }

                        originalSum += original;
                        removedSum  += removed;

                        if (exactCutOutMaterials != null)
                        {
                            int value = 0;
                            exactCutOutMaterials.TryGetValue(voxelMat, out value);
                            value += (MyFakes.ENABLE_REMOVED_VOXEL_CONTENT_HACK ? (int)(removed * 3.9f) : removed);
                            exactCutOutMaterials[voxelMat] = value;
                        }
                    }
                }
            }

            if (removedSum > 0 && !onlyCheck)
            {
                //  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.
                //!! TODO AR & MK : check if this is needed !!
                RemoveSmallVoxelsUsingChachedVoxels();

                voxelMap.Storage.WriteRange(m_cache, true, false, ref cacheMin, ref cacheMax);
                voxelMap.InvalidateCache(cacheMin, cacheMax);
            }
            voxelsCountInPercent = (originalSum > 0f) ? (float)removedSum / (float)originalSum : 0f;
            Profiler.End();
        }
Esempio n. 3
0
        public static void FillInShape(
            MyVoxelMap voxelMap,
            MyShape shape,
            out float voxelsCountInPercent,
            byte materialIdx,
            float fillRatio = 1,
            bool updateSync = false,
            bool onlyCheck  = false)
        {
            Profiler.Begin("MyVoxelGenerator::FillInShape()");

            if (voxelMap == null)
            {
                voxelsCountInPercent = 0f;
                return;
            }

            if (updateSync && Sync.IsServer)
            {
                shape.SendFillRequest(voxelMap.SyncObject, materialIdx, fillRatio);
            }

            int originalSum = 0;
            int filledSum   = 0;

            Vector3I minCorner = voxelMap.GetVoxelCoordinateFromMeters(shape.GetMin() - MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * 1.01f);
            Vector3I maxCorner = voxelMap.GetVoxelCoordinateFromMeters(shape.GetMax() + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * 1.01f);

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

            m_cache.Resize(ref minCorner, ref maxCorner);
            voxelMap.Storage.ReadRange(m_cache, true, true, MyVoxelGeometry.GetLodIndex(MyLodTypeEnum.LOD0), ref minCorner, ref maxCorner);

            Vector3I 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++)
                    {
                        var relPos   = tempVoxelCoord - minCorner; // get original amount
                        var original = m_cache.Content(ref relPos);

                        if (original == MyVoxelConstants.VOXEL_CONTENT_FULL) // if there is nothing to add
                        {
                            continue;
                        }

                        var vpos   = voxelMap.GetVoxelPositionAbsolute(ref tempVoxelCoord);
                        var volume = shape.GetVolume(ref vpos);

                        if (volume <= 0f) // there is nothing to fill
                        {
                            continue;
                        }

                        m_cache.Material(ref relPos, materialIdx); // set material

                        var maxFill = (int)(volume * MyVoxelConstants.VOXEL_CONTENT_FULL);
                        var toFill  = (int)(maxFill * fillRatio);

                        if (original > maxFill)
                        {
                            maxFill = original;
                        }

                        var newVal = MathHelper.Clamp(original + toFill, 0, maxFill);

                        if (!onlyCheck)
                        {
                            m_cache.Content(ref relPos, (byte)newVal);
                        }

                        originalSum += original;
                        filledSum   += original + newVal;
                    }
                }
            }

            if (filledSum > 0 && !onlyCheck)
            {
                voxelMap.Storage.WriteRange(m_cache, true, true, ref minCorner, ref maxCorner);
                voxelMap.InvalidateCache(minCorner - 1, maxCorner + 1);
            }
            voxelsCountInPercent = (originalSum > 0f) ? (float)filledSum / (float)originalSum : 0f;
            Profiler.End();
        }
        public static void CutOutShape(
            MyVoxelMap voxelMap,
            MyShape shape,
            out float voxelsCountInPercent,
            out MyVoxelMaterialDefinition voxelMaterial,
            float removeRatio = 1,
            Dictionary<MyVoxelMaterialDefinition, int> exactCutOutMaterials = null,
            bool updateSync = true,
            bool onlyCheck = false)
        {
            Profiler.Begin("MyVoxelGenerator::CutOutShape()");

            if (updateSync && Sync.IsServer)
            {
                shape.SendCutOutRequest(voxelMap.SyncObject, removeRatio);
            }

            int originalSum = 0;
            int removedSum  = 0;

            Vector3I minCorner = voxelMap.GetVoxelCoordinateFromMeters(shape.GetMin());
            Vector3I maxCorner = voxelMap.GetVoxelCoordinateFromMeters(shape.GetMax());
            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            var cacheMin = minCorner - 1;
            var cacheMax = maxCorner + 1;
            voxelMap.FixVoxelCoord(ref cacheMin);
            voxelMap.FixVoxelCoord(ref cacheMax);
            m_cache.Resize(ref cacheMin, ref cacheMax);
            voxelMap.Storage.ReadRange(m_cache, true, true, MyVoxelGeometry.GetLodIndex(MyLodTypeEnum.LOD0), ref cacheMin, ref cacheMax);

            {
                Vector3I exactCenter = voxelMap.GetVoxelCoordinateFromMeters(shape.GetCenter());
                exactCenter -= cacheMin;
                exactCenter = Vector3I.Clamp(exactCenter, Vector3I.Zero, m_cache.Size3D-1);
                voxelMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref exactCenter));
            }

            Vector3I 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++)
            {
                var relPos   = tempVoxelCoord - cacheMin; // get original amount
                var original = m_cache.Content(ref relPos);

                if (original == MyVoxelConstants.VOXEL_CONTENT_EMPTY) // if there is nothing to remove
                    continue;

                var vpos   = voxelMap.GetVoxelPositionAbsolute(ref tempVoxelCoord);
                var volume = shape.GetVolume(ref vpos);

                if (volume == 0f) // if there is no intersection
                    continue;

                var maxRemove = (int)(volume * MyVoxelConstants.VOXEL_CONTENT_FULL);
                var voxelMat  = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref relPos));
                var toRemove  = (int)(maxRemove * removeRatio * voxelMat.DamageRatio);
                if (voxelMap.Storage is MyCellStorage)
                {
                    if (toRemove < MyCellStorage.Quantizer.GetMinimumQuantizableValue())
                        toRemove = MyCellStorage.Quantizer.GetMinimumQuantizableValue();
                }
                var newVal    = MathHelper.Clamp(original - toRemove, 0, maxRemove);
                var removed   = Math.Abs(original - newVal);

                if (!onlyCheck)
                    m_cache.Content(ref relPos, (byte)newVal);

                originalSum += original;
                removedSum  += removed;

                if (exactCutOutMaterials != null)
                {
                    int value = 0;
                    exactCutOutMaterials.TryGetValue(voxelMat, out value);
                    value += (MyFakes.ENABLE_REMOVED_VOXEL_CONTENT_HACK ? (int)(removed * 3.9f) : removed);
                    exactCutOutMaterials[voxelMat] = value;
                }
            }

            if (removedSum > 0 && !onlyCheck)
            {
                //  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.
                //!! TODO AR & MK : check if this is needed !!
                RemoveSmallVoxelsUsingChachedVoxels();

                voxelMap.Storage.WriteRange(m_cache, true, false, ref cacheMin, ref cacheMax);
                voxelMap.InvalidateCache(cacheMin, cacheMax);
            }
            voxelsCountInPercent = (originalSum > 0f) ? (float)removedSum / (float)originalSum : 0f;
            Profiler.End();
        }
        public static void PaintInShape(
            MyVoxelMap voxelMap,
            MyShape shape,
            byte materialIdx,
            bool updateSync = false)
        {
            Profiler.Begin("MyVoxelGenerator::PaintInShape()");

            if (voxelMap == null)
            {
                return;
            }

            if (updateSync && Sync.IsServer)
            {
                shape.SendPaintRequest(voxelMap.SyncObject, materialIdx);
            }

            Vector3I minCorner = voxelMap.GetVoxelCoordinateFromMeters(shape.GetMin());
            Vector3I maxCorner = voxelMap.GetVoxelCoordinateFromMeters(shape.GetMax());
            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            m_cache.Resize(ref minCorner, ref maxCorner);
            voxelMap.Storage.ReadRange(m_cache, false, true, MyVoxelGeometry.GetLodIndex(MyLodTypeEnum.LOD0), ref minCorner, ref maxCorner);

            Vector3I 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++)
            {
                var relPos = tempVoxelCoord - minCorner;
                m_cache.Material(ref relPos, materialIdx); // set material
            }

            Profiler.End();
        }
        public static void FillInShape(
            MyVoxelMap voxelMap,
            MyShape shape,
            out float voxelsCountInPercent,
            byte materialIdx,
            float fillRatio = 1,
            bool updateSync = false,
            bool onlyCheck = false)
        {
            Profiler.Begin("MyVoxelGenerator::FillInShape()");

            if (voxelMap == null)
            {
                voxelsCountInPercent = 0f;
                return;
            }

            if (updateSync && Sync.IsServer)
            {
                shape.SendFillRequest(voxelMap.SyncObject, materialIdx, fillRatio);
            }

            int originalSum = 0;
            int filledSum   = 0;

            Vector3I minCorner = voxelMap.GetVoxelCoordinateFromMeters(shape.GetMin() - MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * 1.01f);
            Vector3I maxCorner = voxelMap.GetVoxelCoordinateFromMeters(shape.GetMax() + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * 1.01f);
            voxelMap.FixVoxelCoord(ref minCorner);
            voxelMap.FixVoxelCoord(ref maxCorner);

            m_cache.Resize(ref minCorner, ref maxCorner);
            voxelMap.Storage.ReadRange(m_cache, true, true, MyVoxelGeometry.GetLodIndex(MyLodTypeEnum.LOD0), ref minCorner, ref maxCorner);

            Vector3I 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++)
            {
                var relPos   = tempVoxelCoord - minCorner; // get original amount
                var original = m_cache.Content(ref relPos);

                if (original == MyVoxelConstants.VOXEL_CONTENT_FULL) // if there is nothing to add
                    continue;

                var vpos   = voxelMap.GetVoxelPositionAbsolute(ref tempVoxelCoord);
                var volume = shape.GetVolume(ref vpos);

                if (volume <= 0f) // there is nothing to fill
                    continue;

                m_cache.Material(ref relPos, materialIdx); // set material

                var maxFill = (int)(volume * MyVoxelConstants.VOXEL_CONTENT_FULL);
                var toFill  = (int)(maxFill * fillRatio);

                if (original > maxFill)
                    maxFill = original;

                var newVal = MathHelper.Clamp(original + toFill, 0, maxFill);

                if (!onlyCheck)
                    m_cache.Content(ref relPos, (byte)newVal);

                originalSum += original;
                filledSum += original + newVal;
            }

            if (filledSum > 0 && !onlyCheck)
            {
                voxelMap.Storage.WriteRange(m_cache, true, true, ref minCorner, ref maxCorner);
                voxelMap.InvalidateCache(minCorner - 1, maxCorner + 1);
            }
            voxelsCountInPercent = (originalSum > 0f) ? (float)filledSum / (float)originalSum : 0f;
            Profiler.End();
        }