Example #1
0
        protected override void WriteRangeInternal(MyStorageDataCache source, MyStorageDataTypeFlags dataToWrite, ref Vector3I voxelRangeMin, ref Vector3I voxelRangeMax)
        {
            ProfilerShort.Begin("MyOctreeStorage.WriteRange");

            Debug.Assert(dataToWrite != MyStorageDataTypeFlags.None);
            if ((dataToWrite & MyStorageDataTypeFlags.Content) != 0)
            {
                var args = new WriteRangeArgs()
                {
                    DataFilter = MyOctreeNode.ContentFilter,
                    DataType   = MyStorageDataTypeEnum.Content,
                    Leaves     = m_contentLeaves,
                    Nodes      = m_contentNodes,
                    Provider   = m_dataProvider,
                    Source     = source,
                };
                WriteRange(ref args, 0, m_treeHeight + LeafLodCount, Vector3I.Zero, ref voxelRangeMin, ref voxelRangeMax);
            }

            if ((dataToWrite & MyStorageDataTypeFlags.Material) != 0)
            {
                var args = new WriteRangeArgs()
                {
                    DataFilter = MyOctreeNode.MaterialFilter,
                    DataType   = MyStorageDataTypeEnum.Material,
                    Leaves     = m_materialLeaves,
                    Nodes      = m_materialNodes,
                    Provider   = m_dataProvider,
                    Source     = source,
                };
                WriteRange(ref args, 0, m_treeHeight + LeafLodCount, Vector3I.Zero, ref voxelRangeMin, ref voxelRangeMax);
            }

            ProfilerShort.End();
        }
        internal void BuildFrom(MyStorageDataCache source)
        {
            Debug.Assert(source.Size3D == new Vector3I(m_octree.TreeWidth));
            var enumer = new MyStorageDataCache.MortonEnumerator(source, m_dataType);

            m_octree.Build(enumer);
        }
Example #3
0
        public override void ReadMaterialRange(MyStorageDataCache target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod, float lodVoxelSizeHalf)
        {
            float lodVoxelSize = 2f * lodVoxelSizeHalf;

            byte defaultMaterial = m_material.Index;

            Vector3I v = new Vector3I();

            for (v.Z = minInLod.Z; v.Z <= maxInLod.Z; ++v.Z)
            {
                for (v.Y = minInLod.Y; v.Y <= maxInLod.Y; ++v.Y)
                {
                    for (v.X = minInLod.X; v.X <= maxInLod.X; ++v.X)
                    {
                        var write = v - minInLod + writeOffset;

                        byte slope = target.Material(ref write);
                        if (slope == 0)
                        {
                            continue;
                        }

                        Vector3 localPos = v * lodVoxelSize;

                        var mat = GetMaterialForPosition(ref localPos, lodVoxelSize);
                        target.Material(ref write, mat.Index);
                    }
                }
            }
        }
        /// <summary>
        /// Create a new Asteroid, ready for some manipulation.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="size">Currently the size must be multiple of 64, eg. 128x64x256</param>
        /// <param name="position"></param>
        public static IMyVoxelMap CreateNewAsteroid(string storageName, Vector3I size, Vector3D position)
        {
            var cache = new MyStorageDataCache();

            // new storage is created completely full
            // no geometry will be created because that requires full-empty transition
            var storage = MyAPIGateway.Session.VoxelMaps.CreateStorage(size);

            // midspace's Note: The following steps appear redundant, as the storage space is created empty.
            /*
            // always ensure cache is large enough for whatever you plan to load into it
            cache.Resize(size);

            // range is specified using inclusive min and max coordinates
            // Choose a reasonable size of range you plan to work with, to avoid high memory usage
            // memory size in bytes required by cache is computed as Size.X * Size.Y * Size.Z * 2, where Size is size of the range.
            // min and max coordinates are inclusive, so if you want to read 8^3 voxels starting at coordinate [8,8,8], you
            // should pass in min = [8,8,8], max = [15,15,15]
            // For LOD, you should only use LOD0 or LOD1
            // When you write data inside cache back to storage, you always write to LOD0 (the most detailed LOD), LOD1 can only be read from.
            storage.ReadRange(cache, MyStorageDataTypeFlags.All, 0, Vector3I.Zero, size - 1);

            // resets all loaded content to empty
            cache.ClearContent(0);

            // write new data back to the storage
            storage.WriteRange(cache, MyStorageDataTypeFlags.Content, Vector3I.Zero, size - 1);
            */

            return MyAPIGateway.Session.VoxelMaps.CreateVoxelMap(storageName, storage, position, 0);
        }
        public override void ReadMaterialRange(MyStorageDataCache target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod, float lodVoxelSizeHalf)
        {
            float lodVoxelSize = 2f * lodVoxelSizeHalf;

            byte defaultMaterial = m_material.Index;

            Vector3I v = new Vector3I();
            for (v.Z = minInLod.Z; v.Z <= maxInLod.Z; ++v.Z)
            {
                for (v.Y = minInLod.Y; v.Y <= maxInLod.Y; ++v.Y)
                {
                    for (v.X = minInLod.X; v.X <= maxInLod.X; ++v.X)
                    {
                        var write = v - minInLod + writeOffset;

                        byte slope = target.Material(ref write);
                        if (slope == 0) continue;

                        Vector3 localPos = v * lodVoxelSize;

                        var mat = GetMaterialForPosition(ref localPos, lodVoxelSize);
                        target.Material(ref write, mat.Index);
                    }
                }
            }
        }
        void ModAPI.Interfaces.IMyStorage.ReadRange(MyStorageDataCache target, MyStorageDataTypeFlags dataToRead, int lodIndex,  Vector3I lodVoxelRangeMin,  Vector3I lodVoxelRangeMax)
        {
            if ((uint)lodIndex >= (uint)MyCellCoord.MAX_LOD_COUNT)
                return;

            ReadRange(target, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax);
        }
Example #7
0
        void ModAPI.Interfaces.IMyStorage.ReadRange(MyStorageDataCache target, MyStorageDataTypeFlags dataToRead, int lodIndex, Vector3I lodVoxelRangeMin, Vector3I lodVoxelRangeMax)
        {
            if ((uint)lodIndex >= (uint)MyCellCoord.MAX_LOD_COUNT)
            {
                return;
            }

            ReadRange(target, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax);
        }
 void IMyOctreeLeafNode.ReadRange(MyStorageDataCache target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
 {
     var leafMinInLod = m_leafMin >> lodIndex;
     var min = minInLod + leafMinInLod;
     var max = maxInLod + leafMinInLod;
     AssertRangeIsInside(lodIndex, ref min, ref max);
     ProfilerShort.Begin("MyProviderLeaf.ReadRange");
     m_provider.ReadRange(target, m_dataType, ref writeOffset, lodIndex, ref min, ref max);
     ProfilerShort.End();
 }
Example #9
0
        void IMyOctreeLeafNode.ReadRange(MyStorageDataCache target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
        {
            var leafMinInLod = m_leafMin >> lodIndex;
            var min          = minInLod + leafMinInLod;
            var max          = maxInLod + leafMinInLod;

            AssertRangeIsInside(lodIndex, ref min, ref max);
            ProfilerShort.Begin("MyProviderLeaf.ReadRange");
            m_provider.ReadRange(target, m_dataType, ref writeOffset, lodIndex, ref min, ref max);
            ProfilerShort.End();
        }
        //  Linearly interpolates position, normal and material on poly-cube edge. Interpolated point is where an isosurface cuts an edge between two vertices, each with their own scalar value.
        void GetVertexInterpolation(MyStorageDataCache cache, MyTemporaryVoxel inputVoxelA, MyTemporaryVoxel inputVoxelB, int edgeIndex)
        {
            MyEdge edge = m_edges[edgeIndex];

            byte contentA  = cache.Content(inputVoxelA.IdxInCache);
            byte contentB  = cache.Content(inputVoxelB.IdxInCache);
            byte materialA = cache.Material(inputVoxelA.IdxInCache);
            byte materialB = cache.Material(inputVoxelB.IdxInCache);

            if (Math.Abs(MyVoxelConstants.VOXEL_ISO_LEVEL - contentA) < 0.00001f)
            {
                edge.Position = inputVoxelA.Position;
                edge.Normal   = inputVoxelA.Normal;
                edge.Material = materialA;
                edge.Ambient  = inputVoxelA.Ambient;
                return;
            }

            if (Math.Abs(MyVoxelConstants.VOXEL_ISO_LEVEL - contentB) < 0.00001f)
            {
                edge.Position = inputVoxelB.Position;
                edge.Normal   = inputVoxelB.Normal;
                edge.Material = materialB;
                edge.Ambient  = inputVoxelB.Ambient;
                return;
            }

            float mu = (float)(MyVoxelConstants.VOXEL_ISO_LEVEL - contentA) / (float)(contentB - contentA);

            Debug.Assert(mu > 0.0f && mu < 1.0f);

            edge.Position.X = inputVoxelA.Position.X + mu * (inputVoxelB.Position.X - inputVoxelA.Position.X);
            edge.Position.Y = inputVoxelA.Position.Y + mu * (inputVoxelB.Position.Y - inputVoxelA.Position.Y);
            edge.Position.Z = inputVoxelA.Position.Z + mu * (inputVoxelB.Position.Z - inputVoxelA.Position.Z);

            edge.Normal.X = inputVoxelA.Normal.X + mu * (inputVoxelB.Normal.X - inputVoxelA.Normal.X);
            edge.Normal.Y = inputVoxelA.Normal.Y + mu * (inputVoxelB.Normal.Y - inputVoxelA.Normal.Y);
            edge.Normal.Z = inputVoxelA.Normal.Z + mu * (inputVoxelB.Normal.Z - inputVoxelA.Normal.Z);
            if (MyVRageUtils.IsZero(edge.Normal))
            {
                edge.Normal = inputVoxelA.Normal;
            }
            else
            {
                edge.Normal = MyVRageUtils.Normalize(edge.Normal);
            }

            float mu2 = ((float)contentB) / (((float)contentA) + ((float)contentB));

            edge.Material = (mu2 <= 0.5f) ? materialA : materialB;
            edge.Ambient  = inputVoxelA.Ambient + mu2 * (inputVoxelB.Ambient - inputVoxelA.Ambient);

            return;
        }
 void IMyStorageDataProvider.ReadRange(MyStorageDataCache target, MyStorageDataTypeEnum dataType, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
 {
     if (dataType == MyStorageDataTypeEnum.Content)
     {
         ReadContentRange(target, ref writeOffset, lodIndex, ref minInLod, ref maxInLod);
     }
     else
     {
         ReadMaterialRange(target, ref writeOffset, lodIndex, ref minInLod, ref maxInLod);
     }
 }
Example #12
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();
            }
        }
        private void RemoveAllAsteroids(MyGuiControlButton sender)
        {
            MyCsgShapePlanetShapeAttributes shapeAttributes = new MyCsgShapePlanetShapeAttributes();

            shapeAttributes.Seed           = 12345;
            shapeAttributes.Diameter       = 60;
            shapeAttributes.Radius         = 60 / 2.0f;
            shapeAttributes.DeviationScale = 0.003f;
            float maxHillSize = 10;

            float planetHalfDeviation = (shapeAttributes.Diameter * shapeAttributes.DeviationScale) / 2.0f;
            float hillHalfDeviation   = planetHalfDeviation * maxHillSize;
            float canyonHalfDeviation = 1;


            float averagePlanetRadius = shapeAttributes.Radius - hillHalfDeviation;

            float outerRadius = averagePlanetRadius + hillHalfDeviation;
            float innerRadius = averagePlanetRadius - canyonHalfDeviation;

            float atmosphereRadius = MathHelper.Max(outerRadius, averagePlanetRadius * 1.08f);
            float minPlanetRadius  = MathHelper.Min(innerRadius, averagePlanetRadius - planetHalfDeviation * 2 * 2.5f);

            MyCsgShapePlanetMaterialAttributes materialAttributes = new MyCsgShapePlanetMaterialAttributes();

            materialAttributes.OreStartDepth = innerRadius;
            materialAttributes.OreEndDepth   = innerRadius;
            materialAttributes.OreEndDepth   = MathHelper.Max(materialAttributes.OreEndDepth, 0);
            materialAttributes.OreStartDepth = MathHelper.Max(materialAttributes.OreStartDepth, 0);

            materialAttributes.OreProbabilities = new MyOreProbability[10];

            for (int i = 0; i < 10; ++i)
            {
                materialAttributes.OreProbabilities[i]         = new MyOreProbability();
                materialAttributes.OreProbabilities[i].OreName = "Ice_01";
                materialAttributes.OreProbabilities[i].CummulativeProbability = 0.0f;
            }

            shapeAttributes.AveragePlanetRadius = averagePlanetRadius;

            IMyStorageDataProvider dataProvider = MyCompositeShapeProvider.CreatePlanetShape(0, ref shapeAttributes, maxHillSize, ref materialAttributes);
            IMyStorage             storage      = new MyOctreeStorage(dataProvider, MyVoxelCoordSystems.FindBestOctreeSize(shapeAttributes.Diameter));
            MyStorageDataCache     cache        = new MyStorageDataCache();

            cache.Resize(storage.Size);
            Vector3I start = Vector3I.Zero;
            Vector3I end   = storage.Size;

            storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 1, ref start, ref end);
            dataProvider.ReleaseHeightMaps();
        }
