private Image TryGetPlanetTexture(string name, MyModContext context, string p, out string fullPath)
        {
            bool found = false;

            name    += p;
            fullPath = Path.Combine(context.ModPathData, "PlanetDataFiles", name) + ".png";

            // Check for modded textures
            if (!context.IsBaseGame)
            {
                if (!MyFileSystem.FileExists(fullPath))
                {
                    fullPath = Path.Combine(context.ModPathData, "PlanetDataFiles", name) + ".dds";
                    if (MyFileSystem.FileExists(fullPath))
                    {
                        found = true;
                    }
                }
                else
                {
                    found = true;
                }
            }

            // Check for default textures
            if (!found)
            {
                fullPath = Path.Combine(m_planetDataFolder, name) + ".png";

                if (!MyFileSystem.FileExists(fullPath))
                {
                    fullPath = Path.Combine(m_planetDataFolder, name) + ".dds";
                    if (!MyFileSystem.FileExists(fullPath))
                    {
                        return(null);
                    }
                }
            }

            if (fullPath.Contains(".sbm"))
            {
                string archivePath             = fullPath.Substring(0, fullPath.IndexOf(".sbm") + 4);
                string fileRelativeArchivePath = fullPath.Replace(archivePath + "\\", "");
                using (var sbm = VRage.Compression.MyZipArchive.OpenOnFile(archivePath))
                {
                    try
                    {
                        return(SharpDXImage.Load(sbm.GetFile(fileRelativeArchivePath).GetStream()));
                    }
                    catch (Exception ex)
                    {
                        MyDebug.FailRelease("Failed to load existing " + p + " file from .sbm archive. " + fullPath);
                        return(null);
                    }
                }
            }

            return(SharpDXImage.Load(fullPath));
        }
示例#2
0
 public MyCubemap(params MyCubemapData <byte>[] faces)
 {
     if (faces.Length != 6)
     {
         MyDebug.FailRelease("When loading cubemap exactly 6 faces are expected.");
     }
     base.m_faces      = faces;
     base.m_resolution = faces[0].Resolution;
     base.PrepareSides();
 }
示例#3
0
        internal void Unregister(IMyGunObject <MyDeviceBase> gun)
        {
            MyDebug.AssertDebug(gun != null);
            if (!m_gunsByDefId.ContainsKey(gun.DefinitionId))
            {
                MyDebug.FailRelease("deinition ID " + gun.DefinitionId + " not in m_gunsByDefId");
                return;
            }
            MyDebug.AssertDebug(m_gunsByDefId[gun.DefinitionId].Contains(gun));

            m_gunsByDefId[gun.DefinitionId].Remove(gun);

            if (WeaponUnregistered != null)
            {
                WeaponUnregistered(this, new EventArgs()
                {
                    Weapon = gun
                });
            }
        }
