Example #1
0
        public override MyShape Clone()
        {
            MyShapeSphere sphere1 = new MyShapeSphere();

            sphere1.Transformation = base.Transformation;
            sphere1.Center         = this.Center;
            sphere1.Radius         = this.Radius;
            return(sphere1);
        }
Example #2
0
        public static void MakeCrater(MyVoxelBase voxelMap, BoundingSphereD sphere, Vector3 direction, MyVoxelMaterialDefinition material)
        {
            ProfilerShort.Begin("MakeCrater");

            Vector3 normal = Vector3.Normalize(sphere.Center - voxelMap.RootVoxel.WorldMatrix.Translation);

            Vector3I minCorner, maxCorner;
            {
                Vector3D sphereMin = sphere.Center - (sphere.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES) * 1.3f;
                Vector3D sphereMax = sphere.Center + (sphere.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES) * 1.3f;
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref sphereMin, out minCorner);
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref sphereMax, out maxCorner);
            }

            voxelMap.Storage.ClampVoxelCoord(ref minCorner);
            voxelMap.Storage.ClampVoxelCoord(ref maxCorner);

            Vector3I worldMinCorner = minCorner + voxelMap.StorageMin;
            Vector3I worldMaxCorner = maxCorner + voxelMap.StorageMin;

            //  We are tracking which voxels were changed, so we can invalidate only needed cells in the cache
            bool changed = false;
            ProfilerShort.Begin("Reading cache");
            m_cache.Resize(minCorner, maxCorner);

            voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, ref worldMinCorner, ref worldMaxCorner);

            ProfilerShort.End();

            ProfilerShort.Begin("Changing cache");
            int removedVoxelContent = 0;
            Vector3I tempVoxelCoord;
            Vector3I cachePos = (maxCorner - minCorner) / 2;

            byte oldMaterial = m_cache.Material(ref cachePos);

            float digRatio = 1 - Vector3.Dot(normal, direction);

            Vector3 newCenter = sphere.Center - normal * (float)sphere.Radius * 1.1f;//0.9f;
            float sphRadA = (float)(sphere.Radius * 1.5f);
            float sphRadSqA = (float)(sphRadA * sphRadA);
            float voxelSizeHalfTransformedPosA = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (2 * sphRadA + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);
            float voxelSizeHalfTransformedNegA = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (-2 * sphRadA + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);

            Vector3 newDelCenter = newCenter + normal * (float)sphere.Radius * (0.7f + digRatio) + direction * (float)sphere.Radius * 0.65f;
            float sphRadD = (float)(sphere.Radius);
            float sphRadSqD = (float)(sphRadD * sphRadD);
            float voxelSizeHalfTransformedPosD = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (2 * sphRadD + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);
            float voxelSizeHalfTransformedNegD = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (-2 * sphRadD + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);

            Vector3 newSetCenter = newCenter + normal * (float)sphere.Radius * (digRatio) + direction * (float)sphere.Radius * 0.3f;
            float sphRadS = (float)(sphere.Radius * 0.1f);
            float sphRadSqS = (float)(sphRadS * sphRadS);
            float voxelSizeHalfTransformedPosS = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (2 * sphRadS + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);

            for (tempVoxelCoord.Z = minCorner.Z, cachePos.Z = 0; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++, ++cachePos.Z)
            {
                for (tempVoxelCoord.Y = minCorner.Y, cachePos.Y = 0; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++, ++cachePos.Y)
                {
                    for (tempVoxelCoord.X = minCorner.X, cachePos.X = 0; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++, ++cachePos.X)
                    {
                        Vector3D voxelPosition;
                        MyVoxelCoordSystems.VoxelCoordToWorldPosition(voxelMap.PositionLeftBottomCorner, ref tempVoxelCoord, out voxelPosition);

                        byte originalContent = m_cache.Content(ref cachePos);

                        //Add sphere
                        if (originalContent != MyVoxelConstants.VOXEL_CONTENT_FULL)
                        {

                            float addDist = (float)(voxelPosition - newCenter).LengthSquared();
                            float addDiff = (float)(addDist - sphRadSqA);

                        byte newContent;
                            if (addDiff > voxelSizeHalfTransformedPosA)
                        {
                            newContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                        }
                            else if (addDiff < voxelSizeHalfTransformedNegA)
                        {
                            newContent = MyVoxelConstants.VOXEL_CONTENT_FULL;
                        }
                        else
                        {
                                float value = (float)Math.Sqrt(addDist + sphRadSqA - 2 * sphRadA * Math.Sqrt(addDist));
                                if (addDiff < 0) { value = -value; }
                            //  This formula will work even if diff is positive or negative
                                newContent = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - value / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                        }

                            if (newContent > originalContent)
                        {
                            if (material != null)
                            {
                                    m_cache.Material(ref cachePos, oldMaterial);
                            }

                            changed = true;
                            m_cache.Content(ref cachePos, newContent);
                        }
                        }

                        //Delete sphere
                        float delDist = (float)(voxelPosition - newDelCenter).LengthSquared();
                        float delDiff = (float)(delDist - sphRadSqD);

                        byte contentToRemove;
                        if (delDiff > voxelSizeHalfTransformedPosD)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                        }
                        else if (delDiff < voxelSizeHalfTransformedNegD)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_FULL;
                        }
                        else
                        {
                            float value = (float)Math.Sqrt(delDist + sphRadSqD - 2 * sphRadD * Math.Sqrt(delDist));
                            if (delDiff < 0) { value = -value; }
                            //  This formula will work even if diff is positive or negative
                            contentToRemove = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - value / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                        }

                        originalContent = m_cache.Content(ref cachePos);

                        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;
                            m_cache.Content(ref cachePos, (byte)newVal);

                            removedVoxelContent += originalContent - newVal;
                        }

                        //Set material

                        float setDist = (float)(voxelPosition - newSetCenter).LengthSquared();
                        float setDiff = (float)(setDist - sphRadSqS);

                        if (setDiff <= MyVoxelConstants.VOXEL_SIZE_IN_METRES * 1.5f)  // could be VOXEL_SIZE_IN_METRES_HALF, but we want to set material in empty cells correctly
                        {

                            MyVoxelMaterialDefinition originalMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref cachePos));

                            // Change the material:
                            // - always on boundaries between material and nothing
                            // - smoothly on inner boundaries
                            MyVoxelMaterialDefinition newMaterial = material;
                            if (setDiff > 0)
                            {
                                byte content = m_cache.Content(ref cachePos);
                                if (content == MyVoxelConstants.VOXEL_CONTENT_FULL)
                                    newMaterial = originalMaterial;
                                if (setDiff >= voxelSizeHalfTransformedPosS && content != MyVoxelConstants.VOXEL_CONTENT_EMPTY)  // set material behind boundary only for empty voxels
                                    newMaterial = originalMaterial;
                            }

                            if (originalMaterial == newMaterial)
                            {
                                continue;
                            }

                            m_cache.Material(ref cachePos, newMaterial.Index);
                            changed = true;
                        }

                        float dist = (float)(voxelPosition - newCenter).LengthSquared();
                        float diff = (float)(dist - sphRadSqA);

                        if (diff <= 0f)
                        {
                            originalContent = m_cache.Content(ref cachePos);
                            if (originalContent > MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                            {
                                bool wrinkled = m_cache.WrinkleVoxelContent(ref cachePos, MyVoxelConstants.DEFAULT_WRINKLE_WEIGHT_ADD, MyVoxelConstants.DEFAULT_WRINKLE_WEIGHT_REMOVE);
                                if (wrinkled)
                                    changed = true;
                            }
                        }
                    }
                }
            }
            ProfilerShort.End();

            if (changed)
            {
                ProfilerShort.Begin("RemoveSmallVoxelsUsingChachedVoxels");
                RemoveSmallVoxelsUsingChachedVoxels();
                ProfilerShort.BeginNextBlock("Writing cache");
                minCorner += voxelMap.StorageMin;
                maxCorner += voxelMap.StorageMin;
                voxelMap.Storage.WriteRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, ref minCorner, ref maxCorner);
                MyShapeSphere sphereShape = new MyShapeSphere();
                sphereShape.Center = sphere.Center;
                sphereShape.Radius = (float)(sphere.Radius*1.5);
                OnVoxelChanged(OperationType.Cut, voxelMap, sphereShape);
                ProfilerShort.End();
            }

            ProfilerShort.End();
        }
        private MyBrushSphere()
        {
            m_shape = new MyShapeSphere();
            m_shape.Radius = MinScale;
            m_transform = MatrixD.Identity;

            m_radius = new MyBrushGUIPropertyNumberSlider(
                m_shape.Radius, MinScale, MaxScale,
                MySessionComponentVoxelHand.VOXEL_HALF,
                MyVoxelBrushGUIPropertyOrder.First, MyCommonTexts.VoxelHandProperty_Sphere_Radius
            );
            m_radius.ValueChanged += RadiusChanged;

            m_list = new List<MyGuiControlBase>();
            m_radius.AddControlsToList(m_list);
        }
