private void LoadSde(Stream stream)
        {
            ZipArchive zip = new ZipArchive(stream, ZipArchiveMode.Read);

            _descJson = JObject.Parse(EntryToString(zip.GetEntry(SDEConstants.DESCRIPTOR_FILENAME)));

            foreach (ZipArchiveEntry entry in zip.Entries)
            {
                if (SDEConstants.IsEmitterXmlName(entry.Name))
                {
                    string         emitterId = SDEConstants.GetEmitterId(entry.Name);
                    RawEmitterData rawData   = new RawEmitterData();
                    rawData.EmitterId     = emitterId;
                    rawData.EmitterString = EntryToString(entry);
                    // + parse snapshot
                    var snapshot = zip.GetEntry(SDEConstants.GetParticleSnapshotName(emitterId));
                    if (snapshot != null)
                    {
                        rawData.Snapshot = snapshot.Open();
                    }
                    _rawEmitterDatas.Add(rawData);
                }
            }
            // texture atlas
            var    atlasZipEntry  = zip.GetEntry(SDEConstants.ATLAS_XML_NAME);
            string atlasXmlString = EntryToString(atlasZipEntry);

            var     atlasImageEntry = zip.GetEntry(SDEConstants.ATLAS_IMAGE_NAME);
            Texture tex             = SimpleTextureLoader.LoadImageFromStream(atlasImageEntry.Open());

            _atlas = new TextureAtlas(atlasXmlString, tex);

            _projectLoaded = true;
        }
        public ProjectValueObject CreateProjectInstance()
        {
            if (!_projectLoaded)
            {
                throw new InvalidOperationException("No project is loaded, call LoadSim() first!");
            }
            float version = _descJson["version"].Value <float>();
            var   project = new ProjectValueObject(version);

            foreach (RawEmitterData rawData in _rawEmitterDatas)
            {
                Emitter emitter = _stardusSerializer.Deserialize(rawData.EmitterString);
                emitter.Name = rawData.EmitterId;
                EmitterValueObject emitterVo = new EmitterValueObject(emitter);
                project.Emitters.Add(emitterVo);
                if (rawData.Snapshot != null)
                {
                    var snapshots = ParticleSnapshots.Parser.ParseFrom(rawData.Snapshot);
                    emitterVo.EmitterSnapshot = snapshots.Particles;
                    emitterVo.AddParticlesFromSnapshot();
                }
                var textures    = _atlas.GetTextures(SDEConstants.GetSubtexturePrefix(emitterVo.Id));
                var subTextures = textures.Cast <SubTexture>().ToList();
                ((StarlingHandler)(emitterVo.Emitter.ParticleHandler)).Textures = subTextures;
            }

            foreach (var emitterVo in project.Emitters)
            {
                foreach (var action in emitterVo.Emitter.Actions)
                {
                    Spawn spawn = action as Spawn;
                    if (spawn?.SpawnerEmitterId != null)
                    {
                        foreach (var emitterValueObject in project.Emitters)
                        {
                            if (spawn.SpawnerEmitterId == emitterValueObject.Id)
                            {
                                spawn.SpawnerEmitter = emitterValueObject.Emitter;
                            }
                        }
                    }
                }
            }
            return(project);
        }
        private static void ValidateSde(Stream stream)
        {
            if (stream == null)
            {
                throw new NullReferenceException("stream cannot be null");
            }
            ZipArchive zip  = new ZipArchive(stream, ZipArchiveMode.Read);
            var        desc = zip.GetEntry(SDEConstants.DESCRIPTOR_FILENAME);

            if (desc == null)
            {
                throw new Exception(SDEConstants.DESCRIPTOR_FILENAME + " not found");
            }
            var descJson = JObject.Parse(EntryToString(desc));

            if (descJson["version"].Value <float>() < StardustInfo.Version)
            {
                Debug.WriteLine("Stardust Sim Loader: WARNING loaded simulation is created with an old " +
                                "version of the editor, it might not run.");
            }

            if (zip.GetEntry(SDEConstants.ATLAS_IMAGE_NAME) == null)
            {
                throw new Exception(SDEConstants.ATLAS_IMAGE_NAME + " not found");
            }
            if (zip.GetEntry(SDEConstants.ATLAS_XML_NAME) == null)
            {
                throw new Exception(SDEConstants.ATLAS_XML_NAME + " not found");
            }
            bool emitterXmlFound = false;

            foreach (var entry in zip.Entries)
            {
                if (SDEConstants.IsEmitterXmlName(entry.Name))
                {
                    emitterXmlFound = true;
                }
            }
            if (!emitterXmlFound)
            {
                throw new Exception("Emitter descriptor XML not found");
            }
        }