Example #14
0
        private static void VoxelReading()
        {
            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;
            }

            var      targetMin = targetPosition - Vector3.One * MyVoxelConstants.VOXEL_SIZE_IN_METRES;
            var      targetMax = targetPosition + Vector3.One * MyVoxelConstants.VOXEL_SIZE_IN_METRES;
            Vector3I minVoxel, maxVoxel;

            MyVoxelCoordSystems.WorldPositionToVoxelCoord(targetVoxelMap.PositionLeftBottomCorner, ref targetMin, out minVoxel);
            MyVoxelCoordSystems.WorldPositionToVoxelCoord(targetVoxelMap.PositionLeftBottomCorner, ref targetMax, out maxVoxel);
            MyVoxelCoordSystems.VoxelCoordToWorldPosition(targetVoxelMap.PositionLeftBottomCorner, ref minVoxel, out targetMin);
            MyVoxelCoordSystems.VoxelCoordToWorldPosition(targetVoxelMap.PositionLeftBottomCorner, ref maxVoxel, out targetMax);

            {
                BoundingBoxD bbox = BoundingBoxD.CreateInvalid();
                bbox.Include(targetMin);
                bbox.Include(targetMax);
                VRageRender.MyRenderProxy.DebugDrawAABB(bbox, Vector3.One, 1f, 1f, true);
            }

            if (MyInput.Static.IsNewLeftMousePressed())
            {
                var cache = new MyStorageDataCache();
                cache.Resize(minVoxel, maxVoxel);
                targetVoxelMap.Storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, ref minVoxel, ref maxVoxel);
                targetVoxelMap.Storage.WriteRange(cache, MyStorageDataTypeFlags.Content, ref minVoxel, ref maxVoxel);
                Debug.Assert(true);
            }
        }
        /// <summary>
        /// called multiple times for ships, to be kept up to date.
        /// </summary>
        public override void UpdateAfterSimulation10()
        {
            if (CommandAsteroidEditClear.ActiveVoxelDeleter)
            {
                var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix;
                var position = worldMatrix.Translation + worldMatrix.Forward * 1.6f + worldMatrix.Up * 1.35f + worldMatrix.Right * 0.1f;

                var currentAsteroidList = new List<IMyVoxelBase>();
                var bb = new BoundingBoxD(position - 0.2f, position + 0.2f);
                MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb));

                if (currentAsteroidList.Count > 0)
                {
                    _isInRange = true;
                    var storage = currentAsteroidList[0].Storage;

                    var point = new Vector3I(position - currentAsteroidList[0].PositionLeftBottomCorner);
                    var cache = new MyStorageDataCache();
                    var min = (point / 64) * 64;
                    var max = min + 63;
                    var size = max - min;
                    cache.Resize(size);
                    storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, min, max);

                    Vector3I p = point - min;
                    var content = cache.Content(ref p);
                    if (content > 0)
                    {
                        content = 0x00;
                        cache.Content(ref p, content);
                        storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, min, max);
                    }
                    //storage = null;
                }
                else
                {
                    _isInRange = false;
                }
            }

            if (CommandAsteroidEditSet.ActiveVoxelSetter)
            {
                var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix;
                CommandAsteroidEditSet.ActiveVoxelSetterPosition = worldMatrix.Translation + worldMatrix.Forward * 1.6f + worldMatrix.Up * 1.35f + worldMatrix.Right * 0.1f;
            }
            else
            {
                CommandAsteroidEditSet.ActiveVoxelSetterPosition = null;
            }
        }
Example #16
0
        public static MyVoxelMaterialDefinition GetMaterialAt(this IMyStorage self, ref Vector3I voxelCoords)
        {
            MyVoxelMaterialDefinition def;

            MyStorageDataCache cache = new MyStorageDataCache();
            cache.Resize(Vector3I.One);
            cache.ClearMaterials(0);

            self.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, ref voxelCoords, ref voxelCoords);

            def = MyDefinitionManager.Static.GetVoxelMaterialDefinition(cache.Material(0));

            return def;
        }
        private void RemoveAllAsteroids(MyGuiControlButton sender)
        {
            MyCsgShapePlanetShapeAttributes shapeAttributes = new MyCsgShapePlanetShapeAttributes();

            shapeAttributes.Seed = 12345;
            shapeAttributes.Diameter = 60;
            shapeAttributes.Radius = 60 / 2.0f;
            shapeAttributes.DeviationScale = 0.003f;
            float maxHillSize = 10;

            float planetHalfDeviation = (shapeAttributes.Diameter * shapeAttributes.DeviationScale) / 2.0f;
            float hillHalfDeviation = planetHalfDeviation * maxHillSize;
            float canyonHalfDeviation = 1;


            float averagePlanetRadius = shapeAttributes.Radius - hillHalfDeviation;

            float outerRadius = averagePlanetRadius + hillHalfDeviation;
            float innerRadius = averagePlanetRadius - canyonHalfDeviation;

            float atmosphereRadius = MathHelper.Max(outerRadius, averagePlanetRadius * 1.08f);
            float minPlanetRadius = MathHelper.Min(innerRadius, averagePlanetRadius - planetHalfDeviation * 2 * 2.5f);

            MyCsgShapePlanetMaterialAttributes materialAttributes = new MyCsgShapePlanetMaterialAttributes();
            materialAttributes.OreStartDepth = innerRadius;
            materialAttributes.OreEndDepth = innerRadius;
            materialAttributes.OreEndDepth = MathHelper.Max(materialAttributes.OreEndDepth, 0);
            materialAttributes.OreStartDepth = MathHelper.Max(materialAttributes.OreStartDepth, 0);

            materialAttributes.OreProbabilities = new MyOreProbability[10];

            for (int i = 0; i < 10; ++i)
            {
                materialAttributes.OreProbabilities[i] = new MyOreProbability();
                materialAttributes.OreProbabilities[i].OreName = "Ice_01";
                materialAttributes.OreProbabilities[i].CummulativeProbability = 0.0f;
            }

            shapeAttributes.AveragePlanetRadius = averagePlanetRadius;

            IMyStorageDataProvider dataProvider = MyCompositeShapeProvider.CreatePlanetShape(0, ref shapeAttributes, maxHillSize, ref materialAttributes);
            IMyStorage storage = new MyOctreeStorage(dataProvider, MyVoxelCoordSystems.FindBestOctreeSize(shapeAttributes.Diameter));
            MyStorageDataCache cache = new MyStorageDataCache();
            cache.Resize(storage.Size);
            Vector3I start = Vector3I.Zero;
            Vector3I end = storage.Size;
            storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 1, ref start, ref end);
            dataProvider.ReleaseHeightMaps();
        }
Example #18
0
        public static MyVoxelMaterialDefinition GetMaterialAt(this IMyStorage self, ref Vector3I voxelCoords)
        {
            MyVoxelMaterialDefinition def;

            MyStorageDataCache cache = new MyStorageDataCache();

            cache.Resize(Vector3I.One);
            cache.ClearMaterials(0);

            self.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, ref voxelCoords, ref voxelCoords);

            def = MyDefinitionManager.Static.GetVoxelMaterialDefinition(cache.Material(0));

            return(def);
        }
Example #19
0
        protected void RefreshCache( )
        {
            IMyVoxelMap voxelMap = (IMyVoxelMap)BackingObject;

            m_cache = new MyStorageDataCache( );
            Vector3I size = voxelMap.Storage.Size;

            m_cache.Resize(size);

            //			SandboxGameAssemblyWrapper.Instance.GameAction(() =>
            //			{
            voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.Material, 0, Vector3I.Zero, size - 1);
            //voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.Material, Vector3I.Zero, size - 1);
            //			});

            foreach (byte materialIndex in m_cache.Data)
            {
                try
                {
                    MyVoxelMaterialDefinition material = MyDefinitionManager.Static.GetVoxelMaterialDefinition(materialIndex);
                    if (material == null)
                    {
                        continue;
                    }

                    if (!m_materialTotals.ContainsKey(material))
                    {
                        m_materialTotals.Add(material, 1);
                    }
                    else
                    {
                        m_materialTotals[material]++;
                    }
                }
                catch (Exception ex)
                {
                    ApplicationLog.BaseLog.Error(ex);
                }
            }
        }
Example #20
0
        /// <summary>
        /// For debugging/testing only! This can be very slow for large storage.
        /// </summary>
        public void Voxelize(MyStorageDataTypeFlags data)
        {
            var cache = new MyStorageDataCache();

            cache.Resize(new Vector3I(LeafSizeInVoxels));
            var      leafCount = (Size / LeafSizeInVoxels);
            Vector3I leaf      = Vector3I.Zero;
            var      end       = leafCount - 1;

            for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref end);
                 it.IsValid();
                 it.GetNext(out leaf))
            {
                Debug.WriteLine("Processing {0} / {1}", leaf, end);
                var min = leaf * LeafSizeInVoxels;
                var max = min + (LeafSizeInVoxels - 1);
                ReadRangeInternal(cache, ref Vector3I.Zero, data, 0, ref min, ref max);
                WriteRangeInternal(cache, data, ref min, ref max);
            }

            OnRangeChanged(Vector3I.Zero, Size - 1, data);
        }
Example #21
0
        public void WriteRange(MyStorageDataCache source, MyStorageDataTypeFlags dataToWrite, ref Vector3I voxelRangeMin, ref Vector3I voxelRangeMax)
        {
            MyPrecalcComponent.AssertUpdateThread();

            ProfilerShort.Begin(GetType().Name + ".WriteRange");
            try
            {
                using (m_lock.AcquireExclusiveUsing())
                {
                    m_compressedData = null;
                    WriteRangeInternal(source, dataToWrite, ref voxelRangeMin, ref voxelRangeMax);
                }

                ProfilerShort.BeginNextBlock(GetType().Name + ".OnRangeChanged");

                OnRangeChanged(voxelRangeMin, voxelRangeMax, dataToWrite);
            }
            finally
            {
                ProfilerShort.End();
            }
        }