示例#4
0
        public override bool IsOverlapOverThreshold(BoundingBoxD worldAabb, float thresholdPercentage)
        {
            if (m_storage == null)
            {
                if (MyEntities.GetEntityByIdOrDefault(this.EntityId) != this)
                {
                    MyDebug.FailRelease("Voxel map was deleted!");
                }
                else
                {
                    MyDebug.FailRelease("Voxel map is still in world but has null storage!");
                }
                return(false);
            }

            //Debug.Assert(
            //    worldAabb.Size.X > MyVoxelConstants.VOXEL_SIZE_IN_METRES &&
            //    worldAabb.Size.Y > MyVoxelConstants.VOXEL_SIZE_IN_METRES &&
            //    worldAabb.Size.Z > MyVoxelConstants.VOXEL_SIZE_IN_METRES,
            //    "One of the sides of queried AABB is too small compared to voxel size. Results will be unreliable.");

            Vector3I minCorner, maxCorner;

            MyVoxelCoordSystems.WorldPositionToVoxelCoord(PositionLeftBottomCorner, ref worldAabb.Min, out minCorner);
            MyVoxelCoordSystems.WorldPositionToVoxelCoord(PositionLeftBottomCorner, ref worldAabb.Max, out maxCorner);

            minCorner += StorageMin;
            maxCorner += StorageMin;

            Storage.ClampVoxelCoord(ref minCorner);
            Storage.ClampVoxelCoord(ref maxCorner);
            m_tempStorage.Resize(minCorner, maxCorner);
            Storage.ReadRange(m_tempStorage, MyStorageDataTypeFlags.Content, 0, ref minCorner, ref maxCorner);
            BoundingBoxD voxelBox;

            //MyRenderProxy.DebugDrawAABB(worldAabb, Color.White, 1f, 1f, true);

            var    invFullVoxel         = 1.0 / (double)MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT;
            var    voxelVolume          = 1.0 / (double)MyVoxelConstants.VOXEL_VOLUME_IN_METERS;
            double overlapContentVolume = 0.0;

            var queryVolume = worldAabb.Volume;

            //using (var batch = MyRenderProxy.DebugDrawBatchAABB(Matrix.Identity, new Color(Color.Green, 0.1f), true, true))
            {
                Vector3I coord, cache;
                for (coord.Z = minCorner.Z, cache.Z = 0; coord.Z <= maxCorner.Z; coord.Z++, cache.Z++)
                {
                    for (coord.Y = minCorner.Y, cache.Y = 0; coord.Y <= maxCorner.Y; coord.Y++, cache.Y++)
                    {
                        for (coord.X = minCorner.X, cache.X = 0; coord.X <= maxCorner.X; coord.X++, cache.X++)
                        {
                            MyVoxelCoordSystems.VoxelCoordToWorldAABB(PositionLeftBottomCorner, ref coord, out voxelBox);
                            if (worldAabb.Intersects(voxelBox))
                            {
                                var contentVolume = m_tempStorage.Content(ref cache) * invFullVoxel * voxelVolume;
                                var overlapVolume = worldAabb.Intersect(voxelBox).Volume;
                                overlapContentVolume += contentVolume * overlapVolume;

                                //batch.Add(ref voxelBox);
                            }
                        }
                    }
                }
            }

            var overlapVolumePercentage = overlapContentVolume / queryVolume;

            //MyRenderProxy.DebugDrawText3D(worldAabb.Center, overlapVolumePercentage.ToString("0.000"), Color.White, 1f, false);
            return(overlapVolumePercentage >= thresholdPercentage);
        }
