Exemplo n.º 1
0
        private void CreateHalfExtents()
        {
            _oldGridHalfExtents = DsState.State.GridHalfExtents;
            var myAabb       = MyGrid.PositionComp.LocalAABB;
            var shieldGrid   = MyGrid;
            var expandedAabb = myAabb;

            if (ShieldComp.GetSubGrids.Count > 1)
            {
                foreach (var grid in ShieldComp.GetSubGrids)
                {
                    if (grid == null || grid == shieldGrid)
                    {
                        continue;
                    }
                    var shieldMatrix = shieldGrid.PositionComp.WorldMatrixNormalizedInv;
                    var gQuaternion  = Quaternion.CreateFromRotationMatrix(grid.WorldMatrix);
                    var gOriBBoxD    = new MyOrientedBoundingBox(grid.PositionComp.WorldAABB.Center, grid.PositionComp.LocalAABB.HalfExtents, gQuaternion);
                    gOriBBoxD.Transform(shieldMatrix);
                    expandedAabb.Include(gOriBBoxD.GetAABB());
                }
            }

            if (DsSet.Settings.SphereFit || DsSet.Settings.FortifyShield)
            {
                var extend  = DsSet.Settings.ExtendFit ? 2 : 1;
                var fortify = DsSet.Settings.FortifyShield ? 3 : 1;
                var size    = expandedAabb.HalfExtents.Max() * fortify;
                var scaler  = 4;
                if (shieldGrid.GridSizeEnum == MyCubeSize.Small && !DsSet.Settings.ExtendFit)
                {
                    scaler = 5;
                }
                var vectorSize  = new Vector3D(size, size, size);
                var fudge       = shieldGrid.GridSize * scaler * extend;
                var extentsDiff = DsState.State.GridHalfExtents.LengthSquared() - vectorSize.LengthSquared();
                if (extentsDiff < -1 || extentsDiff > 1 || DsState.State.GridHalfExtents == Vector3D.Zero || !fudge.Equals(DsState.State.ShieldFudge))
                {
                    DsState.State.GridHalfExtents = vectorSize;
                }
                DsState.State.ShieldFudge = fudge;
            }
            else
            {
                var blockHalfSize = MyGrid.GridSize * 0.5;
                DsState.State.ShieldFudge = 0f;
                var extentsDiff = DsState.State.GridHalfExtents.LengthSquared() - expandedAabb.HalfExtents.LengthSquared();
                var overThreshold = extentsDiff <-blockHalfSize || extentsDiff> blockHalfSize;
                if (overThreshold || DsState.State.GridHalfExtents == Vector3D.Zero)
                {
                    DsState.State.GridHalfExtents = expandedAabb.HalfExtents;
                }
            }
            _halfExtentsChanged = !DsState.State.GridHalfExtents.Equals(_oldGridHalfExtents);
            if (_halfExtentsChanged)
            {
                _adjustShape = true;
            }
        }
        protected override void ReadEntitiesInRange()
        {
            m_entitiesInRange.Clear();

            MyOrientedBoundingBox bbox = new MyOrientedBoundingBox(Center, m_halfExtents, m_orientation);
            var aabb = bbox.GetAABB();
            var res = MyEntities.GetEntitiesInAABB(ref aabb);
            for (int i = 0; i < res.Count; ++i)
            {
                var rootEntity = res[i].GetTopMostParent();
                if (!IgnoredEntities.Contains(rootEntity))
                    m_entitiesInRange[rootEntity.EntityId] = new DetectionInfo(rootEntity, FrontPoint);
            }
            res.Clear();
        }