Example #4
0
        protected virtual bool TryDrillVoxels(MyVoxelBase voxels, Vector3D hitPosition, bool collectOre, bool onlyCheck)
        {
            const float DISCARDING_MULTIPLIER = 3.0f;

            bool somethingDrilled = false;
            var  bsphere = new MyShapeSphere()
            {
                Center = m_cutOut.Sphere.Center,
                Radius = (float)m_cutOut.Sphere.Radius
            };
            if (!collectOre) bsphere.Radius *= DISCARDING_MULTIPLIER;

            float voxelsCountInPercent;
            MyVoxelMaterialDefinition material;
            MyVoxelGenerator.CutOutShapeWithProperties(voxels, bsphere,
                out voxelsCountInPercent, out material, m_drilledMaterialBuffer, Sync.IsServer, onlyCheck);

            foreach (var entry in m_drilledMaterialBuffer)
            {
                somethingDrilled = (!collectOre || TryHarvestOreMaterial(entry.Key, hitPosition, entry.Value, onlyCheck)) || somethingDrilled;

                if (somethingDrilled && !onlyCheck)
                {
                    MyDebris.Static.CreateDirectedDebris(hitPosition,
                            MyUtils.GetRandomVector3Normalized(), 0.1f, 1, 0, MathHelper.Pi, 5, 1, 0.15f, entry.Key);
                }
            }

            m_drilledMaterialBuffer.Clear();
            return somethingDrilled;
        }