示例#5
0
        public void CreatePruningTree(string mapName)
        {
            int depth = 0;

            int res = Resolution;

            res /= HeightmapNode.HEIGHTMAP_LEAF_SIZE;

            // check if we get an even tree, for now we will rely on that.
            while (res != 1)
            {
                if (res % HeightmapNode.HEIGHTMAP_BRANCH_FACTOR != 0)
                {
                    MyDebug.FailRelease("Cannot build prunning tree for heightmap face {0}!", mapName);
                    MyDebug.FailRelease("Heightmap resolution must be divisible by {1}, and after that a power of {0}. Failing to achieve so will disable several important optimizations!!", HeightmapNode.HEIGHTMAP_BRANCH_FACTOR, HeightmapNode.HEIGHTMAP_LEAF_SIZE);
                    return;
                }
                depth++;
                res /= HeightmapNode.HEIGHTMAP_BRANCH_FACTOR;
            }

            PruningTree = new HeightmapLevel[depth];

            int offset = GetRowStart(0);

            if (depth == 0)
            {
                float min = float.PositiveInfinity;
                float max = float.NegativeInfinity;

                int localOffset = offset;
                for (int y = 0; y < HeightmapNode.HEIGHTMAP_LEAF_SIZE; ++y)
                {
                    for (int x = 0; x < HeightmapNode.HEIGHTMAP_LEAF_SIZE; ++x)
                    {
                        float value = ((float)Data[localOffset + x] * MyCubemapHelpers.USHORT_RECIP);
                        if (min > value)
                        {
                            min = value;
                        }
                        if (max < value)
                        {
                            max = value;
                        }
                    }
                    localOffset += m_real_resolution;
                }

                Root.Max = max;
                Root.Min = min;
                return;
            }

            int nodes = HeightmapNode.HEIGHTMAP_BRANCH_FACTOR;

            res = Resolution / HeightmapNode.HEIGHTMAP_LEAF_SIZE;

            // prepare leaf level
            PruningTree[0].Nodes = new HeightmapNode[res * res];
            PruningTree[0].Res   = (uint)res;

            int cell = 0;

            for (int j = 0; j < res; ++j)
            {
                int coffset = offset;
                for (int i = 0; i < res; ++i)
                {
                    float min = float.PositiveInfinity;
                    float max = float.NegativeInfinity;

                    int localOffset = coffset - m_real_resolution;
                    for (int y = -1; y <= HeightmapNode.HEIGHTMAP_LEAF_SIZE; ++y)
                    {
                        for (int x = -1; x <= HeightmapNode.HEIGHTMAP_LEAF_SIZE; ++x)
                        {
                            float value = ((float)Data[localOffset + x] * MyCubemapHelpers.USHORT_RECIP);
                            if (min > value)
                            {
                                min = value;
                            }
                            if (max < value)
                            {
                                max = value;
                            }
                        }
                        localOffset += m_real_resolution;
                    }

                    PruningTree[0].Nodes[cell] = new HeightmapNode()
                    {
                        Max = max,
                        Min = min
                    };

                    cell++;
                    coffset += HeightmapNode.HEIGHTMAP_LEAF_SIZE;
                }
                offset += HeightmapNode.HEIGHTMAP_LEAF_SIZE * m_real_resolution;
            }

            int l = 0;

            for (int k = 1; k < depth; k++)
            {
                offset = 0;
                int levelRes = res / HeightmapNode.HEIGHTMAP_BRANCH_FACTOR;

                PruningTree[k].Nodes = new HeightmapNode[levelRes * levelRes];
                PruningTree[k].Res   = (uint)levelRes;

                cell = 0;
                for (int j = 0; j < levelRes; ++j)
                {
                    int coffset = offset;
                    for (int i = 0; i < levelRes; ++i)
                    {
                        float min = float.PositiveInfinity;
                        float max = float.NegativeInfinity;

                        int localOffset = coffset;
                        for (int y = 0; y < HeightmapNode.HEIGHTMAP_BRANCH_FACTOR; ++y)
                        {
                            for (int x = 0; x < HeightmapNode.HEIGHTMAP_BRANCH_FACTOR; ++x)
                            {
                                HeightmapNode n = PruningTree[l].Nodes[localOffset + x];
                                if (min > n.Min)
                                {
                                    min = n.Min;
                                }
                                if (max < n.Max)
                                {
                                    max = n.Max;
                                }
                            }
                            localOffset += res;
                        }

                        PruningTree[k].Nodes[cell] = new HeightmapNode()
                        {
                            Max = max,
                            Min = min
                        };

                        cell++;
                        coffset += HeightmapNode.HEIGHTMAP_BRANCH_FACTOR;
                    }
                    offset += HeightmapNode.HEIGHTMAP_BRANCH_FACTOR * res;
                }

                // previous level
                l++;
                res = levelRes;
            }

            float tmin = float.PositiveInfinity;
            float tmax = float.NegativeInfinity;

            offset = 0;
            for (int y = 0; y < HeightmapNode.HEIGHTMAP_BRANCH_FACTOR; ++y)
            {
                for (int x = 0; x < HeightmapNode.HEIGHTMAP_BRANCH_FACTOR; ++x)
                {
                    HeightmapNode n = PruningTree[depth - 1].Nodes[offset++];
                    if (tmin > n.Min)
                    {
                        tmin = n.Min;
                    }
                    if (tmax < n.Max)
                    {
                        tmax = n.Max;
                    }
                }
            }

            Root.Max = tmax;
            Root.Min = tmin;
        }
        public void GetPlanetMaps(string folder, MyModContext context, MyPlanetMaps mapsToUse, out MyCubemap[] maps)
        {
            if (m_planetMaps.ContainsKey(folder))
            {
                maps = m_planetMaps[folder];
                return;
            }

            maps = new MyCubemap[4];

            MyCubemapData <byte>[] tmpMaps = new MyCubemapData <byte> [4 * 6];

            byte[][] streams = new byte[4][];

            string fullPath;

            ProfilerShort.Begin("MyHeightmapLoadingSystem::GetPlanetMaps()");

            ProfilerShort.Begin("Load _mat");
            // Round one: material, ore, biome
            if (mapsToUse.Material || mapsToUse.Biome || mapsToUse.Ores)
            {
                for (int i = 0; i < 6; ++i)
                {
                    string name = Path.Combine(folder, MyCubemapHelpers.GetNameForFace(i));

                    using (var texture = TryGetPlanetTexture(name, context, "_mat", out fullPath))
                    {
                        if (texture == null)
                        {
                            ClearMatValues(tmpMaps);
                            break;
                        }

                        PixelBuffer buffer = texture.GetPixelBuffer(0, 0, 0);

                        if (buffer.Format != Format.B8G8R8A8_UNorm &&
                            buffer.Format != Format.R8G8B8A8_UNorm)
                        {
                            MyDebug.FailRelease("While loading maps from {1}: Unsupported planet map format: {0}.", buffer.Format, fullPath);
                            break;
                        }

                        if (buffer.Width != buffer.Height)
                        {
                            MyDebug.FailRelease("While loading maps from {0}: Width and height must be the same.", fullPath);
                            break;
                        }

                        if (mapsToUse.Material)
                        {
                            tmpMaps[i * 4] = new MyCubemapData <byte>(buffer.Width);
                            streams[0]     = tmpMaps[i * 4].Data;
                        }

                        if (mapsToUse.Biome)
                        {
                            tmpMaps[i * 4 + 1] = new MyCubemapData <byte>(buffer.Width);
                            streams[1]         = tmpMaps[i * 4 + 1].Data;
                        }

                        if (mapsToUse.Ores)
                        {
                            tmpMaps[i * 4 + 2] = new MyCubemapData <byte>(buffer.Width);
                            streams[2]         = tmpMaps[i * 4 + 2].Data;
                        }

                        // Invert channels for BGRA
                        if (buffer.Format == Format.B8G8R8A8_UNorm)
                        {
                            var tmp = streams[2];
                            streams[2] = streams[0];
                            streams[0] = tmp;
                        }

                        ReadChannelsFromImage(streams, buffer);
                    }
                }
            }

            ProfilerShort.BeginNextBlock("Load _add");
            // round two: add map
            if (mapsToUse.Occlusion)
            {
                for (int i = 0; i < 6; ++i)
                {
                    string name = Path.Combine(folder, MyCubemapHelpers.GetNameForFace(i));

                    using (var texture = TryGetPlanetTexture(name, context, "_add", out fullPath))
                    {
                        if (texture == null)
                        {
                            ClearAddValues(tmpMaps);
                            break;
                        }

                        PixelBuffer buffer = texture.GetPixelBuffer(0, 0, 0);

                        if (buffer.Format != Format.B8G8R8A8_UNorm &&
                            buffer.Format != Format.R8G8B8A8_UNorm)
                        {
                            MyDebug.FailRelease("While loading maps from {1}: Unsupported planet map format: {0}.", buffer.Format, fullPath);
                            break;
                        }

                        if (buffer.Width != buffer.Height)
                        {
                            MyDebug.FailRelease("While loading maps from {0}: Width and height must be the same.", fullPath);
                            break;
                        }

                        if (mapsToUse.Occlusion)
                        {
                            tmpMaps[i * 4 + 3] = new MyCubemapData <byte>(buffer.Width);
                            streams[0]         = tmpMaps[i * 4 + 3].Data;
                        }

                        streams[1] = streams[2] = null;

                        // Invert channels for BGRA
                        if (buffer.Format == Format.B8G8R8A8_UNorm)
                        {
                            var tmp = streams[2];
                            streams[2] = streams[0];
                            streams[0] = tmp;
                        }

                        ReadChannelsFromImage(streams, buffer);
                    }
                }
            }

            ProfilerShort.BeginNextBlock("Finish");

            for (int i = 0; i < 4; ++i)
            {
                if (tmpMaps[i] != null)
                {
                    var cmaps = new MyCubemapData <byte> [6];
                    for (int j = 0; j < 6; j++)
                    {
                        cmaps[j] = tmpMaps[i + j * 4];
                    }
                    maps[i] = new MyCubemap(cmaps);
                }
            }

            m_planetMaps[folder] = maps;

            ProfilerShort.End();
            ProfilerShort.End();
        }
        public MyHeightmapFace GetHeightMap(string folderName, string faceName, MyModContext context)
        {
            ProfilerShort.Begin("MyHeightmapLoadingSystem::GetHeightMap()");
            if (m_first)
            {
                PreloadCrashingData();
                m_first = false;
            }
            string fullPath = null;
            bool   found    = false;


            // Look for modded textures
            if (!context.IsBaseGame)
            {
                fullPath = Path.Combine(Path.Combine(context.ModPathData, "PlanetDataFiles"), folderName, faceName);
                if (MyFileSystem.FileExists(fullPath + ".png"))
                {
                    found     = true;
                    fullPath += ".png";
                }
                else if (MyFileSystem.FileExists(fullPath + ".dds"))
                {
                    found     = true;
                    fullPath += ".dds";
                }
            }

            // Use default ones
            if (!found)
            {
                fullPath = Path.Combine(m_planetDataFolder, folderName, faceName);
                if (MyFileSystem.FileExists(fullPath + ".png"))
                {
                    found     = true;
                    fullPath += ".png";
                }
                else if (MyFileSystem.FileExists(fullPath + ".dds"))
                {
                    fullPath += ".dds";
                }
            }

            MyHeightmapFace value;

            if (m_heightMaps.TryGetValue(fullPath, out value))
            {
                ProfilerShort.End();
                return(value);
            }
            try
            {
                using (SharpDXImage image = LoadTexture(fullPath))
                {
                    if (image == null)
                    {
                        MyLog.Default.WriteLine("Could not load texture {0}, no suitable format found. " + fullPath);
                    }
                    else
                    {
                        PixelBuffer buffer = image.GetPixelBuffer(0, 0, 0);

                        value = new MyHeightmapFace(buffer.Height);

                        if (buffer.Format == Format.R16_UNorm)
                        {
                            PrepareHeightMap(value, buffer);
                        }
                        else if (buffer.Format == Format.R8_UNorm)
                        {
                            PrepareHeightMap8Bit(value, buffer);
                        }
                        else
                        {
                            MyDebug.FailRelease(String.Format("Heighmap texture {0}: Invalid format {1} (expecting R16_UNorm or R8_UNorm).", fullPath, buffer.Format));
                        }
                        buffer = null;
                    }
                }
                m_heightMaps[fullPath] = value;
            }
            catch (Exception e)
            {
                MyLog.Default.WriteLine(e.Message);
            }
            ProfilerShort.End();

            return(value);
        }
