public WadToolUndoManager(WadToolClass tool, int undoDepth) : base(undoDepth) { Tool = tool; UndoStackChanged += (s, e) => Tool.UndoStackChanged(); MessageSent += (s, e) => Tool.SendMessage(e.Message, TombLib.Forms.PopupType.Warning); }
public FormMain(WadToolClass tool) { InitializeComponent(); Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath); // Only how debug menu when a debugger is attached... debugToolStripMenuItem.Visible = Debugger.IsAttached; _tool = tool; panel3D.Configuration = tool.Configuration; panel3D.InitializeRendering(DeviceManager.DefaultDeviceManager.Device, tool.Configuration.RenderingItem_Antialias); tool.EditorEventRaised += Tool_EditorEventRaised; Tool_EditorEventRaised(new InitEvent()); // Load window size Configuration.LoadWindowProperties(this, _tool.Configuration); // Try to load reference project on start-up, if specified in config if (!string.IsNullOrEmpty(tool.Configuration.Tool_ReferenceProject) && File.Exists(tool.Configuration.Tool_ReferenceProject)) { WadActions.LoadReferenceLevel(tool, this, tool.Configuration.Tool_ReferenceProject); } }
public static bool LoadReferenceLevel(WadToolClass tool, IWin32Window owner, string path = null) { if (string.IsNullOrEmpty(path)) { path = LevelFileDialog.BrowseFile(owner, null, null, "Open Tomb Editor reference level", LevelSettings.FileFormatsLevel, null, false); } if (string.IsNullOrEmpty(path)) { return(false); } tool.ReferenceLevel = Prj2Loader.LoadFromPrj2(path, null, new Prj2Loader.Settings { IgnoreTextures = true, IgnoreWads = true }); if (tool.ReferenceLevel != null) { tool.Configuration.Tool_ReferenceProject = path; return(true); } else { return(false); } }
public FormStaticEditor(WadToolClass tool, DeviceManager deviceManager, Wad2 wad, WadStatic @static) { _doChangesInLighting = false; InitializeComponent(); _wad = wad; _tool = tool; _device = deviceManager.___LegacyDevice; Static = @static; _workingStatic = @static.Clone(); panelRendering.InitializeRendering(tool, deviceManager); panelRendering.Configuration = _tool.Configuration; panelRendering.Static = _workingStatic; panelRendering.DrawGrid = true; panelRendering.DrawGizmo = true; panelRendering.DrawLights = true; comboLightType.SelectedIndex = (int)_workingStatic.LightingType; UpdateVisibilityBoxUI(); UpdateCollisionBoxUI(); UpdatePositionUI(); UpdateLightsList(); UpdateLightUI(); numAmbient.Value = (decimal)_workingStatic.AmbientLight; _tool.EditorEventRaised += Tool_EditorEventRaised; _doChangesInLighting = true; }
public GizmoSkeletonEditor(WadToolClass tool, Configuration configuration, GraphicsDevice device, Effect effect, PanelRenderingSkeleton control) : base(device, effect) { _configuration = configuration; _control = control; _tool = tool; }
public FormOptions(WadToolClass tool) : base(tool.Configuration) { InitializeComponent(); InitializeDialog(); this.SetActualSize(630, 458); this.LockWidth(); _tool = tool; _tool.EditorEventRaised += EditorEventRaised; ReadConfigIntoControls(this); }
public static void ImportModelAsStaticMesh(WadToolClass tool, IWin32Window owner) { if (tool.DestinationWad == null) { tool.SendMessage("You must have a wad opened", PopupType.Error); return; } using (FileDialog dialog = new OpenFileDialog()) { try { dialog.InitialDirectory = Path.GetDirectoryName(tool.DestinationWad.FileName); dialog.FileName = Path.GetFileName(tool.DestinationWad.FileName); } catch { // ignored } dialog.Filter = BaseGeometryImporter.FileExtensions.GetFilter(); dialog.Title = "Select a 3D file that you want to see imported."; if (dialog.ShowDialog(owner) != DialogResult.OK) { return; } using (var form = new GeometryIOSettingsDialog(new IOGeometrySettings())) { form.AddPreset(IOSettingsPresets.GeometryImportSettingsPresets); if (form.ShowDialog(owner) != DialogResult.OK) { return; } var @static = new WadStatic(tool.DestinationWad.GetFirstFreeStaticMesh()); var mesh = WadMesh.ImportFromExternalModel(dialog.FileName, form.Settings); if (mesh == null) { tool.SendMessage("Error while loading the 3D model. Please check that the file " + "is one of the supported formats and that the meshes are textured", PopupType.Error); return; } @static.Mesh = mesh; @static.VisibilityBox = @static.Mesh.BoundingBox; @static.CollisionBox = @static.Mesh.BoundingBox; tool.DestinationWad.Statics.Add(@static.Id, @static); tool.WadChanged(WadArea.Destination); } } }
public static void CreateNewWad(WadToolClass tool, IWin32Window owner) { using (var form = new FormNewWad2()) { if (form.ShowDialog(owner) == DialogResult.Cancel) { return; } tool.DestinationWad = new Wad2 { GameVersion = form.Version, SoundSystem = SoundSystem.Xml }; tool.ToggleUnsavedChanges(false); } }
public FormSkeletonEditor(WadToolClass tool, DeviceManager manager, Wad2 wad, WadMoveableId moveableId) { InitializeComponent(); _wad = wad; _moveable = _wad.Moveables[moveableId].Clone(); _tool = tool; panelRendering.Configuration = _tool.Configuration; panelRendering.InitializeRendering(tool, manager); _tool.EditorEventRaised += Tool_EditorEventRaised; WadMoveable skin; var skinId = new WadMoveableId(TrCatalog.GetMoveableSkin(_tool.DestinationWad.GameVersion, _moveable.Id.TypeId)); if (_tool.DestinationWad.Moveables.ContainsKey(skinId)) { skin = _tool.DestinationWad.Moveables[skinId]; } else { skin = _tool.DestinationWad.Moveables[_moveable.Id]; } // Clone the skeleton and load it _bones = new List <WadMeshBoneNode>(); for (int i = 0; i < _moveable.Bones.Count; i++) { var boneNode = new WadMeshBoneNode(null, skin.Bones[i].Mesh, _moveable.Bones[i]); boneNode.Bone.Translation = _moveable.Bones[i].Translation; boneNode.GlobalTransform = Matrix4x4.Identity; _bones.Add(boneNode); } treeSkeleton.Nodes.AddRange(LoadSkeleton()); ExpandSkeleton(); panelRendering.Skeleton = _bones; if (treeSkeleton.SelectedNodes.Count <= 0) { treeSkeleton.SelectNode(treeSkeleton.Nodes[0]); panelRendering.SelectedNode = (WadMeshBoneNode)treeSkeleton.SelectedNodes[0].Tag; } panelRendering.Invalidate(); }
public static void EditObject(WadToolClass tool, IWin32Window owner, DeviceManager deviceManager) { Wad2 wad = tool.GetWad(tool.MainSelection?.WadArea); IWadObject wadObject = wad?.TryGet(tool.MainSelection?.Id); if (wadObject == null || tool.MainSelection?.WadArea == WadArea.Source) { return; } if (wad == null) { tool.SendMessage("You must have a wad loaded and an object selected.", PopupType.Error); return; } // Choose behaviour if (wadObject is WadStatic) { using (var form = new FormStaticEditor(tool, deviceManager, wad, (WadStatic)wadObject)) if (form.ShowDialog(owner) != DialogResult.OK) { return; } tool.WadChanged(tool.MainSelection.Value.WadArea); } else if (wadObject is WadMoveable) { using (var form = new FormAnimationEditor(tool, deviceManager, wad, ((WadMoveable)wadObject).Id)) { if (form.ShowDialog(owner) != DialogResult.OK) { return; } tool.WadChanged(tool.MainSelection.Value.WadArea); } } else if (wadObject is WadSpriteSequence) { using (var form = new FormSpriteSequenceEditor(tool, wad, (WadSpriteSequence)wadObject)) if (form.ShowDialog(owner) != DialogResult.OK) { return; } tool.WadChanged(tool.MainSelection.Value.WadArea); } }
public AnimationEditor(WadToolClass tool, Wad2 wad, WadMoveableId idToEdit) { Tool = tool; Wad = wad; Moveable = Wad.Moveables.ContainsKey(idToEdit) ? Wad.Moveables[idToEdit] : null; // NOTE: we work with a pair WadAnimation - Animation. All changes to animation data like name, // framerate, next animation, state changes... will be saved directly to WadAnimation. // All changes to keyframes will be instead stored directly in the renderer's Animation class. // While saving, WadAnimation and Animation will be combined and original animations will be overwritten. Animations = new List <AnimationNode>(); for (int i = 0; i < Moveable.Animations.Count; i++) { var animation = Moveable.Animations[i].Clone();; Animations.Add(new AnimationNode(animation, Animation.FromWad2(Moveable.Bones, animation), i)); } }
public static void EditSkeletion(WadToolClass tool, IWin32Window owner) { if (tool.MainSelection?.WadArea == WadArea.Source) { return; } var wad = tool.GetWad(tool.MainSelection.Value.WadArea); var moveableId = (WadMoveableId)tool.MainSelection.Value.Id; using (var form = new FormSkeletonEditor(tool, DeviceManager.DefaultDeviceManager, wad, moveableId)) { if (form.ShowDialog(owner) != DialogResult.OK) { return; } tool.WadChanged(WadArea.Destination); } }
public static IWadObjectId CreateObject(WadToolClass tool, IWin32Window owner, IWadObject initialWadObject) { Wad2 destinationWad = tool.DestinationWad; if (destinationWad == null) { tool.SendMessage("You must have a destination wad opened.", PopupType.Error); return(null); } IWadObjectId result; using (var form = new FormSelectSlot(tool.DestinationWad, initialWadObject.Id)) { if (form.ShowDialog(owner) != DialogResult.OK) { return(null); } if (destinationWad.Contains(form.NewId)) { tool.SendMessage("The slot " + form.NewId.ToString(destinationWad.GameVersion) + " is already occupied.", PopupType.Error); return(null); } if (initialWadObject is WadMoveable) { var moveable = initialWadObject as WadMoveable; var bone = new WadBone(); bone.Name = "Root"; bone.Mesh = CreateFakeMesh("Root"); moveable.Bones.Add(bone); } destinationWad.Add(form.NewId, initialWadObject); result = form.NewId; } tool.WadChanged(WadArea.Destination); tool.ToggleUnsavedChanges(); return(result); }
public static void DeleteObjects(WadToolClass tool, IWin32Window owner, WadArea wadArea, List <IWadObjectId> ObjectIdsToDelete) { if (ObjectIdsToDelete.Count == 0) { return; } if (DarkMessageBox.Show(owner, "You are about to delete " + ObjectIdsToDelete.Count + " objects. Are you sure?", "A question just in case...", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) { return; } Wad2 wad = tool.GetWad(wadArea); foreach (IWadObjectId id in ObjectIdsToDelete) { wad.Remove(id); } tool.WadChanged(wadArea); }
public static WadAnimation ImportAnimationFromXml(WadToolClass tool, string fileName) { try { // Read animation from XML XmlSerializer deserializer = new XmlSerializer(typeof(WadAnimation)); TextReader reader = new StreamReader(fileName); object obj = deserializer.Deserialize(reader); WadAnimation animation = (WadAnimation)obj; reader.Close(); return(animation); } catch (Exception exc) { tool.SendMessage("Unknown error while importing animation! Possible reason: not valid XML format.", PopupType.Error); logger.Warn(exc, "'ImportAnimationFromXml' failed."); return(null); } }
public FormMesh(WadToolClass tool, DeviceManager deviceManager, Wad2 wad) { InitializeComponent(); _tool = tool; _wad = wad; _deviceManager = deviceManager; panelMesh.InitializeRendering(_tool, _deviceManager); var moveablesNode = new DarkUI.Controls.DarkTreeNode("Moveables"); foreach (var moveable in _wad.Moveables) { var list = new List <DarkUI.Controls.DarkTreeNode>(); var moveableNode = new DarkUI.Controls.DarkTreeNode(moveable.Key.ToString(_wad.GameVersion)); for (int i = 0; i < moveable.Value.Meshes.Count(); i++) { var wadMesh = moveable.Value.Meshes.ElementAt(i); var node = new DarkUI.Controls.DarkTreeNode(wadMesh.Name); node.Tag = new MeshTreeNode(moveable.Key, wadMesh); list.Add(node); } moveableNode.Nodes.AddRange(list); moveablesNode.Nodes.Add(moveableNode); } lstMeshes.Nodes.Add(moveablesNode); var staticsNode = new DarkUI.Controls.DarkTreeNode("Statics"); foreach (var @static in _wad.Statics) { var staticNode = new DarkUI.Controls.DarkTreeNode(@static.Key.ToString(_wad.GameVersion)); var wadMesh = @static.Value.Mesh; var node = new DarkUI.Controls.DarkTreeNode(wadMesh.Name); node.Tag = new MeshTreeNode(@static.Key, wadMesh); staticNode.Nodes.Add(node); staticsNode.Nodes.Add(staticNode); } lstMeshes.Nodes.Add(staticsNode); }
public static void LoadWadOpenFileDialog(WadToolClass tool, IWin32Window owner, bool destination) { // Open the file dialog using (var dialog = new OpenFileDialog()) { string previousFilePath; if (destination) { previousFilePath = tool.DestinationWad?.FileName; } else { previousFilePath = tool.SourceWad?.FileName; } if (!string.IsNullOrWhiteSpace(previousFilePath)) { try { dialog.InitialDirectory = Path.GetDirectoryName(previousFilePath); dialog.FileName = Path.GetFileName(previousFilePath); } catch { // ignored } } dialog.Filter = Wad2.WadFormatExtensions.GetFilter(); dialog.Title = "Open " + (destination ? "destination" : "source") + " WAD - Wad2 - Level"; if (dialog.ShowDialog(owner) != DialogResult.OK) { return; } LoadWad(tool, owner, destination, dialog.FileName); } }
public static IWadObjectId ChangeSlot(WadToolClass tool, IWin32Window owner) { if (tool.MainSelection?.WadArea == WadArea.Source) { return(null); } Wad2 wad = tool.GetWad(tool.MainSelection?.WadArea); IWadObject wadObject = wad?.TryGet(tool.MainSelection?.Id); if (wad == null || wadObject == null) { tool.SendMessage("You must have an object selected", PopupType.Error); return(null); } // Ask for the new slot using (var form = new FormSelectSlot(tool.DestinationWad, wadObject.Id)) { if (form.ShowDialog(owner) != DialogResult.OK) { return(null); } if (form.NewId == wadObject.Id) { return(null); } if (wad.Contains(form.NewId)) { tool.SendMessage("The slot " + form.NewId.ToString(wad.GameVersion) + " is already occupied.", PopupType.Error); return(null); } wad.AssignNewId(wadObject.Id, form.NewId); } tool.WadChanged(tool.MainSelection.Value.WadArea); return(wadObject.Id); }
public FormSpriteSequenceEditor(WadToolClass tool, Wad2 wad, WadSpriteSequence spriteSequence) { InitializeComponent(); SpriteSequence = spriteSequence; Wad = wad; _tool = tool; _currentPath = Wad.FileName; // Load data Text = "Sprite sequence '" + spriteSequence.Id.ToString(Wad.GameVersion) + "'"; dataGridView.DataSource = new BindingList <WadSprite>(new List <WadSprite>(spriteSequence.Sprites)); dataGridViewControls.CreateNewRow = newObject; dataGridViewControls.DataGridView = dataGridView; dataGridViewControls.Enabled = true; // Refresh initially if (dataGridView.Rows.Count > 0) { dataGridView.Rows[0].Selected = true; } SelectSprite(); }
public static void LoadWad(WadToolClass tool, IWin32Window owner, bool destination, string fileName) { bool isWad2 = Path.GetExtension(fileName).ToLower() == ".wad2"; // Load the WAD/Wad2 Wad2 newWad = null; try { newWad = Wad2.ImportFromFile(fileName, true, new GraphicalDialogHandler(owner), tool.Configuration.Tool_AllowTRNGDecryption); if (isWad2 && newWad.SoundSystem == SoundSystem.Dynamic) { if (DarkMessageBox.Show(owner, "This Wad2 is using the old dynamic sound system and needs to be converted " + "to the new Xml sound system. A backup copy will be created under the same directory. " + "Do you want to continue?", "Convert Wad2", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) { return; } File.Copy(fileName, fileName + ".bak", true); if (!FileFormatConversions.ConvertWad2ToNewSoundFormat(fileName, fileName)) { tool.SendMessage("Converting the file failed!", PopupType.Error); return; } if (newWad.HasUnknownData) { tool.SendMessage("Loaded wad2 is of newer version.\nSome data was lost. Don't save this wad2 and use newest version of Wad Tool.", PopupType.Warning); } newWad = Wad2.ImportFromFile(fileName, true, new GraphicalDialogHandler(owner), tool.Configuration.Tool_AllowTRNGDecryption); } } catch (OperationCanceledException) { return; } catch (Exception exc) { logger.Info(exc, "Unable to load " + (destination ? "destination" : "source") + " file from '" + fileName + "'."); tool.SendMessage("Loading the file failed! \n" + exc.Message, PopupType.Error); return; } // Set wad if (destination) { tool.DestinationWad = newWad; tool.ToggleUnsavedChanges(false); } else { if (!isWad2) { newWad.FileName = fileName; // Keep original path only for source old wad, as it's not saveable } tool.SourceWad = newWad; } }
public static void Main(string[] args) { // Load configuration var initialEvents = new List <LogEventInfo>(); var configuration = new Configuration().LoadOrUseDefault <Configuration>(initialEvents); // Update DarkUI configuration Colors.Brightness = configuration.UI_FormColor_Brightness / 100.0f; // Setup logging using (var log = new Logging(configuration.Log_MinLevel, configuration.Log_WriteToFile, configuration.Log_ArchiveN, initialEvents)) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); Application.ThreadException += (sender, e) => { log.HandleException(e.Exception); using (var dialog = new ThreadExceptionDialog(e.Exception)) if (dialog.ShowDialog() == DialogResult.Abort) { Environment.Exit(1); } }; // Show startup help if (configuration.StartUpHelp_Show) { var help = new FormStartupHelp(); Application.Run(help); switch (help.DialogResult) { case DialogResult.Cancel: return; case DialogResult.OK: configuration.StartUpHelp_Show = false; break; } } configuration.SaveTry(); // Run if (!File.Exists(Application.StartupPath + "\\Catalogs\\TrCatalog.xml")) { MessageBox.Show("TrCatalog.xml is missing.\nMake sure you have TrCatalog.xml in /Catalogs/ subfolder."); Environment.Exit(1); } TrCatalog.LoadCatalog(Application.StartupPath + "\\Catalogs\\TRCatalog.xml"); Application.AddMessageFilter(new ControlScrollFilter()); SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext()); using (WadToolClass tool = new WadToolClass(configuration)) { string startWad = null; string refLevel = null; if (args.Length > 0) { bool loadAsRefLevel = false; foreach (var arg in args) { if (arg.Equals("-r", StringComparison.InvariantCultureIgnoreCase)) { loadAsRefLevel = true; } else { if (!File.Exists(arg)) { continue; // No file and no valid argument, don't even try to load anything } if (loadAsRefLevel) { if (arg.EndsWith("prj2", StringComparison.InvariantCultureIgnoreCase)) { refLevel = arg; } } else { startWad = arg; } loadAsRefLevel = false; // Reset arg mode if no expected path was found next to it } } } using (FormMain form = new FormMain(tool)) { form.Show(); if (!string.IsNullOrEmpty(refLevel)) { WadActions.LoadReferenceLevel(tool, form, refLevel); } if (!string.IsNullOrEmpty(startWad)) { WadActions.LoadWad(tool, form, true, startWad); } Application.Run(form); } } } }
public static WadAnimation ImportAnimationFromModel(WadToolClass tool, IWin32Window owner, int nodeCount, string fileName) { IOModel tmpModel = null; // Import the model try { var settings = new IOGeometrySettings() { ProcessAnimations = true, ProcessGeometry = false }; using (var form = new GeometryIOSettingsDialog(settings)) { form.AddPreset(IOSettingsPresets.AnimationSettingsPresets); string resultingExtension = Path.GetExtension(fileName).ToLowerInvariant(); if (resultingExtension.Equals(".fbx")) { form.SelectPreset("3dsmax Filmbox (FBX)"); } else if (resultingExtension.Equals(".dae")) { form.SelectPreset("3dsmax COLLADA"); } if (form.ShowDialog(owner) != DialogResult.OK) { return(null); } var importer = BaseGeometryImporter.CreateForFile(fileName, settings, null); tmpModel = importer.ImportFromFile(fileName); // We don't support animation importing from custom-written mqo importer yet... if (importer is MetasequoiaImporter) { tool.SendMessage("Metasequoia importer isn't currently supported.", PopupType.Error); return(null); } // If no animations, return null if (tmpModel.Animations.Count == 0) { tool.SendMessage("Selected file has no supported animations!", PopupType.Error); return(null); } } } catch (Exception ex) { tool.SendMessage("Unknown error while importing animation. \n" + ex?.Message, PopupType.Error); logger.Warn(ex, "'ImportAnimationFromModel' failed."); return(null); } IOAnimation animToImport; if (tmpModel.Animations.Count > 1) { using (var dialog = new AnimationImportDialog(tmpModel.Animations.Select(o => o.Name).ToList())) { dialog.ShowDialog(owner); if (dialog.DialogResult == DialogResult.Cancel) { return(null); } else { animToImport = tmpModel.Animations[dialog.AnimationToImport]; } } } else { animToImport = tmpModel.Animations[0]; } // Integrity check, for cases when something totally went wrong with assimp if (animToImport == null) { tool.SendMessage("Animation importer encountered serious error. No animation imported.", PopupType.Error); return(null); } // Integrity check, is there any valid frames? if (animToImport.Frames.Count <= 0) { tool.SendMessage("Selected animation has no frames!", PopupType.Error); return(null); } // Integrity check, number of bones = number of nodes? if (animToImport.NumNodes != nodeCount) { tool.SendMessage("Selected animation has different number of bones!", PopupType.Error); return(null); } WadAnimation animation = new WadAnimation(); animation.Name = animToImport.Name; foreach (var frame in animToImport.Frames) { var keyFrame = new WadKeyFrame(); keyFrame.Offset = frame.Offset; frame.Angles.ForEach(angle => keyFrame.Angles.Add(new WadKeyFrameRotation() { Rotations = angle })); animation.KeyFrames.Add(keyFrame); } animation.EndFrame = (ushort)(animToImport.Frames.Count - 1); return(animation); }
public static void SaveWad(WadToolClass tool, IWin32Window owner, Wad2 wadToSave, bool ask) { if (wadToSave == null) { tool.SendMessage("You have no wad opened. Nothing to save.", PopupType.Warning); return; } // Figure out the output path string outPath = wadToSave.FileName; if (!string.IsNullOrWhiteSpace(wadToSave.FileName)) { try { outPath = Path.ChangeExtension(outPath, "wad2"); } catch { // ignored } } // Ask about it if (ask || string.IsNullOrWhiteSpace(outPath)) { using (var dialog = new SaveFileDialog()) { if (!string.IsNullOrWhiteSpace(outPath)) { dialog.InitialDirectory = Path.GetDirectoryName(outPath); dialog.FileName = Path.GetFileName(outPath); } dialog.Filter = Wad2Writer.FileFormats.GetFilter(); dialog.Title = "Save Wad2"; dialog.AddExtension = true; if (dialog.ShowDialog(owner) != DialogResult.OK) { return; } outPath = dialog.FileName; } } // Save the wad2 try { // XML_SOUND_SYSTEM Wad2Writer.SaveToFile(wadToSave, outPath); // Immediately reload new wad, if it wasn't saved before (new or imported) if (wadToSave.FileName == null) { LoadWad(tool, owner, true, outPath); } // Update last actual filename and call global event to update UI etc wadToSave.FileName = outPath; tool.ToggleUnsavedChanges(false); } catch (Exception exc) { logger.Warn(exc, "Unable to save to '" + outPath + "'"); tool.SendMessage("Unable to save to '" + outPath + "'. " + exc, PopupType.Error); } }
public static void UnloadReferenceLevel(WadToolClass tool) { tool.ReferenceLevel = null; tool.Configuration.Tool_ReferenceProject = string.Empty; }
public static void ExportMesh(WadToolClass tool, IWin32Window owner, WadMesh m) { // Step 1: collect all textures /*var texturePieces = new Dictionary<Hash, WadTexture>(); * for (int i = 0; i < m.Polys.Count; i++) * { * var poly = m.Polys[i]; * * // Create the new tile and compute hash * var textureQuad = poly.Texture.GetRect(poly.Shape == WadPolygonShape.Triangle); * var image = ImageC.CreateNew((int)textureQuad.Width, (int)textureQuad.Height); * image.CopyFrom(0, 0, poly.Texture.Texture.Image, (int)textureQuad.X0, (int)textureQuad.Y0, * (int)(textureQuad.X0 + textureQuad.X1), (int)(textureQuad.Y0 + textureQuad.Y1)); * WadTexture text = new WadTexture(image); * * // Store the hash for the next steps * poly.TextureHash = text.Hash; * * //Add uniquely the texture to the dictionary * if (!texturePieces.ContainsKey(text.Hash)) * texturePieces.Add(text.Hash, text); * } * * // Step 2: collect textures in 256x256 pages * int processedTextures = 0; * var lastTexture = ImageC.CreateNew(256, 256); * var packer = new RectPackerSimpleStack(new VectorInt2(256, 256)); * while (processedTextures < texturePieces.Count) * { * var texture = texturePieces.ElementAt(processedTextures).Value; * var result = packer.TryAdd(new VectorInt2(texture.Image.Width, texture.Image.Height)); * if (!result.HasValue) * { * * } * processedTextures++; * } * * var matOpaque = new IOMaterial(Material.Material_Opaque + "_" + j + "_" + i, * texture, * fileName, * i, * false, * false, * 0); * * var matOpaqueDoubleSided = new IOMaterial(Material.Material_OpaqueDoubleSided + "_" + j + "_" + i, * texture, * fileName, * i, * false, * true, * 0); * * var matAdditiveBlending = new IOMaterial(Material.Material_AdditiveBlending + "_" + j + "_" + i, * texture, * fileName, * i, * true, * false, * 0); * * var matAdditiveBlendingDoubleSided = new IOMaterial(Material.Material_AdditiveBlendingDoubleSided + "_" + j + "_" + i, * texture, * fileName, * i, * true, * true, * 0); * * var mesh = new IOMesh(m.Name); * * foreach (var poly in m.Polys) * { * * } * * m.Polys[0].Texture.*/ return; }
public static List <IWadObjectId> CopyObject(WadToolClass tool, IWin32Window owner, List <IWadObjectId> objectIdsToMove, bool alwaysChooseId) { Wad2 sourceWad = tool.SourceWad; Wad2 destinationWad = tool.DestinationWad; if (destinationWad == null || sourceWad == null || objectIdsToMove.Count == 0) { tool.SendMessage("You must have two wads loaded and at least one source object selected.", PopupType.Error); return(null); } var listInProgress = new List <uint>(); // Figure out the new ids if there are any id collisions IWadObjectId[] newIds = objectIdsToMove.ToArray(); // If destination is TR5Main, try to remap object IDs if (destinationWad.GameVersion == TRVersion.Game.TR5Main) { for (int i = 0; i < objectIdsToMove.Count; ++i) { var objectId = objectIdsToMove[i]; if (objectId is WadMoveableId) { var moveableId = (WadMoveableId)objectId; // Try to get a compatible slot var newSlot = TrCatalog.GetMoveableTR5MainSlot(sourceWad.GameVersion, moveableId.TypeId); if (newSlot == "") { continue; } // Get the new ID bool isMoveable; var newId = TrCatalog.GetItemIndex(destinationWad.GameVersion, newSlot, out isMoveable); if (!newId.HasValue) { continue; } // Save the new ID newIds[i] = new WadMoveableId(newId.Value); } } } for (int i = 0; i < objectIdsToMove.Count; ++i) { if (!sourceWad.Contains(objectIdsToMove[i])) { continue; } if (!alwaysChooseId) { if (!destinationWad.Contains(newIds[i])) { if (!newIds.Take(i).Contains(newIds[i])) // There also must not be collisions with the other custom assigned ids. { continue; } } } bool askConfirm = !alwaysChooseId; // Ask for the new slot do { DialogResult dialogResult; if (askConfirm) { dialogResult = DarkMessageBox.Show(owner, "The id " + newIds[i].ToString(destinationWad.GameVersion) + " is already occupied in the destination wad.\n" + "Do you want to replace it (Yes) or to select another Id (No)?", "Occupied slot", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); } else { dialogResult = DialogResult.No; } // From this time, always ask for confirm askConfirm = true; if (dialogResult == DialogResult.Cancel) { return(null); } else if (dialogResult == DialogResult.No) { using (var form = new FormSelectSlot(destinationWad, newIds[i], listInProgress)) { if (form.ShowDialog(owner) != DialogResult.OK) { return(null); } if (destinationWad.Contains(form.NewId) || newIds.Take(i).Contains(form.NewId)) { destinationWad.Remove(form.NewId); tool.WadChanged(WadArea.Destination); } newIds[i] = form.NewId; if (form.NewId is WadStaticId) { listInProgress.Add(((WadStaticId)form.NewId).TypeId); } if (form.NewId is WadMoveableId) { listInProgress.Add(((WadMoveableId)form.NewId).TypeId); } if (form.NewId is WadSpriteSequenceId) { listInProgress.Add(((WadSpriteSequenceId)form.NewId).TypeId); } break; } } else { destinationWad.Remove(objectIdsToMove[i]); tool.WadChanged(WadArea.Destination); break; } } while (destinationWad.Contains(newIds[i]) || newIds.Take(i).Contains(newIds[i])); // There also must not be collisions with the other custom assigned ids. } // HACK: Until this is fixed... https://github.com/MontyTRC89/Tomb-Editor/issues/413 // We just block copying of same object to another slot and warn user it's in another slot. var failedIdList = new List <IWadObjectId>(); // Move objects for (int i = 0; i < objectIdsToMove.Count; ++i) { IWadObject obj = sourceWad.TryGet(objectIdsToMove[i]); if (obj == null) { continue; } if (destinationWad.Contains(obj)) // Aforementioned HACK continues here - just add object which failed to copy to failed list { failedIdList.Add(newIds[i]); } else { destinationWad.Add(newIds[i], obj); if (destinationWad.GameVersion == TRVersion.Game.TR5Main && obj is WadMoveable) { var moveable = obj as WadMoveable; foreach (var animation in moveable.Animations) { foreach (var command in animation.AnimCommands) { if (command.Type == WadAnimCommandType.PlaySound) { int id = command.Parameter2 & 0x3FFF; id += TrCatalog.GetTR5MainSoundMapStart(sourceWad.GameVersion); command.Parameter2 = (short)((command.Parameter2 & 0xC000) | (id & 0x3FFF)); } } } } } } // Aforementioned HACK continues here - count amount of actually copied objects int actualAmountOfCopiedObjects = objectIdsToMove.Count - failedIdList.Count; if (actualAmountOfCopiedObjects > 0) { // Update the situation tool.WadChanged(WadArea.Destination); string infoString = (objectIdsToMove.Count == 1 ? "Object" : "Objects") + " successfully copied."; // Aforementioned HACK continues here - additionally inform user that some objects are in different slots. if (failedIdList.Count > 0) { infoString += "\n" + failedIdList.Count + " object" + (failedIdList.Count > 1 ? "s" : "") + " weren't copied because " + (failedIdList.Count > 1 ? "they are" : "it's") + " already in different slot" + (failedIdList.Count > 1 ? "s." : "."); } // Indicate that object is copied tool.SendMessage(infoString, PopupType.Info); } return(newIds.Where(item => !failedIdList.Any(failed => failed == item)).ToList()); }
public static Wad2 ConvertWad2ToTR5Main(WadToolClass tool, IWin32Window owner, Wad2 src) { Wad2 dest = new Wad2(); dest.GameVersion = TRVersion.Game.TR5Main; dest.SoundSystem = SoundSystem.Xml; foreach (var moveable in src.Moveables) { var compatibleSlot = TrCatalog.GetMoveableTR5MainSlot(src.GameVersion, moveable.Key.TypeId); if (compatibleSlot == "") { continue; } bool isMoveable = false; var destId = TrCatalog.GetItemIndex(TRVersion.Game.TR5Main, compatibleSlot, out isMoveable); if (!destId.HasValue) { continue; } var newId = new WadMoveableId(destId.Value); foreach (var animation in moveable.Value.Animations) { foreach (var command in animation.AnimCommands) { if (command.Type == WadAnimCommandType.PlaySound) { int id = command.Parameter2 & 0x3FFF; id += TrCatalog.GetTR5MainSoundMapStart(src.GameVersion); command.Parameter2 = (short)((command.Parameter2 & 0xC000) | (id & 0x3FFF)); } } } dest.Add(newId, moveable.Value); } foreach (var sequence in src.SpriteSequences) { var compatibleSlot = TrCatalog.GetSpriteSequenceTR5MainSlot(src.GameVersion, sequence.Key.TypeId); if (compatibleSlot == "") { continue; } bool isMoveable = false; var destId = TrCatalog.GetItemIndex(TRVersion.Game.TR5Main, compatibleSlot, out isMoveable); if (!destId.HasValue) { continue; } var newId = new WadSpriteSequenceId(destId.Value); dest.Add(newId, sequence.Value); } foreach (var staticObject in src.Statics) { dest.Add(staticObject.Key, staticObject.Value); } return(dest); }