Example #22
0
        protected override void ReadRangeInternal(MyStorageDataCache target, ref Vector3I targetWriteOffset,
                                                  MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelCoordStart, ref Vector3I lodVoxelCoordEnd)
        {
            bool hasLod = lodIndex <= (m_treeHeight + LeafLodCount);

            Debug.Assert(dataToRead != MyStorageDataTypeFlags.None);
            if ((dataToRead & MyStorageDataTypeFlags.Content) != 0)
            {
                if (hasLod)
                {
                    ReadRange(target, ref targetWriteOffset, MyStorageDataTypeEnum.Content, m_treeHeight, m_contentNodes, m_contentLeaves, lodIndex, ref lodVoxelCoordStart, ref lodVoxelCoordEnd);
                }
            }

            if ((dataToRead & MyStorageDataTypeFlags.Material) != 0)
            {
                if (hasLod)
                {
                    ReadRange(target, ref targetWriteOffset, MyStorageDataTypeEnum.Material, m_treeHeight, m_materialNodes, m_materialLeaves, lodIndex, ref lodVoxelCoordStart, ref lodVoxelCoordEnd);
                }
            }
        }
 void IMyOctreeLeafNode.WriteRange(MyStorageDataCache source, ref Vector3I readOffset, ref Vector3I min, ref Vector3I max)
 {
     m_octree.WriteRange(source, m_dataType, ref readOffset, ref min, ref max);
     if (DEBUG_WRITES)
     {
         var tmp = new MyStorageDataCache();
         tmp.Resize(min, max);
         m_octree.ReadRange(tmp, m_dataType, ref Vector3I.Zero, 0, ref min, ref max);
         Vector3I p            = Vector3I.Zero;
         var      cacheEnd     = max - min;
         int      errorCounter = 0;
         for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref cacheEnd);
              it.IsValid(); it.GetNext(out p))
         {
             var read = readOffset + p;
             if (source.Get(m_dataType, ref read) != tmp.Get(m_dataType, ref p))
             {
                 ++errorCounter;
             }
         }
         Debug.Assert(errorCounter == 0, string.Format("{0} errors writing to leaf octree.", errorCounter));
     }
 }
        internal void ReadContentRange(MyStorageDataCache target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
        {
            float lodVoxelSizeHalf;
            BoundingBox queryBox;
            BoundingSphere querySphere;
            SetupReading(lodIndex, ref minInLod, ref maxInLod, out lodVoxelSizeHalf, out queryBox, out querySphere);
            float lodVoxelSize = 2f * lodVoxelSizeHalf;

            ProfilerShort.Begin("Testing removed shapes");
            var overlappedRemovedShapes = OverlappedRemovedShapes;
            overlappedRemovedShapes.Clear();
            ContainmentType testRemove = ContainmentType.Disjoint;
            for (int i = 0; i < m_data.RemovedShapes.Length; ++i)
            {
                var test = m_data.RemovedShapes[i].Contains(ref queryBox, ref querySphere, lodVoxelSize);
                if (test == ContainmentType.Contains)
                {
                    testRemove = ContainmentType.Contains;
                    break; // completely empty so we can leave
                }
                else if (test == ContainmentType.Intersects)
                {
                    testRemove = ContainmentType.Intersects;
                    overlappedRemovedShapes.Add(m_data.RemovedShapes[i]);
                }
            }
            ProfilerShort.End();
            if (testRemove == ContainmentType.Contains)
            {
                ProfilerShort.Begin("target.BlockFillContent");
                target.BlockFillContent(writeOffset, writeOffset + (maxInLod - minInLod), MyVoxelConstants.VOXEL_CONTENT_EMPTY);
                ProfilerShort.End();
                return;
            }

            ProfilerShort.Begin("Testing filled shapes");
            var overlappedFilledShapes = OverlappedFilledShapes;
            overlappedFilledShapes.Clear();
            ContainmentType testFill = ContainmentType.Disjoint;
            for (int i = 0; i < m_data.FilledShapes.Length; ++i)
            {
                var test = m_data.FilledShapes[i].Contains(ref queryBox, ref querySphere, lodVoxelSize);
                if (test == ContainmentType.Contains)
                {
                    overlappedFilledShapes.Clear();
                    testFill = ContainmentType.Contains;
                    break;
                }
                else if (test == ContainmentType.Intersects)
                {
                    overlappedFilledShapes.Add(m_data.FilledShapes[i]);
                    testFill = ContainmentType.Intersects;
                }
            }
            ProfilerShort.End();

            if (testFill == ContainmentType.Disjoint)
            {
                ProfilerShort.Begin("target.BlockFillContent");
                target.BlockFillContent(writeOffset, writeOffset + (maxInLod - minInLod), MyVoxelConstants.VOXEL_CONTENT_EMPTY);
                ProfilerShort.End();
                return;
            }
            else if (testRemove == ContainmentType.Disjoint && testFill == ContainmentType.Contains)
            {
                ProfilerShort.Begin("target.BlockFillContent");
                target.BlockFillContent(writeOffset, writeOffset + (maxInLod - minInLod), MyVoxelConstants.VOXEL_CONTENT_FULL);
                ProfilerShort.End();
                return;
            }

            ProfilerShort.Begin("Distance field computation");
            Vector3I v;
            for (v.Z = minInLod.Z; v.Z <= maxInLod.Z; ++v.Z)
            {
                for (v.Y = minInLod.Y; v.Y <= maxInLod.Y; ++v.Y)
                {
                    for (v.X = minInLod.X; v.X <= maxInLod.X; ++v.X)
                    {
                        Vector3 localPos = v * lodVoxelSize;

                        float distFill;
                        if (testFill == ContainmentType.Contains)
                        {
                            distFill = -1f;
                        }
                        else
                        {
                            distFill = 1f;
                            foreach (var shape in overlappedFilledShapes)
                            {
                                distFill = Math.Min(distFill, shape.SignedDistance(ref localPos, lodVoxelSize, m_data.MacroModule, m_data.DetailModule));
                                if (distFill <= -1)
                                    break;
                            }
                        }

                        float distRemoved = 1f;
                        if (testRemove != ContainmentType.Disjoint)
                        {
                            foreach (var shape in overlappedRemovedShapes)
                            {
                                distRemoved = Math.Min(distRemoved, shape.SignedDistance(ref localPos, lodVoxelSize, m_data.MacroModule, m_data.DetailModule));
                                if (distRemoved <= -1)
                                    break;
                            }
                        }

                        float signedDist = MathHelper.Max(distFill, -distRemoved);

                        var fillRatio = MathHelper.Clamp(-signedDist, -1f, 1f) * 0.5f + 0.5f;
                        var write = v - minInLod + writeOffset;
                        target.Content(ref write, (byte)(fillRatio * MyVoxelConstants.VOXEL_CONTENT_FULL));
                    }
                }
            }
            ProfilerShort.End();
        }
        private bool FindMaterial(IMyStorage storage, byte[] findMaterial)
        {
            if (findMaterial.Length == 0)
                return false;

            var oldCache = new MyStorageDataCache();
            oldCache.Resize(storage.Size);
            storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 2, Vector3I.Zero, storage.Size - 1);
            //MyAPIGateway.Utilities.ShowMessage("check", string.Format("SizeLinear {0}  {1}.", oldCache.SizeLinear, oldCache.StepLinear));

            Vector3I p;
            for (p.Z = 0; p.Z < storage.Size.Z; ++p.Z)
                for (p.Y = 0; p.Y < storage.Size.Y; ++p.Y)
                    for (p.X = 0; p.X < storage.Size.X; ++p.X)
                    {
                        var content = oldCache.Content(ref p);
                        var material = oldCache.Material(ref p);

                        if (content > 0 && findMaterial.Contains(material))
                        {
                            return true;
                        }
                    }
            return false;
        }
Example #26
0
        protected void RefreshCache( )
        {
            IMyVoxelMap voxelMap = (IMyVoxelMap)BackingObject;
            m_cache = new MyStorageDataCache( );
            Vector3I size = voxelMap.Storage.Size;
            m_cache.Resize( size );

            //			SandboxGameAssemblyWrapper.Instance.GameAction(() =>
            //			{
            voxelMap.Storage.ReadRange( m_cache, MyStorageDataTypeFlags.Material, 0, Vector3I.Zero, size - 1 );
            //voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.Material, Vector3I.Zero, size - 1);
            //			});

            foreach ( byte materialIndex in m_cache.Data )
            {
                try
                {
                    MyVoxelMaterialDefinition material = MyDefinitionManager.Static.GetVoxelMaterialDefinition( materialIndex );
                    if ( material == null )
                        continue;

                    if ( !m_materialTotals.ContainsKey( material ) )
                        m_materialTotals.Add( material, 1 );
                    else
                        m_materialTotals[ material ]++;
                }
                catch ( Exception ex )
                {
                    ApplicationLog.BaseLog.Error( ex );
                }
            }
        }
 void ModAPI.Interfaces.IMyStorage.WriteRange(MyStorageDataCache source, MyStorageDataTypeFlags dataToWrite, Vector3I voxelRangeMin,  Vector3I voxelRangeMax)
 {
     WriteRange(source, dataToWrite, ref voxelRangeMin, ref voxelRangeMax);
 }
Example #28
0
 void IMyOctreeLeafNode.WriteRange(MyStorageDataCache source, ref Vector3I readOffset, ref Vector3I min, ref Vector3I max)
 {
     throw new NotSupportedException();
 }
Example #29
0
        private unsafe void WriteRange(
            MyCellCoord cell,
            TLeafData defaultData,
            MyStorageDataCache source,
            MyStorageDataTypeEnum type,
            ref Vector3I readOffset,
            ref Vector3I min,
            ref Vector3I max)
        {
            var          nodeKey = cell.PackId32();
            MyOctreeNode node;

            if (!m_nodes.TryGetValue(nodeKey, out node))
            {
                for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i)
                {
                    node.Data[i] = defaultData;
                }
            }

            if (cell.Lod == 0)
            {
                var      childBase = cell.CoordInLod << 1;
                Vector3I childOffset;
                for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i)
                {
                    ComputeChildCoord(i, out childOffset);
                    var child = childBase + childOffset;
                    if (!child.IsInsideInclusive(ref min, ref max))
                    {
                        continue;
                    }

                    child       -= min;
                    child       += readOffset;
                    node.Data[i] = source.Get(type, ref child);
                }
                m_nodes[nodeKey] = node;
            }
            else
            {
                var      childBase = cell.CoordInLod << 1;
                Vector3I childOffset;
                var      minInChild = (min >> cell.Lod) - childBase;
                var      maxInChild = (max >> cell.Lod) - childBase;
                for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i)
                {
                    ComputeChildCoord(i, out childOffset);
                    if (!childOffset.IsInsideInclusive(ref minInChild, ref maxInChild))
                    {
                        continue;
                    }

                    var childCell = new MyCellCoord(cell.Lod - 1, childBase + childOffset);
                    WriteRange(childCell, node.Data[i], source, type, ref readOffset, ref min, ref max);
                    var childKey  = childCell.PackId32();
                    var childNode = m_nodes[childKey];
                    if (!childNode.HasChildren && MyOctreeNode.AllDataSame(childNode.Data))
                    {
                        node.SetChild(i, false);
                        node.Data[i] = childNode.Data[0];
                        m_nodes.Remove(childKey);
                    }
                    else
                    {
                        node.SetChild(i, true);
                        node.Data[i] = m_nodeFilter(childNode.Data);
                    }
                }

                m_nodes[nodeKey] = node;
            }
        }