Exemplo n.º 3
0
        protected override void ReadEntitiesInRange()
        {
            m_entitiesInRange.Clear();

            MyOrientedBoundingBox bbox = new MyOrientedBoundingBox(Center, m_halfExtents, m_orientation);
            var aabb = bbox.GetAABB();
            var res  = MyEntities.GetEntitiesInAABB(ref aabb);

            for (int i = 0; i < res.Count; ++i)
            {
                var rootEntity = res[i].GetTopMostParent();
                if (!IgnoredEntities.Contains(rootEntity))
                {
                    m_entitiesInRange[rootEntity.EntityId] = new DetectionInfo(rootEntity, FrontPoint);
                }
            }
            res.Clear();
        }
Exemplo n.º 4
0
        //public List<object> m_debugBones = new List<object>();

        /// <summary>
        /// Applies deformation, returns true when block was destroyed (explosion should be generated)
        /// </summary>
        /// <param name="deformationOffset">Amount of deformation in the localPos</param>
        /// <param name="offsetThreshold">When deformation offset for bone is lower then threshold, it won't move the bone at all or do damage</param>
        public int ApplyDeformation(float deformationOffset, float softAreaPlanar, float softAreaVertical, Vector3 localPos, Vector3 localNormal, MyStringHash damageType, float offsetThreshold = 0, float lowerRatioLimit = 0, long attackerId = 0)
        {
            if (!m_grid.BlocksDestructionEnabled)
                return 0;

            int blocksDeformed = 0;
            offsetThreshold /= m_grid.GridSizeEnum == MyCubeSize.Large ? 1 : 5;
            float roundSize = m_grid.GridSize / MyGridSkeleton.BoneDensity;
            Vector3I roundedPos = Vector3I.Round((localPos + new Vector3(m_grid.GridSize / 2)) / roundSize);
            Vector3I gridPos = Vector3I.Round((localPos + new Vector3(m_grid.GridSize / 2)) / m_grid.GridSize);
            Vector3I gridOffset = roundedPos - gridPos * MyGridSkeleton.BoneDensity;

            float breakOffset = m_grid.GridSize * 0.7f;
            float breakOffsetDestruction = breakOffset;

            Vector3I min = Vector3I.MaxValue;
            Vector3I max = Vector3I.MinValue;
            bool isDirty = false;

            bool destructionDone = false;

            Vector3 absNormal = Vector3.Abs(localNormal);
            float maxNorm = Math.Max(Math.Max(absNormal.X, absNormal.Y), absNormal.Z);
            float maxDef = maxNorm * deformationOffset;

            float destructionPotencial = (1 - breakOffsetDestruction / maxDef);
            float minDeformationRatio = 1;

            var softAreaPlanarR = 1.0f / softAreaPlanar;
            var softAreaVerticalR = 1.0f / softAreaVertical;
            var gridSizeR = 1.0f / m_grid.GridSize;
            Vector3D forward = localNormal;
            var up = MyUtils.GetRandomPerpendicularVector(ref forward);
            float minLength = Math.Min(m_grid.GridSize / 256.0f, deformationOffset * 0.06f);

            // When we're sure that there will be destroyed blocks, it's not necessary to do deformations, just do destruction
            MyDamageInformation damageInfo = new MyDamageInformation(true, 1f, MyDamageType.Deformation, attackerId);
            if (destructionPotencial > 0)
            {
                float critVertical = destructionPotencial * softAreaVertical;
                float critPlanar = destructionPotencial * softAreaPlanar;

                var he = new Vector3(critPlanar, critPlanar, critVertical);
                MyOrientedBoundingBox obb = new MyOrientedBoundingBox(gridPos,he, Quaternion.CreateFromForwardUp(forward, up));
                var aabb = obb.GetAABB();

                //float maxCritDist = Math.Max(critPlanar, critVertical);
                //Vector3I distCubes = new Vector3I((int)Math.Ceiling(maxCritDist / m_grid.GridSize));
                //Vector3I minOffset = gridPos - distCubes;
                //Vector3I maxOffset = gridPos + distCubes;
                var minOffset = Vector3I.Floor(aabb.Min);
                var maxOffset = Vector3I.Ceiling(aabb.Max);
                minOffset = Vector3I.Max(minOffset, m_grid.Min);
                maxOffset = Vector3I.Min(maxOffset, m_grid.Max);

                ProfilerShort.Begin("Update destruction");

                Vector3I offset;
                for (offset.X = minOffset.X; offset.X <= maxOffset.X; offset.X++)
                {
                    for (offset.Y = minOffset.Y; offset.Y <= maxOffset.Y; offset.Y++)
                    {
                        for (offset.Z = minOffset.Z; offset.Z <= maxOffset.Z; offset.Z++)
                        {
                            Vector3 closestCorner = m_grid.GetClosestCorner(offset, localPos);
                            
                            float soften = 1.0f;
                            if (offset != gridPos)
                            {
                                soften = CalculateSoften(softAreaPlanarR, softAreaVerticalR, ref localNormal, closestCorner - localPos);
                            }
                            float deformation = maxDef * soften;

                            if (deformation > breakOffsetDestruction)
                            {
                                var block = m_grid.GetCubeBlock(offset);
                                if (block != null)
                                {
                                    if (block.UseDamageSystem)
                                    {
                                        damageInfo.Amount = 1;
                                        MyDamageSystem.Static.RaiseBeforeDamageApplied(block, ref damageInfo);
                                        if (damageInfo.Amount == 0f)
                                            continue;
                                    }

                                    minDeformationRatio = Math.Min(minDeformationRatio, block.DeformationRatio);

                                    if (Math.Max(lowerRatioLimit, block.DeformationRatio) * deformation > breakOffsetDestruction)
                                    {
                                        ProfilerShort.Begin("Remove destroyed blocks");
                                        min = Vector3I.Min(min, block.Min - Vector3I.One);
                                        max = Vector3I.Max(max, block.Max + Vector3I.One);
                                        isDirty = true;
                                        m_grid.RemoveDestroyedBlock(block);
                                        ProfilerShort.End();
                                        destructionDone = true;
                                        blocksDeformed++;
                                    }
                                }
                            }
                        }
                    }
                }
                ProfilerShort.End();

                // When there was no destruction, reduce area and do deformation
                minDeformationRatio = Math.Max(minDeformationRatio, 0.2f);
                softAreaPlanar *= minDeformationRatio;
                softAreaVertical *= minDeformationRatio;
            }

            if (!destructionDone)
            {
                //m_debugBones.Clear();
                var boneDensity = MyGridSkeleton.BoneDensity;
                ProfilerShort.Begin("Update deformation");
                MyOrientedBoundingBox obb = new MyOrientedBoundingBox(
                    gridPos * boneDensity + gridOffset,
                    new Vector3(softAreaPlanar * gridSizeR * boneDensity, softAreaPlanar * gridSizeR * boneDensity , softAreaVertical * gridSizeR * boneDensity),
                    Quaternion.CreateFromForwardUp(forward, up));
                var aabb = obb.GetAABB();

                //float softArea = Math.Max(softAreaPlanar, softAreaVertical);
                //var distBones = new Vector3I((int)Math.Ceiling(softArea / m_grid.GridSize * m_grid.Skeleton.BoneDensity));

                //Vector3I minOffset = gridPos * m_grid.Skeleton.BoneDensity + gridOffset - distBones;
                //Vector3I maxOffset = gridPos * m_grid.Skeleton.BoneDensity + gridOffset + distBones;
                var minOffset = Vector3I.Floor(aabb.Min);
                var maxOffset = Vector3I.Ceiling(aabb.Max);
                minOffset = Vector3I.Max(minOffset, m_grid.Min * MyGridSkeleton.BoneDensity);
                maxOffset = Vector3I.Min(maxOffset, m_grid.Max * MyGridSkeleton.BoneDensity);

                Vector3I minDirtyBone = Vector3I.MaxValue;
                Vector3I maxDirtyBone = Vector3I.MinValue;

                ProfilerShort.Begin("Get bones");
                Debug.Assert(m_tmpBoneList.Count == 0, "Temporary dictionary not cleared properly");
                m_grid.GetExistingBones(minOffset, maxOffset, m_tmpBoneList, damageInfo);
                ProfilerShort.End();

                ProfilerShort.Begin("Deform bones");
                Vector3 bone;
                Vector3I baseOffset = gridPos * MyGridSkeleton.BoneDensity;
                float boneDensityR = 1.0f / MyGridSkeleton.BoneDensity;
                var halfGridSize = new Vector3(m_grid.GridSize * 0.5f);

                ProfilerShort.CustomValue("Bone Count", m_tmpBoneList.Count, 0);
                foreach (var b in m_tmpBoneList)
                {
                    var boneIndex = b.Key;

                    var baseBonePos = boneIndex * m_grid.GridSize * boneDensityR - halfGridSize;

                    m_grid.Skeleton.GetBone(ref boneIndex, out bone);
                    var bonePos = bone + baseBonePos;

                    float soften = CalculateSoften(softAreaPlanarR, softAreaVerticalR, ref localNormal, bonePos - localPos);

                    if (soften == 0)
                        continue;

                    min = Vector3I.Min(min, Vector3I.Floor(bonePos * gridSizeR - Vector3.One * boneDensityR));
                    max = Vector3I.Max(max, Vector3I.Ceiling(bonePos *gridSizeR + Vector3.One * boneDensityR));
                    isDirty = true;

                    float deformationRatio = 1.0f;
                    bool doDeformation = true;
                    var block2 = b.Value;
                    {
                        Debug.Assert(block2 != null, "Block cannot be null");
                        deformationRatio = Math.Max(lowerRatioLimit, block2.DeformationRatio); // + some deformation coeficient based on integrity

                        float maxAxisDeformation = maxNorm * deformationOffset * soften;
                        doDeformation = block2.UsesDeformation;

                        if (block2.IsDestroyed) // ||  block2.DoDamage(maxAxisDeformation / m_grid.GridSize, damageType, addDirtyParts: false))
                        {
                            destructionDone = true;
                        }
                    }

                    if (deformationOffset * deformationRatio < offsetThreshold)
                        continue;

                    float deformationLength = deformationOffset * soften * deformationRatio;
                    var deformation = localNormal * deformationLength;

                    bool canDeform = damageType != MyDamageType.Bullet || (Math.Abs(bone.X + deformation.X) < breakOffset && Math.Abs(bone.Y + deformation.Y) < breakOffset && Math.Abs(bone.Z + deformation.Z) < breakOffset);

                    if (canDeform && deformationLength > minLength)
                    {
                        bone += deformation;

                        //m_debugBones.Add(new Tuple<Vector3, float>(bonePos, deformationRatio));
                        var offset = boneIndex - baseOffset;

                        if (Math.Abs(bone.X) > breakOffset || Math.Abs(bone.Y) > breakOffset || Math.Abs(bone.Z) > breakOffset)
                        {
                            m_tmpCubeList.Clear();

                            Vector3I wrappedBoneOffset = offset;
                            Vector3I wrappedGridPos = gridPos;
                            m_grid.Skeleton.Wrap(ref wrappedGridPos, ref wrappedBoneOffset);
                            m_grid.Skeleton.GetAffectedCubes(wrappedGridPos, wrappedBoneOffset, m_tmpCubeList, m_grid);

                            foreach (var c in m_tmpCubeList)
                            {
                                var block = m_grid.GetCubeBlock(c);
                                if (block != null)
                                {
                                    ProfilerShort.Begin("Remove destroyed blocks");
                                    m_grid.RemoveDestroyedBlock(block);
                                    AddDirtyBlock(block);
                                    ProfilerShort.End();
                                    destructionDone = true;
                                    blocksDeformed++;
                                }
                            }
                        }
                        else if (doDeformation && Sync.IsServer)
                        {
                            minDirtyBone = Vector3I.Min(minDirtyBone, boneIndex);
                            maxDirtyBone = Vector3I.Max(maxDirtyBone, boneIndex);

                            m_grid.Skeleton.SetBone(ref boneIndex, ref bone);
                            m_grid.AddDirtyBone(gridPos, offset);

                            m_grid.BonesToSend.AddInput(boneIndex);
                        }
                    }
                }
                m_tmpBoneList.Clear();
                ProfilerShort.End();
                ProfilerShort.End();
            }

            if (isDirty)
            {
                m_dirtyCubesInfo.DirtyParts.Add(new BoundingBoxI() { Min = min, Max = max });
            }
            return blocksDeformed;
        }