Example #5
0
        public static void MakeCrater(MyVoxelBase voxelMap, BoundingSphereD sphere, Vector3 direction, MyVoxelMaterialDefinition material)
        {
            ProfilerShort.Begin("MakeCrater");

            Vector3 normal = Vector3.Normalize(sphere.Center - voxelMap.RootVoxel.WorldMatrix.Translation);

            Vector3I minCorner, maxCorner;

            {
                Vector3D sphereMin = sphere.Center - (sphere.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES) * 1.3f;
                Vector3D sphereMax = sphere.Center + (sphere.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES) * 1.3f;
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref sphereMin, out minCorner);
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref sphereMax, out maxCorner);
            }

            voxelMap.Storage.ClampVoxelCoord(ref minCorner);
            voxelMap.Storage.ClampVoxelCoord(ref maxCorner);

            Vector3I worldMinCorner = minCorner + voxelMap.StorageMin;
            Vector3I worldMaxCorner = maxCorner + voxelMap.StorageMin;

            //  We are tracking which voxels were changed, so we can invalidate only needed cells in the cache
            bool changed = false;

            ProfilerShort.Begin("Reading cache");
            m_cache.Resize(minCorner, maxCorner);

            voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, ref worldMinCorner, ref worldMaxCorner);

            ProfilerShort.End();

            ProfilerShort.Begin("Changing cache");
            int      removedVoxelContent = 0;
            Vector3I tempVoxelCoord;
            Vector3I cachePos = (maxCorner - minCorner) / 2;

            byte oldMaterial = m_cache.Material(ref cachePos);

            float digRatio = 1 - Vector3.Dot(normal, direction);

            Vector3 newCenter = sphere.Center - normal * (float)sphere.Radius * 1.1f;//0.9f;
            float   sphRadA   = (float)(sphere.Radius * 1.5f);
            float   sphRadSqA = (float)(sphRadA * sphRadA);
            float   voxelSizeHalfTransformedPosA = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (2 * sphRadA + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);
            float   voxelSizeHalfTransformedNegA = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (-2 * sphRadA + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);

            Vector3 newDelCenter = newCenter + normal * (float)sphere.Radius * (0.7f + digRatio) + direction * (float)sphere.Radius * 0.65f;
            float   sphRadD      = (float)(sphere.Radius);
            float   sphRadSqD    = (float)(sphRadD * sphRadD);
            float   voxelSizeHalfTransformedPosD = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (2 * sphRadD + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);
            float   voxelSizeHalfTransformedNegD = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (-2 * sphRadD + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);

            Vector3 newSetCenter = newCenter + normal * (float)sphere.Radius * (digRatio) + direction * (float)sphere.Radius * 0.3f;
            float   sphRadS      = (float)(sphere.Radius * 0.1f);
            float   sphRadSqS    = (float)(sphRadS * sphRadS);
            float   voxelSizeHalfTransformedPosS = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (2 * sphRadS + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);

            for (tempVoxelCoord.Z = minCorner.Z, cachePos.Z = 0; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++, ++cachePos.Z)
            {
                for (tempVoxelCoord.Y = minCorner.Y, cachePos.Y = 0; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++, ++cachePos.Y)
                {
                    for (tempVoxelCoord.X = minCorner.X, cachePos.X = 0; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++, ++cachePos.X)
                    {
                        Vector3D voxelPosition;
                        MyVoxelCoordSystems.VoxelCoordToWorldPosition(voxelMap.PositionLeftBottomCorner, ref tempVoxelCoord, out voxelPosition);

                        byte originalContent = m_cache.Content(ref cachePos);

                        //Add sphere
                        if (originalContent != MyVoxelConstants.VOXEL_CONTENT_FULL)
                        {
                            float addDist = (float)(voxelPosition - newCenter).LengthSquared();
                            float addDiff = (float)(addDist - sphRadSqA);

                            byte newContent;
                            if (addDiff > voxelSizeHalfTransformedPosA)
                            {
                                newContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            }
                            else if (addDiff < voxelSizeHalfTransformedNegA)
                            {
                                newContent = MyVoxelConstants.VOXEL_CONTENT_FULL;
                            }
                            else
                            {
                                float value = (float)Math.Sqrt(addDist + sphRadSqA - 2 * sphRadA * Math.Sqrt(addDist));
                                if (addDiff < 0)
                                {
                                    value = -value;
                                }
                                //  This formula will work even if diff is positive or negative
                                newContent = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - value / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                            }

                            if (newContent > originalContent)
                            {
                                if (material != null)
                                {
                                    m_cache.Material(ref cachePos, oldMaterial);
                                }

                                changed = true;
                                m_cache.Content(ref cachePos, newContent);
                            }
                        }

                        //Delete sphere
                        float delDist = (float)(voxelPosition - newDelCenter).LengthSquared();
                        float delDiff = (float)(delDist - sphRadSqD);

                        byte contentToRemove;
                        if (delDiff > voxelSizeHalfTransformedPosD)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                        }
                        else if (delDiff < voxelSizeHalfTransformedNegD)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_FULL;
                        }
                        else
                        {
                            float value = (float)Math.Sqrt(delDist + sphRadSqD - 2 * sphRadD * Math.Sqrt(delDist));
                            if (delDiff < 0)
                            {
                                value = -value;
                            }
                            //  This formula will work even if diff is positive or negative
                            contentToRemove = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - value / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                        }

                        originalContent = m_cache.Content(ref cachePos);

                        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;
                            }
                            m_cache.Content(ref cachePos, (byte)newVal);

                            removedVoxelContent += originalContent - newVal;
                        }

                        //Set material

                        float setDist = (float)(voxelPosition - newSetCenter).LengthSquared();
                        float setDiff = (float)(setDist - sphRadSqS);

                        if (setDiff <= MyVoxelConstants.VOXEL_SIZE_IN_METRES * 1.5f)  // could be VOXEL_SIZE_IN_METRES_HALF, but we want to set material in empty cells correctly
                        {
                            MyVoxelMaterialDefinition originalMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref cachePos));

                            // Change the material:
                            // - always on boundaries between material and nothing
                            // - smoothly on inner boundaries
                            MyVoxelMaterialDefinition newMaterial = material;
                            if (setDiff > 0)
                            {
                                byte content = m_cache.Content(ref cachePos);
                                if (content == MyVoxelConstants.VOXEL_CONTENT_FULL)
                                {
                                    newMaterial = originalMaterial;
                                }
                                if (setDiff >= voxelSizeHalfTransformedPosS && content != MyVoxelConstants.VOXEL_CONTENT_EMPTY)  // set material behind boundary only for empty voxels
                                {
                                    newMaterial = originalMaterial;
                                }
                            }

                            if (originalMaterial == newMaterial)
                            {
                                continue;
                            }

                            m_cache.Material(ref cachePos, newMaterial.Index);
                            changed = true;
                        }

                        float dist = (float)(voxelPosition - newCenter).LengthSquared();
                        float diff = (float)(dist - sphRadSqA);

                        if (diff <= 0f)
                        {
                            originalContent = m_cache.Content(ref cachePos);
                            if (originalContent > MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                            {
                                bool wrinkled = m_cache.WrinkleVoxelContent(ref cachePos, MyVoxelConstants.DEFAULT_WRINKLE_WEIGHT_ADD, MyVoxelConstants.DEFAULT_WRINKLE_WEIGHT_REMOVE);
                                if (wrinkled)
                                {
                                    changed = true;
                                }
                            }
                        }
                    }
                }
            }
            ProfilerShort.End();

            if (changed)
            {
                ProfilerShort.Begin("RemoveSmallVoxelsUsingChachedVoxels");
                RemoveSmallVoxelsUsingChachedVoxels();
                ProfilerShort.BeginNextBlock("Writing cache");
                minCorner += voxelMap.StorageMin;
                maxCorner += voxelMap.StorageMin;
                voxelMap.Storage.WriteRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, ref minCorner, ref maxCorner);
                MyShapeSphere sphereShape = new MyShapeSphere();
                sphereShape.Center = sphere.Center;
                sphereShape.Radius = (float)(sphere.Radius * 1.5);
                OnVoxelChanged(MyVoxelBase.OperationType.Cut, voxelMap, sphereShape);
                ProfilerShort.End();
            }

            ProfilerShort.End();
        }
        private static void VoxelPlacement()
        {
            var camera = MySector.MainCamera;
            if (camera == null)
                return;

            var offset = 0; // MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF;
            var targetPosition = camera.Position + (Vector3D)camera.ForwardVector * 4.5f - offset;
            MyVoxelBase targetVoxelMap = null;
            foreach (var voxelMap in MySession.Static.VoxelMaps.Instances)
            {
                if (voxelMap.PositionComp.WorldAABB.Contains(targetPosition) == ContainmentType.Contains)
                {
                    targetVoxelMap = voxelMap;
                    break;
                }
            }
            if (targetVoxelMap == null)
                return;

            Vector3I targetVoxel;
            MyVoxelCoordSystems.WorldPositionToVoxelCoord(targetVoxelMap.PositionLeftBottomCorner, ref targetPosition, out targetVoxel);
            MyVoxelCoordSystems.VoxelCoordToWorldPosition(targetVoxelMap.PositionLeftBottomCorner, ref targetVoxel, out targetPosition);
            targetPosition += offset;
            var size = 3.0f;
            const int shapeType = 0;

            {
                BoundingBoxD aabb;
                MyVoxelCoordSystems.VoxelCoordToWorldAABB(targetVoxelMap.PositionLeftBottomCorner, ref targetVoxel, out aabb);
                VRageRender.MyRenderProxy.DebugDrawAABB(aabb, Color.Blue, 1f, 1f, true);
            }

            BoundingSphereD sphere;
            BoundingBoxD box;
            if (shapeType == 0)
            {
                sphere = new BoundingSphereD(targetPosition, size * 0.5f);
                VRageRender.MyRenderProxy.DebugDrawSphere(targetPosition, size * 0.5f, Color.White, 1f, true);
            }
            else if (shapeType == 1)
            {
                box = new BoundingBoxD(
                    targetPosition - size * 0.5f,
                    targetPosition + size * 0.5f);
                VRageRender.MyRenderProxy.DebugDrawAABB(box, Color.White, 1f, 1f, true);
            }
            else if (shapeType == 2)
            {
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(targetVoxelMap.PositionLeftBottomCorner, ref targetPosition, out targetVoxel);
                //targetVoxel = Vector3I.Zero;
                MyVoxelCoordSystems.VoxelCoordToWorldAABB(targetVoxelMap.PositionLeftBottomCorner, ref targetVoxel, out box);
                VRageRender.MyRenderProxy.DebugDrawAABB(box, Vector3.One, 1f, 1f, true);
            }

            bool leftPressed = MyInput.Static.IsLeftMousePressed();
            if (leftPressed)
            {
                MyShape shape;
                if (shapeType == 0)
                {
                    shape = new MyShapeSphere()
                    {
                        Center = sphere.Center,
                        Radius = (float)sphere.Radius,
                    };
                }
                else if (shapeType == 1 || shapeType == 2)
                {
                    shape = new MyShapeBox()
                    {
                        Boundaries = box,
                    };
                }
                if (shape != null)
                {
                    float dummy;
                    MyVoxelMaterialDefinition dummy2;
                    MyVoxelGenerator.CutOutShapeWithProperties(targetVoxelMap, shape, out dummy, out dummy2);
                }
            }
        }
        public static void CutOutVoxelMap(float radius, Vector3D center, MyVoxelBase voxelMap, bool createDebris, bool damage = false)
        {
            MyVoxelMaterialDefinition voxelMaterial = null;
            float voxelContentRemovedInPercent = 0;

            //cut off
            var sphereShape = new MyShapeSphere()
            {
                Center = center,
                Radius = radius
            };
            MyVoxelGenerator.CutOutShapeWithProperties(voxelMap, sphereShape, out voxelContentRemovedInPercent, out voxelMaterial, null, false, applyDamageMaterial: damage);

            //  Only if at least something was removed from voxel map
            //  If voxelContentRemovedInPercent is more than zero than also voxelMaterial shouldn't be null, but I rather check both of them.
            if ((voxelContentRemovedInPercent > 0) && (voxelMaterial != null))
            {
                BoundingSphereD voxelExpSphere = new BoundingSphereD(center, radius);

                //remove decals
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("HideTrianglesAfterExplosion");
                foreach (uint id in voxelMap.Render.RenderObjectIDs)
                    VRageRender.MyRenderProxy.HideDecals(id, voxelExpSphere.Center, (float)voxelExpSphere.Radius);
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("CreateDebris");

                if (createDebris && MyRenderConstants.RenderQualityProfile.ExplosionDebrisCountMultiplier > 0)
                {
                    //  Create debris rocks thrown from the explosion
                    //  This must be called before ApplyExplosionForceAndDamage (because there we apply impulses to the debris)
                    MyDebris.Static.CreateExplosionDebris(ref voxelExpSphere, voxelContentRemovedInPercent, voxelMaterial, voxelMap);
                }

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("CreateParticleEffect");

                if (createDebris)
                {
                    MyParticleEffect explosionEffect;
                    if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.MaterialExplosion_Destructible, out explosionEffect))
                    {
                        explosionEffect.WorldMatrix = MatrixD.CreateTranslation(voxelExpSphere.Center);
                        explosionEffect.UserRadiusMultiplier = (float)voxelExpSphere.Radius;
                    }
                }

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }
        }