Example #30
0
        private static unsafe void ReadRange(
            MyStorageDataCache target,
            ref Vector3I targetWriteOffset,
            MyStorageDataTypeEnum type,
            int treeHeight,
            Dictionary <UInt64, MyOctreeNode> nodes,
            Dictionary <UInt64, IMyOctreeLeafNode> leaves,
            int lodIndex,
            ref Vector3I minInLod,
            ref Vector3I maxInLod)
        {
            int          stackIdx  = 0;
            int          stackSize = MySparseOctree.EstimateStackSize(treeHeight);
            MyCellCoord *stack     = stackalloc MyCellCoord[stackSize];
            MyCellCoord  data      = new MyCellCoord(treeHeight + LeafLodCount, ref Vector3I.Zero);

            stack[stackIdx++] = data;
            MyCellCoord cell = new MyCellCoord();

            while (stackIdx > 0)
            {
                Debug.Assert(stackIdx <= stackSize);
                data = stack[--stackIdx];

                cell.Lod        = data.Lod - LeafLodCount;
                cell.CoordInLod = data.CoordInLod;

                int lodDiff;
                IMyOctreeLeafNode leaf;
                if (leaves.TryGetValue(cell.PackId64(), out leaf))
                {
                    lodDiff = data.Lod - lodIndex;
                    var rangeMinInDataLod = minInLod >> lodDiff;
                    var rangeMaxInDataLod = maxInLod >> lodDiff;
                    if (data.CoordInLod.IsInsideInclusive(ref rangeMinInDataLod, ref rangeMaxInDataLod))
                    {
                        var nodePosInLod = data.CoordInLod << lodDiff;
                        var writeOffset  = nodePosInLod - minInLod;
                        Vector3I.Max(ref writeOffset, ref Vector3I.Zero, out writeOffset);
                        writeOffset += targetWriteOffset;
                        var lodSizeMinusOne = new Vector3I((1 << lodDiff) - 1);
                        var minInLeaf       = Vector3I.Clamp(minInLod - nodePosInLod, Vector3I.Zero, lodSizeMinusOne);
                        var maxInLeaf       = Vector3I.Clamp(maxInLod - nodePosInLod, Vector3I.Zero, lodSizeMinusOne);
                        leaf.ReadRange(target, ref writeOffset, lodIndex, ref minInLeaf, ref maxInLeaf);
                    }
                    continue;
                }

                cell.Lod -= 1;
                lodDiff   = data.Lod - 1 - lodIndex;
                var node = nodes[cell.PackId64()];

                var min = minInLod >> lodDiff;
                var max = maxInLod >> lodDiff;
                var nodePositionInChild = data.CoordInLod << 1;
                min -= nodePositionInChild;
                max -= nodePositionInChild;
                for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i)
                {
                    Vector3I childPosRelative;
                    ComputeChildCoord(i, out childPosRelative);
                    if (!childPosRelative.IsInsideInclusive(ref min, ref max))
                    {
                        continue;
                    }
                    if (lodIndex < data.Lod && node.HasChild(i))
                    {
                        Debug.Assert(stackIdx < stackSize);
                        stack[stackIdx++] = new MyCellCoord(data.Lod - 1, nodePositionInChild + childPosRelative);
                    }
                    else
                    {
                        var childMin = nodePositionInChild + childPosRelative;
                        childMin <<= lodDiff;
                        var writeOffset = childMin - minInLod;
                        Vector3I.Max(ref writeOffset, ref Vector3I.Zero, out writeOffset);
                        writeOffset += targetWriteOffset;
                        var nodeData = node.GetData(i);
                        if (lodDiff == 0)
                        {
                            target.Set(type, ref writeOffset, nodeData);
                        }
                        else
                        {
                            var childMax = childMin + ((1 << lodDiff) - 1);
                            Vector3I.Max(ref childMin, ref minInLod, out childMin);
                            Vector3I.Min(ref childMax, ref maxInLod, out childMax);
                            for (int z = childMin.Z; z <= childMax.Z; ++z)
                            {
                                for (int y = childMin.Y; y <= childMax.Y; ++y)
                                {
                                    for (int x = childMin.X; x <= childMax.X; ++x)
                                    {
                                        Vector3I write = writeOffset;
                                        write.X += x - childMin.X;
                                        write.Y += y - childMin.Y;
                                        write.Z += z - childMin.Z;
                                        target.Set(type, ref write, nodeData);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #31
0
 protected abstract void ReadRangeInternal(MyStorageDataCache target, ref Vector3I targetWriteRange, MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax);
        private static MyStorageBase Compatibility_LoadCellStorage(int fileVersion, Stream stream)
        {
            //  Size of this voxel map (in voxels)
            Vector3I tmpSize;
            tmpSize.X = stream.ReadInt32();
            tmpSize.Y = stream.ReadInt32();
            tmpSize.Z = stream.ReadInt32();
            var storage = new MyOctreeStorage(null, tmpSize);

            //  Size of data cell in voxels. Has to be the same as current size specified by our constants.
            Vector3I cellSize;
            cellSize.X = stream.ReadInt32();
            cellSize.Y = stream.ReadInt32();
            cellSize.Z = stream.ReadInt32();
            Trace.Assert(cellSize.X == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS &&
                         cellSize.Y == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS &&
                         cellSize.Z == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS);

            Vector3I cellsCount = tmpSize / cellSize;

            Dictionary<byte, MyVoxelMaterialDefinition> mappingTable = null;
            if (fileVersion == STORAGE_TYPE_VERSION_CELL)
            {
                // loading material names->index mappings
                mappingTable = Compatibility_LoadMaterialIndexMapping(stream);
            }
            else if (fileVersion == 1)
            {
                // material name->index mappings were not saved in this version
            }

            var startCoord = Vector3I.Zero;
            var endCoord = new Vector3I(MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1);

            var cache = new MyStorageDataCache();
            cache.Resize(Vector3I.Zero, endCoord);
            Vector3I cellCoord;
            for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++)
            {
                for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++)
                {
                    for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++)
                    {
                        MyVoxelRangeType cellType = (MyVoxelRangeType)stream.ReadByteNoAlloc();

                        //  Cell's are FULL by default, therefore we don't need to change them
                        switch (cellType)
                        {
                            case MyVoxelRangeType.EMPTY: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_EMPTY); break;
                            case MyVoxelRangeType.FULL: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_FULL); break;
                            case MyVoxelRangeType.MIXED:
                                Vector3I v;
                                for (v.X = 0; v.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.X++)
                                {
                                    for (v.Y = 0; v.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Y++)
                                    {
                                        for (v.Z = 0; v.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Z++)
                                        {
                                            cache.Content(ref v, stream.ReadByteNoAlloc());
                                        }
                                    }
                                }
                                break;
                        }
                        startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS;
                        endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1);
                        storage.WriteRange(cache, MyStorageDataTypeFlags.Content, ref startCoord, ref endCoord);
                    }
                }
            }

            try
            { // In case materials are not saved, catch any exceptions caused by this.
                // Read materials and indestructible
                for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++)
                {
                    for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++)
                    {
                        for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++)
                        {
                            bool isSingleMaterial = stream.ReadByteNoAlloc() == 1;
                            MyVoxelMaterialDefinition material = null;

                            if (isSingleMaterial)
                            {
                                material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable);
                                cache.ClearMaterials(material.Index);
                            }
                            else
                            {
                                byte indestructibleContent;
                                Vector3I voxelCoordInCell;
                                for (voxelCoordInCell.X = 0; voxelCoordInCell.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.X++)
                                {
                                    for (voxelCoordInCell.Y = 0; voxelCoordInCell.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Y++)
                                    {
                                        for (voxelCoordInCell.Z = 0; voxelCoordInCell.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Z++)
                                        {
                                            material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable);
                                            indestructibleContent = stream.ReadByteNoAlloc();
                                            cache.Material(ref voxelCoordInCell, material.Index);
                                        }
                                    }
                                }
                            }
                            startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS;
                            endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1);
                            storage.WriteRange(cache, MyStorageDataTypeFlags.Material, ref startCoord, ref endCoord);
                        }
                    }
                }
            }
            catch (EndOfStreamException ex)
            {
                MySandboxGame.Log.WriteLine(ex);
            }

            return storage;
        }
 void IMyOctreeLeafNode.WriteRange(MyStorageDataCache source, ref Vector3I readOffset, ref Vector3I min, ref Vector3I max)
 {
     m_octree.WriteRange(source, m_dataType, ref readOffset, ref min, ref max);
     if (DEBUG_WRITES)
     {
         var tmp = new MyStorageDataCache();
         tmp.Resize(min, max);
         m_octree.ReadRange(tmp, m_dataType, ref Vector3I.Zero, 0, ref min, ref max);
         Vector3I p = Vector3I.Zero;
         var cacheEnd = max - min;
         int errorCounter = 0;
         for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref cacheEnd);
             it.IsValid(); it.GetNext(out p))
         {
             var read = readOffset + p;
             if (source.Get(m_dataType, ref read) != tmp.Get(m_dataType, ref p))
                 ++errorCounter;
         }
         Debug.Assert(errorCounter == 0, string.Format("{0} errors writing to leaf octree.", errorCounter));
     }
 }
 void IMyOctreeLeafNode.ReadRange(MyStorageDataCache target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
 {
     m_octree.ReadRange(target, m_dataType, ref writeOffset, lodIndex, ref minInLod, ref maxInLod);
 }
 internal void BuildFrom(MyStorageDataCache source)
 {
     Debug.Assert(source.Size3D == new Vector3I(m_octree.TreeWidth));
     var enumer = new MyStorageDataCache.MortonEnumerator(source, m_dataType);
     m_octree.Build(enumer);
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="voxelMap"></param>
        /// <param name="resolution">0 to 8. 0 for fine/slow detail.</param>
        /// <param name="distance"></param>
        /// <returns></returns>
        private int FindMaterial(IMyVoxelBase voxelMap, Vector3D center, int resolution, double distance)
        {
            int hits = 0;
            var materials = MyDefinitionManager.Static.GetVoxelMaterialDefinitions().Where(v => v.IsRare).ToArray();
            var findMaterial = materials.Select(f => f.Index).ToArray();
            var storage = voxelMap.Storage;
            var scale = (int)Math.Pow(2, resolution);

            //MyAPIGateway.Utilities.ShowMessage("center", center.ToString());
            var point = new Vector3I(center - voxelMap.PositionLeftBottomCorner);
            //MyAPIGateway.Utilities.ShowMessage("point", point.ToString());

            var min = ((point - (int)distance) / 64) * 64;
            min = Vector3I.Max(min, Vector3I.Zero);
            //MyAPIGateway.Utilities.ShowMessage("min", min.ToString());

            var max = ((point + (int)distance) / 64) * 64;
            max = Vector3I.Max(max, min + 64);
            //MyAPIGateway.Utilities.ShowMessage("max", max.ToString());

            //MyAPIGateway.Utilities.ShowMessage("size", voxelMap.StorageName + " " + storage.Size.ToString());

            if (min.X >= storage.Size.X ||
                min.Y >= storage.Size.Y ||
                min.Z >= storage.Size.Z)
            {
                //MyAPIGateway.Utilities.ShowMessage("size", "out of range");
                return 0;
            }

            var oldCache = new MyStorageDataCache();

            //var smin = new Vector3I(0, 0, 0);
            //var smax = new Vector3I(31, 31, 31);
            ////var size = storage.Size;
            //var size = smax - smin + 1;
            //size = new Vector3I(16, 16, 16);
            //oldCache.Resize(size);
            //storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, resolution, Vector3I.Zero, size - 1);

            var smax = (max / scale) - 1;
            var smin = (min / scale);
            var size = smax - smin + 1;
            oldCache.Resize(size);
            storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, resolution, smin, smax);

            //MyAPIGateway.Utilities.ShowMessage("smax", smax.ToString());
            //MyAPIGateway.Utilities.ShowMessage("size", size .ToString());
            //MyAPIGateway.Utilities.ShowMessage("size - 1", (size - 1).ToString());

            Vector3I p;
            for (p.Z = 0; p.Z < size.Z; ++p.Z)
                for (p.Y = 0; p.Y < size.Y; ++p.Y)
                    for (p.X = 0; p.X < size.X; ++p.X)
                    {
                        // place GPS in the center of the Voxel
                        var position = voxelMap.PositionLeftBottomCorner + (p * scale) + (scale / 2) + min;

                        if (Math.Sqrt((position - center).LengthSquared()) < distance)
                        {
                            var content = oldCache.Content(ref p);
                            var material = oldCache.Material(ref p);

                            if (content > 0 && findMaterial.Contains(material))
                            {
                                var index = Array.IndexOf(findMaterial, material);
                                var name = materials[index].MinedOre;
                                var gps = MyAPIGateway.Session.GPS.Create("Ore " + name, "scanore", position, true, false);
                                MyAPIGateway.Session.GPS.AddLocalGps(gps);
                                hits++;
                            }
                        }
                    }
            return hits;
        }
Example #37
0
        private void UpdateLoad()
        {
            ConstructAreas();

            if (m_checkQueue.Count == 0)
            {
                bool finishedLoading = true;
                m_ground = MySession.Static.VoxelMaps.TryGetVoxelMapByName("Ground");
                if (m_ground != null)
                {
                    m_worldArea = m_ground.SizeInMetres.X * m_ground.SizeInMetres.Z;
                    m_voxelCache = new MyStorageDataCache();
                    m_voxelCache.Resize(Vector3I.One * 3);

                    InvalidateAreaValues();

                    if (m_highLevelBoxes.Count == 0)
                    {
                        // MW: we need to find some candidates for forest starting points
                        finishedLoading = false;
                        m_findValidForestPhase = true;
                    }
                }

                if (finishedLoading)
                {
                    m_loadPhase = false;
                    if (LoadFinished != null)
                        LoadFinished();
                }
            }
        }
 void IMyStorageDataProvider.ReadRange(MyStorageDataCache target, MyStorageDataTypeEnum dataType, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
 {
     if (dataType == MyStorageDataTypeEnum.Content)
         ReadContentRange(target, ref writeOffset, lodIndex, ref minInLod, ref maxInLod);
     else
         ReadMaterialRange(target, ref writeOffset, lodIndex, ref minInLod, ref maxInLod);
 }
 void IMyStorage.ReadRange(MyStorageDataCache target, bool readContent, bool readMaterials, int lodIndex, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax)
 {
     m_trueStorage.ReadRange(target, readContent, readMaterials, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax);
 }
 void IMyOctreeLeafNode.ReadRange(MyStorageDataCache target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
 {
     m_octree.ReadRange(target, m_dataType, ref writeOffset, lodIndex, ref minInLod, ref maxInLod);
 }
 public virtual void ReadMaterialRange(MyStorageDataCache target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod, float lodVoxelSizeHalf)
 {
     target.BlockFillMaterial(writeOffset, writeOffset + (maxInLod - minInLod), m_material.Index);
 }
        internal void ReadContentRange(MyStorageDataCache target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
        {
            float          lodVoxelSizeHalf;
            BoundingBox    queryBox;
            BoundingSphere querySphere;

            SetupReading(lodIndex, ref minInLod, ref maxInLod, out lodVoxelSizeHalf, out queryBox, out querySphere);
            float lodVoxelSize = 2f * lodVoxelSizeHalf;

            ProfilerShort.Begin("Testing removed shapes");
            var overlappedRemovedShapes = OverlappedRemovedShapes;

            overlappedRemovedShapes.Clear();
            ContainmentType testRemove = ContainmentType.Disjoint;

            for (int i = 0; i < m_data.RemovedShapes.Length; ++i)
            {
                var test = m_data.RemovedShapes[i].Contains(ref queryBox, ref querySphere, lodVoxelSize);
                if (test == ContainmentType.Contains)
                {
                    testRemove = ContainmentType.Contains;
                    break; // completely empty so we can leave
                }
                else if (test == ContainmentType.Intersects)
                {
                    testRemove = ContainmentType.Intersects;
                    overlappedRemovedShapes.Add(m_data.RemovedShapes[i]);
                }
            }
            ProfilerShort.End();
            if (testRemove == ContainmentType.Contains)
            {
                ProfilerShort.Begin("target.BlockFillContent");
                target.BlockFillContent(writeOffset, writeOffset + (maxInLod - minInLod), MyVoxelConstants.VOXEL_CONTENT_EMPTY);
                ProfilerShort.End();
                return;
            }

            ProfilerShort.Begin("Testing filled shapes");
            var overlappedFilledShapes = OverlappedFilledShapes;

            overlappedFilledShapes.Clear();
            ContainmentType testFill = ContainmentType.Disjoint;

            for (int i = 0; i < m_data.FilledShapes.Length; ++i)
            {
                var test = m_data.FilledShapes[i].Contains(ref queryBox, ref querySphere, lodVoxelSize);
                if (test == ContainmentType.Contains)
                {
                    overlappedFilledShapes.Clear();
                    testFill = ContainmentType.Contains;
                    break;
                }
                else if (test == ContainmentType.Intersects)
                {
                    overlappedFilledShapes.Add(m_data.FilledShapes[i]);
                    testFill = ContainmentType.Intersects;
                }
            }
            ProfilerShort.End();

            if (testFill == ContainmentType.Disjoint)
            {
                ProfilerShort.Begin("target.BlockFillContent");
                target.BlockFillContent(writeOffset, writeOffset + (maxInLod - minInLod), MyVoxelConstants.VOXEL_CONTENT_EMPTY);
                ProfilerShort.End();
                return;
            }
            else if (testRemove == ContainmentType.Disjoint && testFill == ContainmentType.Contains)
            {
                ProfilerShort.Begin("target.BlockFillContent");
                target.BlockFillContent(writeOffset, writeOffset + (maxInLod - minInLod), MyVoxelConstants.VOXEL_CONTENT_FULL);
                ProfilerShort.End();
                return;
            }

            ProfilerShort.Begin("Distance field computation");
            Vector3I v;

            for (v.Z = minInLod.Z; v.Z <= maxInLod.Z; ++v.Z)
            {
                for (v.Y = minInLod.Y; v.Y <= maxInLod.Y; ++v.Y)
                {
                    for (v.X = minInLod.X; v.X <= maxInLod.X; ++v.X)
                    {
                        Vector3 localPos = v * lodVoxelSize;

                        float distFill;
                        if (testFill == ContainmentType.Contains)
                        {
                            distFill = -1f;
                        }
                        else
                        {
                            distFill = 1f;
                            foreach (var shape in overlappedFilledShapes)
                            {
                                ProfilerShort.Begin("shape distance");
                                distFill = Math.Min(distFill, shape.SignedDistance(ref localPos, lodVoxelSize, m_data.MacroModule, m_data.DetailModule));
                                ProfilerShort.End();
                                if (distFill <= -1)
                                {
                                    break;
                                }
                            }
                        }

                        float distRemoved = 1f;
                        if (testRemove != ContainmentType.Disjoint)
                        {
                            foreach (var shape in overlappedRemovedShapes)
                            {
                                distRemoved = Math.Min(distRemoved, shape.SignedDistance(ref localPos, lodVoxelSize, m_data.MacroModule, m_data.DetailModule));
                                if (distRemoved <= -1)
                                {
                                    break;
                                }
                            }
                        }
                        ProfilerShort.Begin("content");
                        float signedDist = MathHelper.Max(distFill, -distRemoved);

                        var fillRatio = MathHelper.Clamp(-signedDist, -1f, 1f) * 0.5f + 0.5f;
                        var write     = v - minInLod + writeOffset;
                        target.Content(ref write, (byte)(fillRatio * MyVoxelConstants.VOXEL_CONTENT_FULL));
                        ProfilerShort.End();
                    }
                }
            }
            ProfilerShort.End();
        }
Example #43
0
 internal void WriteRange(MyStorageDataCache source, MyStorageDataTypeEnum type, ref Vector3I readOffset, ref Vector3I min, ref Vector3I max)
 {
     ProfilerShort.Begin("MySparseOctree2.WriteRange");
     WriteRange(new MyCellCoord(m_treeHeight - 1, Vector3I.Zero), m_defaultContent, source, type, ref readOffset, ref min, ref max);
     ProfilerShort.End();
 }
        internal void ReadMaterialRange(MyStorageDataCache target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
        {
            float          lodVoxelSizeHalf;
            BoundingBox    queryBox;
            BoundingSphere querySphere;

            SetupReading(lodIndex, ref minInLod, ref maxInLod, out lodVoxelSizeHalf, out queryBox, out querySphere);
            float lodVoxelSize = 2f * lodVoxelSizeHalf;

            var overlappedDeposits = OverlappedDeposits;

            {
                ProfilerShort.Begin("Testing deposit shapes");
                overlappedDeposits.Clear();
                ContainmentType testDeposits = ContainmentType.Disjoint;
                for (int i = 0; i < m_data.Deposits.Length; ++i)
                {
                    var test = m_data.Deposits[i].Shape.Contains(ref queryBox, ref querySphere, lodVoxelSize);
                    if (test != ContainmentType.Disjoint)
                    {
                        overlappedDeposits.Add(m_data.Deposits[i]);
                        testDeposits = ContainmentType.Intersects;
                    }
                }
                ProfilerShort.End();

                if (testDeposits == ContainmentType.Disjoint)
                {
                    ProfilerShort.Begin("target.BlockFillMaterial");
                    target.BlockFillMaterial(writeOffset, writeOffset + (maxInLod - minInLod), m_data.DefaultMaterial.Index);
                    ProfilerShort.End();
                    return;
                }
            }

            ProfilerShort.Begin("Material computation");
            Vector3I v;

            for (v.Z = minInLod.Z; v.Z <= maxInLod.Z; ++v.Z)
            {
                for (v.Y = minInLod.Y; v.Y <= maxInLod.Y; ++v.Y)
                {
                    for (v.X = minInLod.X; v.X <= maxInLod.X; ++v.X)
                    {
                        Vector3 localPos = v * lodVoxelSize;

                        float closestDistance    = 1f;
                        byte  closestMaterialIdx = m_data.DefaultMaterial.Index;
                        foreach (var deposit in overlappedDeposits)
                        {
                            float distance = deposit.Shape.SignedDistance(ref localPos, MyVoxelConstants.VOXEL_SIZE_IN_METRES, m_data.MacroModule, m_data.DetailModule);
                            if (distance < 0f && distance <= closestDistance)
                            {
                                closestDistance = distance;
                                // DA: Pass default material to the layered deposit so only that does these if-s.
                                var materialDef = deposit.GetMaterialForPosition(ref localPos, lodVoxelSize);
                                closestMaterialIdx = materialDef == null ? m_data.DefaultMaterial.Index : materialDef.Index;
                            }
                        }

                        var write = v - minInLod + writeOffset;
                        target.Material(ref write, closestMaterialIdx);
                    }
                }
            }
            ProfilerShort.End();
        }
Example #45
0
        internal unsafe void ReadRange(MyStorageDataCache target, MyStorageDataTypeEnum type, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
        {
            ProfilerShort.Begin("MySparseOctree2.ReadRangeToContent"); try {
                int          stackIdx  = 0;
                int          stackSize = MySparseOctree.EstimateStackSize(m_treeHeight);
                MyCellCoord *stack     = stackalloc MyCellCoord[stackSize];
                MyCellCoord  data      = new MyCellCoord(m_treeHeight - 1, ref Vector3I.Zero);
                stack[stackIdx++] = data;

                MyOctreeNode node;
                Vector3I     childPosRelative, min, max, nodePositionInChild;
                int          lodDiff;
                while (stackIdx > 0)
                {
                    Debug.Assert(stackIdx <= stackSize);
                    data = stack[--stackIdx];
                    node = m_nodes[data.PackId32()];

                    lodDiff             = data.Lod - lodIndex;
                    min                 = minInLod >> lodDiff;
                    max                 = maxInLod >> lodDiff;
                    nodePositionInChild = data.CoordInLod << 1;
                    min                -= nodePositionInChild;
                    max                -= nodePositionInChild;
                    for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i)
                    {
                        ComputeChildCoord(i, out childPosRelative);
                        if (!childPosRelative.IsInsideInclusive(ref min, ref max))
                        {
                            continue;
                        }
                        if (lodIndex < data.Lod && node.HasChild(i))
                        {
                            Debug.Assert(stackIdx < stackSize);
                            stack[stackIdx++] = new MyCellCoord(data.Lod - 1, nodePositionInChild + childPosRelative);
                        }
                        else
                        {
                            var nodeData = node.Data[i];
                            var childMin = nodePositionInChild + childPosRelative;
                            if (lodDiff == 0)
                            {
                                var write = writeOffset + childMin - minInLod;
                                target.Set(type, ref write, nodeData);
                            }
                            else
                            {
                                childMin <<= lodDiff;
                                var childMax = childMin + (1 << lodDiff) - 1;
                                Vector3I.Max(ref childMin, ref minInLod, out childMin);
                                Vector3I.Min(ref childMax, ref maxInLod, out childMax);
                                for (int z = childMin.Z; z <= childMax.Z; ++z)
                                {
                                    for (int y = childMin.Y; y <= childMax.Y; ++y)
                                    {
                                        for (int x = childMin.X; x <= childMax.X; ++x)
                                        {
                                            var write = writeOffset;
                                            write.X += x - minInLod.X;
                                            write.Y += y - minInLod.Y;
                                            write.Z += z - minInLod.Z;
                                            target.Set(type, ref write, nodeData);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            } finally { ProfilerShort.End(); }
        }
Example #46
0
 protected abstract void WriteRangeInternal(MyStorageDataCache source, MyStorageDataTypeFlags dataToWrite, ref Vector3I voxelRangeMin, ref Vector3I voxelRangeMax);
        public override bool Invoke(string messageText)
        {
            // voxelset [0/off] [1/on] [A] [B] [C/Clear]
            if (messageText.StartsWith("/voxelset ", StringComparison.InvariantCultureIgnoreCase))
            {
                var strings = messageText.Split(' ');
                if (strings.Length > 1)
                {
                    if (strings[1].Equals("off", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("0", StringComparison.InvariantCultureIgnoreCase))
                    {
                        ActiveVoxelSetterPosition = null;
                        _activeVoxelSetterPositionA = null;
                        _activeVoxelSetterPositionB = null;
                        _activeVoxelSetterNameA = null;
                        _activeVoxelSetterNameB = null;
                        ActiveVoxelSetter = false;
                        MyAPIGateway.Utilities.ShowNotification("Voxel setter off", 1000, MyFontEnum.Green);
                        return true;
                    }
                    if (strings[1].Equals("on", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("1", StringComparison.InvariantCultureIgnoreCase))
                    {
                        ActiveVoxelSetterPosition = null;
                        _activeVoxelSetterPositionA = null;
                        _activeVoxelSetterPositionB = null;
                        _activeVoxelSetterNameA = null;
                        _activeVoxelSetterNameB = null;
                        ActiveVoxelSetter = true;
                        MyAPIGateway.Utilities.ShowNotification("Voxel setter activated", 1000, MyFontEnum.Green);
                        return true;
                    }
                    if (!ActiveVoxelSetter)
                    {
                        MyAPIGateway.Utilities.ShowNotification("Voxel setter hasn't been actived.", 2000, MyFontEnum.Red);
                        return true;
                    }
                    if (strings[1].Equals("A", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var tmp = ActiveVoxelSetterPosition;
                        if (tmp.HasValue)
                        {
                            var currentAsteroidList = new List<IMyVoxelBase>();
                            var bb = new BoundingBoxD(tmp.Value - 0.2f, tmp.Value + 0.2f);
                            MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb));

                            if (currentAsteroidList.Count > 0)
                            {
                                _activeVoxelSetterNameA = currentAsteroidList[0].StorageName;
                                _activeVoxelSetterPositionA = tmp;
                            }
                        }

                        if (_activeVoxelSetterPositionA.HasValue)
                            MyAPIGateway.Utilities.ShowMessage(_activeVoxelSetterNameA, "Voxel setter point A: active");
                        //MyAPIGateway.Utilities.ShowNotification("Voxel setter A: active.", 1000, MyFontEnum.Green);
                        else
                            MyAPIGateway.Utilities.ShowNotification("Voxel setter A: invalid.", 1000, MyFontEnum.Red);
                        return true;
                    }
                    if (strings[1].Equals("B", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var tmp = ActiveVoxelSetterPosition;
                        if (tmp.HasValue)
                        {
                            var currentAsteroidList = new List<IMyVoxelBase>();
                            var bb = new BoundingBoxD(tmp.Value - 0.2f, tmp.Value + 0.2f);
                            MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb));

                            if (currentAsteroidList.Count > 0)
                            {
                                _activeVoxelSetterNameB = currentAsteroidList[0].StorageName;
                                _activeVoxelSetterPositionB = tmp;
                            }
                        }

                        if (_activeVoxelSetterPositionB.HasValue)
                            MyAPIGateway.Utilities.ShowMessage(_activeVoxelSetterNameB, "Voxel setter point B: active");
                        //MyAPIGateway.Utilities.ShowNotification("Voxel setter B: active.", 1000, MyFontEnum.Green);
                        else
                            MyAPIGateway.Utilities.ShowNotification("Voxel setter B: invalid.", 1000, MyFontEnum.Red);
                        return true;
                    }
                    if (strings[1].Equals("C", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("Clear", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (_activeVoxelSetterPositionA.HasValue && _activeVoxelSetterPositionB.HasValue && _activeVoxelSetterNameA == _activeVoxelSetterNameB)
                        {
                            var currentAsteroidList = new List<IMyVoxelBase>();
                            MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.Equals(_activeVoxelSetterNameA, StringComparison.InvariantCultureIgnoreCase));
                            if (currentAsteroidList.Count > 0)
                            {
                                var storage = currentAsteroidList[0].Storage;
                                var point1 = new Vector3I(_activeVoxelSetterPositionA.Value - currentAsteroidList[0].PositionLeftBottomCorner);
                                var point2 = new Vector3I(_activeVoxelSetterPositionB.Value - currentAsteroidList[0].PositionLeftBottomCorner);

                                var cache = new MyStorageDataCache();
                                var size = storage.Size;
                                cache.Resize(size);
                                storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, Vector3I.Zero, size - 1);

                                var min = Vector3I.Min(point1, point2);
                                var max = Vector3I.Max(point1, point2);

                                MyAPIGateway.Utilities.ShowMessage("Cutting", min.ToString() + " " + max.ToString());
                                //MyAPIGateway.Utilities.ShowNotification("cutting:" + min.ToString() + " " + max.ToString(), 5000, MyFontEnum.Blue);

                                Vector3I p;
                                for (p.Z = min.Z; p.Z <= max.Z; ++p.Z)
                                    for (p.Y = min.Y; p.Y <= max.Y; ++p.Y)
                                        for (p.X = min.X; p.X <= max.X; ++p.X)
                                            cache.Content(ref p, 0);
                                storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, Vector3I.Zero, size - 1);
                            }
                        }
                        else if (_activeVoxelSetterNameA != _activeVoxelSetterNameB)
                        {
                            MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: different asteroids.", 2000, MyFontEnum.Red);
                        }
                        else
                        {
                            MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: invalid points.", 2000, MyFontEnum.Red);
                        }
                        return true;
                    }
                    if (strings[1].Equals("F", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("Fill", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (_activeVoxelSetterPositionA.HasValue && _activeVoxelSetterPositionB.HasValue && _activeVoxelSetterNameA == _activeVoxelSetterNameB)
                        {
                            var currentAsteroidList = new List<IMyVoxelBase>();
                            MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.Equals(_activeVoxelSetterNameA, StringComparison.InvariantCultureIgnoreCase));
                            if (currentAsteroidList.Count > 0)
                            {
                                var storage = currentAsteroidList[0].Storage;
                                var point1 = new Vector3I(_activeVoxelSetterPositionA.Value - currentAsteroidList[0].PositionLeftBottomCorner);
                                var point2 = new Vector3I(_activeVoxelSetterPositionB.Value - currentAsteroidList[0].PositionLeftBottomCorner);

                                var cache = new MyStorageDataCache();
                                var size = storage.Size;
                                cache.Resize(size);
                                storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, Vector3I.Zero, size - 1);

                                var min = Vector3I.Min(point1, point2);
                                var max = Vector3I.Max(point1, point2);

                                MyAPIGateway.Utilities.ShowMessage("Filling", min.ToString() + " " + max.ToString());
                                //MyAPIGateway.Utilities.ShowNotification("filling:" + min.ToString() + " " + max.ToString(), 5000, MyFontEnum.Blue);

                                Vector3I p;
                                for (p.Z = min.Z; p.Z <= max.Z; ++p.Z)
                                    for (p.Y = min.Y; p.Y <= max.Y; ++p.Y)
                                        for (p.X = min.X; p.X <= max.X; ++p.X)
                                            cache.Content(ref p, 0xff);
                                storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, Vector3I.Zero, size - 1);
                            }
                        }
                        else if (_activeVoxelSetterNameA != _activeVoxelSetterNameB)
                        {
                            MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: different asteroids.", 2000, MyFontEnum.Red);
                        }
                        else
                        {
                            MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: invalid points.", 2000, MyFontEnum.Red);
                        }
                        return true;
                    }
                }
            }

            return false;
        }
Example #48
0
        protected override void ReadRangeInternal(MyStorageDataCache target, ref Vector3I targetWriteOffset,
            MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelCoordStart, ref Vector3I lodVoxelCoordEnd)
        {
            bool hasLod = lodIndex <= (m_treeHeight + LeafLodCount);
            Debug.Assert(dataToRead != MyStorageDataTypeFlags.None);
            if ((dataToRead & MyStorageDataTypeFlags.Content) != 0)
            {
                if (hasLod)
                {
                    ReadRange(target, ref targetWriteOffset, MyStorageDataTypeEnum.Content, m_treeHeight, m_contentNodes, m_contentLeaves, lodIndex, ref lodVoxelCoordStart, ref lodVoxelCoordEnd);
                }
            }

            if ((dataToRead & MyStorageDataTypeFlags.Material) != 0)
            {
                if (hasLod)
                {
                    ReadRange(target, ref targetWriteOffset, MyStorageDataTypeEnum.Material, m_treeHeight, m_materialNodes, m_materialLeaves, lodIndex, ref lodVoxelCoordStart, ref lodVoxelCoordEnd);
                }
            }
        }
        private Vector3I ComputeTemporaryVoxelData(MyStorageDataCache cache, ref Vector3I coord0, int cubeIndex, int lod)
        {
            int coord0LinIdx = coord0.X * m_sX + coord0.Y * m_sY + coord0.Z * m_sZ;

            MyTemporaryVoxel tempVoxel0 = m_temporaryVoxels[coord0LinIdx];
            MyTemporaryVoxel tempVoxel1 = m_temporaryVoxels[coord0LinIdx + m_sX];
            MyTemporaryVoxel tempVoxel2 = m_temporaryVoxels[coord0LinIdx + m_sX + m_sZ];
            MyTemporaryVoxel tempVoxel3 = m_temporaryVoxels[coord0LinIdx + m_sZ];
            MyTemporaryVoxel tempVoxel4 = m_temporaryVoxels[coord0LinIdx + m_sY];
            MyTemporaryVoxel tempVoxel5 = m_temporaryVoxels[coord0LinIdx + m_sX + m_sY];
            MyTemporaryVoxel tempVoxel6 = m_temporaryVoxels[coord0LinIdx + m_sX + m_sY + m_sZ];
            MyTemporaryVoxel tempVoxel7 = m_temporaryVoxels[coord0LinIdx + m_sY + m_sZ];



            Vector3I coord1 = new Vector3I(coord0.X + 1, coord0.Y + 0, coord0.Z + 0);
            Vector3I coord2 = new Vector3I(coord0.X + 1, coord0.Y + 0, coord0.Z + 1);
            Vector3I coord3 = new Vector3I(coord0.X + 0, coord0.Y + 0, coord0.Z + 1);
            Vector3I coord4 = new Vector3I(coord0.X + 0, coord0.Y + 1, coord0.Z + 0);
            Vector3I coord5 = new Vector3I(coord0.X + 1, coord0.Y + 1, coord0.Z + 0);
            Vector3I coord6 = new Vector3I(coord0.X + 1, coord0.Y + 1, coord0.Z + 1);
            Vector3I coord7 = new Vector3I(coord0.X + 0, coord0.Y + 1, coord0.Z + 1);

            Vector3I tempVoxelCoord0 = coord0;
            Vector3I tempVoxelCoord1 = coord1;
            Vector3I tempVoxelCoord2 = coord2;
            Vector3I tempVoxelCoord3 = coord3;
            Vector3I tempVoxelCoord4 = coord4;
            Vector3I tempVoxelCoord5 = coord5;
            Vector3I tempVoxelCoord6 = coord6;
            Vector3I tempVoxelCoord7 = coord7;


            tempVoxel0.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord0);
            tempVoxel1.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord1);
            tempVoxel2.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord2);
            tempVoxel3.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord3);
            tempVoxel4.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord4);
            tempVoxel5.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord5);
            tempVoxel6.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord6);
            tempVoxel7.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord7);

            //tempVoxel0.Position.X = m_originPosition.X + (coord0.X) * m_voxelSizeInMeters;
            //tempVoxel0.Position.Y = m_originPosition.Y + (coord0.Y) * m_voxelSizeInMeters;
            //tempVoxel0.Position.Z = m_originPosition.Z + (coord0.Z) * m_voxelSizeInMeters;

            tempVoxel0.Position.X = (m_voxelStart.X + coord0.X) * m_voxelSizeInMeters;
            tempVoxel0.Position.Y = (m_voxelStart.Y + coord0.Y) * m_voxelSizeInMeters;
            tempVoxel0.Position.Z = (m_voxelStart.Z + coord0.Z) * m_voxelSizeInMeters;


            tempVoxel1.Position.X = tempVoxel0.Position.X + m_voxelSizeInMeters;
            tempVoxel1.Position.Y = tempVoxel0.Position.Y;
            tempVoxel1.Position.Z = tempVoxel0.Position.Z;

            tempVoxel2.Position.X = tempVoxel0.Position.X + m_voxelSizeInMeters;
            tempVoxel2.Position.Y = tempVoxel0.Position.Y;
            tempVoxel2.Position.Z = tempVoxel0.Position.Z + m_voxelSizeInMeters;

            tempVoxel3.Position.X = tempVoxel0.Position.X;
            tempVoxel3.Position.Y = tempVoxel0.Position.Y;
            tempVoxel3.Position.Z = tempVoxel0.Position.Z + m_voxelSizeInMeters;

            tempVoxel4.Position.X = tempVoxel0.Position.X;
            tempVoxel4.Position.Y = tempVoxel0.Position.Y + m_voxelSizeInMeters;
            tempVoxel4.Position.Z = tempVoxel0.Position.Z;

            tempVoxel5.Position.X = tempVoxel0.Position.X + m_voxelSizeInMeters;
            tempVoxel5.Position.Y = tempVoxel0.Position.Y + m_voxelSizeInMeters;
            tempVoxel5.Position.Z = tempVoxel0.Position.Z;

            tempVoxel6.Position.X = tempVoxel0.Position.X + m_voxelSizeInMeters;
            tempVoxel6.Position.Y = tempVoxel0.Position.Y + m_voxelSizeInMeters;
            tempVoxel6.Position.Z = tempVoxel0.Position.Z + m_voxelSizeInMeters;

            tempVoxel7.Position.X = tempVoxel0.Position.X;
            tempVoxel7.Position.Y = tempVoxel0.Position.Y + m_voxelSizeInMeters;
            tempVoxel7.Position.Z = tempVoxel0.Position.Z + m_voxelSizeInMeters;

            //  Normals at grid corners (calculated from gradient)
            GetVoxelNormal(tempVoxel0, ref coord0, ref tempVoxelCoord0, tempVoxel0);
            GetVoxelNormal(tempVoxel1, ref coord1, ref tempVoxelCoord1, tempVoxel0);
            GetVoxelNormal(tempVoxel2, ref coord2, ref tempVoxelCoord2, tempVoxel0);
            GetVoxelNormal(tempVoxel3, ref coord3, ref tempVoxelCoord3, tempVoxel0);
            GetVoxelNormal(tempVoxel4, ref coord4, ref tempVoxelCoord4, tempVoxel0);
            GetVoxelNormal(tempVoxel5, ref coord5, ref tempVoxelCoord5, tempVoxel0);
            GetVoxelNormal(tempVoxel6, ref coord6, ref tempVoxelCoord6, tempVoxel0);
            GetVoxelNormal(tempVoxel7, ref coord7, ref tempVoxelCoord7, tempVoxel0);

            //  Ambient occlusion colors at grid corners
            //  IMPORTANT: At this point normals must be calculated because GetVoxelAmbientAndSun() will be retrieving them from temp table and not checking if there is actual value
            GetVoxelAmbient(tempVoxel0, ref coord0, ref tempVoxelCoord0);
            GetVoxelAmbient(tempVoxel1, ref coord1, ref tempVoxelCoord1);
            GetVoxelAmbient(tempVoxel2, ref coord2, ref tempVoxelCoord2);
            GetVoxelAmbient(tempVoxel3, ref coord3, ref tempVoxelCoord3);
            GetVoxelAmbient(tempVoxel4, ref coord4, ref tempVoxelCoord4);
            GetVoxelAmbient(tempVoxel5, ref coord5, ref tempVoxelCoord5);
            GetVoxelAmbient(tempVoxel6, ref coord6, ref tempVoxelCoord6);
            GetVoxelAmbient(tempVoxel7, ref coord7, ref tempVoxelCoord7);

            //  Find the vertices where the surface intersects the cube
            int edgeVal = MyMarchingCubesConstants.EdgeTable[cubeIndex];

            if ((edgeVal & 1) == 1)
            {
                GetVertexInterpolation(cache, tempVoxel0, tempVoxel1, 0);
            }
            if ((edgeVal & 2) == 2)
            {
                GetVertexInterpolation(cache, tempVoxel1, tempVoxel2, 1);
            }
            if ((edgeVal & 4) == 4)
            {
                GetVertexInterpolation(cache, tempVoxel2, tempVoxel3, 2);
            }
            if ((edgeVal & 8) == 8)
            {
                GetVertexInterpolation(cache, tempVoxel3, tempVoxel0, 3);
            }
            if ((edgeVal & 16) == 16)
            {
                GetVertexInterpolation(cache, tempVoxel4, tempVoxel5, 4);
            }
            if ((edgeVal & 32) == 32)
            {
                GetVertexInterpolation(cache, tempVoxel5, tempVoxel6, 5);
            }
            if ((edgeVal & 64) == 64)
            {
                GetVertexInterpolation(cache, tempVoxel6, tempVoxel7, 6);
            }
            if ((edgeVal & 128) == 128)
            {
                GetVertexInterpolation(cache, tempVoxel7, tempVoxel4, 7);
            }
            if ((edgeVal & 256) == 256)
            {
                GetVertexInterpolation(cache, tempVoxel0, tempVoxel4, 8);
            }
            if ((edgeVal & 512) == 512)
            {
                GetVertexInterpolation(cache, tempVoxel1, tempVoxel5, 9);
            }
            if ((edgeVal & 1024) == 1024)
            {
                GetVertexInterpolation(cache, tempVoxel2, tempVoxel6, 10);
            }
            if ((edgeVal & 2048) == 2048)
            {
                GetVertexInterpolation(cache, tempVoxel3, tempVoxel7, 11);
            }

            return(tempVoxelCoord0);
        }
Example #50
0
        protected override void WriteRangeInternal(MyStorageDataCache source, MyStorageDataTypeFlags dataToWrite, ref Vector3I voxelRangeMin, ref Vector3I voxelRangeMax)
        {
            ProfilerShort.Begin("MyOctreeStorage.WriteRange");

            Debug.Assert(dataToWrite != MyStorageDataTypeFlags.None);
            if ((dataToWrite & MyStorageDataTypeFlags.Content) != 0)
            {
                var args = new WriteRangeArgs()
                {
                    DataFilter = MyOctreeNode.ContentFilter,
                    DataType = MyStorageDataTypeEnum.Content,
                    Leaves = m_contentLeaves,
                    Nodes = m_contentNodes,
                    Provider = m_dataProvider,
                    Source = source,
                };
                WriteRange(ref args, 0, m_treeHeight + LeafLodCount, Vector3I.Zero, ref voxelRangeMin, ref voxelRangeMax);
            }

            if ((dataToWrite & MyStorageDataTypeFlags.Material) != 0)
            {
                var args = new WriteRangeArgs()
                {
                    DataFilter = MyOctreeNode.MaterialFilter,
                    DataType = MyStorageDataTypeEnum.Material,
                    Leaves = m_materialLeaves,
                    Nodes = m_materialNodes,
                    Provider = m_dataProvider,
                    Source = source,
                };
                WriteRange(ref args, 0, m_treeHeight + LeafLodCount, Vector3I.Zero, ref voxelRangeMin, ref voxelRangeMax);
            }

            ProfilerShort.End();
        }
 public virtual void ReadMaterialRange(MyStorageDataCache target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod, float lodVoxelSizeHalf)
 {
     target.BlockFillMaterial(writeOffset, writeOffset + (maxInLod - minInLod), m_material.Index);
 }
Example #52
0
        /// <summary>
        /// For debugging/testing only! This can be very slow for large storage.
        /// </summary>
        public void Voxelize(MyStorageDataTypeFlags data)
        {
            var cache = new MyStorageDataCache();

            cache.Resize(new Vector3I(LeafSizeInVoxels));
            var leafCount = (Size / LeafSizeInVoxels);
            Vector3I leaf = Vector3I.Zero;
            var end = leafCount - 1;
            for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref end);
                it.IsValid();
                it.GetNext(out leaf))
            {
                Debug.WriteLine("Processing {0} / {1}", leaf, end);
                var min = leaf * LeafSizeInVoxels;
                var max = min + (LeafSizeInVoxels - 1);
                ReadRangeInternal(cache, ref Vector3I.Zero, data, 0, ref min, ref max);
                WriteRangeInternal(cache, data, ref min, ref max);
            }

            OnRangeChanged(Vector3I.Zero, Size - 1, data);
        }
        internal void ReadMaterialRange(MyStorageDataCache target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
        {
            float lodVoxelSizeHalf;
            BoundingBox queryBox;
            BoundingSphere querySphere;
            SetupReading(lodIndex, ref minInLod, ref maxInLod, out lodVoxelSizeHalf, out queryBox, out querySphere);
            float lodVoxelSize = 2f * lodVoxelSizeHalf;

            var overlappedDeposits = OverlappedDeposits;
            {
                ProfilerShort.Begin("Testing deposit shapes");
                overlappedDeposits.Clear();
                ContainmentType testDeposits = ContainmentType.Disjoint;
                for (int i = 0; i < m_data.Deposits.Length; ++i)
                {
                    var test = m_data.Deposits[i].Shape.Contains(ref queryBox, ref querySphere, lodVoxelSize);
                    if (test != ContainmentType.Disjoint)
                    {
                        overlappedDeposits.Add(m_data.Deposits[i]);
                        testDeposits = ContainmentType.Intersects;
                    }
                }
                ProfilerShort.End();

                if (testDeposits == ContainmentType.Disjoint)
                {
                    ProfilerShort.Begin("target.BlockFillMaterial");
                    target.BlockFillMaterial(writeOffset, writeOffset + (maxInLod - minInLod), m_data.DefaultMaterial.Index);
                    ProfilerShort.End();
                    return;
                }
            }

            ProfilerShort.Begin("Material computation");
            Vector3I v;
            for (v.Z = minInLod.Z; v.Z <= maxInLod.Z; ++v.Z)
            {
                for (v.Y = minInLod.Y; v.Y <= maxInLod.Y; ++v.Y)
                {
                    for (v.X = minInLod.X; v.X <= maxInLod.X; ++v.X)
                    {
                        Vector3 localPos = v * lodVoxelSize;

                        float closestDistance = 1f;
                        byte closestMaterialIdx = m_data.DefaultMaterial.Index;
                        foreach (var deposit in overlappedDeposits)
                        {
                            float distance = deposit.Shape.SignedDistance(ref localPos, MyVoxelConstants.VOXEL_SIZE_IN_METRES, m_data.MacroModule, m_data.DetailModule);
                            if (distance < 0f && distance <= closestDistance)
                            {
                                closestDistance = distance;
                                // DA: Pass default material to the layered deposit so only that does these if-s.
                                var materialDef = deposit.GetMaterialForPosition(ref localPos, lodVoxelSize);
                                closestMaterialIdx = materialDef == null ? m_data.DefaultMaterial.Index : materialDef.Index;
                            }
                        }

                        var write = v - minInLod + writeOffset;
                        target.Material(ref write, closestMaterialIdx);
                    }
                }
            }
            ProfilerShort.End();
        }
Example #54
0
        private static unsafe void ReadRange(
            MyStorageDataCache target,
            ref Vector3I targetWriteOffset,
            MyStorageDataTypeEnum type,
            int treeHeight,
            Dictionary<UInt64, MyOctreeNode> nodes,
            Dictionary<UInt64, IMyOctreeLeafNode> leaves,
            int lodIndex,
            ref Vector3I minInLod,
            ref Vector3I maxInLod)
        {
            int stackIdx = 0;
            int stackSize = MySparseOctree.EstimateStackSize(treeHeight);
            MyCellCoord* stack = stackalloc MyCellCoord[stackSize];
            MyCellCoord data = new MyCellCoord(treeHeight + LeafLodCount, ref Vector3I.Zero);
            stack[stackIdx++] = data;
            MyCellCoord cell = new MyCellCoord();

            while (stackIdx > 0)
            {
                Debug.Assert(stackIdx <= stackSize);
                data = stack[--stackIdx];

                cell.Lod = data.Lod - LeafLodCount;
                cell.CoordInLod = data.CoordInLod;

                int lodDiff;
                IMyOctreeLeafNode leaf;
                if (leaves.TryGetValue(cell.PackId64(), out leaf))
                {
                    lodDiff = data.Lod - lodIndex;
                    var rangeMinInDataLod = minInLod >> lodDiff;
                    var rangeMaxInDataLod = maxInLod >> lodDiff;
                    if (data.CoordInLod.IsInsideInclusive(ref rangeMinInDataLod, ref rangeMaxInDataLod))
                    {
                        var nodePosInLod = data.CoordInLod << lodDiff;
                        var writeOffset = nodePosInLod - minInLod;
                        Vector3I.Max(ref writeOffset, ref Vector3I.Zero, out writeOffset);
                        writeOffset += targetWriteOffset;
                        var lodSizeMinusOne = new Vector3I((1 << lodDiff) - 1);
                        var minInLeaf = Vector3I.Clamp(minInLod - nodePosInLod, Vector3I.Zero, lodSizeMinusOne);
                        var maxInLeaf = Vector3I.Clamp(maxInLod - nodePosInLod, Vector3I.Zero, lodSizeMinusOne);
                        leaf.ReadRange(target, ref writeOffset, lodIndex, ref minInLeaf, ref maxInLeaf);
                    }
                    continue;
                }

                cell.Lod -= 1;
                lodDiff = data.Lod - 1 - lodIndex;
                var node = nodes[cell.PackId64()];

                var min = minInLod >> lodDiff;
                var max = maxInLod >> lodDiff;
                var nodePositionInChild = data.CoordInLod << 1;
                min -= nodePositionInChild;
                max -= nodePositionInChild;
                for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i)
                {
                    Vector3I childPosRelative;
                    ComputeChildCoord(i, out childPosRelative);
                    if (!childPosRelative.IsInsideInclusive(ref min, ref max))
                        continue;
                    if (lodIndex < data.Lod && node.HasChild(i))
                    {
                        Debug.Assert(stackIdx < stackSize);
                        stack[stackIdx++] = new MyCellCoord(data.Lod - 1, nodePositionInChild + childPosRelative);
                    }
                    else
                    {
                        var childMin = nodePositionInChild + childPosRelative;
                        childMin <<= lodDiff;
                        var writeOffset = childMin - minInLod;
                        Vector3I.Max(ref writeOffset, ref Vector3I.Zero, out writeOffset);
                        writeOffset += targetWriteOffset;
                        var nodeData = node.GetData(i);
                        if (lodDiff == 0)
                        {
                            target.Set(type, ref writeOffset, nodeData);
                        }
                        else
                        {
                            var childMax = childMin + ((1 << lodDiff) - 1);
                            Vector3I.Max(ref childMin, ref minInLod, out childMin);
                            Vector3I.Min(ref childMax, ref maxInLod, out childMax);
                            for (int z = childMin.Z; z <= childMax.Z; ++z)
                            for (int y = childMin.Y; y <= childMax.Y; ++y)
                            for (int x = childMin.X; x <= childMax.X; ++x)
                            {
                                Vector3I write = writeOffset;
                                write.X += x - childMin.X;
                                write.Y += y - childMin.Y;
                                write.Z += z - childMin.Z;
                                target.Set(type, ref write, nodeData);
                            }
                        }
                    }
                }
            }
        }
        private bool ReplaceAsteroidMaterial(IMyVoxelBase originalAsteroid, string searchMaterialName1, string searchMaterialName2)
        {
            MyVoxelMaterialDefinition material1;
            string suggestedMaterials = "";
            if (!Support.FindMaterial(searchMaterialName1, out material1, ref suggestedMaterials))
            {
                MyAPIGateway.Utilities.ShowMessage("Invalid Material1 specified.", "Cannot find the material '{0}'.\r\nTry the following: {1}", searchMaterialName1, suggestedMaterials);
                return true;
            }

            MyVoxelMaterialDefinition material2;
            if (!Support.FindMaterial(searchMaterialName2, out material2, ref suggestedMaterials))
            {
                MyAPIGateway.Utilities.ShowMessage("Invalid Material2 specified.", "Cannot find the material '{0}'.\r\nTry the following: {1}", searchMaterialName2, suggestedMaterials);
                return true;
            }

            var oldStorage = originalAsteroid.Storage;
            var oldCache = new MyStorageDataCache();
            oldCache.Resize(oldStorage.Size);
            oldStorage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, Vector3I.Zero, oldStorage.Size - 1);

            Vector3I p;
            for (p.Z = 0; p.Z < oldStorage.Size.Z; ++p.Z)
                for (p.Y = 0; p.Y < oldStorage.Size.Y; ++p.Y)
                    for (p.X = 0; p.X < oldStorage.Size.X; ++p.X)
                    {
                        var material = oldCache.Material(ref p);
                        if (material == material1.Index)
                            oldCache.Material(ref p, material2.Index);
                    }

            oldStorage.WriteRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, Vector3I.Zero, oldStorage.Size - 1);

            MyAPIGateway.Utilities.ShowMessage("Asteroid", "'{0}' material '{1}' replaced with '{2}'.", originalAsteroid.StorageName, material1.Id.SubtypeName, material2.Id.SubtypeName);
            return true;
        }
        //  Linearly interpolates position, normal and material on poly-cube edge. Interpolated point is where an isosurface cuts an edge between two vertices, each with their own scalar value.
        void GetVertexInterpolation(MyStorageDataCache cache, MyTemporaryVoxel inputVoxelA, MyTemporaryVoxel inputVoxelB, int edgeIndex)
        {
            MyEdge edge = m_edges[edgeIndex];

            byte contentA = cache.Content(inputVoxelA.IdxInCache);
            byte contentB = cache.Content(inputVoxelB.IdxInCache);
            byte materialA = cache.Material(inputVoxelA.IdxInCache);
            byte materialB = cache.Material(inputVoxelB.IdxInCache);

            if (Math.Abs(MyVoxelConstants.VOXEL_ISO_LEVEL - contentA) < 0.00001f)
            {
                edge.Position = inputVoxelA.Position;
                edge.Normal = inputVoxelA.Normal;
                edge.Material = materialA;
                edge.Ambient = inputVoxelA.Ambient;
                return;
            }

            if (Math.Abs(MyVoxelConstants.VOXEL_ISO_LEVEL - contentB) < 0.00001f)
            {
                edge.Position = inputVoxelB.Position;
                edge.Normal = inputVoxelB.Normal;
                edge.Material = materialB;
                edge.Ambient = inputVoxelB.Ambient;
                return;
            }

            float mu = (float)(MyVoxelConstants.VOXEL_ISO_LEVEL - contentA) / (float)(contentB - contentA);
            Debug.Assert(mu > 0.0f && mu < 1.0f);

            edge.Position.X = inputVoxelA.Position.X + mu * (inputVoxelB.Position.X - inputVoxelA.Position.X);
            edge.Position.Y = inputVoxelA.Position.Y + mu * (inputVoxelB.Position.Y - inputVoxelA.Position.Y);
            edge.Position.Z = inputVoxelA.Position.Z + mu * (inputVoxelB.Position.Z - inputVoxelA.Position.Z);
            //edge.Normal = ComputeVertexNormal(ref edge.Position);

            edge.Normal.X = inputVoxelA.Normal.X + mu * (inputVoxelB.Normal.X - inputVoxelA.Normal.X);
            edge.Normal.Y = inputVoxelA.Normal.Y + mu * (inputVoxelB.Normal.Y - inputVoxelA.Normal.Y);
            edge.Normal.Z = inputVoxelA.Normal.Z + mu * (inputVoxelB.Normal.Z - inputVoxelA.Normal.Z);
            if (MyUtils.IsZero(edge.Normal))
                edge.Normal = inputVoxelA.Normal;
            else
                edge.Normal = MyUtils.Normalize(edge.Normal);


            if (MyUtils.IsZero(edge.Normal))
                edge.Normal = inputVoxelA.Normal;

            float mu2 = ((float)contentB) / (((float)contentA) + ((float)contentB));
            edge.Material = (mu2 <= 0.5f) ? materialA : materialB;
            edge.Ambient = inputVoxelA.Ambient + mu2 * (inputVoxelB.Ambient - inputVoxelA.Ambient);

            return;
        }
 void IMyStorage.WriteRange(MyStorageDataCache source, bool writeContent, bool writeMaterials, ref Vector3I voxelRangeMin, ref Vector3I voxelRangeMax)
 {
     EnsureMutable();
     m_trueStorage.WriteRange(source, writeContent, writeMaterials, ref voxelRangeMin, ref voxelRangeMax);
 }
        private Vector3I ComputeTemporaryVoxelData(MyStorageDataCache cache, ref Vector3I coord0, int cubeIndex, int lod)
        {
            int coord0LinIdx = coord0.X * m_sX + coord0.Y * m_sY + coord0.Z * m_sZ;

            MyTemporaryVoxel tempVoxel0 = m_temporaryVoxels[coord0LinIdx];
            MyTemporaryVoxel tempVoxel1 = m_temporaryVoxels[coord0LinIdx + m_sX];
            MyTemporaryVoxel tempVoxel2 = m_temporaryVoxels[coord0LinIdx + m_sX + m_sZ];
            MyTemporaryVoxel tempVoxel3 = m_temporaryVoxels[coord0LinIdx + m_sZ];
            MyTemporaryVoxel tempVoxel4 = m_temporaryVoxels[coord0LinIdx + m_sY];
            MyTemporaryVoxel tempVoxel5 = m_temporaryVoxels[coord0LinIdx + m_sX + m_sY];
            MyTemporaryVoxel tempVoxel6 = m_temporaryVoxels[coord0LinIdx + m_sX + m_sY + m_sZ];
            MyTemporaryVoxel tempVoxel7 = m_temporaryVoxels[coord0LinIdx + m_sY + m_sZ];



            Vector3I coord1 = new Vector3I(coord0.X + 1, coord0.Y + 0, coord0.Z + 0);
            Vector3I coord2 = new Vector3I(coord0.X + 1, coord0.Y + 0, coord0.Z + 1);
            Vector3I coord3 = new Vector3I(coord0.X + 0, coord0.Y + 0, coord0.Z + 1);
            Vector3I coord4 = new Vector3I(coord0.X + 0, coord0.Y + 1, coord0.Z + 0);
            Vector3I coord5 = new Vector3I(coord0.X + 1, coord0.Y + 1, coord0.Z + 0);
            Vector3I coord6 = new Vector3I(coord0.X + 1, coord0.Y + 1, coord0.Z + 1);
            Vector3I coord7 = new Vector3I(coord0.X + 0, coord0.Y + 1, coord0.Z + 1);

            Vector3I tempVoxelCoord0 = coord0;
            Vector3I tempVoxelCoord1 = coord1;
            Vector3I tempVoxelCoord2 = coord2;
            Vector3I tempVoxelCoord3 = coord3;
            Vector3I tempVoxelCoord4 = coord4;
            Vector3I tempVoxelCoord5 = coord5;
            Vector3I tempVoxelCoord6 = coord6;
            Vector3I tempVoxelCoord7 = coord7;


            tempVoxel0.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord0);
            tempVoxel1.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord1);
            tempVoxel2.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord2);
            tempVoxel3.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord3);
            tempVoxel4.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord4);
            tempVoxel5.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord5);
            tempVoxel6.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord6);
            tempVoxel7.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord7);

            //tempVoxel0.Position.X = m_originPosition.X + (coord0.X) * m_voxelSizeInMeters;
            //tempVoxel0.Position.Y = m_originPosition.Y + (coord0.Y) * m_voxelSizeInMeters;
            //tempVoxel0.Position.Z = m_originPosition.Z + (coord0.Z) * m_voxelSizeInMeters;

            tempVoxel0.Position.X = (m_voxelStart.X + coord0.X) * m_voxelSizeInMeters;
            tempVoxel0.Position.Y = (m_voxelStart.Y + coord0.Y) * m_voxelSizeInMeters;
            tempVoxel0.Position.Z = (m_voxelStart.Z + coord0.Z) * m_voxelSizeInMeters;


            tempVoxel1.Position.X = tempVoxel0.Position.X + m_voxelSizeInMeters;
            tempVoxel1.Position.Y = tempVoxel0.Position.Y;
            tempVoxel1.Position.Z = tempVoxel0.Position.Z;

            tempVoxel2.Position.X = tempVoxel0.Position.X + m_voxelSizeInMeters;
            tempVoxel2.Position.Y = tempVoxel0.Position.Y;
            tempVoxel2.Position.Z = tempVoxel0.Position.Z + m_voxelSizeInMeters;

            tempVoxel3.Position.X = tempVoxel0.Position.X;
            tempVoxel3.Position.Y = tempVoxel0.Position.Y;
            tempVoxel3.Position.Z = tempVoxel0.Position.Z + m_voxelSizeInMeters;

            tempVoxel4.Position.X = tempVoxel0.Position.X;
            tempVoxel4.Position.Y = tempVoxel0.Position.Y + m_voxelSizeInMeters;
            tempVoxel4.Position.Z = tempVoxel0.Position.Z;

            tempVoxel5.Position.X = tempVoxel0.Position.X + m_voxelSizeInMeters;
            tempVoxel5.Position.Y = tempVoxel0.Position.Y + m_voxelSizeInMeters;
            tempVoxel5.Position.Z = tempVoxel0.Position.Z;

            tempVoxel6.Position.X = tempVoxel0.Position.X + m_voxelSizeInMeters;
            tempVoxel6.Position.Y = tempVoxel0.Position.Y + m_voxelSizeInMeters;
            tempVoxel6.Position.Z = tempVoxel0.Position.Z + m_voxelSizeInMeters;

            tempVoxel7.Position.X = tempVoxel0.Position.X;
            tempVoxel7.Position.Y = tempVoxel0.Position.Y + m_voxelSizeInMeters;
            tempVoxel7.Position.Z = tempVoxel0.Position.Z + m_voxelSizeInMeters;

            //  Normals at grid corners (calculated from gradient)
            GetVoxelNormal(tempVoxel0, ref coord0, ref tempVoxelCoord0, tempVoxel0);
            GetVoxelNormal(tempVoxel1, ref coord1, ref tempVoxelCoord1, tempVoxel0);
            GetVoxelNormal(tempVoxel2, ref coord2, ref tempVoxelCoord2, tempVoxel0);
            GetVoxelNormal(tempVoxel3, ref coord3, ref tempVoxelCoord3, tempVoxel0);
            GetVoxelNormal(tempVoxel4, ref coord4, ref tempVoxelCoord4, tempVoxel0);
            GetVoxelNormal(tempVoxel5, ref coord5, ref tempVoxelCoord5, tempVoxel0);
            GetVoxelNormal(tempVoxel6, ref coord6, ref tempVoxelCoord6, tempVoxel0);
            GetVoxelNormal(tempVoxel7, ref coord7, ref tempVoxelCoord7, tempVoxel0);

            //  Ambient occlusion colors at grid corners
            //  IMPORTANT: At this point normals must be calculated because GetVoxelAmbientAndSun() will be retrieving them from temp table and not checking if there is actual value
            GetVoxelAmbient(tempVoxel0, ref coord0, ref tempVoxelCoord0);
            GetVoxelAmbient(tempVoxel1, ref coord1, ref tempVoxelCoord1);
            GetVoxelAmbient(tempVoxel2, ref coord2, ref tempVoxelCoord2);
            GetVoxelAmbient(tempVoxel3, ref coord3, ref tempVoxelCoord3);
            GetVoxelAmbient(tempVoxel4, ref coord4, ref tempVoxelCoord4);
            GetVoxelAmbient(tempVoxel5, ref coord5, ref tempVoxelCoord5);
            GetVoxelAmbient(tempVoxel6, ref coord6, ref tempVoxelCoord6);
            GetVoxelAmbient(tempVoxel7, ref coord7, ref tempVoxelCoord7);

            //  Find the vertices where the surface intersects the cube
            int edgeVal = MyMarchingCubesConstants.EdgeTable[cubeIndex];
            if ((edgeVal & 1) == 1) { GetVertexInterpolation(cache, tempVoxel0, tempVoxel1, 0); }
            if ((edgeVal & 2) == 2) { GetVertexInterpolation(cache, tempVoxel1, tempVoxel2, 1); }
            if ((edgeVal & 4) == 4) { GetVertexInterpolation(cache, tempVoxel2, tempVoxel3, 2); }
            if ((edgeVal & 8) == 8) { GetVertexInterpolation(cache, tempVoxel3, tempVoxel0, 3); }
            if ((edgeVal & 16) == 16) { GetVertexInterpolation(cache, tempVoxel4, tempVoxel5, 4); }
            if ((edgeVal & 32) == 32) { GetVertexInterpolation(cache, tempVoxel5, tempVoxel6, 5); }
            if ((edgeVal & 64) == 64) { GetVertexInterpolation(cache, tempVoxel6, tempVoxel7, 6); }
            if ((edgeVal & 128) == 128) { GetVertexInterpolation(cache, tempVoxel7, tempVoxel4, 7); }
            if ((edgeVal & 256) == 256) { GetVertexInterpolation(cache, tempVoxel0, tempVoxel4, 8); }
            if ((edgeVal & 512) == 512) { GetVertexInterpolation(cache, tempVoxel1, tempVoxel5, 9); }
            if ((edgeVal & 1024) == 1024) { GetVertexInterpolation(cache, tempVoxel2, tempVoxel6, 10); }
            if ((edgeVal & 2048) == 2048) { GetVertexInterpolation(cache, tempVoxel3, tempVoxel7, 11); }

            return tempVoxelCoord0;
        }
