예제 #1
0
            private bool AllSiblingsWereLoaded(ref MyCellCoord thisLodCell)
            {
                MyCellCoord sibling;

                sibling.Lod = thisLodCell.Lod;
                var start = new Vector3I( // get rid of lowest bit to make this min child of parent
                    thisLodCell.CoordInLod.X & (-2),
                    thisLodCell.CoordInLod.Y & (-2),
                    thisLodCell.CoordInLod.Z & (-2));
                var end = start + 1;

                Vector3I.Min(ref end, ref m_lodSizeMinusOne, out end);
                for (sibling.CoordInLod.Z = start.Z; sibling.CoordInLod.Z <= end.Z; ++sibling.CoordInLod.Z)
                {
                    for (sibling.CoordInLod.Y = start.Y; sibling.CoordInLod.Y <= end.Y; ++sibling.CoordInLod.Y)
                    {
                        for (sibling.CoordInLod.X = start.X; sibling.CoordInLod.X <= end.X; ++sibling.CoordInLod.X)
                        {
                            var key = sibling.PackId64();
                            MyClipmap_CellData data;
                            if (!m_storedCellData.TryGetValue(key, out data))
                            {
                                return(false);
                            }

                            if (!data.WasLoaded)
                            {
                                return(false);
                            }
                        }
                    }
                }

                return(true);
            }
        protected override void Init(MyObjectBuilder_DefinitionBase builder)
        {
            base.Init(builder);

            var ob = builder as MyObjectBuilder_MultiBlockDefinition;

            MyDebug.AssertDebug(ob != null);

            if (ob.BlockDefinitions != null && ob.BlockDefinitions.Length > 0)
            {
                MinPosition = Vector3I.MaxValue;
                MaxPosition = Vector3I.MinValue;

                BlockDefinitions = new MyMultiBlockPartDefinition[ob.BlockDefinitions.Length];
                for (int i = 0; i < ob.BlockDefinitions.Length; ++i)
                {
                    BlockDefinitions[i] = new MyMultiBlockPartDefinition();

                    var obBlockDef = ob.BlockDefinitions[i];
                    BlockDefinitions[i].Id       = obBlockDef.Id;
                    BlockDefinitions[i].Position = obBlockDef.Position;
                    BlockDefinitions[i].Forward  = obBlockDef.Orientation.Forward;
                    BlockDefinitions[i].Up       = obBlockDef.Orientation.Up;

                    MinPosition = Vector3I.Min(MinPosition, obBlockDef.Position);
                    MaxPosition = Vector3I.Max(MaxPosition, obBlockDef.Position);
                }
            }
        }
예제 #3
0
        void DoCuboid()
        {
            Vector3I min = Vector3I.Min(mark1, mark2);
            Vector3I max = Vector3I.Max(mark1, mark2);

            if (!game.World.IsValidPos(min) || !game.World.IsValidPos(max))
            {
                return;
            }

            BlockID toPlace = (BlockID)block;

            if (block == -1)
            {
                toPlace = game.Inventory.Selected;
            }

            for (int y = min.Y; y <= max.Y; y++)
            {
                for (int z = min.Z; z <= max.Z; z++)
                {
                    for (int x = min.X; x <= max.X; x++)
                    {
                        game.UpdateBlock(x, y, z, toPlace);
                    }
                }
            }
        }
예제 #4
0
            /// <summary>
            /// Checks only immediate children (any deeper would take too long).
            /// </summary>
            private static bool ChildrenWereLoaded(LodLevel childLod, ref MyCellCoord thisLodCell)
            {
                if (childLod == null)
                {
                    return(false);
                }

                Debug.Assert(thisLodCell.Lod == childLod.m_lodIndex + 1);

                var childLodCell = new MyCellCoord();

                childLodCell.Lod = childLod.m_lodIndex;
                var shiftToChild = MyVoxelCoordSystems.RenderCellSizeShiftToMoreDetailed(thisLodCell.Lod);
                var start        = thisLodCell.CoordInLod << shiftToChild;
                var end          = start + ((1 << shiftToChild) >> 1);

                Vector3I.Max(ref childLod.m_lodSizeMinusOne, ref Vector3I.Zero, out childLod.m_lodSizeMinusOne);
                Vector3I.Min(ref end, ref childLod.m_lodSizeMinusOne, out end);
                childLodCell.CoordInLod = start;
                for (var it = new Vector3I_RangeIterator(ref start, ref end);
                     it.IsValid(); it.GetNext(out childLodCell.CoordInLod))
                {
                    var key = childLodCell.PackId64();
                    MyClipmap_CellData data;
                    if (!childLod.m_storedCellData.TryGetValue(key, out data) || !data.WasLoaded)
                    {
                        return(false);
                    }
                }

                return(true);
            }