示例#8
0
        void ProcessTags()
        {
            // TODO: This code could be better.

            // Get the list of existing tags, if there are any
            var existingTags = GetTags();
            var length       = m_tags.Length;

            // Order or tag processing matters
            // 1) Copy mod type into tags
            var modtype = m_type.ToString();

            // 2) Verify the modtype matches what was listed in the workshop
            // TODO If type doesn't match, process as workshop type
            if (existingTags != null && existingTags.Length > 0)
            {
                MyDebug.AssertDebug(existingTags.Contains(modtype), string.Format("Mod type '{0}' does not match workshop '{1}'", modtype, existingTags[0]));
            }

            // 3a) check if user passed in the 'development' tag
            // If so, remove it, and mark the mod as 'dev' so it doesn't get flagged later
            if (m_tags.Contains(MySteamWorkshop.WORKSHOP_DEVELOPMENT_TAG))
            {
                m_tags  = (from tag in m_tags where tag != MySteamWorkshop.WORKSHOP_DEVELOPMENT_TAG select tag).ToArray();
                m_isDev = true;
            }

            // 3b If tags contain mod type, remove it
            if (m_tags.Contains(modtype))
            {
                m_tags = (from tag in m_tags where tag != modtype select tag).ToArray();
            }

            // 4)
            if (m_tags.Length == 1 && m_tags[0] == null && existingTags != null && existingTags.Length > 0)
            {
                // 4a) If user passed no tags, use existing ones
                Array.Resize(ref m_tags, existingTags.Length);
                Array.Copy(existingTags, m_tags, existingTags.Length);
            }
            else
            {
                // 4b) Verify passed in tags are valid for this mod type
                MySteamWorkshop.Category[] validTags = new MySteamWorkshop.Category[0];
                switch (m_type)
                {
                case WorkshopType.Mod:
                    validTags = MySteamWorkshop.ModCategories;
                    break;

                case WorkshopType.Blueprint:
                    validTags = MySteamWorkshop.BlueprintCategories;
                    break;

                case WorkshopType.Scenario:
                    validTags = MySteamWorkshop.ScenarioCategories;
                    break;

                case WorkshopType.World:
                    validTags = MySteamWorkshop.WorldCategories;
                    break;

                case WorkshopType.IngameScript:
                    //tags = new MySteamWorkshop.Category[0];     // There are none currently
                    break;

                default:
                    MyDebug.FailRelease("Invalid category.");
                    break;
                }

                // This query gets all the items in 'm_tags' that do *not* exist in 'validTags'
                // This is for detecting invalid tags passed in
                var invalidItems = from utag in m_tags
                                   where !(
                    from tag in validTags
                    select tag.Id
                    ).Contains(utag)
                                   select utag;

                if (invalidItems.Count() > 0)
                {
                    MySandboxGame.Log.WriteLineAndConsole(string.Format("{0} invalid tags: {1}", (m_force ? "Forced" : "Removing"), string.Join(", ", invalidItems)));

                    if (!m_force)
                    {
                        m_tags = (from tag in m_tags where !invalidItems.Contains(tag) select tag).ToArray();
                    }
                }

                // Now prepend the 'Type' tag
                string[] newTags = new string[m_tags.Length + 1];
                newTags[0] = m_type.ToString();
                Array.Copy(m_tags, 0, newTags, 1, m_tags.Length);
                m_tags = newTags;
            }

            // 5) Set or clear development tag
            if (m_isDev)
            {
                // If user selected dev, add dev tag
                if (!m_tags.Contains(MySteamWorkshop.WORKSHOP_DEVELOPMENT_TAG))
                {
                    Array.Resize(ref m_tags, m_tags.Length + 1);
                    m_tags[m_tags.Length - 1] = MySteamWorkshop.WORKSHOP_DEVELOPMENT_TAG;
                }
            }
            else
            {
                // If not, remove tag
                if (m_tags.Contains(MySteamWorkshop.WORKSHOP_DEVELOPMENT_TAG))
                {
                    m_tags = (from tag in m_tags where tag != MySteamWorkshop.WORKSHOP_DEVELOPMENT_TAG select tag).ToArray();
                }
            }

            // 6) Strip empty values
            m_tags = m_tags.Where(x => !string.IsNullOrEmpty(x)).ToArray();

            // Done
            MySandboxGame.Log.WriteLineAndConsole(string.Format("Publishing with tags: {0}", string.Join(", ", m_tags)));
        }