Example #59
0
 void ModAPI.Interfaces.IMyStorage.WriteRange(MyStorageDataCache source, MyStorageDataTypeFlags dataToWrite, Vector3I voxelRangeMin, Vector3I voxelRangeMax)
 {
     WriteRange(source, dataToWrite, ref voxelRangeMin, ref voxelRangeMax);
 }
Example #60
0
        private static MyStorageBase Compatibility_LoadCellStorage(int fileVersion, Stream stream)
        {
            //  Size of this voxel map (in voxels)
            Vector3I tmpSize;

            tmpSize.X = stream.ReadInt32();
            tmpSize.Y = stream.ReadInt32();
            tmpSize.Z = stream.ReadInt32();
            var storage = new MyOctreeStorage(null, tmpSize);

            //  Size of data cell in voxels. Has to be the same as current size specified by our constants.
            Vector3I cellSize;

            cellSize.X = stream.ReadInt32();
            cellSize.Y = stream.ReadInt32();
            cellSize.Z = stream.ReadInt32();
            Trace.Assert(cellSize.X == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS &&
                         cellSize.Y == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS &&
                         cellSize.Z == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS);

            Vector3I cellsCount = tmpSize / cellSize;

            Dictionary <byte, MyVoxelMaterialDefinition> mappingTable = null;

            if (fileVersion == STORAGE_TYPE_VERSION_CELL)
            {
                // loading material names->index mappings
                mappingTable = Compatibility_LoadMaterialIndexMapping(stream);
            }
            else if (fileVersion == 1)
            {
                // material name->index mappings were not saved in this version
            }

            var startCoord = Vector3I.Zero;
            var endCoord   = new Vector3I(MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1);

            var cache = new MyStorageDataCache();

            cache.Resize(Vector3I.Zero, endCoord);
            Vector3I cellCoord;

            for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++)
            {
                for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++)
                {
                    for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++)
                    {
                        MyVoxelRangeType cellType = (MyVoxelRangeType)stream.ReadByteNoAlloc();

                        //  Cell's are FULL by default, therefore we don't need to change them
                        switch (cellType)
                        {
                        case MyVoxelRangeType.EMPTY: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_EMPTY); break;

                        case MyVoxelRangeType.FULL: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_FULL); break;

                        case MyVoxelRangeType.MIXED:
                            Vector3I v;
                            for (v.X = 0; v.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.X++)
                            {
                                for (v.Y = 0; v.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Y++)
                                {
                                    for (v.Z = 0; v.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Z++)
                                    {
                                        cache.Content(ref v, stream.ReadByteNoAlloc());
                                    }
                                }
                            }
                            break;
                        }
                        startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS;
                        endCoord   = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1);
                        storage.WriteRange(cache, MyStorageDataTypeFlags.Content, ref startCoord, ref endCoord);
                    }
                }
            }

            try
            { // In case materials are not saved, catch any exceptions caused by this.
                // Read materials and indestructible
                for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++)
                {
                    for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++)
                    {
                        for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++)
                        {
                            bool isSingleMaterial = stream.ReadByteNoAlloc() == 1;
                            MyVoxelMaterialDefinition material = null;

                            if (isSingleMaterial)
                            {
                                material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable);
                                cache.ClearMaterials(material.Index);
                            }
                            else
                            {
                                byte     indestructibleContent;
                                Vector3I voxelCoordInCell;
                                for (voxelCoordInCell.X = 0; voxelCoordInCell.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.X++)
                                {
                                    for (voxelCoordInCell.Y = 0; voxelCoordInCell.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Y++)
                                    {
                                        for (voxelCoordInCell.Z = 0; voxelCoordInCell.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Z++)
                                        {
                                            material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable);
                                            indestructibleContent = stream.ReadByteNoAlloc();
                                            cache.Material(ref voxelCoordInCell, material.Index);
                                        }
                                    }
                                }
                            }
                            startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS;
                            endCoord   = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1);
                            storage.WriteRange(cache, MyStorageDataTypeFlags.Material, ref startCoord, ref endCoord);
                        }
                    }
                }
            }
            catch (EndOfStreamException ex)
            {
                MySandboxGame.Log.WriteLine(ex);
            }

            return(storage);
        }