diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Editors/RavenSoftware/Carcass/CarcassEditor.glade b/Content/UniversalEditor.Content.PlatformIndependent/Editors/RavenSoftware/Carcass/CarcassEditor.glade
new file mode 100644
index 00000000..f75086df
--- /dev/null
+++ b/Content/UniversalEditor.Content.PlatformIndependent/Editors/RavenSoftware/Carcass/CarcassEditor.glade
@@ -0,0 +1,994 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Editors/RavenSoftware/Carcass/Dialogs/ModelReferencePropertiesDialog.glade b/Content/UniversalEditor.Content.PlatformIndependent/Editors/RavenSoftware/Carcass/Dialogs/ModelReferencePropertiesDialog.glade
new file mode 100644
index 00000000..6fe09625
--- /dev/null
+++ b/Content/UniversalEditor.Content.PlatformIndependent/Editors/RavenSoftware/Carcass/Dialogs/ModelReferencePropertiesDialog.glade
@@ -0,0 +1,320 @@
+
+
+
+
+
+ False
+ Edit Model Reference
+ dialog
+
+
+
+
+
+ False
+ vertical
+ 2
+
+
+ False
+ end
+
+
+ gtk-ok
+ True
+ True
+ True
+ True
+
+
+
+ True
+ True
+ 0
+
+
+
+
+ gtk-cancel
+ True
+ True
+ True
+ True
+
+
+ True
+ True
+ 1
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+
+
+ True
+ False
+ File _path
+ True
+ 0
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ True
+
+
+
+ 1
+ 0
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 0
+ none
+
+
+ True
+ False
+ 12
+
+
+ True
+ False
+ True
+
+
+ True
+ False
+ Start
+
+
+ 1
+ 0
+
+
+
+
+ True
+ False
+ Master
+ 0
+
+
+ 0
+ 1
+
+
+
+
+ True
+ False
+
+
+ 5
+ 0
+
+
+
+
+ True
+ False
+ Loop Frame
+
+
+ 3
+ 0
+
+
+
+
+ True
+ False
+ Frame
+
+
+ 2
+ 0
+
+
+
+
+ True
+ False
+ Frame Speed
+
+
+ 4
+ 0
+
+
+
+
+ True
+ False
+ Animation Enum
+
+
+ 6
+ 0
+ 3
+
+
+
+
+ GenLoopFrame
+ True
+ True
+ False
+ True
+
+
+ 5
+ 1
+
+
+
+
+ True
+ True
+
+
+ 2
+ 1
+
+
+
+
+ True
+ True
+
+
+ 3
+ 1
+
+
+
+
+ True
+ True
+
+
+ 4
+ 1
+
+
+
+
+ True
+ True
+ False
+
+
+ 6
+ 1
+
+
+
+
+ Choose
+ True
+ True
+ True
+
+
+ 7
+ 1
+
+
+
+
+ Clear
+ True
+ True
+ True
+
+
+ 8
+ 1
+
+
+
+
+ True
+ False
+
+
+ 0
+ 0
+
+
+
+
+ True
+ True
+
+
+ 1
+ 1
+
+
+
+
+
+
+
+
+ True
+ False
+ Sequence
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+
+
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj b/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
index 47ddd581..2328f4b6 100644
--- a/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
+++ b/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
@@ -306,6 +306,8 @@
+
+
@@ -335,6 +337,7 @@
+
diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/Editors/Carcass/CarcassEditor.cs b/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/Editors/Carcass/CarcassEditor.cs
new file mode 100644
index 00000000..066a8b33
--- /dev/null
+++ b/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/Editors/Carcass/CarcassEditor.cs
@@ -0,0 +1,368 @@
+//
+// CarcassEditor.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+using MBS.Framework.UserInterface;
+using MBS.Framework.UserInterface.Controls;
+using MBS.Framework.UserInterface.Controls.ListView;
+using MBS.Framework.UserInterface.Dialogs;
+using UniversalEditor.Plugins.RavenSoftware.ObjectModels.Carcass;
+using UniversalEditor.Plugins.RavenSoftware.UserInterface.Editors.Carcass.Dialogs;
+using UniversalEditor.UserInterface;
+
+namespace UniversalEditor.Plugins.RavenSoftware.UserInterface.Editors.Carcass
+{
+ [ContainerLayout("~/Editors/RavenSoftware/Carcass/CarcassEditor.glade")]
+ public class CarcassEditor : Editor
+ {
+ private Toolbar tbModelFiles;
+ private ListViewControl lvModelFiles;
+ private CheckBox chkSkew90;
+ private CheckBox chkSmoothAllSurfaces;
+ private CheckBox chkRemoveDuplicateVertices;
+ private CheckBox chkMakeSkinFile;
+ private CheckBox chkKeepMotionBone;
+ private NumericTextBox txtFramestepValue;
+ private NumericTextBox txtOriginX;
+ private NumericTextBox txtOriginY;
+ private NumericTextBox txtOriginZ;
+ private CheckBox chkMakeSkeleton;
+ private CheckBox chkUseLegacyCompression;
+ private FileChooserButton fcbSkeletonPath;
+ private FileChooserButton fcbSkeletonGLAFile;
+ private NumericTextBox txtSkeletonScale;
+ private Toolbar tbPCJList;
+ private ListViewControl lvPCJList;
+ private TextBox txtPCJName;
+
+ private Label lblSkeletonPath;
+ private Label lblSkeletonGLAFile;
+ private Label lblSkeletonScale;
+ private Container fraPCJList;
+
+ private static EditorReference _er = null;
+ public override EditorReference MakeReference()
+ {
+ if (_er == null)
+ {
+ _er = base.MakeReference();
+ _er.SupportedObjectModels.Add(typeof(CarcassObjectModel));
+ }
+ return _er;
+ }
+
+ protected override void OnCreated(EventArgs e)
+ {
+ base.OnCreated(e);
+
+ fcbSkeletonPath.RequireExistingFile = false;
+ fcbSkeletonGLAFile.RequireExistingFile = false;
+
+ chkMakeSkinFile.Changed += chk_Changed;
+ chkKeepMotionBone.Changed += chk_Changed;
+ chkSmoothAllSurfaces.Changed += chk_Changed;
+ chkUseLegacyCompression.Changed += chk_Changed;
+ chkRemoveDuplicateVertices.Changed += chk_Changed;
+
+ txtOriginX.Changed += txtOrigin_Changed;
+ txtOriginY.Changed += txtOrigin_Changed;
+ txtOriginZ.Changed += txtOrigin_Changed;
+
+ (tbModelFiles.Items["tsbModelFileAdd"] as ToolbarItemButton).Click += tsbModelFileAdd_Click;
+ (tbModelFiles.Items["tsbModelFileEdit"] as ToolbarItemButton).Click += tsbModelFileEdit_Click;
+ (tbModelFiles.Items["tsbModelFileRemove"] as ToolbarItemButton).Click += tsbModelFileRemove_Click;
+ (tbModelFiles.Items["tsbModelFileMoveUp"] as ToolbarItemButton).Click += tsbModelFileMoveUp_Click;
+ (tbModelFiles.Items["tsbModelFileMoveDown"] as ToolbarItemButton).Click += tsbModelFileMoveDown_Click;
+
+ (tbPCJList.Items["tsbPCJListAdd"] as ToolbarItemButton).Click += tsbPCJListAdd_Click;
+ (tbPCJList.Items["tsbPCJListRemove"] as ToolbarItemButton).Click += tsbPCJListRemove_Click;
+ (tbPCJList.Items["tsbPCJListMoveUp"] as ToolbarItemButton).Click += tsbPCJListMoveUp_Click;
+ (tbPCJList.Items["tsbPCJListMoveDown"] as ToolbarItemButton).Click += tsbPCJListMoveDown_Click;
+
+ OnObjectModelChanged(e);
+ }
+
+ private void tsbPCJListAdd_Click(object sender, EventArgs e)
+ {
+ CarcassObjectModel car = (ObjectModel as CarcassObjectModel);
+ if (car == null) return;
+
+ if (txtPCJName.Text == String.Empty)
+ {
+ MessageDialog.ShowDialog("Please enter a name for the PCJ to add it to the list!", "Missing PCJ Name", MessageDialogButtons.OK, MessageDialogIcon.Error);
+ return;
+ }
+
+ BeginEdit();
+
+ lvPCJList.Model.Rows.Add(new TreeModelRow(new TreeModelRowColumn[]
+ {
+ new TreeModelRowColumn(lvPCJList.Model.Columns[0], txtPCJName.Text)
+ }));
+ car.PCJ.Add(txtPCJName.Text);
+ txtPCJName.Text = String.Empty;
+
+ EndEdit();
+ }
+ private void tsbPCJListRemove_Click(object sender, EventArgs e)
+ {
+ if (lvPCJList.SelectedRows.Count > 0)
+ {
+ // FIXME: this CRASHES!!! in GTK native code: "gtk_tree_store_remove: assertion failed (parent != NULL)"
+ for (int i = 0; i < lvPCJList.SelectedRows.Count; i++)
+ {
+ lvPCJList.Model.Rows.Remove(lvPCJList.SelectedRows[i]);
+ }
+ }
+ }
+ private void tsbPCJListMoveUp_Click(object sender, EventArgs e)
+ {
+
+ }
+ private void tsbPCJListMoveDown_Click(object sender, EventArgs e)
+ {
+
+ }
+
+ [EventHandler(nameof(chkMakeSkeleton), "Changed")]
+ private void chkMakeSkeleton_Changed(object sender, EventArgs e)
+ {
+ bool enabled = chkMakeSkeleton.Checked;
+ chkUseLegacyCompression.Enabled = enabled;
+ lblSkeletonPath.Enabled = enabled;
+ fcbSkeletonPath.Enabled = enabled;
+ lblSkeletonGLAFile.Enabled = enabled;
+ fcbSkeletonGLAFile.Enabled = enabled;
+ lblSkeletonScale.Enabled = enabled;
+ txtSkeletonScale.Enabled = enabled;
+ chkKeepMotionBone.Enabled = enabled;
+ // fraPCJList.Enabled = enabled;
+ tbPCJList.Enabled = enabled;
+ lvPCJList.Enabled = enabled;
+ }
+
+ private void tsbModelFileAdd_Click(object sender, EventArgs e)
+ {
+ ModelReference mr = lvModelFiles.SelectedRows[0].GetExtraData("model");
+ ModelReferencePropertiesDialog dlg = new ModelReferencePropertiesDialog();
+ if (dlg.ShowDialog() == DialogResult.OK)
+ {
+ ModelReference ase = new ModelReference();
+ ase.FileName = dlg.SelectedFileName;
+ BeginEdit();
+ EndEdit();
+ }
+ }
+ private void tsbModelFileEdit_Click(object sender, EventArgs e)
+ {
+ if (lvModelFiles.SelectedRows.Count != 1)
+ {
+ MessageDialog.ShowDialog("Please select EXACTLY ONE item to edit!", "Invalid Selection", MessageDialogButtons.OK, MessageDialogIcon.Error);
+ return;
+ }
+
+ ModelReference mr = lvModelFiles.SelectedRows[0].GetExtraData("model");
+ ModelReferencePropertiesDialog dlg = new ModelReferencePropertiesDialog();
+ dlg.Item = mr;
+ if (dlg.ShowDialog() == DialogResult.OK)
+ {
+ BeginEdit();
+ EndEdit();
+ }
+ }
+ private void tsbModelFileRemove_Click(object sender, EventArgs e)
+ {
+
+ }
+ private void tsbModelFileMoveUp_Click(object sender, EventArgs e)
+ {
+
+ }
+ private void tsbModelFileMoveDown_Click(object sender, EventArgs e)
+ {
+
+ }
+
+ [EventHandler(nameof(lvModelFiles), "RowActivated")]
+ private void lvModelFiles_RowActivated(object sender, ListViewRowActivatedEventArgs e)
+ {
+ tsbModelFileEdit_Click(sender, e);
+ }
+
+ [EventHandler(nameof(fcbSkeletonPath), "Changed")]
+ private void fcbSkeletonPath_Changed(object sender, EventArgs e)
+ {
+ CarcassObjectModel car = (ObjectModel as CarcassObjectModel);
+ if (car == null) return;
+
+ BeginEdit();
+ car.SkeletonFileName = fcbSkeletonPath.SelectedFileName;
+ EndEdit();
+ }
+
+ [EventHandler(nameof(fcbSkeletonGLAFile), "Changed")]
+ private void fcbSkeletonGLAFile_Changed(object sender, EventArgs e)
+ {
+ CarcassObjectModel car = (ObjectModel as CarcassObjectModel);
+ if (car == null) return;
+
+ BeginEdit();
+ car.GLAFileName = fcbSkeletonGLAFile.SelectedFileName;
+ EndEdit();
+ }
+
+ protected override void OnObjectModelChanged(EventArgs e)
+ {
+ base.OnObjectModelChanged(e);
+
+ if (!IsCreated) return;
+
+ lvModelFiles.Model.Rows.Clear();
+
+ CarcassObjectModel car = (ObjectModel as CarcassObjectModel);
+ if (car == null) return;
+
+ chkSmoothAllSurfaces.Checked = car.SmoothAllSurfaces;
+ chkRemoveDuplicateVertices.Checked = car.RemoveDuplicateVertices;
+ chkMakeSkinFile.Checked = car.MakeSkin;
+ chkMakeSkeleton.Checked = (car.SkeletonFileName != null);
+ chkKeepMotionBone.Checked = car.KeepMotionBone;
+
+ _inhibit_txtOrigin_Changed = true;
+ txtOriginX.Value = car.Origin.X;
+ txtOriginY.Value = car.Origin.Y;
+ txtOriginZ.Value = car.Origin.Z;
+ _inhibit_txtOrigin_Changed = false;
+
+ chkUseLegacyCompression.Checked = car.UseLegacyCompression;
+ txtSkeletonScale.Value = car.Scale;
+
+ fcbSkeletonPath.SelectedFileName = car.SkeletonFileName;
+ fcbSkeletonGLAFile.SelectedFileName = car.GLAFileName;
+
+ int frameStart = 0, frameCount = 250;
+ for (int i = 0; i < car.ModelReferences.Count; i++)
+ {
+ ModelReference mr = car.ModelReferences[i];
+ string modelName = System.IO.Path.GetFileNameWithoutExtension(mr.FileName).ToUpper();
+ string enumName = mr.EnumName;
+
+ TreeModelRow row = new TreeModelRow(new TreeModelRowColumn[]
+ {
+ new TreeModelRowColumn(lvModelFiles.Model.Columns[0], frameStart),
+ new TreeModelRowColumn(lvModelFiles.Model.Columns[1], frameCount),
+ new TreeModelRowColumn(lvModelFiles.Model.Columns[2], mr.LoopCount),
+ new TreeModelRowColumn(lvModelFiles.Model.Columns[3], mr.FrameSpeed),
+ new TreeModelRowColumn(lvModelFiles.Model.Columns[4], modelName),
+ new TreeModelRowColumn(lvModelFiles.Model.Columns[5], enumName ?? String.Format("( (BAD: {0}) )", modelName))
+ });
+ row.SetExtraData("model", mr);
+ lvModelFiles.Model.Rows.Add(row);
+ frameStart += frameCount;
+ }
+
+ for (int i = 0; i < car.PCJ.Count; i++)
+ {
+ TreeModelRow row = new TreeModelRow(new TreeModelRowColumn[]
+ {
+ new TreeModelRowColumn(lvPCJList.Model.Columns[0], car.PCJ[i])
+ });
+ row.SetExtraData("index", i);
+ lvPCJList.Model.Rows.Add(row);
+ }
+ }
+
+ private void chk_Changed(object sender, EventArgs e)
+ {
+ CarcassObjectModel car = (ObjectModel as CarcassObjectModel);
+ if (car == null) return;
+
+ CheckBox chk = (sender as CheckBox);
+
+ BeginEdit();
+ if (chk == chkMakeSkinFile)
+ {
+ car.MakeSkin = chk.Checked;
+ }
+ else if (chk == chkKeepMotionBone)
+ {
+ car.KeepMotionBone = chk.Checked;
+ }
+ else if (chk == chkSmoothAllSurfaces)
+ {
+ car.SmoothAllSurfaces = chk.Checked;
+ }
+ else if (chk == chkUseLegacyCompression)
+ {
+ car.UseLegacyCompression = chk.Checked;
+ }
+ else if (chk == chkRemoveDuplicateVertices)
+ {
+ car.RemoveDuplicateVertices = chk.Checked;
+ }
+ EndEdit();
+ }
+
+ private bool _inhibit_txtOrigin_Changed = false;
+ private void txtOrigin_Changed(object sender, EventArgs e)
+ {
+ CarcassObjectModel car = (ObjectModel as CarcassObjectModel);
+ if (car == null) return;
+
+ if (_inhibit_txtOrigin_Changed) return;
+
+ BeginEdit();
+ car.Origin = new PositionVector3(txtOriginX.Value, txtOriginY.Value, txtOriginZ.Value);
+ EndEdit();
+ }
+
+ [EventHandler(nameof(txtFramestepValue), "Changed")]
+ private void txtFramestepValue_Changed(object sender, EventArgs e)
+ {
+ CarcassObjectModel car = (ObjectModel as CarcassObjectModel);
+ if (car == null) return;
+
+ BeginEdit();
+ car.Framestep = (int)txtFramestepValue.Value;
+ EndEdit();
+ }
+
+ [EventHandler(nameof(txtSkeletonScale), "Changed")]
+ private void txtSkeletonScale_Changed(object sender, EventArgs e)
+ {
+ CarcassObjectModel car = (ObjectModel as CarcassObjectModel);
+ if (car == null) return;
+
+ BeginEdit();
+ car.Scale = txtSkeletonScale.Value;
+ EndEdit();
+ }
+
+ public override void UpdateSelections()
+ {
+
+ }
+
+ protected override Selection CreateSelectionInternal(object content)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/Editors/Carcass/Dialogs/ModelReferencePropertiesDialog.cs b/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/Editors/Carcass/Dialogs/ModelReferencePropertiesDialog.cs
new file mode 100644
index 00000000..ae55fcd4
--- /dev/null
+++ b/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/Editors/Carcass/Dialogs/ModelReferencePropertiesDialog.cs
@@ -0,0 +1,142 @@
+//
+// ModelReferencePropertiesDialog.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+using MBS.Framework.UserInterface;
+using MBS.Framework.UserInterface.Controls;
+using MBS.Framework.UserInterface.Layouts;
+using UniversalEditor.Plugins.RavenSoftware.ObjectModels.Carcass;
+
+namespace UniversalEditor.Plugins.RavenSoftware.UserInterface.Editors.Carcass.Dialogs
+{
+ [ContainerLayout("~/Editors/RavenSoftware/Carcass/Dialogs/ModelReferencePropertiesDialog.glade")]
+ public class ModelReferencePropertiesDialog : CustomDialog
+ {
+ private Button cmdCancel;
+ private Button cmdOK;
+ private Container ct;
+
+ private FileChooserButton fcbFilePath;
+
+ private NumericTextBox txtStart1;
+ private NumericTextBox txtFrame1;
+ private NumericTextBox txtLoop1;
+ private NumericTextBox txtSpeed1;
+ private TextBox txtEnum1;
+ private Button cmdChoose1;
+ private Button cmdClear1;
+
+ private NumericTextBox[] txtStart = new NumericTextBox[MAX_ITEMS];
+ private NumericTextBox[] txtFrame = new NumericTextBox[MAX_ITEMS];
+ private NumericTextBox[] txtLoop = new NumericTextBox[MAX_ITEMS];
+ private NumericTextBox[] txtSpeed = new NumericTextBox[MAX_ITEMS];
+ private TextBox[] txtEnum = new TextBox[MAX_ITEMS];
+ private Button[] cmdChoose = new Button[MAX_ITEMS];
+ private Button[] cmdClear = new Button[MAX_ITEMS];
+
+ public string SelectedFileName { get; set; } = null;
+
+ public ModelReference Item { get; set; } = null;
+
+ private const int MAX_ITEMS = 18;
+
+ protected override void OnCreated(EventArgs e)
+ {
+ base.OnCreated(e);
+
+ fcbFilePath.RequireExistingFile = false;
+ DefaultButton = cmdOK;
+
+ txtStart[0] = txtStart1;
+ txtFrame[0] = txtFrame1;
+ txtLoop[0] = txtLoop1;
+ txtSpeed[0] = txtSpeed1;
+ txtEnum[0] = txtEnum1;
+ txtEnum[0].Editable = false;
+
+ cmdChoose[0] = cmdChoose1;
+ cmdClear[0] = cmdClear1;
+
+ for (int i = 1; i < MAX_ITEMS; i++)
+ {
+ Label lblAdditional = new Label();
+ lblAdditional.Text = "Additional " + i.ToString();
+ ct.Controls.Add(lblAdditional, new GridLayout.Constraints(i + 2, 0, 1, 1));
+
+ txtStart[i] = new NumericTextBox();
+ txtStart[i].Enabled = false;
+ ct.Controls.Add(txtStart[i], new GridLayout.Constraints(i + 2, 1, 1, 1));
+
+ txtFrame[i] = new NumericTextBox();
+ txtFrame[i].Enabled = false;
+ ct.Controls.Add(txtFrame[i], new GridLayout.Constraints(i + 2, 2, 1, 1));
+
+ txtLoop[i] = new NumericTextBox();
+ txtLoop[i].Enabled = false;
+ ct.Controls.Add(txtLoop[i], new GridLayout.Constraints(i + 2, 3, 1, 1));
+
+ txtSpeed[i] = new NumericTextBox();
+ txtSpeed[i].Enabled = false;
+ ct.Controls.Add(txtSpeed[i], new GridLayout.Constraints(i + 2, 4, 1, 1));
+
+ txtEnum[i] = new TextBox();
+ txtEnum[i].Enabled = false;
+ ct.Controls.Add(txtEnum[i], new GridLayout.Constraints(i + 2, 6, 1, 1));
+
+ cmdChoose[i] = new Button();
+ cmdChoose[i].Text = "Choose";
+ cmdChoose[i].Enabled = false;
+ ct.Controls.Add(cmdChoose[i], new GridLayout.Constraints(i + 2, 7, 1, 1));
+
+ cmdClear[i] = new Button();
+ cmdClear[i].Text = "Clear";
+ cmdClear[i].Enabled = false;
+ ct.Controls.Add(cmdClear[i], new GridLayout.Constraints(i + 2, 8, 1, 1));
+
+ if (Item != null)
+ {
+ fcbFilePath.SelectedFileName = Item.FileName;
+ if (i - 1 < Item.AdditionalFrames.Count)
+ {
+ txtStart[i].Enabled = true;
+ txtStart[i].Value = Item.AdditionalFrames[i - 1].Target;
+
+ txtFrame[i].Enabled = true;
+ txtFrame[i].Value = Item.AdditionalFrames[i - 1].Count;
+
+ txtLoop[i].Enabled = true;
+ txtLoop[i].Value = Item.AdditionalFrames[i - 1].Loop;
+
+ txtSpeed[i].Enabled = true;
+ txtSpeed[i].Value = Item.AdditionalFrames[i - 1].Speed;
+
+ txtEnum[i].Enabled = true;
+ txtEnum[i].Editable = false;
+ txtEnum[i].Text = Item.AdditionalFrames[i - 1].Animation;
+
+ cmdChoose[i].Enabled = true;
+ cmdClear[i].Enabled = true;
+ }
+ }
+
+ }
+ }
+ }
+}
diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/Editors/Icarus/IcarusScriptEditor.cs b/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/Editors/Icarus/IcarusScriptEditor.cs
index fca41509..de6a47ff 100644
--- a/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/Editors/Icarus/IcarusScriptEditor.cs
+++ b/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/Editors/Icarus/IcarusScriptEditor.cs
@@ -28,7 +28,7 @@ using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Controls;
using MBS.Framework.UserInterface.Controls.ListView;
using MBS.Framework.UserInterface.Dialogs;
-
+using UniversalEditor.DataFormats.Icarus;
using UniversalEditor.ObjectModels.Icarus;
using UniversalEditor.ObjectModels.Icarus.Commands;
using UniversalEditor.ObjectModels.Icarus.Expressions;
@@ -344,7 +344,7 @@ namespace UniversalEditor.Plugins.RavenSoftware.UserInterface.Editors.Icarus
IcarusScriptObjectModel script = (ObjectModel as IcarusScriptObjectModel);
IcarusScriptObjectModel icarus = new IcarusScriptObjectModel();
- DataFormats.Icarus.IcarusTextDataFormat ictxt = new DataFormats.Icarus.IcarusTextDataFormat();
+ IcarusTextDataFormat ictxt = new IcarusTextDataFormat();
Document.Load(icarus, ictxt, new Accessors.FileAccessor(dlg.SelectedFileName));
int start = script.Commands.Count;
diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface.csproj b/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface.csproj
index e2975593..ed1b5e9e 100644
--- a/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface.csproj
+++ b/Plugins.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface/UniversalEditor.Plugins.RavenSoftware.UserInterface.csproj
@@ -38,12 +38,16 @@
+
+
+
+
@@ -70,6 +74,14 @@
{B2DFA94A-A468-48A1-AB31-04EE432E7B2B}
UniversalEditor.Plugins.RavenSoftware
+
+ {BE4D0BA3-0888-42A5-9C09-FC308A4509D2}
+ UniversalEditor.Plugins.Multimedia
+
+
+ {4FD9DB1D-76AA-48D1-8446-95376C4A2BC2}
+ UniversalEditor.Plugins.Multimedia3D
+
\ No newline at end of file
diff --git a/Plugins/UniversalEditor.Plugins.RavenSoftware/Associations/CarcassTextDataFormat.uexml b/Plugins/UniversalEditor.Plugins.RavenSoftware/Associations/CarcassTextDataFormat.uexml
new file mode 100644
index 00000000..39f7286a
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.RavenSoftware/Associations/CarcassTextDataFormat.uexml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ *.car
+
+
+
+ $aseanimgrabinit
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Plugins/UniversalEditor.Plugins.RavenSoftware/DataFormats/Carcass/Text/CarcassTextDataFormat.cs b/Plugins/UniversalEditor.Plugins.RavenSoftware/DataFormats/Carcass/Text/CarcassTextDataFormat.cs
new file mode 100644
index 00000000..ba5a3c5c
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.RavenSoftware/DataFormats/Carcass/Text/CarcassTextDataFormat.cs
@@ -0,0 +1,250 @@
+//
+// CarcassTextDataFormat.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+using UniversalEditor.Plugins.RavenSoftware.ObjectModels.Carcass;
+
+namespace UniversalEditor.Plugins.RavenSoftware.DataFormats.Carcass.Text
+{
+ public class CarcassTextDataFormat : DataFormat
+ {
+ private static DataFormatReference _dfr = null;
+ protected override DataFormatReference MakeReferenceInternal()
+ {
+ if (_dfr == null)
+ {
+ _dfr = base.MakeReferenceInternal();
+ _dfr.Capabilities.Add(typeof(CarcassObjectModel), DataFormatCapabilities.All);
+ }
+ return _dfr;
+ }
+
+ protected override void LoadInternal(ref ObjectModel objectModel)
+ {
+ CarcassObjectModel car = (objectModel as CarcassObjectModel);
+ if (car == null)
+ throw new ObjectModelNotSupportedException();
+
+ IO.Reader reader = Accessor.Reader;
+ string signature = reader.ReadLine();
+
+ if (signature != "$aseanimgrabinit")
+ throw new InvalidDataFormatException("file does not begin with '$aseanimgrabinit' ");
+
+ while (!reader.EndOfStream)
+ {
+ string line = reader.ReadLine();
+ if (line.Equals("$keepmotion"))
+ {
+ car.KeepMotionBone = true;
+ }
+ else if (line.StartsWith("$scale "))
+ {
+ car.Scale = Double.Parse(line.Substring("$scale ".Length));
+ }
+ else if (line.StartsWith("$aseanimref_gla "))
+ {
+ car.GLAFileName = line.Substring("$aseanimref_gla ".Length);
+ }
+ else if (line.StartsWith("$pcj "))
+ {
+ car.PCJ.Add(line.Substring("$pcj ".Length));
+ }
+ else if (line.StartsWith("$aseanimgrab "))
+ {
+ ModelReference ase = new ModelReference();
+ string filenameAndParms = line.Substring("$aseanimgrab ".Length);
+ string filenameOnly = filenameAndParms;
+ string parmsOnly = String.Empty;
+ if (filenameAndParms.IndexOf(' ') != -1)
+ {
+ filenameOnly = filenameAndParms.Substring(0, filenameAndParms.IndexOf(' '));
+ parmsOnly = filenameAndParms.Substring(filenameAndParms.IndexOf(' ') + 1);
+ }
+
+ ase.FileName = filenameOnly;
+ if (filenameOnly.EndsWith(".xsi"))
+ ase.FrameSpeed = ModelReference.DEFAULT_FRAMESPEED_XSI; // weird
+
+ string[] parms = parmsOnly.Split(new char[] { ' ' });
+ for (int i = 0; i < parms.Length; i++)
+ {
+ if (parms[i].Equals("-loop"))
+ {
+ ase.LoopCount = Int32.Parse(parms[i + 1]);
+ }
+ if (parms[i].Equals("-framespeed"))
+ {
+ ase.FrameSpeed = Int32.Parse(parms[i + 1]);
+ }
+ if (parms[i] == "-genloopframe")
+ {
+ ase.GenerateLoopFrame = true;
+ }
+ if (parms[i] == "-prequat")
+ {
+ car.UseLegacyCompression = true;
+ }
+ if (parms[i].Equals("-enum"))
+ {
+ ase.EnumName = parms[i + 1];
+ }
+ if (parms[i].Equals("-additional"))
+ {
+ if (i + 5 < parms.Length)
+ {
+ CarcassFrame addlFrame = new CarcassFrame();
+
+ addlFrame.Target = Int32.Parse(parms[i + 1]);
+ addlFrame.Count = Int32.Parse(parms[i + 2]);
+ addlFrame.Loop = Int32.Parse(parms[i + 3]);
+ addlFrame.Speed = Int32.Parse(parms[i + 4]);
+ addlFrame.Animation = parms[i + 5];
+
+ ase.AdditionalFrames.Add(addlFrame);
+ }
+ }
+ }
+
+ car.ModelReferences.Add(ase);
+ }
+ else if (line.StartsWith("$aseanimconvertmdx_noask "))
+ {
+ string filenameAndParms = line.Substring("$aseanimconvertmdx_noask ".Length);
+ string filenameOnly = filenameAndParms;
+ string parmsOnly = String.Empty;
+ if (filenameAndParms.IndexOf(' ') != -1)
+ {
+ filenameOnly = filenameAndParms.Substring(0, filenameAndParms.IndexOf(' '));
+ parmsOnly = filenameAndParms.Substring(filenameAndParms.IndexOf(' ') + 1);
+ }
+ car.BasePath = filenameOnly;
+
+ string[] parms = parmsOnly.Split(new char[] { ' ' });
+ for (int i = 0; i < parms.Length; i++)
+ {
+ if (parms[i] == "-makeskin")
+ {
+ car.MakeSkin = true;
+ }
+ if (parms[i] == "-smooth")
+ {
+ car.SmoothAllSurfaces = true;
+ }
+ if (parms[i] == "-losedupverts")
+ {
+ car.RemoveDuplicateVertices = true;
+ }
+ if (parms[i].Equals("-makeskel"))
+ {
+ car.SkeletonFileName = parms[i + 1];
+ }
+ if (parms[i].Equals("-origin"))
+ {
+ if (i + 3 < parms.Length)
+ {
+ car.Origin = new PositionVector3(Double.Parse(parms[i + 1]), Double.Parse(parms[i + 2]), Double.Parse(parms[i + 3]));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ protected override void SaveInternal(ObjectModel objectModel)
+ {
+ CarcassObjectModel car = (objectModel as CarcassObjectModel);
+ if (car == null)
+ throw new ObjectModelNotSupportedException();
+
+ IO.Writer writer = Accessor.Writer;
+ writer.WriteLine("$aseanimgrabinit");
+ if (car.Scale != 1.0)
+ {
+ writer.WriteLine(String.Format("$scale {0}", car.Scale));
+ }
+ if (car.KeepMotionBone)
+ {
+ writer.WriteLine("$keepmotion");
+ }
+ if (car.GLAFileName != null)
+ {
+ writer.Write("$aseanimref_gla ");
+ writer.WriteLine(car.GLAFileName);
+ }
+ for (int i = 0; i < car.PCJ.Count; i++)
+ {
+ writer.WriteLine(String.Format("$pcj {0}", car.PCJ[i]));
+ }
+ for (int i = 0; i < car.ModelReferences.Count; i++)
+ {
+ writer.Write(String.Format("$aseanimgrab {0}", car.ModelReferences[i].FileName));
+ writer.Write(String.Format(" -loop {0}", car.ModelReferences[i].LoopCount));
+ if (car.ModelReferences[i].EnumName != null)
+ {
+ writer.Write(String.Format(" -enum {0}", car.ModelReferences[i].EnumName));
+ }
+ if ((!(car.ModelReferences[i].FileName?.ToLower()?.EndsWith(".xsi")).GetValueOrDefault() && car.ModelReferences[i].FrameSpeed != ModelReference.DEFAULT_FRAMESPEED) ||
+ ((car.ModelReferences[i].FileName?.ToLower()?.EndsWith(".xsi")).GetValueOrDefault() && car.ModelReferences[i].FrameSpeed != ModelReference.DEFAULT_FRAMESPEED_XSI))
+ {
+ writer.Write(String.Format(" -framespeed {0}", car.ModelReferences[i].FrameSpeed));
+ }
+ if (car.ModelReferences[i].GenerateLoopFrame)
+ {
+ writer.Write(" -genloopframe");
+ }
+
+ if (i == 0)
+ {
+ if (car.UseLegacyCompression)
+ {
+ writer.Write(" -qdskipstart -prequat -qdskipstop");
+ }
+ }
+ writer.WriteLine();
+ }
+ writer.WriteLine("$aseanimgrabfinalize");
+ writer.Write(String.Format("$aseanimconvertmdx_noask {0}", car.BasePath));
+
+ if (car.MakeSkin)
+ {
+ writer.Write(" -makeskin");
+ }
+ if (car.SmoothAllSurfaces)
+ {
+ writer.Write(" -smooth");
+ }
+ if (car.RemoveDuplicateVertices)
+ {
+ writer.Write(" -losedupverts");
+ }
+ if (car.SkeletonFileName != null)
+ {
+ writer.Write(" -makeskel ");
+ writer.Write(car.SkeletonFileName);
+ }
+
+ if (car.Origin != PositionVector3.Empty)
+ {
+ writer.Write(String.Format(" -origin {0} {1} {2}", car.Origin.X, car.Origin.Y, car.Origin.Z));
+ }
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.RavenSoftware/ObjectModels/Carcass/CarcassFrame.cs b/Plugins/UniversalEditor.Plugins.RavenSoftware/ObjectModels/Carcass/CarcassFrame.cs
new file mode 100644
index 00000000..ee780a0b
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.RavenSoftware/ObjectModels/Carcass/CarcassFrame.cs
@@ -0,0 +1,49 @@
+//
+// CarcassFrame.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.RavenSoftware.ObjectModels.Carcass
+{
+ public class CarcassFrame : ICloneable
+ {
+ public class CarcassFrameCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ public int Target { get; set; }
+ public int Count { get; set; }
+ public int Loop { get; set; } = -1;
+ public int Speed { get; set; } = 1;
+ public string Animation { get; set; } = null;
+
+ public object Clone()
+ {
+ CarcassFrame clone = new CarcassFrame();
+ clone.Target = Target;
+ clone.Count = Count;
+ clone.Loop = Loop;
+ clone.Speed = Speed;
+ clone.Animation = (Animation?.Clone() as string);
+ return clone;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.RavenSoftware/ObjectModels/Carcass/CarcassObjectModel.cs b/Plugins/UniversalEditor.Plugins.RavenSoftware/ObjectModels/Carcass/CarcassObjectModel.cs
new file mode 100644
index 00000000..1604ce63
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.RavenSoftware/ObjectModels/Carcass/CarcassObjectModel.cs
@@ -0,0 +1,117 @@
+//
+// CarcassObjectModel.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.RavenSoftware.ObjectModels.Carcass
+{
+ public class CarcassObjectModel : ObjectModel
+ {
+ public CarcassObjectModel()
+ {
+ }
+
+ public ModelReference.ModelReferenceCollection ModelReferences { get; } = new ModelReference.ModelReferenceCollection();
+ public string BasePath { get; set; }
+
+ public bool MakeSkin { get; set; } = false;
+
+ ///
+ /// Gets or sets the scale at which the skeleton should be made when is true.
+ ///
+ /// The scale.
+ public double Scale { get; set; } = 1.0;
+ ///
+ /// Gets or sets the name of the Ghoul2 animation (GLA) file from which to clone bone indices.
+ ///
+ /// The name of the Ghoul2 animation (GLA) file from which to clone bone indices.
+ public string GLAFileName { get; set; } = null;
+ ///
+ /// Gets or sets a value indicating whether this keep motion bone.
+ ///
+ /// true if keep motion bone; otherwise, false.
+ public bool KeepMotionBone { get; set; } = false;
+ ///
+ /// Gets or sets a value indicating whether this smooth all surfaces.
+ ///
+ /// true if smooth all surfaces; otherwise, false.
+ public bool SmoothAllSurfaces { get; set; } = false;
+ ///
+ /// Gets or sets a value indicating whether duplicate vertices should be removed when compiling this .
+ ///
+ /// true if duplicate vertices should be removed; otherwise, false.
+ public bool RemoveDuplicateVertices { get; set; } = false;
+ public PositionVector3 Origin { get; set; } = PositionVector3.Empty;
+
+ ///
+ /// Gets the pcj.
+ ///
+ /// The pcj.
+ public System.Collections.Specialized.StringCollection PCJ { get; } = new System.Collections.Specialized.StringCollection();
+ ///
+ /// Gets or sets a value indicating whether this uses (older) pre-quaternian animation-compression.
+ ///
+ /// true if (older) pre-quaternian animation-compression should be used; otherwise, false.
+ public bool UseLegacyCompression { get; set; } = false;
+ public string SkeletonFileName { get; set; } = null;
+ public int Framestep { get; set; } = 1;
+
+ public override void Clear()
+ {
+ ModelReferences.Clear();
+ BasePath = null;
+ MakeSkin = false;
+ Scale = 1.0;
+ GLAFileName = null;
+ KeepMotionBone = false;
+ SmoothAllSurfaces = false;
+ RemoveDuplicateVertices = false;
+ Origin = PositionVector3.Empty;
+ UseLegacyCompression = false;
+ SkeletonFileName = null;
+ Framestep = 1;
+ }
+
+ public override void CopyTo(ObjectModel where)
+ {
+ CarcassObjectModel clone = (where as CarcassObjectModel);
+ if (clone == null) throw new ObjectModelNotSupportedException();
+
+ for (int i = 0; i < ModelReferences.Count; i++)
+ {
+ clone.ModelReferences.Add(ModelReferences[i].Clone() as ModelReference);
+ }
+ clone.BasePath = (BasePath?.Clone() as string);
+ clone.MakeSkin = MakeSkin;
+ clone.Scale = Scale;
+ clone.GLAFileName = (GLAFileName?.Clone() as string);
+ clone.KeepMotionBone = KeepMotionBone;
+ clone.SmoothAllSurfaces = SmoothAllSurfaces;
+ clone.RemoveDuplicateVertices = RemoveDuplicateVertices;
+ clone.Origin = (PositionVector3)Origin.Clone();
+ for (int i = 0; i < PCJ.Count; i++)
+ {
+ clone.PCJ.Add(PCJ[i].Clone() as string);
+ }
+ clone.UseLegacyCompression = UseLegacyCompression;
+ clone.SkeletonFileName = (SkeletonFileName?.Clone() as string);
+ clone.Framestep = Framestep;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.RavenSoftware/ObjectModels/Carcass/ModelReference.cs b/Plugins/UniversalEditor.Plugins.RavenSoftware/ObjectModels/Carcass/ModelReference.cs
new file mode 100644
index 00000000..43d3e2a9
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.RavenSoftware/ObjectModels/Carcass/ModelReference.cs
@@ -0,0 +1,61 @@
+//
+// ModelReference.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+using System;
+namespace UniversalEditor.Plugins.RavenSoftware.ObjectModels.Carcass
+{
+ public class ModelReference : ICloneable
+ {
+
+ public class ModelReferenceCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ public string FileName { get; set; } = null;
+ public int LoopCount { get; set; } = -1;
+ public bool GenerateLoopFrame { get; set; } = false;
+ public int FrameSpeed { get; set; } = DEFAULT_FRAMESPEED;
+ public string EnumName { get; set; } = null;
+
+ public CarcassFrame.CarcassFrameCollection AdditionalFrames { get; } = new CarcassFrame.CarcassFrameCollection();
+
+ public const int MAX_FRAMESPEED = 26083348;
+
+ public const int DEFAULT_FRAMESPEED = MAX_FRAMESPEED;
+ public const int DEFAULT_FRAMESPEED_XSI = 20;
+
+ public object Clone()
+ {
+ ModelReference clone = new ModelReference();
+ clone.FileName = (FileName.Clone() as string);
+ clone.LoopCount = LoopCount;
+ clone.GenerateLoopFrame = GenerateLoopFrame;
+ clone.FrameSpeed = FrameSpeed;
+ clone.EnumName = (EnumName?.Clone() as string);
+ for (int i = 0; i < AdditionalFrames.Count; i++)
+ {
+ clone.AdditionalFrames.Add(AdditionalFrames[i].Clone() as CarcassFrame);
+ }
+ return clone;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.RavenSoftware/UniversalEditor.Plugins.RavenSoftware.csproj b/Plugins/UniversalEditor.Plugins.RavenSoftware/UniversalEditor.Plugins.RavenSoftware.csproj
index 079584d3..bcc46d7e 100644
--- a/Plugins/UniversalEditor.Plugins.RavenSoftware/UniversalEditor.Plugins.RavenSoftware.csproj
+++ b/Plugins/UniversalEditor.Plugins.RavenSoftware/UniversalEditor.Plugins.RavenSoftware.csproj
@@ -83,6 +83,10 @@
+
+
+
+
@@ -106,14 +110,26 @@
{00266B21-35C9-4A7F-A6BA-D54D7FDCC25C}
MBS.Framework
+
+ {BE4D0BA3-0888-42A5-9C09-FC308A4509D2}
+ UniversalEditor.Plugins.Multimedia
+
+
+ {4FD9DB1D-76AA-48D1-8446-95376C4A2BC2}
+ UniversalEditor.Plugins.Multimedia3D
+
+
+
+
+
\ No newline at end of file