Example #8
0
        private static unsafe void MakeCraterInternal(MyVoxelBase voxelMap, ref BoundingSphereD sphere, ref Vector3 direction, MyVoxelMaterialDefinition material)
        {
            Vector3I vectori;
            Vector3I vectori2;
            Vector3I vectori5;
            Vector3  vector        = Vector3.Normalize(sphere.Center - voxelMap.RootVoxel.WorldMatrix.Translation);
            Vector3D worldPosition = sphere.Center - ((sphere.Radius - 1.0) * 1.2999999523162842);
            Vector3D vectord2      = sphere.Center + ((sphere.Radius + 1.0) * 1.2999999523162842);

            MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref worldPosition, out vectori);
            MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref vectord2, out vectori2);
            voxelMap.Storage.ClampVoxelCoord(ref vectori, 1);
            voxelMap.Storage.ClampVoxelCoord(ref vectori2, 1);
            Vector3I lodVoxelRangeMin = (Vector3I)(vectori + voxelMap.StorageMin);
            Vector3I lodVoxelRangeMax = (Vector3I)(vectori2 + voxelMap.StorageMin);
            bool     flag             = false;

            if (m_cache == null)
            {
                m_cache = new MyStorageData(MyStorageDataTypeFlags.All);
            }
            m_cache.Resize(vectori, vectori2);
            MyVoxelRequestFlags considerContent = MyVoxelRequestFlags.ConsiderContent;

            voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.All, 0, lodVoxelRangeMin, lodVoxelRangeMax, ref considerContent);
            int      num         = 0;
            Vector3I p           = (Vector3I)((vectori2 - vectori) / 2);
            byte     materialIdx = m_cache.Material(ref p);
            float    num3        = 1f - Vector3.Dot(vector, direction);
            Vector3  vector2     = ((Vector3)sphere.Center) - ((vector * ((float)sphere.Radius)) * 1.1f);
            float    num4        = (float)(sphere.Radius * 1.5);
            float    num5        = num4 * num4;
            float    num6        = 0.5f * ((2f * num4) + 0.5f);
            float    num7        = 0.5f * ((-2f * num4) + 0.5f);
            Vector3  vector3     = (vector2 + ((vector * ((float)sphere.Radius)) * (0.7f + num3))) + ((direction * ((float)sphere.Radius)) * 0.65f);
            float    radius      = (float)sphere.Radius;
            float    num9        = radius * radius;
            float    num10       = 0.5f * ((2f * radius) + 0.5f);
            float    num11       = 0.5f * ((-2f * radius) + 0.5f);
            Vector3  vector4     = (vector2 + ((vector * ((float)sphere.Radius)) * num3)) + ((direction * ((float)sphere.Radius)) * 0.3f);
            float    num12       = (float)(sphere.Radius * 0.10000000149011612);
            float    num13       = num12 * num12;
            float    num14       = 0.5f * ((2f * num12) + 0.5f);

            vectori5.Z = vectori.Z;
            p.Z        = 0;
            goto TR_003C;