예제 #5
0
        private static MyObjectBuilder_CubeBlock ConvertDynamicGridBlockToStatic(ref MatrixD worldMatrix, MyObjectBuilder_CubeBlock origBlock)
        {
            MyDefinitionId        defId = new MyDefinitionId(origBlock.TypeId, origBlock.SubtypeName);
            MyCubeBlockDefinition blockDefinition;

            MyDefinitionManager.Static.TryGetCubeBlockDefinition(defId, out blockDefinition);
            if (blockDefinition == null)
            {
                return(null);
            }

            var blockBuilder = Sandbox.Common.ObjectBuilders.Serializer.MyObjectBuilderSerializer.CreateNewObject(defId) as MyObjectBuilder_CubeBlock;

            blockBuilder.EntityId = origBlock.EntityId;
            // Orientation quaternion is not setup in origblock
            MyBlockOrientation orientation = origBlock.BlockOrientation;
            Quaternion         rotationQuat;

            orientation.GetQuaternion(out rotationQuat);
            Matrix origRotationMatrix = Matrix.CreateFromQuaternion(rotationQuat);
            Matrix rotationMatrix     = origRotationMatrix * worldMatrix;

            blockBuilder.Orientation = Quaternion.CreateFromRotationMatrix(rotationMatrix);

            Vector3I origSizeRotated = Vector3I.Abs(Vector3I.Round(Vector3.TransformNormal((Vector3)blockDefinition.Size, origRotationMatrix)));
            Vector3I origMin         = origBlock.Min;
            Vector3I origMax         = origBlock.Min + origSizeRotated - Vector3I.One;

            Vector3I minXForm = Vector3I.Round(Vector3.TransformNormal((Vector3)origMin, worldMatrix));
            Vector3I maxXForm = Vector3I.Round(Vector3.TransformNormal((Vector3)origMax, worldMatrix));

            blockBuilder.Min = Vector3I.Min(minXForm, maxXForm);
            return(blockBuilder);
        }
        private Vector3I FindTriangleCube(int triIndex, ref Vector3I edgePositionA, ref Vector3I edgePositionB)
        {
            Vector3I min, max;

            Vector3I.Min(ref edgePositionA, ref edgePositionB, out min);
            Vector3I.Max(ref edgePositionA, ref edgePositionB, out max);
            min = Vector3I.Round(new Vector3(min) / 256.0f - Vector3.Half);
            max = Vector3I.Round(new Vector3(max) / 256.0f + Vector3.Half);

            for (var it = new Vector3I_RangeIterator(ref min, ref max); it.IsValid(); it.GetNext(out min))
            {
                List <int> list;
                m_smallTriangleRegistry.TryGetValue(min, out list);
                if (list == null)
                {
                    continue;
                }

                if (list.Contains(triIndex))
                {
                    return(min);
                }
            }

            Debug.Assert(false, "Could not find navmesh triangle cube. Shouldn't get here!");
            return(Vector3I.Zero);
        }
예제 #7
0
        public static void GetExistingCubes(MyCubeGrid grid, Vector3I min, Vector3I max, List <IMySlimBlock> resultSet)
        {
            resultSet.Clear();
            Vector3I result1 = Vector3I.Floor((min - Vector3I.One) / 2f);
            Vector3I result2 = Vector3I.Ceiling((max - Vector3I.One) / 2f);
            var      gridMin = grid.Min;
            var      gridMax = grid.Max;

            Vector3I.Max(ref result1, ref gridMin, out result1);
            Vector3I.Min(ref result2, ref gridMax, out result2);
            Vector3I key;

            for (key.X = result1.X; key.X <= result2.X; ++key.X)
            {
                for (key.Y = result1.Y; key.Y <= result2.Y; ++key.Y)
                {
                    for (key.Z = result1.Z; key.Z <= result2.Z; ++key.Z)
                    {
                        MyCube myCube;
                        if (grid.TryGetCube(key, out myCube))
                        {
                            resultSet.Add(myCube.CubeBlock);
                        }
                    }
                }
            }
        }
