public void Reload(LevelSettings settings, IDialogHandler progressReporter = null) { if (string.IsNullOrEmpty(Path)) { Sounds = null; LoadException = new Exception("Path is empty."); return; } // Load the catalog try { var path = settings.MakeAbsolute(Path); if (File.Exists(path)) { WadSounds newSounds = WadSounds.ReadFromFile(path); Sounds = newSounds; LoadException = null; } else { LoadException = new Exception("File not found: " + path); } } catch (Exception exc) { logger.Warn(exc, "Unable to load catalog '" + Path + "'."); Sounds = null; LoadException = exc; } }
public LevelTexture(LevelSettings settings, string path, bool convert512PixelsToDoubleRows = false, bool replaceWithTransparency = true) { Convert512PixelsToDoubleRows = convert512PixelsToDoubleRows; ReplaceMagentaWithTransparency = replaceWithTransparency; SetPath(settings, path); BumpPath = ""; }
public void Reload(LevelSettings settings, IDialogHandler progressReporter = null) { if (string.IsNullOrEmpty(Path)) { Wad = null; LoadException = new Exception("Path is empty."); return; } // Load wad try { Wad2 newWad = Wad2.ImportFromFile( settings.MakeAbsolute(Path), false, progressReporter ?? new ProgressReporterSimple()); Wad = newWad; LoadException = null; } catch (Exception exc) { logger.Warn(exc, "Unable to load wad '" + Path + "'."); Wad = null; LoadException = exc; } }
public AutoStaticMeshMergeEntry(uint staticMesh, bool merge, bool interpretShadesAsEffect, bool tintAsAmbient, bool clearShades, LevelSettings parent) { this.meshId = staticMesh; this.parent = parent; this.Merge = merge; this.TintAsAmbient = tintAsAmbient; this.InterpretShadesAsEffect = interpretShadesAsEffect; this.ClearShades = clearShades; }
public void SetReplaceMagentaWithTransparency(LevelSettings settings, bool value) { if (ReplaceMagentaWithTransparency == value) { return; } ReplaceMagentaWithTransparency = value; Reload(settings); }
public void SetConvert512PixelsToDoubleRows(LevelSettings settings, bool value) { if (Convert512PixelsToDoubleRows == value) { return; } Convert512PixelsToDoubleRows = value; Reload(settings); }
public LevelSettings Clone() { LevelSettings result = (LevelSettings)MemberwiseClone(); result.Wads = Wads.ConvertAll(wad => wad.Clone()); result.WadSoundPaths = WadSoundPaths.ConvertAll(soundPath => soundPath.Clone()); result.SoundsCatalogs = SoundsCatalogs.ConvertAll(catalog => catalog.Clone()); result.Textures = Textures.ConvertAll(texture => (LevelTexture)texture.Clone()); result.AnimatedTextureSets = AnimatedTextureSets.ConvertAll(set => set.Clone()); result.ImportedGeometries = ImportedGeometries.ConvertAll(geometry => geometry.Clone()); result.AutoStaticMeshMerges = AutoStaticMeshMerges.ConvertAll(entry => entry.Clone()); return(result); }
public void Reload(LevelSettings settings) { LoadException = null; if (string.IsNullOrEmpty(Path)) { Image = UnloadedPlaceholder; return; } // Load image try { ImageC image = ImageC.FromFile(settings.MakeAbsolute(Path)); if (Convert512PixelsToDoubleRows && image.Width == 512) { ImageC newImage = ImageC.CreateNew(256, image.Height * 2); newImage.FileName = image.FileName; for (int oldY = 0; oldY < image.Height; oldY += 64) { newImage.CopyFrom(0, oldY * 2, image, 0, oldY, 256, 64); newImage.CopyFrom(0, oldY * 2 + 64, image, 256, oldY, 256, 64); } image = newImage; } if (ReplaceMagentaWithTransparency) { image.ReplaceColor(new ColorC(255, 0, 255, 255), new ColorC(0, 0, 0, 0)); } image.CalculatePalette(); Image = image; // Resize sound array ResizeFootStepSounds( (int)Math.Ceiling(Image.Width / FootStepSoundGranularity), (int)Math.Ceiling(Image.Height / FootStepSoundGranularity)); // Resize bump maps ResizeBumpMappingInfos( (int)Math.Ceiling(Image.Width / BumpMappingGranularity), (int)Math.Ceiling(Image.Height / BumpMappingGranularity)); } catch (Exception exc) { logger.Warn(exc, "Unable to load texture '" + Path + "'."); Image = UnloadedPlaceholder; LoadException = exc; } }
public void MergeFrom(Level otherLevel, bool unifyData, Action <LevelSettings> applyLevelSettings = null) { IReadOnlyList <ObjectInstance> oldObjects = Rooms.Where(room => room != null).SelectMany(room => room.AnyObjects).ToList(); IReadOnlyList <Room> otherRooms = otherLevel.Rooms.Where(room => room != null).ToList(); // Merge rooms for (int i = 0; i < otherRooms.Count; ++i) { try { AssignRoomToFree(otherRooms[i]); } catch { // If we fail, roll back the changes... while (i > 0) { DeleteRoomWithAlternate(otherRooms[--i]); } throw; } } // Merge dependencies like imported geometries, textures (and wads in the future?) LevelSettings newSettings = applyLevelSettings == null ? Settings : Settings.Clone(); newSettings.Textures = Settings.Textures.ToList(); // Make sure the same references are used. newSettings.ImportedGeometries = Settings.ImportedGeometries.ToList(); var copyInstance = new Room.CopyDependentLevelSettingsArgs(oldObjects, newSettings, otherLevel.Settings, unifyData); foreach (Room room in otherRooms) { room.CopyDependentLevelSettings(copyInstance); } applyLevelSettings?.Invoke(newSettings); GlobalScriptingIdsTable.MergeFrom(otherLevel.GlobalScriptingIdsTable, @object => @object.ScriptId = null); foreach (Room room in otherRooms) { room.Level = this; } }
public ReferencedSoundsCatalog(LevelSettings settings, string path, IDialogHandler progressReporter = null) { Path = path; Reload(settings, progressReporter); }
public ImportedGeometryComparer(LevelSettings settings) { _settings = settings; }
public void SetPath(LevelSettings settings, string path) { Path = path; Reload(settings); }
public void Update(LevelSettings settings, Dictionary <string, Texture> absolutePathTextureLookup, ImportedGeometryInfo info) { Info = info; LoadException = null; DirectXModel = null; Textures.Clear(); try { string importedGeometryPath = settings.MakeAbsolute(info.Path); string importedGeometryDirectory = Path.GetDirectoryName(importedGeometryPath); // Invoke the TombLib geometry import code var settingsIO = new IOGeometrySettings { Scale = info.Scale, SwapXY = info.SwapXY, SwapXZ = info.SwapXZ, SwapYZ = info.SwapYZ, FlipX = info.FlipX, FlipY = info.FlipY, FlipZ = info.FlipZ, FlipUV_V = info.FlipUV_V, InvertFaces = info.InvertFaces, UseVertexColor = true }; BaseGeometryImporter importer = BaseGeometryImporter.CreateForFile(importedGeometryPath, settingsIO, absoluteTexturePath => { return(GetOrAddTexture(absolutePathTextureLookup, importedGeometryDirectory, absoluteTexturePath)); }); var tmpModel = importer.ImportFromFile(importedGeometryPath); SynchronizationContext.Current.Post(unused => // Synchronize DirectX, we can't 'send' because that may deadlock with the level settings reloader { if (Device == null) { return; } // Create a new static model DirectXModel = new Model(Device, info.Scale); DirectXModel.BoundingBox = tmpModel.BoundingBox; // Create materials foreach (var tmpMaterial in tmpModel.Materials) { var material = new Material(tmpMaterial.Name); material.Texture = tmpMaterial.Texture; material.AdditiveBlending = tmpMaterial.AdditiveBlending; material.DoubleSided = tmpMaterial.DoubleSided; DirectXModel.Materials.Add(material); } // Loop for each mesh loaded in scene foreach (var mesh in tmpModel.Meshes) { var modelMesh = new ImportedGeometryMesh(Device, mesh.Name); modelMesh.HasVertexColors = (mesh.Colors.Count != 0); var currentIndex = 0; var currPoly = 0; foreach (var tmpSubmesh in mesh.Submeshes) { var material = DirectXModel.Materials[tmpModel.Materials.IndexOf(tmpSubmesh.Value.Material)]; var submesh = new Submesh(material); foreach (var tmpPoly in tmpSubmesh.Value.Polygons) { if (tmpPoly.Shape == IOPolygonShape.Quad) { var vertexList = new List <ImportedGeometryVertex>(); for (var i = 0; i < 4; i++) { var vertex = new ImportedGeometryVertex(); vertex.Position = mesh.Positions[tmpPoly.Indices[i]]; vertex.Color = tmpPoly.Indices[i] < mesh.Colors.Count ? mesh.Colors[tmpPoly.Indices[i]].To3() : Vector3.One; vertex.UV = tmpPoly.Indices[i] < mesh.UV.Count ? mesh.UV[tmpPoly.Indices[i]] : Vector2.Zero; vertex.Normal = tmpPoly.Indices[i] < mesh.Normals.Count ? mesh.Normals[tmpPoly.Indices[i]] : Vector3.Zero; vertexList.Add(vertex); } // HACK: Triangulate and disjoint quad faces for imported geometry, because otherwise another hack which joints // disjointed vertices together will fail in Rooms.cs submesh.Indices.Add(currentIndex); submesh.Indices.Add(currentIndex + 1); submesh.Indices.Add(currentIndex + 2); submesh.Indices.Add(currentIndex + 3); submesh.Indices.Add(currentIndex + 4); submesh.Indices.Add(currentIndex + 5); modelMesh.Vertices.Add(vertexList[0]); modelMesh.Vertices.Add(vertexList[1]); modelMesh.Vertices.Add(vertexList[2]); modelMesh.Vertices.Add(vertexList[0]); modelMesh.Vertices.Add(vertexList[2]); modelMesh.Vertices.Add(vertexList[3]); currentIndex += 6; } else { for (var i = 0; i < 3; i++) { var vertex = new ImportedGeometryVertex(); vertex.Position = mesh.Positions[tmpPoly.Indices[i]]; vertex.Color = tmpPoly.Indices[i] < mesh.Colors.Count ? mesh.Colors[tmpPoly.Indices[i]].To3() : Vector3.One; vertex.UV = tmpPoly.Indices[i] < mesh.UV.Count ? mesh.UV[tmpPoly.Indices[i]] : Vector2.Zero; vertex.Normal = tmpPoly.Indices[i] < mesh.Normals.Count ? mesh.Normals[tmpPoly.Indices[i]] : Vector3.Zero; modelMesh.Vertices.Add(vertex); submesh.Indices.Add(currentIndex); currentIndex++; } } currPoly++; } modelMesh.Submeshes.Add(material, submesh); } DirectXModel.Meshes.Add(modelMesh); } DirectXModel.UpdateBuffers(); }, null); } catch (OperationCanceledException) { throw; } catch (Exception exc) { LoadException = exc; DirectXModel = null; logger.Warn(exc, "Unable to load model \"" + info.Name + "\" from \"" + info.Path + "\" because an exception occurred during loading."); } }
public ItemType(WadMoveableId moveableId, LevelSettings levelSettings) // wad can be null : this(moveableId, levelSettings?.GameVersion ?? TRVersion.Game.TR4) { }
public ItemType(WadStaticId staticId, LevelSettings levelSettings) // wad can be null : this(staticId, levelSettings?.GameVersion ?? TRVersion.Game.TR4) { }
public void ApplyNewLevelSettings(LevelSettings newSettings) => ApplyNewLevelSettings(newSettings, s => { });
public void ApplyNewLevelSettings(LevelSettings newSettings, Action <ObjectInstance> objectChangedNotification) { LevelSettings oldSettings = Settings; Settings = newSettings; // Imported geometry { // Reuse old imported geometry objects to keep references up to date var oldLookup = new Dictionary <ImportedGeometry.UniqueIDType, ImportedGeometry>(); foreach (ImportedGeometry oldImportedGeometry in oldSettings.ImportedGeometries) { oldLookup.Add(oldImportedGeometry.UniqueID, oldImportedGeometry); } for (int i = 0; i < newSettings.ImportedGeometries.Count; ++i) { ImportedGeometry newImportedGeometry = newSettings.ImportedGeometries[i]; ImportedGeometry oldImportedGeometry; if (oldLookup.TryGetValue(newImportedGeometry.UniqueID, out oldImportedGeometry)) { oldImportedGeometry.Assign(newImportedGeometry); newSettings.ImportedGeometries[i] = oldImportedGeometry; oldLookup.Remove(oldImportedGeometry.UniqueID); // The same object shouldn't be matched multiple times. } } // Reset imported geometry objects if any objects are now missing if (oldLookup.Count != 0) { foreach (Room room in Rooms.Where(room => room != null)) { foreach (var instance in room.Objects.OfType <ImportedGeometryInstance>()) { if (instance.Model != null && oldLookup.ContainsKey(instance.Model.UniqueID)) { instance.Model = null; objectChangedNotification(instance); } } } } } // Level texture { // Reuse old level texture objects to keep references up to date var oldLookup = new Dictionary <LevelTexture.UniqueIDType, LevelTexture>(); foreach (LevelTexture oldLevelTexture in oldSettings.Textures) { oldLookup.Add(oldLevelTexture.UniqueID, oldLevelTexture); } for (int i = 0; i < newSettings.Textures.Count; ++i) { LevelTexture newLevelTexture = newSettings.Textures[i]; LevelTexture oldLevelTexture; if (oldLookup.TryGetValue(newLevelTexture.UniqueID, out oldLevelTexture)) { oldLevelTexture.Assign(newLevelTexture); newSettings.Textures[i] = oldLevelTexture; oldLookup.Remove(oldLevelTexture.UniqueID); // The same object shouldn't be matched multiple times. } } // Reset level texture objects if any objects are now missing if (oldLookup.Count != 0) { RemoveTextures(texture => oldLookup.ContainsKey(texture.UniqueID)); } } }