Skip to content

Commit 916bec5

Browse files
[Bugfix]: KitbashTool: Fixed incorrect saving of meshes with only skin attribute set
[Feature]: KitbashTool: Custom attachmentpoints are kept and saved.
1 parent f557193 commit 916bec5

File tree

24 files changed

+227
-51
lines changed

24 files changed

+227
-51
lines changed

Editors/ImportExportEditor/Editors.ImportExport/Importing/Importers/GltfToRmv/Helper/Rmv2FromGltfFIleConverter.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
using SharpDX.MediaFoundation;
2626
using Editors.ImportExport.Common;
2727
using Pfim;
28+
using Shared.GameFormats.RigidModel.Types;
2829

2930
namespace Editors.ImportExport.Importing.Importers.GltfToRmv.Helper
3031
{
@@ -153,8 +154,9 @@ RmvModel CreateRmvModel(ModelMaterialEnum rigidMaterial, VertexFormat vertexForm
153154

154155
if (addBonesAsAttachmentPoints && skeleton != null)
155156
{
156-
var boneNames = skeleton.BoneNames.Select(x => x.Replace("bn_", "")).ToArray();
157-
newModel.Material.EnrichDataBeforeSaving(boneNames);
157+
var boneNames = skeleton.BoneNames;
158+
var attachmentPoints = AttachmentPointHelper.CreateFromBoneList(boneNames);
159+
newModel.Material.EnrichDataBeforeSaving(attachmentPoints);
158160
}
159161

160162
return newModel;

Editors/ImportExportEditor/Editors.ImportExport/Importing/Importers/GltfToRmv/Helper/RmvMeshBuilder.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,10 @@ private static RmvModel CreateRmvModel(RmvMesh rmv2Mesh, string modelName, Anima
199199
CalculateBoundBox(newModel);
200200

201201
if (addBonesAsAttachmentPoints && animSkeletonFile != null)
202-
{
203-
var boneNames = animSkeletonFile.Bones.Select(x => x.Name).ToArray();
204-
var correctedBoneNames = boneNames.Select(x => x.Replace("bn_", "")).ToArray();
205-
newModel.Material.EnrichDataBeforeSaving(correctedBoneNames);
202+
{
203+
var boneNames = animSkeletonFile.Bones.Select(x => x.Name).ToList();
204+
var attachmentPoints = AttachmentPointHelper.CreateFromBoneList(boneNames);
205+
newModel.Material.EnrichDataBeforeSaving(attachmentPoints);
206206
}
207207

208208
return newModel;

Editors/Kitbashing/KitbasherEditor/ChildEditors/ReRiggingTool/OpenReriggingToolCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using Editors.KitbasherEditor.ChildEditors.MeshFitter;
2+
using Editors.KitbasherEditor.Core;
23
using Editors.KitbasherEditor.Core.MenuBarViews;
3-
using Editors.KitbasherEditor.ViewModels;
44
using Editors.Shared.Core.Services;
55
using GameWorld.Core.Components.Selection;
66
using GameWorld.Core.SceneNodes;

Editors/Kitbashing/KitbasherEditor/Core/Animation/AnimationControllerViewModel.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.IO;
33
using System.Windows.Input;
44
using CommunityToolkit.Mvvm.Input;
5+
using Editors.KitbasherEditor.Core;
56
using Editors.KitbasherEditor.Events;
67
using Editors.Shared.Core.Services;
78
using GameWorld.Core.Animation;

Editors/Kitbashing/KitbasherEditor/Core/KitbasherRootScene.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
using Shared.Core.Events;
77
using Shared.Core.PackFiles;
88
using Shared.GameFormats.Animation;
9+
using Shared.GameFormats.RigidModel.Transforms;
10+
using Shared.GameFormats.RigidModel.Types;
911

10-
namespace Editors.KitbasherEditor.ViewModels
12+
namespace Editors.KitbasherEditor.Core
1113
{
1214
public class KitbasherRootScene : ISkeletonProvider
1315
{
@@ -17,7 +19,7 @@ public class KitbasherRootScene : ISkeletonProvider
1719

1820
public GameSkeleton Skeleton { get; private set; }
1921
public AnimationPlayer Player { get; private set; }
20-
22+
2123
public KitbasherRootScene(AnimationsContainerComponent animationsContainerComponent, IPackFileService packFileService, IEventHub eventHub)
2224
{
2325
_animationsContainerComponent = animationsContainerComponent;

Editors/Kitbashing/KitbasherEditor/Core/SceneNodeEditor/Nodes/MainEditableNode/MainEditableNodeView.xaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,34 @@
4242
<ComboBox SelectedValue="None" VerticalAlignment="Center" Visibility="Collapsed"/>
4343
</DockPanel>
4444

45+
<StackPanel Orientation="Horizontal" DockPanel.Dock="Top">
46+
<Label Width ="{StaticResource labelWidth}" DockPanel.Dock="Left" Content="Attachment points"/>
47+
<Label>:</Label>
48+
49+
<Expander>
50+
<Expander.Header>
51+
<StackPanel Orientation="Horizontal">
52+
<TextBlock Text="Count = "/>
53+
<TextBlock Text="{Binding AttachmentPointList.Count, UpdateSourceTrigger=PropertyChanged}"/>
54+
</StackPanel>
55+
</Expander.Header>
56+
<StackPanel>
57+
<ListView ItemsSource="{Binding AttachmentPointList, UpdateSourceTrigger=PropertyChanged}">
58+
59+
<ListView.View>
60+
<GridView>
61+
<GridViewColumn Header="Bone Id" DisplayMemberBinding="{Binding BoneIndex}" Width="auto"/>
62+
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="auto"/>
63+
<GridViewColumn Header="Use Bone Orientation" DisplayMemberBinding="{Binding IsIdentiy}" Width="auto"/>
64+
</GridView>
65+
</ListView.View>
66+
</ListView>
67+
68+
<Button Content="Create AttachmentPoints from Skeleton" Margin="2" Height="25" Command="{Binding ResetAttachmentPointListCommand }"/>
69+
</StackPanel>
70+
71+
</Expander>
72+
</StackPanel>
4573
</DockPanel>
4674
</Expander>
4775

Editors/Kitbashing/KitbasherEditor/Core/SceneNodeEditor/Nodes/MainEditableNode/MainEditableNodeViewModel.cs

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,110 @@
11
using System.Collections.ObjectModel;
22
using System.IO;
33
using CommunityToolkit.Mvvm.ComponentModel;
4+
using CommunityToolkit.Mvvm.Input;
5+
using Editors.KitbasherEditor.Core;
46
using Editors.KitbasherEditor.UiCommands;
57
using Editors.Shared.Core.Services;
68
using GameWorld.Core.Components.Rendering;
79
using GameWorld.Core.SceneNodes;
810
using KitbasherEditor.Views.EditorViews;
911
using Shared.Core.Events;
12+
using Shared.Core.Services;
13+
using Shared.GameFormats.RigidModel.Types;
1014
using Shared.Ui.Common.DataTemplates;
1115
using static CommonControls.FilterDialog.FilterUserControl;
1216

1317
namespace Editors.KitbasherEditor.ViewModels.SceneExplorer.Nodes
1418
{
19+
20+
public partial class AttachmentPoint : ObservableObject
21+
{
22+
[ObservableProperty] public partial int BoneIndex { get; set; }
23+
[ObservableProperty] public partial string Name { get; set; }
24+
[ObservableProperty] public partial bool IsIdentiy { get; set; }
25+
}
26+
1527
public partial class MainEditableNodeViewModel : ObservableObject, ISceneNodeEditor, IViewProvider<MainEditableNodeView>
1628
{
1729
static public OnSeachDelegate FilterByFullPath { get { return (item, expression) => { return expression.Match(item.ToString()).Success; }; } }
1830

1931
private readonly KitbasherRootScene _kitbasherRootScene;
2032
private readonly RenderEngineComponent _renderEngineComponent;
2133
private readonly IUiCommandFactory _uiCommandFactory;
34+
private readonly IStandardDialogs _standardDialogs;
2235
private readonly SkeletonAnimationLookUpHelper _skeletonAnimationLookUpHelper;
2336

24-
MainEditableNode _mainNode;
37+
MainEditableNode? _mainNode;
2538

26-
[ObservableProperty] ObservableCollection<string> _skeletonNameList;
27-
[ObservableProperty] string? _skeletonName;
39+
[ObservableProperty] public partial ObservableCollection<string> SkeletonNameList { get; set; }
40+
[ObservableProperty] public partial ObservableCollection<AttachmentPoint> AttachmentPointList { get; set; } = [];
41+
[ObservableProperty] public partial string? SkeletonName { get; set; }
2842

2943
public MainEditableNodeViewModel(KitbasherRootScene kitbasherRootScene,
3044
SkeletonAnimationLookUpHelper skeletonAnimationLookUpHelper,
3145
RenderEngineComponent renderEngineComponent,
32-
IUiCommandFactory uiCommandFactory)
46+
IUiCommandFactory uiCommandFactory,
47+
IStandardDialogs standardDialogs)
3348
{
3449
_kitbasherRootScene = kitbasherRootScene;
3550
_skeletonAnimationLookUpHelper = skeletonAnimationLookUpHelper;
3651
_renderEngineComponent = renderEngineComponent;
3752
_uiCommandFactory = uiCommandFactory;
38-
53+
_standardDialogs = standardDialogs;
3954
SkeletonNameList = _skeletonAnimationLookUpHelper.GetAllSkeletonFileNames();
55+
4056
}
4157

58+
static private ObservableCollection<AttachmentPoint> CreateAttachmentPointList(List<RmvAttachmentPoint> attachmentPoints)
59+
{
60+
var output = new ObservableCollection<AttachmentPoint>();
61+
foreach (var attachmentPoint in attachmentPoints)
62+
{
63+
var name = attachmentPoint.Name;
64+
var newAttachmentPoint = new AttachmentPoint()
65+
{
66+
BoneIndex = attachmentPoint.BoneIndex,
67+
Name = name,
68+
IsIdentiy = attachmentPoint.Matrix.IsIdentity()
69+
};
70+
output.Add(newAttachmentPoint);
71+
}
72+
73+
return output;
74+
}
4275

43-
partial void OnSkeletonNameChanged(string? value)
76+
[RelayCommand]
77+
private void ResetAttachmentPointList()
78+
{
79+
if (_mainNode != null)
80+
{
81+
_mainNode.SetAttachmentPoints([], true);
82+
AttachmentPointList = CreateAttachmentPointList(_mainNode.AttachmentPoints);
83+
}
84+
}
85+
86+
partial void OnSkeletonNameChanged(string? oldValue, string? newValue)
4487
{
4588
var cleanSkeletonName = "";
46-
if (!string.IsNullOrWhiteSpace(value))
47-
cleanSkeletonName = Path.GetFileNameWithoutExtension(value);
89+
if (!string.IsNullOrWhiteSpace(newValue))
90+
cleanSkeletonName = Path.GetFileNameWithoutExtension(newValue);
4891
_kitbasherRootScene.SetSkeletonFromName(cleanSkeletonName);
92+
93+
// Changing the skeleton can cause the current attachment points to be invalid.
94+
// If we change skeleton, reset the list
95+
if (oldValue != null && oldValue != newValue)
96+
ResetAttachmentPointList();
4997
}
5098

5199
public void Initialize(ISceneNode node)
52100
{
53101
if (node is MainEditableNode mainEditableNode)
54102
{
55103
_mainNode = mainEditableNode;
56-
if (_mainNode.SkeletonNode != null)
104+
if (_mainNode.SkeletonNode != null && _mainNode.SkeletonNode.Skeleton != null)
57105
SkeletonName = SkeletonNameList.FirstOrDefault(x => Path.GetFileNameWithoutExtension(x).ToLower() == _mainNode.SkeletonNode.Skeleton.SkeletonName.ToLower());
106+
107+
AttachmentPointList = CreateAttachmentPointList(_mainNode.AttachmentPoints);
58108
}
59109
else
60110
{

Editors/Kitbashing/KitbasherEditor/Core/SceneNodeEditor/Nodes/MeshNode/Mesh.Animation/AnimationViewModel.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Windows;
22
using CommunityToolkit.Mvvm.ComponentModel;
3+
using Editors.KitbasherEditor.Core;
34
using Editors.Shared.Core.Services;
45
using GameWorld.Core.SceneNodes;
56
using GameWorld.Core.Utility;

Editors/Kitbashing/KitbasherEditor/Core/SceneNodeEditor/Nodes/MeshNode/Mesh.Geometry/MeshViewModel.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using CommunityToolkit.Mvvm.ComponentModel;
22
using CommunityToolkit.Mvvm.Input;
3+
using Editors.KitbasherEditor.Core;
34
using GameWorld.Core.Components;
45
using GameWorld.Core.SceneNodes;
56
using Microsoft.Xna.Framework;

Editors/Kitbashing/KitbasherEditor/DependencyInjectionContainer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Editors.KitbasherEditor.ChildEditors.PinTool.Commands;
44
using Editors.KitbasherEditor.ChildEditors.ReRiggingTool;
55
using Editors.KitbasherEditor.ChildEditors.VertexDebugger;
6+
using Editors.KitbasherEditor.Core;
67
using Editors.KitbasherEditor.Core.MenuBarViews;
78
using Editors.KitbasherEditor.EventHandlers;
89
using Editors.KitbasherEditor.Services;

0 commit comments

Comments
 (0)