예제 #8
0
        public static void GetExistingCubes(MyCubeGrid grid, Vector3I min, Vector3I max, BoundingSphere localSphere, bool checkDestroyed, List <IMySlimBlock> resultSet)
        {
            resultSet.Clear();
            Vector3I result1 = Vector3I.Floor((min - Vector3I.One) / 2f);
            Vector3I result2 = Vector3I.Ceiling((max - Vector3I.One) / 2f);
            var      gridMin = grid.Min;
            var      gridMax = grid.Max;

            Vector3I.Max(ref result1, ref gridMin, out result1);
            Vector3I.Min(ref result2, ref gridMax, out result2);
            Vector3I key;

            for (key.X = result1.X; key.X <= result2.X; ++key.X)
            {
                for (key.Y = result1.Y; key.Y <= result2.Y; ++key.Y)
                {
                    for (key.Z = result1.Z; key.Z <= result2.Z; ++key.Z)
                    {
                        MyCube myCube;
                        if (grid.TryGetCube(key, out myCube))
                        {
                            var block = (IMySlimBlock)myCube.CubeBlock;
                            if (checkDestroyed && block.IsDestroyed || !new BoundingBox(block.Min * grid.GridSize - grid.GridSizeHalf, block.Max * grid.GridSize + grid.GridSizeHalf).Intersects(localSphere))
                            {
                                continue;
                            }

                            resultSet.Add(block);
                        }
                    }
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Converts the given block with the given matrix for static grid.
        /// </summary>
        private static void ConvertRotatedGridBlockToStatic(ref MatrixI transform, MyObjectBuilder_CubeBlock origBlock)
        {
            MyDefinitionId        defId = new MyDefinitionId(origBlock.TypeId, origBlock.SubtypeName);
            MyCubeBlockDefinition blockDefinition;

            MyDefinitionManager.Static.TryGetCubeBlockDefinition(defId, out blockDefinition);
            if (blockDefinition == null)
            {
                return;
            }

            // Orientation quaternion is not setup in origblock
            MyBlockOrientation origOrientation = origBlock.BlockOrientation;
            Vector3I           origMin         = origBlock.Min;
            Vector3I           origMax;

            MySlimBlock.ComputeMax(blockDefinition, origOrientation, ref origMin, out origMax);

            Vector3I tMin;
            Vector3I tMax;

            Vector3I.Transform(ref origMin, ref transform, out tMin);
            Vector3I.Transform(ref origMax, ref transform, out tMax);
            Base6Directions.Direction forward = transform.GetDirection(origOrientation.Forward);
            Base6Directions.Direction up      = transform.GetDirection(origOrientation.Up);

            // Write data
            MyBlockOrientation newBlockOrientation = new MyBlockOrientation(forward, up);
            Quaternion         rotationQuat;

            newBlockOrientation.GetQuaternion(out rotationQuat);
            origBlock.Orientation = rotationQuat;
            origBlock.Min         = Vector3I.Min(tMin, tMax);
        }
예제 #10
0
        /// <summary>
        /// Transforms given compound block with matrix for static grid. Rotation of block is not changed.
        /// </summary>
        private static void ConvertRotatedGridCompoundBlockToStatic(ref MatrixI transform, MyObjectBuilder_CompoundCubeBlock origBlock)
        {
            MyDefinitionId        defId = new MyDefinitionId(origBlock.TypeId, origBlock.SubtypeName);
            MyCubeBlockDefinition blockDefinition;

            MyDefinitionManager.Static.TryGetCubeBlockDefinition(defId, out blockDefinition);
            if (blockDefinition == null)
            {
                return;
            }

            // Orientation quaternion is not setup in origblock
            MyBlockOrientation origOrientation = origBlock.BlockOrientation;
            Vector3I           origMin         = origBlock.Min;
            Vector3I           origMax;

            MySlimBlock.ComputeMax(blockDefinition, origOrientation, ref origMin, out origMax);

            Vector3I tMin;
            Vector3I tMax;

            Vector3I.Transform(ref origMin, ref transform, out tMin);
            Vector3I.Transform(ref origMax, ref transform, out tMax);

            // Write data
            origBlock.Min = Vector3I.Min(tMin, tMax);
        }
예제 #11
0
            /// <summary>
            /// Checks only immediate children (any deeper would take too long).
            /// </summary>
            private static bool ChildrenWereLoaded(LodLevel childLod, ref MyCellCoord thisLodCell)
            {
                if (childLod == null || !childLod.Visible)
                    return false;

                Debug.Assert(thisLodCell.Lod == childLod.m_lodIndex + 1);

                var childLodCell = new MyCellCoord();
                childLodCell.Lod = childLod.m_lodIndex;
                var start = thisLodCell.CoordInLod << 1;
                var end = start + 1;

                Vector3I.Min(ref end, ref childLod.m_lodSizeMinusOne, out end);
                for (childLodCell.CoordInLod.Z = start.Z; childLodCell.CoordInLod.Z <= end.Z; ++childLodCell.CoordInLod.Z)
                for (childLodCell.CoordInLod.Y = start.Y; childLodCell.CoordInLod.Y <= end.Y; ++childLodCell.CoordInLod.Y)
                for (childLodCell.CoordInLod.X = start.X; childLodCell.CoordInLod.X <= end.X; ++childLodCell.CoordInLod.X)
                {
                    var key = childLodCell.PackId64();
                    CellData data;
                    if (!childLod.m_storedCellData.TryGetValue(key, out data))
                    {
                        return false;
                    }

                    if (!data.WasLoaded)
                    {
                        return false;
                    }
                }

                return true;
            }
예제 #12
0
        private bool IsInInflatedBounds(IMyCubeGrid grid, Vector3I pos)
        {
            var min = grid.Min - Vector3I.One;
            var max = grid.Max + Vector3I.One;

            return(!(min != Vector3I.Min(pos, min)) && !(max != Vector3I.Max(pos, max)));
        }
예제 #13
0
        public void GetFilledStorageBounds(out Vector3I min, out Vector3I max)
        {
            min = Vector3I.MaxValue;
            max = Vector3I.MinValue;

            Vector3I sz = Size;

            Vector3I SMax = Size - 1;

            MyStorageData data = new MyStorageData();

            data.Resize(Size);

            Storage.ReadRange(data, MyStorageDataTypeFlags.Content, 0, Vector3I.Zero, SMax);

            for (int z = 0; z < sz.Z; ++z)
            {
                for (int y = 0; y < sz.Y; ++y)
                {
                    for (int x = 0; x < sz.X; ++x)
                    {
                        if (data.Content(x, y, z) > MyVoxelConstants.VOXEL_ISO_LEVEL)
                        {
                            Vector3I l = Vector3I.Max(new Vector3I(x - 1, y - 1, z - 1), Vector3I.Zero);
                            min = Vector3I.Min(l, min);

                            Vector3I h = Vector3I.Min(new Vector3I(x + 1, y + 1, z + 1), SMax);
                            max = Vector3I.Max(h, max);
                        }
                    }
                }
            }
        }
예제 #14
0
        public static BoundingBoxI TransformBoundingBox(BoundingBoxI box, ref MatrixI matrix)
        {
            Vector3I a, b;

            Vector3I.Transform(ref box.Min, ref matrix, out a);
            Vector3I.Transform(ref box.Max, ref matrix, out b);
            return(new BoundingBoxI(Vector3I.Min(a, b), Vector3I.Max(a, b)));
        }
예제 #15
0
        private unsafe void AddSegmentedParts(float gridSize, MyVoxelSegmentation segmenter, MyVoxelSegmentationType segmentationType)
        {
            int     num    = (int)Math.Floor((double)(40f / gridSize));
            Vector3 vector = new Vector3(gridSize * 0.5f);

            if (segmenter != null)
            {
                int mergeIterations = (segmentationType == MyVoxelSegmentationType.Optimized) ? 1 : 0;
                segmenter.ClearInput();
                foreach (Vector3I vectori3 in this.m_tmpCubes)
                {
                    segmenter.AddInput(vectori3);
                }
                foreach (MyVoxelSegmentation.Segment segment in segmenter.FindSegments(segmentationType, mergeIterations))
                {
                    Vector3I vectori;
                    vectori.X = segment.Min.X;
                    while (vectori.X <= segment.Max.X)
                    {
                        vectori.Y = segment.Min.Y;
                        while (true)
                        {
                            if (vectori.Y > segment.Max.Y)
                            {
                                int *numPtr3 = (int *)ref vectori.X;
                                numPtr3[0] += num;
                                break;
                            }
                            vectori.Z = segment.Min.Z;
                            while (true)
                            {
                                if (vectori.Z > segment.Max.Z)
                                {
                                    int *numPtr2 = (int *)ref vectori.Y;
                                    numPtr2[0] += num;
                                    break;
                                }
                                Vector3I maxPos = Vector3I.Min((Vector3I)((vectori + num) - 1), segment.Max);
                                Vector3  min    = ((Vector3)(vectori * gridSize)) - vector;
                                Vector3  max    = (maxPos * gridSize) + vector;
                                this.AddBox(vectori, maxPos, ref min, ref max);
                                int *numPtr1 = (int *)ref vectori.Z;
                                numPtr1[0] += num;
                            }
                        }
                    }
                }
            }
            else
            {
                foreach (Vector3I vectori4 in this.m_tmpCubes)
                {
                    Vector3 min = ((Vector3)(vectori4 * gridSize)) - vector;
                    Vector3 max = (vectori4 * gridSize) + vector;
                    this.AddBox(vectori4, vectori4, ref min, ref max);
                }
            }
        }
예제 #16
0
        private static bool IntersectsVoxelSurface(OrientedBoundingBoxD box)
        {
            var data = VoxelData;

            using (PoolManager.Get(out List <MyEntity> entities))
            {
                MyGamePruningStructure.GetTopmostEntitiesInBox(box.GetAABB(), entities, MyEntityQueryType.Static);
                foreach (var ent in entities)
                {
                    if (ent is MyVoxelBase voxel && !(ent is MyVoxelPhysics))
                    {
                        var invWorld      = voxel.PositionComp.WorldMatrixInvScaled;
                        var storageBounds = BoundingBoxD.CreateInvalid();
                        var voxelOffset   = (voxel.Size >> 1) + voxel.StorageMin;
                        var storageObb    = box;
                        storageObb.Transform(invWorld);
                        storageObb.HalfExtent /= voxel.VoxelSize;
                        storageObb.Center      = storageObb.Center / voxel.VoxelSize + voxelOffset;
                        storageBounds.Include(storageObb.GetAABB());

                        var storageMin = Vector3I.Max(Vector3I.Floor(storageBounds.Min), voxel.StorageMin);
                        var storageMax = Vector3I.Min(Vector3I.Ceiling(storageBounds.Max), voxel.StorageMax);
                        var localBox   = new BoundingBoxI(storageMin, storageMax);
                        localBox.Inflate(1);
                        var floatBox = new BoundingBox(localBox);
                        if (voxel.IntersectStorage(ref floatBox) == ContainmentType.Disjoint)
                        {
                            continue;
                        }
                        data.Resize(storageMin, storageMax);
                        voxel.Storage.ReadRange(data, MyStorageDataTypeFlags.Content, 0, storageMin, storageMax);
                        foreach (var pt in new BoundingBoxI(Vector3I.Zero, storageMax - storageMin).EnumeratePoints())
                        {
                            var voxelBox    = new BoundingBoxD(storageMin + pt, storageMin + pt + 1);
                            var containment = storageObb.Contains(ref voxelBox);
                            if (containment == ContainmentType.Disjoint)
                            {
                                continue;
                            }
                            var tmpPt   = pt;
                            var index   = data.ComputeLinear(ref tmpPt);
                            var content = data.Content(index);
                            if (containment == ContainmentType.Intersects && content >= 127)
                            {
                                return(true);
                            }
                            if (containment == ContainmentType.Contains && content > 0)
                            {
                                return(true);
                            }
                        }
                    }
                }
            }

            return(false);
        }
예제 #17
0
        public void ReadRange(MyStorageData target, MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax, ref MyVoxelRequestFlags requestFlags)
        {
            ProfilerShort.Begin(GetType().Name + ".ReadRange");
            try
            {
                const int SUBRANGE_SIZE_SHIFT = 3;
                const int SUBRANGE_SIZE       = 1 << SUBRANGE_SIZE_SHIFT;
                var       threshold           = new Vector3I(SUBRANGE_SIZE);
                var       rangeSize           = lodVoxelRangeMax - lodVoxelRangeMin + 1;
                if ((dataToRead & MyStorageDataTypeFlags.Content) != 0)
                {
                    target.ClearContent(0);
                }

                if ((rangeSize.X <= threshold.X &&
                     rangeSize.Y <= threshold.Y &&
                     rangeSize.Z <= threshold.Z) || !MyFakes.ENABLE_SPLIT_VOXEL_READ_QUERIES)
                {
                    using (m_lock.AcquireSharedUsing())
                    {
                        ReadRangeInternal(target, ref Vector3I.Zero, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax, ref requestFlags);
                    }
                }
                else
                {
                    // These optimizations don't work when splitting the range.
                    requestFlags &= ~(MyVoxelRequestFlags.OneMaterial | MyVoxelRequestFlags.ContentChecked);
                    MyVoxelRequestFlags flags = requestFlags;

                    // splitting to smaller ranges to make sure the lock is not held for too long, preventing write on update thread
                    // subranges could be aligned to multiple of their size for possibly better performance
                    var steps = (rangeSize - 1) >> SUBRANGE_SIZE_SHIFT;
                    for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref steps); it.IsValid(); it.MoveNext())
                    {
                        flags = requestFlags;
                        var offset = it.Current << SUBRANGE_SIZE_SHIFT;
                        var min    = lodVoxelRangeMin + offset;
                        var max    = min + SUBRANGE_SIZE - 1;
                        Vector3I.Min(ref max, ref lodVoxelRangeMax, out max);
                        Debug.Assert(min.IsInsideInclusive(ref lodVoxelRangeMin, ref lodVoxelRangeMax));
                        Debug.Assert(max.IsInsideInclusive(ref lodVoxelRangeMin, ref lodVoxelRangeMax));
                        using (m_lock.AcquireSharedUsing())
                        {
                            ReadRangeInternal(target, ref offset, dataToRead, lodIndex, ref min, ref max, ref flags);
                        }
                    }

                    // If the storage is consistent this should be fine.
                    requestFlags = flags;
                }
            }
            finally
            {
                ProfilerShort.End();
            }
        }
예제 #18
0
 public void Replace(IEnumerable <Vector3I> voxels)
 {
     Min = Vector3I.MaxValue;
     Max = Vector3I.MinValue;
     foreach (var v in voxels)
     {
         Min = Vector3I.Min(Min, v);
         Max = Vector3I.Max(Max, v);
     }
 }
예제 #19
0
 public void Replace(IEnumerable <Vector3I> voxels)
 {
     this.Min = Vector3I.MaxValue;
     this.Max = Vector3I.MinValue;
     foreach (Vector3I vectori in voxels)
     {
         this.Min = Vector3I.Min(this.Min, vectori);
         this.Max = Vector3I.Max(this.Max, vectori);
     }
 }
예제 #20
0
        private static bool HasBlocksInside(MyCubeGrid grid, ref MyOrientedBoundingBoxD obb)
        {
            Vector3I center = grid.WorldToGridInteger(obb.Center);
            double   radius = obb.HalfExtent.Length();

            radius *= grid.GridSizeR;
            Vector3I gridMin    = grid.Min;
            Vector3I gridMax    = grid.Max;
            double   radiusSq   = radius * radius;
            int      radiusCeil = (int)Math.Ceiling(radius);

            BoundingSphereD cubeSphere = new BoundingSphereD(new Vector3D(), grid.GridSizeHalf * Math.Sqrt(3));

            Vector3I max = Vector3I.Min(Vector3I.One * radiusCeil, gridMax - center);
            Vector3I min = Vector3I.Max(Vector3I.One * -radiusCeil, gridMin - center);
            int      x, y, z;

            for (x = min.X; x <= max.X; ++x)
            {
                for (y = min.Y; y <= max.Y; ++y)
                {
                    for (z = min.Z; z <= max.Z; ++z)
                    {
                        if (x * x + y * y + z * z >= radiusSq)
                        {
                            continue;
                        }

                        Vector3I offset = new Vector3I(x, y, z);

                        Vector3I cubePos = center + offset;
                        MyCube   cube;
                        if (!grid.TryGetCube(cubePos, out cube))
                        {
                            continue;
                        }

                        IMySlimBlock slim = cube.CubeBlock;
                        if (slim.IsDestroyed)
                        {
                            continue;
                        }

                        cubeSphere.Center = grid.GridIntegerToWorld(cubePos);
                        if (obb.Contains(ref cubeSphere) != ContainmentType.Disjoint)
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
예제 #21
0
        private unsafe void MergeSegments()
        {
            int num = 0;

            while (true)
            {
                int num2;
                while (true)
                {
                    if (num >= this.m_segments.Count)
                    {
                        return;
                    }
                    num2 = num + 1;
                    break;
                }
                while (true)
                {
                    if (num2 >= this.m_segments.Count)
                    {
                        num++;
                        break;
                    }
                    Segment segment  = this.m_segments[num];
                    Segment segment2 = this.m_segments[num2];
                    int     num3     = 0;
                    if ((segment.Min.X == segment2.Min.X) && (segment.Max.X == segment2.Max.X))
                    {
                        num3++;
                    }
                    if ((segment.Min.Y == segment2.Min.Y) && (segment.Max.Y == segment2.Max.Y))
                    {
                        num3++;
                    }
                    if ((segment.Min.Z == segment2.Min.Z) && (segment.Max.Z == segment2.Max.Z))
                    {
                        num3++;
                    }
                    if ((num3 == 2) && (((segment.Min.X == (segment2.Max.X + 1)) || (((segment.Max.X + 1) == segment2.Min.X) || ((segment.Min.Y == (segment2.Max.Y + 1)) || (((segment.Max.Y + 1) == segment2.Min.Y) || (segment.Min.Z == (segment2.Max.Z + 1)))))) || ((segment.Max.Z + 1) == segment2.Min.Z)))
                    {
                        Segment *segmentPtr1 = (Segment *)ref segment;
                        segmentPtr1->Min = Vector3I.Min(segment.Min, segment2.Min);
                        Segment *segmentPtr2 = (Segment *)ref segment;
                        segmentPtr2->Max     = Vector3I.Max(segment.Max, segment2.Max);
                        this.m_segments[num] = segment;
                        this.m_segments.RemoveAt(num2);
                        continue;
                    }
                    num2++;
                }
            }
        }
예제 #22
0
        public void ReadRange(MyStorageDataCache target, MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax)
        {
            ProfilerShort.Begin(GetType().Name + ".ReadRange");
            try
            {
                const int SUBRANGE_SIZE_SHIFT = 3;
                const int SUBRANGE_SIZE       = 1 << SUBRANGE_SIZE_SHIFT;
                var       threshold           = new Vector3I(SUBRANGE_SIZE);
                var       rangeSize           = lodVoxelRangeMax - lodVoxelRangeMin + 1;
                if ((dataToRead & MyStorageDataTypeFlags.Content) != 0)
                {
                    target.ClearContent(0);
                }
                if ((dataToRead & MyStorageDataTypeFlags.Material) != 0)
                {
                    target.ClearMaterials(m_defaultMaterial);
                }

                if (rangeSize.X <= threshold.X &&
                    rangeSize.Y <= threshold.Y &&
                    rangeSize.Z <= threshold.Z)
                {
                    using (m_lock.AcquireSharedUsing())
                    {
                        ReadRangeInternal(target, ref Vector3I.Zero, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax);
                    }
                }
                else
                {
                    // splitting to smaller ranges to make sure the lock is not held for too long, preventing write on update thread
                    // subranges could be aligned to multiple of their size for possibly better performance
                    var steps = (rangeSize - 1) >> SUBRANGE_SIZE_SHIFT;
                    for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref steps); it.IsValid(); it.MoveNext())
                    {
                        var offset = it.Current << SUBRANGE_SIZE_SHIFT;
                        var min    = lodVoxelRangeMin + offset;
                        var max    = min + SUBRANGE_SIZE - 1;
                        Vector3I.Min(ref max, ref lodVoxelRangeMax, out max);
                        Debug.Assert(min.IsInsideInclusive(ref lodVoxelRangeMin, ref lodVoxelRangeMax));
                        Debug.Assert(max.IsInsideInclusive(ref lodVoxelRangeMin, ref lodVoxelRangeMax));
                        using (m_lock.AcquireSharedUsing())
                        {
                            ReadRangeInternal(target, ref offset, dataToRead, lodIndex, ref min, ref max);
                        }
                    }
                }
            }
            finally
            {
                ProfilerShort.End();
            }
        }
예제 #23
0
        internal static void Export(Entity entity, string schematic)
        {
            EntityCheck(entity);

            var target = PositionClone()[entity];

            var cube  = new VectorCubeI(target.Pos1.From3Dto3I(), target.Pos2.From3Dto3I());
            var cube0 = Vector3I.Min(new Vector3I(cube.Start.X, cube.Start.Y, cube.Start.Z), new Vector3I(cube.End.X, cube.End.Y, cube.End.Z));
            var cube1 = Vector3I.Max(new Vector3I(cube.Start.X, cube.Start.Y, cube.Start.Z),
                                     new Vector3I(cube.End.X, cube.End.Y, cube.End.Z)) - cube0 + Vector3I.One;

            FoxCore.SaveDirectory.FetchDirectory("Exports").ExportCube(cube1, cube0, schematic);
        }
예제 #24
0
        private void Create(List <MyObjectBuilder_CubeGrid> grids)
        {
            Vector3D centerSum = new Vector3D();

            MatrixD mRef   = reference.WorldMatrix;
            MatrixD mRefNI = MatrixD.Normalize(MatrixD.Invert(mRef));

            obbs        = new List <MyOrientedBoundingBoxD>(grids.Count);
            orientation = new GridOrientation(reference);
            entityIds   = new HashSet <long>();
            foreach (MyObjectBuilder_CubeGrid grid in grids)
            {
                entityIds.Add(grid.EntityId);
                Vector3I min = Vector3I.MaxValue;
                Vector3I max = Vector3I.MinValue;
                foreach (MyObjectBuilder_CubeBlock cube in grid.CubeBlocks)
                {
                    min = Vector3I.Min(min, cube.Min);
                    max = Vector3I.Max(max, ComputeMax(cube));
                }

                double   cubeGridSize = grid.GridSizeEnum == MyCubeSize.Large ? 2.5 : 0.5;
                Vector3D pMin         = min * cubeGridSize - (cubeGridSize * 0.5);
                Vector3D pMax         = max * cubeGridSize + (cubeGridSize * 0.5);

                MyPositionAndOrientation pos = grid.PositionAndOrientation.Value;
                Vector3D center = Vector3D.Transform((pMin + pMax) * 0.5, pos.GetMatrix());
                centerSum += center;
                MyOrientedBoundingBoxD box = new MyOrientedBoundingBoxD(center, (pMax - pMin) * 0.5, pos.Orientation);
                obbs.Add(box);

                orientation.Include(MatrixD.CreateWorld(center, pos.Forward, pos.Up));
            }


            centerSum     /= obbs.Count;
            relativeCenter = Vector3D.TransformNormal(centerSum - mRef.Translation, MatrixD.Transpose(mRef));

            double radius2 = 0;

            foreach (MyOrientedBoundingBoxD obb in obbs)
            {
                double dist2 = Vector3D.DistanceSquared(centerSum, obb.Center) + obb.HalfExtent.LengthSquared();
                if (dist2 > radius2)
                {
                    radius2 = dist2;
                }
            }

            worldVolume = new BoundingSphereD(centerSum, Math.Sqrt(radius2));
        }
예제 #25
0
        private bool IsInBounds(Vector3I pos)
        {
            if (GridMin() != Vector3I.Min(pos, GridMin()))
            {
                return(false);
            }

            if (GridMax() != Vector3I.Max(pos, GridMax()))
            {
                return(false);
            }

            return(true);
        }
예제 #26
0
        private static DeformationTable CreateTable(Vector3I normal)
        {
            DeformationTable table = new DeformationTable {
                Normal = normal
            };
            Vector3I vectori  = new Vector3I(1, 1, 1);
            Vector3I vectori2 = Vector3I.Abs(normal);
            Vector3I vectori3 = (new Vector3I(1, 1, 1) - vectori2) * 2;
            int      x        = -vectori3.X;

            while (x <= vectori3.X)
            {
                int y = -vectori3.Y;
                while (true)
                {
                    if (y > vectori3.Y)
                    {
                        x++;
                        break;
                    }
                    int z = -vectori3.Z;
                    while (true)
                    {
                        if (z > vectori3.Z)
                        {
                            y++;
                            break;
                        }
                        Vector3I vectori4 = new Vector3I(x, y, z);
                        float    num4     = 1f;
                        if (Math.Max(Math.Abs(z), Math.Max(Math.Abs(x), Math.Abs(y))) > 1f)
                        {
                            num4 = 0.3f;
                        }
                        float    num5 = num4 * 0.25f;
                        Vector3I key  = (Vector3I)((vectori + new Vector3I(x, y, z)) + normal);
                        table.OffsetTable.Add(key, Matrix.CreateFromDir((Vector3)(-normal * num5)));
                        Vector3I item     = key >> 1;
                        Vector3I vectori7 = (key - Vector3I.One) >> 1;
                        table.CubeOffsets.Add(item);
                        table.CubeOffsets.Add(vectori7);
                        table.MinOffset = Vector3I.Min(table.MinOffset, vectori4);
                        table.MaxOffset = Vector3I.Max(table.MaxOffset, vectori4);
                        z++;
                    }
                }
            }
            return(table);
        }
예제 #27
0
        public static VoxelModel GenerateTreeModel(int seed, TreeBluePrint blueprint, TreeLSystem treeSystem = null)
        {
            if (treeSystem == null)
            {
                treeSystem = new TreeLSystem();
            }

            var blocks = treeSystem.Generate(seed, new Vector3I(), blueprint);

            var max = new Vector3I(int.MinValue);
            var min = new Vector3I(int.MaxValue);

            foreach (var blockWithPosition in blocks)
            {
                max = Vector3I.Max(max, blockWithPosition.WorldPosition);
                min = Vector3I.Min(min, blockWithPosition.WorldPosition);
            }

            var size  = max - min + Vector3I.One;
            var model = new VoxelModel();

            model.Name                        = "Tree Example";
            model.ColorMapping                = new ColorMapping();
            model.ColorMapping.BlockColors    = new Color4[64];
            model.ColorMapping.BlockColors[0] = Color.Brown.ToColor4();
            model.ColorMapping.BlockColors[1] = Color.Green.ToColor4();

            var frame = new VoxelFrame(size);

            foreach (var blockWithPosition in blocks)
            {
                frame.BlockData.SetBlock(blockWithPosition.WorldPosition - min, blockWithPosition.BlockId == blueprint.TrunkBlock ? (byte)1 : (byte)2);
            }

            model.Frames.Add(frame);
            var part = new VoxelModelPart();

            part.Name = "Main";
            model.Parts.Add(part);

            var state = new VoxelModelState(model);

            state.Name = "Default";
            state.PartsStates[0].Translation = new Vector3(min.X, 0, min.Z);
            model.States.Add(state);

            return(model);
        }
예제 #28
0
        public static void ApplyTransformation(MyObjectBuilder_CubeBlock output, MatrixI transform)
        {
            var      cMin = (Vector3I)output.Min;
            Vector3I cMax;

            ComputeBlockMax(output, out cMax);

            output.BlockOrientation.Forward = transform.GetDirection(output.BlockOrientation.Forward);
            output.BlockOrientation.Up      = transform.GetDirection(output.BlockOrientation.Up);


            Vector3I.Transform(ref cMin, ref transform, out cMin);
            Vector3I.Transform(ref cMax, ref transform, out cMax);

            output.Min = Vector3I.Min(cMin, cMax);
        }
예제 #29
0
        static MySlimBlock GetContactBlock(MyCubeGrid grid, Vector3D worldPosition, float graceDistance)
        {
            graceDistance  = Math.Max(Math.Abs(graceDistance), grid.GridSize * 0.2f);
            graceDistance += 1f;
            MatrixD  invWorld      = grid.PositionComp.GetWorldMatrixNormalizedInv();
            Vector3D localVelocity = Vector3D.TransformNormal(grid.Physics.LinearVelocity * Sandbox.Common.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS, invWorld);
            Vector3D localPos;

            Vector3D.Transform(ref worldPosition, ref invWorld, out localPos);

            // MW:TODO optimize
            var min1 = Vector3I.Round((localPos - graceDistance - localVelocity) / grid.GridSize);
            var max1 = Vector3I.Round((localPos + graceDistance + localVelocity) / grid.GridSize);
            var min2 = Vector3I.Round((localPos + graceDistance - localVelocity) / grid.GridSize);
            var max2 = Vector3I.Round((localPos - graceDistance + localVelocity) / grid.GridSize);

            Vector3I min = Vector3I.Min(Vector3I.Min(Vector3I.Min(min1, max1), min2), max2);
            Vector3I max = Vector3I.Max(Vector3I.Max(Vector3I.Max(min1, max1), min2), max2);

            MySlimBlock resultBlock = null;
            float       distSq      = float.MaxValue;

            // TODO: optimize this, it should be possible using normal from contact
            Vector3I pos;

            for (pos.X = min.X; pos.X <= max.X; pos.X++)
            {
                for (pos.Y = min.Y; pos.Y <= max.Y; pos.Y++)
                {
                    for (pos.Z = min.Z; pos.Z <= max.Z; pos.Z++)
                    {
                        var block = grid.GetCubeBlock(pos);
                        if (block != null)
                        {
                            var testDistSq = (float)(pos * grid.GridSize - localPos).LengthSquared();
                            if (testDistSq < distSq)
                            {
                                distSq      = testDistSq;
                                resultBlock = block;
                            }
                        }
                    }
                }
            }

            return(resultBlock);
        }
        protected static bool TestBlockPlacementOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid)
        {
            Vector3I positionMin;

            Vector3I.Transform(ref block.Min, ref transform, out positionMin);
            Vector3I positionMax;

            Vector3I.Transform(ref block.Max, ref transform, out positionMax);
            Vector3I min = Vector3I.Min(positionMin, positionMax);
            Vector3I max = Vector3I.Max(positionMin, positionMax);

            var forward = transform.GetDirection(block.Orientation.Forward);
            var up      = transform.GetDirection(block.Orientation.Up);
            MyBlockOrientation blockOrientation = new MyBlockOrientation(forward, up);

            return(hitGrid.CanPlaceBlock(min, max, blockOrientation, block.BlockDefinition, ref settings));
        }