Exemplo n.º 5
0
        public void CreateHalfExtents(bool forceUpdate = false, bool growOnly = false)
        {
            _oldGridHalfExtents = DsState.State.GridHalfExtents;
            var myAabb       = MyGrid.PositionComp.LocalAABB;
            var shieldGrid   = MyGrid;
            var expandedAabb = myAabb;

            if (ShieldComp.SubGrids.Count > 1)
            {
                foreach (var grid in ShieldComp.SubGrids.Keys)
                {
                    using (grid.Pin())
                    {
                        if (grid == shieldGrid || grid.MarkedForClose)
                        {
                            continue;
                        }
                        var shieldMatrix = shieldGrid.PositionComp.WorldMatrixNormalizedInv;
                        var gQuaternion  = Quaternion.CreateFromRotationMatrix(grid.WorldMatrix);
                        var gOriBBoxD    = new MyOrientedBoundingBox(grid.PositionComp.WorldAABB.Center, grid.PositionComp.LocalAABB.HalfExtents, gQuaternion);
                        gOriBBoxD.Transform(shieldMatrix);
                        expandedAabb.Include(gOriBBoxD.GetAABB());
                    }
                }
            }

            if (DsSet.Settings.SphereFit || DsSet.Settings.FortifyShield)
            {
                var fortify = DsSet.Settings.FortifyShield ? 3 : 1;
                var fit     = (float)UtilsStatic.GetFit(DsSet.Settings.Fit) * 0.5f;
                var scaler  = 4f;
                if (shieldGrid.GridSizeEnum == MyCubeSize.Small && DsSet.Settings.Fit < 15)
                {
                    scaler = 5;
                }


                var size       = (expandedAabb.HalfExtents.Max() * fortify) * fit;
                var vectorSize = new Vector3D(size, size, size);

                var fudge       = shieldGrid.GridSize * scaler;
                var extentsDiff = DsState.State.GridHalfExtents.LengthSquared() - vectorSize.LengthSquared();
                if (extentsDiff < -1 || extentsDiff > 1 || DsState.State.GridHalfExtents == Vector3D.Zero || !fudge.Equals(DsState.State.ShieldFudge))
                {
                    DsState.State.GridHalfExtents = vectorSize;
                }
                DsState.State.ShieldFudge = fudge;
            }
            else
            {
                var offset = MyGrid.GridSize * 0.01;
                DsState.State.ShieldFudge = 0f;
                var extentsDiff = DsState.State.GridHalfExtents.Length() - expandedAabb.HalfExtents.Length();
                var overThreshold = extentsDiff <-offset || extentsDiff> offset || forceUpdate;   //first grow, second shrink
                if (overThreshold || DsState.State.GridHalfExtents == Vector3D.Zero)
                {
                    DsState.State.GridHalfExtents = expandedAabb.HalfExtents;
                }
            }
            _halfExtentsChanged = !DsState.State.GridHalfExtents.Equals(_oldGridHalfExtents) || (DsSet.Settings.SphereFit || DsSet.Settings.FortifyShield) && SettingsUpdated;

            if (_halfExtentsChanged || SettingsUpdated)
            {
                _adjustShape = true;
            }
        }
Exemplo n.º 6
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
Exemplo n.º 7
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();
        }