TR_0005:
            int *numPtr1 = (int *)ref vectori5.X;

            numPtr1[0]++;
            int *numPtr2 = (int *)ref p.X;

            numPtr2[0]++;
TR_0036:
            while (true)
            {
                Vector3D vectord3;
                byte     num18;
                if (vectori5.X > vectori2.X)
                {
                    int *numPtr3 = (int *)ref vectori5.Y;
                    numPtr3[0]++;
                    int *numPtr4 = (int *)ref p.Y;
                    numPtr4[0]++;
                    break;
                }
                MyVoxelCoordSystems.VoxelCoordToWorldPosition(voxelMap.PositionLeftBottomCorner, ref vectori5, out vectord3);
                byte num15 = m_cache.Content(ref p);
                if (num15 != 0xff)
                {
                    byte  num22;
                    float num20 = (float)(vectord3 - vector2).LengthSquared();
                    float num21 = num20 - num5;
                    if (num21 > num6)
                    {
                        num22 = 0;
                    }
                    else if (num21 < num7)
                    {
                        num22 = 0xff;
                    }
                    else
                    {
                        float num23 = (float)Math.Sqrt((num20 + num5) - ((2f * num4) * Math.Sqrt((double)num20)));
                        if (num21 < 0f)
                        {
                            num23 = -num23;
                        }
                        num22 = (byte)(127f - ((num23 / 0.5f) * 127f));
                    }
                    if (num22 > num15)
                    {
                        if (material != null)
                        {
                            m_cache.Material(ref p, materialIdx);
                        }
                        flag = true;
                        m_cache.Content(ref p, num22);
                    }
                }
                float num16 = (float)(vectord3 - vector3).LengthSquared();
                float num17 = num16 - num9;
                if (num17 > num10)
                {
                    num18 = 0;
                }
                else if (num17 < num11)
                {
                    num18 = 0xff;
                }
                else
                {
                    float num24 = (float)Math.Sqrt((num16 + num9) - ((2f * radius) * Math.Sqrt((double)num16)));
                    if (num17 < 0f)
                    {
                        num24 = -num24;
                    }
                    num18 = (byte)(127f - ((num24 / 0.5f) * 127f));
                }
                num15 = m_cache.Content(ref p);
                if ((num15 > 0) && (num18 > 0))
                {
                    flag = true;
                    int num25 = num15 - num18;
                    if (num25 < 0)
                    {
                        num25 = 0;
                    }
                    m_cache.Content(ref p, (byte)num25);
                    num += num15 - num25;
                }
                float num19 = ((float)(vectord3 - vector4).LengthSquared()) - num13;
                if (num19 <= 1.5f)
                {
                    MyVoxelMaterialDefinition voxelMaterialDefinition = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref p));
                    MyVoxelMaterialDefinition objB = material;
                    if (num19 > 0f)
                    {
                        byte num26 = m_cache.Content(ref p);
                        if (num26 == 0xff)
                        {
                            objB = voxelMaterialDefinition;
                        }
                        if ((num19 >= num14) && (num26 != 0))
                        {
                            objB = voxelMaterialDefinition;
                        }
                    }
                    if (ReferenceEquals(voxelMaterialDefinition, objB))
                    {
                        goto TR_0005;
                    }
                    else
                    {
                        m_cache.Material(ref p, objB.Index);
                        flag = true;
                    }
                }
                if ((((((float)(vectord3 - vector2).LengthSquared()) - num5) <= 0f) && (m_cache.Content(ref p) > 0)) && m_cache.WrinkleVoxelContent(ref p, 0.5f, 0.45f))
                {
                    flag = true;
                }
                goto TR_0005;
            }
