Пример #1
0
        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);
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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;
        }
Пример #5
0
 public GizmoSkeletonEditor(WadToolClass tool, Configuration configuration, GraphicsDevice device,
                            Effect effect, PanelRenderingSkeleton control)
     : base(device, effect)
 {
     _configuration = configuration;
     _control       = control;
     _tool          = tool;
 }
Пример #6
0
        public FormOptions(WadToolClass tool) : base(tool.Configuration)
        {
            InitializeComponent();
            InitializeDialog();
            this.SetActualSize(630, 458);
            this.LockWidth();

            _tool = tool;
            _tool.EditorEventRaised += EditorEventRaised;

            ReadConfigIntoControls(this);
        }
Пример #7
0
        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);
                }
            }
        }
Пример #8
0
        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);
            }
        }
Пример #9
0
        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();
        }
Пример #10
0
        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);
            }
        }
Пример #11
0
        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));
            }
        }
Пример #12
0
        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);
            }
        }
Пример #13
0
        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);
        }
Пример #14
0
        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);
        }
Пример #15
0
        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);
            }
        }
Пример #16
0
        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);
        }
Пример #17
0
        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);
            }
        }
Пример #18
0
        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);
        }
Пример #19
0
        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();
        }
Пример #20
0
        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;
            }
        }
Пример #21
0
        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);
                    }
                }
            }
        }
Пример #22
0
        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);
        }
Пример #23
0
        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);
            }
        }
Пример #24
0
 public static void UnloadReferenceLevel(WadToolClass tool)
 {
     tool.ReferenceLevel = null;
     tool.Configuration.Tool_ReferenceProject = string.Empty;
 }
Пример #25
0
        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;
        }
Пример #26
0
        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());
        }
Пример #27
0
        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);
        }