/ContentSystem/Rendering/LevelData.cs
C# | 181 lines | 107 code | 14 blank | 60 comment | 11 complexity | 7fb610979467bd1c6dfd88b8ccb399bc MD5 | raw file
1using System; 2using System.Collections.Generic; 3using System.IO; 4using Delta.Utilities; 5using Delta.Utilities.Helpers; 6 7namespace Delta.ContentSystem.Rendering 8{ 9 /// <summary> 10 /// Level data for loading and saving levels, which are currently just 11 /// a bunch of meshes and the camera data. 12 /// </summary> 13 public class LevelData : Content, ISaveLoadBinary 14 { 15 #region Constants 16 /// <summary> 17 /// Version number for this MaterialData. If this goes above 1, we need 18 /// to support loading older versions as well. Saving is always going 19 /// to be the latest version (this one). 20 /// </summary> 21 private const int VersionNumber = 1; 22 #endregion 23 24 #region Get (Static) 25 /// <summary> 26 /// Get and load content based on the content name. This method makes sure 27 /// we do not load the same content twice (the constructor is protected). 28 /// </summary> 29 /// <param name="contentName">Content name we want to load, this is 30 /// passed onto the Content System, which will do the actual loading with 31 /// help of the Load method in this class.</param> 32 /// <returns>The loaded Content object, always unique for the same 33 /// name, this helps comparing data.</returns> 34 public static LevelData Get(string contentName) 35 { 36 return Get<LevelData>(contentName, ContentType.Level); 37 } 38 #endregion 39 40 #region optimizedMeshes (Public) 41 /// <summary> 42 /// List of optimized level meshes that have all geometry merged by 43 /// material usage. Stuff that does not fit into the index buffer range 44 /// (65535) will be split up into multiple meshes (rarely happens). 45 /// </summary> 46 public List<MeshData> optimizedMeshes = new List<MeshData>(); 47 #endregion 48 49 #region cameraData (Public) 50 /// <summary> 51 /// Quick hack for camera support for MWC demo 52 /// </summary> 53 public CameraData cameraData; 54 #endregion 55 56 #region Constructors 57 /// <summary> 58 /// Loads level data. Use the static Get method to call this. 59 /// </summary> 60 /// <param name="setLevelName">Set level name</param> 61 protected LevelData(string setLevelName) 62 : base(setLevelName, ContentType.Level) 63 { 64 } 65 #endregion 66 67 #region ISaveLoadBinary Members 68 /// <summary> 69 /// Load level data from a binary reader. 70 /// </summary> 71 /// <param name="reader">Reader to get the data from, underlying stream 72 /// must be in the correct position.</param> 73 public void Load(BinaryReader reader) 74 { 75 // We currently only support our version, if more versions are added, 76 // we need to do different loading code depending on the version here. 77 int version = reader.ReadInt32(); 78 if (version != VersionNumber) 79 { 80 Log.InvalidVersionWarning(GetType().Name, version, VersionNumber); 81 return; 82 } 83 84 int numberOfMeshes = reader.ReadInt32(); 85 optimizedMeshes.Clear(); 86 for (int index = 0; index < numberOfMeshes; index++) 87 { 88 // Load meshes from just their unique names 89 string meshDataName = reader.ReadString(); 90 optimizedMeshes.Add(MeshData.Get(meshDataName)); 91 } 92 93 bool hasCamera = reader.ReadBoolean(); 94 if (hasCamera) 95 { 96 cameraData = CameraData.Get(reader.ReadString()); 97 } 98 } 99 100 /// <summary> 101 /// Save level data into a stream. 102 /// </summary> 103 /// <param name="writer">Binary stream writer to save data into.</param> 104 public void Save(BinaryWriter writer) 105 { 106 writer.Write(VersionNumber); 107 writer.Write(optimizedMeshes.Count); 108 foreach (MeshData mesh in optimizedMeshes) 109 { 110 // Save just the "clean" mesh data name without "<" and ">" 111 string meshName = mesh.Name; 112 if (meshName.StartsWith("<")) 113 { 114 meshName = meshName.Substring(1); 115 } 116 if (meshName.StartsWith(">")) 117 { 118 meshName = meshName.Substring(0, meshName.Length - 1); 119 } 120 writer.Write(meshName); 121 } 122 123 // Save if we have a camera. 124 writer.Write(cameraData != null); 125 if (cameraData != null) 126 { 127 writer.Write(cameraData.Name); 128 } 129 } 130 #endregion 131 132 #region Dispose (Public) 133 /// <summary> 134 /// Dispose meshes data, which is called when the content system disposes 135 /// this class (or someone else wants to get rid of the memory). 136 /// </summary> 137 public override void Dispose() 138 { 139 // Dispose all meshes, they can all be automatically reload if their 140 // data is needed again. 141 foreach (MeshData mesh in optimizedMeshes) 142 { 143 mesh.Dispose(); 144 } 145 } 146 #endregion 147 148 #region Methods (Private) 149 150 #region Load 151 /// <summary> 152 /// Native load method, will just load the xml data. 153 /// </summary> 154 /// <param name="alreadyLoadedNativeData"> 155 /// The first instance that has already loaded the required content data 156 /// of this content class or just 'null' if there is none loaded yet (or 157 /// anymore). 158 /// </param> 159 protected override void Load(Content alreadyLoadedNativeData) 160 { 161 try 162 { 163 if (String.IsNullOrEmpty(RelativeFilePath) == false) 164 { 165 // Load via the ISaveLoadBinary interface methods below. 166 // Cloning should not really happen for levels anyway. 167 FileHelper.Load(RelativeFilePath, this); 168 } 169 } 170 catch (Exception ex) 171 { 172 Log.Warning("Failed to load level data from file '" + 173 RelativeFilePath + "': " + ex); 174 FailedToLoad = true; 175 } 176 } 177 #endregion 178 179 #endregion 180 } 181}