TR_0039:
            while (true)
            {
                if (vectori5.Y > vectori2.Y)
                {
                    int *numPtr5 = (int *)ref vectori5.Z;
                    numPtr5[0]++;
                    int *numPtr6 = (int *)ref p.Z;
                    numPtr6[0]++;
                    break;
                }
                vectori5.X = vectori.X;
                p.X        = 0;
                goto TR_0036;
            }
TR_003C:
            while (true)
            {
                if (vectori5.Z <= vectori2.Z)
                {
                    vectori5.Y = vectori.Y;
                    p.Y        = 0;
                    break;
                }
                if (flag)
                {
                    RemoveSmallVoxelsUsingChachedVoxels();
                    vectori = (Vector3I)(vectori + voxelMap.StorageMin);
                    voxelMap.Storage.WriteRange(m_cache, MyStorageDataTypeFlags.All, vectori, (Vector3I)(vectori2 + voxelMap.StorageMin), true, false);
                    MyShapeSphere sphere1 = new MyShapeSphere();
                    sphere1.Center = sphere.Center;
                    sphere1.Radius = (float)(sphere.Radius * 1.5);
                    BoundingBoxD worldBoundaries = sphere1.GetWorldBoundaries();
                    NotifyVoxelChanged(MyVoxelBase.OperationType.Cut, voxelMap, ref worldBoundaries);
                }
                return;
            }
            goto TR_0039;
        }