Skip to content

Commit 412b22c

Browse files
Merge pull request #269 from mr-phazer/master
Updates and fixes for GFLT Import
2 parents 639ab5a + cb725f7 commit 412b22c

40 files changed

+1437
-166
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using DirectXTexNet;
7+
using Shared.Core.Settings;
8+
using Shared.GameFormats.RigidModel.Types;
9+
10+
namespace Editors.ImportExport.Common.Interfaces
11+
{
12+
public interface IImageProcessor
13+
{
14+
ScratchImage Transform(ScratchImage scratchImage);
15+
}
16+
17+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Editors.ImportExport.Importing.Importers.PngToDds.Helpers.ImageProcessor;
7+
using Shared.Core.Settings;
8+
using Shared.GameFormats.RigidModel.Types;
9+
10+
namespace Editors.ImportExport.Common.Interfaces
11+
{
12+
public static class ImageProcessorFactory
13+
{
14+
private static readonly Dictionary<TextureType, IImageProcessor> _textureAndGameTypeToTranformer = new Dictionary<TextureType, IImageProcessor>()
15+
{
16+
{TextureType.Diffuse, new DefaultImageProcessor() },
17+
{TextureType.MaterialMap, new BlenderToWH3MaterialMapProcessor() },
18+
{TextureType.BaseColour, new DefaultImageProcessor() },
19+
{TextureType.Normal, new BlueToOrangeNormalMapProcessor() }
20+
};
21+
22+
public static IImageProcessor CreateImageProcessor(TextureType textureType)
23+
{
24+
if (_textureAndGameTypeToTranformer.TryGetValue(textureType, out var imageProcessor))
25+
{
26+
return imageProcessor;
27+
}
28+
29+
return new DefaultImageProcessor();
30+
}
31+
}
32+
}

Editors/ImportExportEditor/Editors.ImportExport/DependencyInjectionContainer.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
using Editors.ImportExport.Importing;
1414
using Editors.ImportExport.Importing.Importers.GltfToRmv;
1515
using Editors.ImportExport.Importing.Importers.GltfToRmv.Helper;
16+
using Editors.ImportExport.Importing.Presentation;
1617
using Microsoft.Extensions.DependencyInjection;
1718
using Shared.Core.DependencyInjection;
1819
using Shared.Core.DevConfig;
20+
using Editors.ImportImport.Importing.Presentation.RmvToGltf;
1921
using Shared.Ui.BaseDialogs.PackFileTree.ContextMenu.External;
2022

2123
namespace Editors.ImportExport
@@ -38,8 +40,14 @@ public override void Register(IServiceCollection services)
3840
services.AddTransient<IDdsToNormalPngExporter, DdsToNormalPngExporter>();
3941
services.AddTransient<RmvToGltfExporter>();
4042

43+
// Importer ViewModels
44+
RegisterWindow<ImportWindow>(services);
45+
services.AddTransient<ImporterCoreViewModel>();
46+
services.AddTransient<IImporterViewModel, RmvToGltfImporterViewModel>();
47+
4148
// Importers
4249
services.AddTransient<GltfImporter>();
50+
services.AddTransient<RmvMaterialBuilder>();
4351

4452
// Image Save Helper
4553
services.AddScoped<IImageSaveHandler, SystemImageSaveHandler>();
@@ -57,7 +65,7 @@ public override void Register(IServiceCollection services)
5765
services.AddTransient<IGltfSceneLoader, GltfSceneLoader>();
5866
services.AddTransient<GltfSkeletonBuilder>();
5967
services.AddTransient<GltfAnimationBuilder>();
60-
68+
6169
RegisterAllAsInterface<IDeveloperConfiguration>(services, ServiceLifetime.Transient);
6270
}
6371
}

Editors/ImportExportEditor/Editors.ImportExport/DevConfig/Export_Karl.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public void OpenFileOnLoad()
3939

4040
Directory.CreateDirectory(destPath);
4141

42-
var settings = new RmvToGltfExporterSettings(meshPackFile, new List<PackFile>() { animPackFile }, destPath + "myKarl.gltf", true, true, true, true);
42+
var settings = new RmvToGltfExporterSettings(meshPackFile, new List<PackFile>() { animPackFile }, destPath + "myKarl.gltf", true, true, true, true, true);
4343
_exporter.Export(settings);
4444
}
4545

Editors/ImportExportEditor/Editors.ImportExport/Editors.ImportExport.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
</ItemGroup>
1818

1919
<ItemGroup>
20+
<PackageReference Include="DirectXTexNet" Version="1.0.7" />
2021
<PackageReference Include="SharpGLTF.Core" Version="1.0.3" />
2122
<PackageReference Include="SharpGLTF.Toolkit" Version="1.0.3" />
2223
</ItemGroup>

Editors/ImportExportEditor/Editors.ImportExport/Exporting/ExportFileContextMenuHelper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using Editors.ImportExport.Exporting.Exporters;
2-
using Editors.ImportExport.Misc;
1+
using Editors.ImportExport.Misc;
2+
using Editors.ImportExport.Exporting.Exporters;
33
using Shared.Core.Events;
44
using Shared.Core.PackFiles.Models;
55
using Shared.Core.Settings;

Editors/ImportExportEditor/Editors.ImportExport/Exporting/Exporters/RmvToGltf/Helpers/GltfMeshBuilder.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Numerics;
1+
using System.IO;
2+
using System.Numerics;
23
using Editors.ImportExport.Common;
34
using Shared.GameFormats.RigidModel;
45
using Shared.GameFormats.RigidModel.Vertex;
@@ -120,8 +121,17 @@ MaterialBuilder Create(RmvToGltfExporterSettings settings, string materialName,
120121
.WithAlpha(AlphaMode.MASK);
121122

122123
foreach (var texture in texturesForModel)
124+
{
123125
material.WithChannelImage(texture.GlftTexureType, texture.SystemFilePath);
124126

127+
var channel = material.UseChannel(texture.GlftTexureType);
128+
if (channel?.Texture?.PrimaryImage != null)
129+
{
130+
// Set SharpGLTF to re-resave textures with specified paths, default behavior is texturePath = "{folder}\meshName{counter}.png"
131+
channel.Texture.PrimaryImage.AlternateWriteFileName = Path.GetFileName(texture.SystemFilePath);
132+
}
133+
}
134+
125135
return material;
126136
}
127137
}

Editors/ImportExportEditor/Editors.ImportExport/Exporting/Exporters/RmvToGltf/Helpers/GltfSkeletonBuilder.cs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.Numerics;
22
using Editors.ImportExport.Common;
3-
using Editors.ImportExport.Exporting.Exporters.GltfSkeleton;
43
using Editors.Shared.Core.Services;
54
using GameWorld.Core.Animation;
65
using GameWorld.Core.SceneNodes;
@@ -22,14 +21,14 @@ public class GltfSkeletonBuilder
2221

2322
public GltfSkeletonBuilder(IPackFileService packFileService)
2423
{
25-
_packFileService = packFileService;
24+
_packFileService = packFileService;
2625
}
2726

2827
public ProcessedGltfSkeleton CreateSkeleton(AnimationFile skeletonAnimFile, ModelRoot outputScene, RmvToGltfExporterSettings settings)
29-
{
28+
{
3029
var gltfSkeleton = CreateSkeleton(outputScene, skeletonAnimFile, settings.MirrorMesh);
31-
32-
return gltfSkeleton;
30+
31+
return gltfSkeleton;
3332
}
3433

3534
ProcessedGltfSkeleton CreateSkeleton(ModelRoot outputScene, AnimationFile animSkeletonFil, bool doMirror)
@@ -48,8 +47,8 @@ ProcessedGltfSkeleton CreateSkeleton(ModelRoot outputScene, AnimationFile animSk
4847
var outputGltfBindings = new List<(Node node, Matrix4x4 invMatrix)>();
4948

5049
var scene = outputScene.UseScene("default");
51-
52-
scene.CreateNode($"//skeleton//{animSkeletonFil.Header.SkeletonName.ToLower()}");
50+
51+
AddSkeletonIdNodeToScene(animSkeletonFil, scene);
5352

5453
var parentIdToGltfNode = new Dictionary<int, Node>();
5554
parentIdToGltfNode[-1] = scene.CreateNode(""); // bones with no parent will be children of the scene
@@ -58,7 +57,7 @@ ProcessedGltfSkeleton CreateSkeleton(ModelRoot outputScene, AnimationFile animSk
5857
{
5958
var parentNode = parentIdToGltfNode[animSkeletonFil.Bones[boneIndex].ParentId];
6059
if (parentNode == null)
61-
throw new Exception($"Parent Node not found for boneIndex={boneIndex}");
60+
throw new Exception($"Parent Node cannot be null. boneIndex={boneIndex}");
6261

6362
parentIdToGltfNode[boneIndex] = parentNode.CreateNode(animSkeletonFil.Bones[boneIndex].Name);
6463

@@ -74,7 +73,10 @@ ProcessedGltfSkeleton CreateSkeleton(ModelRoot outputScene, AnimationFile animSk
7473

7574
return new ProcessedGltfSkeleton() { Data = outputGltfBindings };
7675
}
77-
78-
76+
77+
private static void AddSkeletonIdNodeToScene(AnimationFile animSkeletonFil, Scene scene)
78+
{
79+
scene.CreateNode($"//skeleton//{animSkeletonFil.Header.SkeletonName.ToLower()}");
80+
}
7981
}
8082
}

Editors/ImportExportEditor/Editors.ImportExport/Exporting/Exporters/RmvToGltf/Helpers/GltfTextureHandler.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ public List<TextureResult> HandleTextures(RmvFile rmvFile, RmvToGltfExporterSett
2828
{
2929
var output = new List<TextureResult>();
3030

31+
if (!settings.ExportMaterials)
32+
return output;
33+
3134
var exportedTextures = new Dictionary<string, string>(); // To avoid exporting same texture multiple times
3235

3336
int lodICounnt = 1;

Editors/ImportExportEditor/Editors.ImportExport/Exporting/Exporters/RmvToGltf/Helpers/SkeletalAnimationMath.cs

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using Editors.ImportExport.Common;
22
using Microsoft.Xna.Framework;
33
using Shared.GameFormats.Animation;
4+
using SharpGLTF.Animations;
5+
using SharpGLTF.Schema2;
46

5-
namespace Editors.ImportExport.Exporting.Exporters.GltfSkeleton
7+
namespace Editors.ImportExport.Exporting.Exporters.RmvToGltf.Helpers
68
{
79
public class TransformData
810
{
@@ -32,7 +34,51 @@ public Matrix GlobalTransform
3234
}
3335
}
3436
}
37+
public class GltfAnimationTrackSampler
38+
{
39+
static public Vector3 SampleTranslation(ModelRoot model, string boneName, float time)
40+
{
41+
// Access the first animation
42+
var animation = model.LogicalAnimations[0];
43+
44+
// Access the first node
45+
var node = model.LogicalNodes.FirstOrDefault(n => n.Name.ToLower() == boneName.ToLower());
46+
47+
if (node == null)
48+
{
49+
throw new Exception("Error, Unexpected, Node not found");
50+
}
51+
52+
// Get the translation sampler for the node
53+
var translationSampler = animation.FindTranslationChannel(node).GetTranslationSampler().CreateCurveSampler();
54+
55+
var translationVector = translationSampler.GetPoint(time);
56+
57+
return GlobalSceneTransforms.FlipVector(translationVector, true);
58+
}
59+
60+
static public Quaternion SampleQuaternion(ModelRoot model, string boneName, float time)
61+
{
62+
// Access the first animation
63+
var animation = model.LogicalAnimations[0];
3564

65+
// Access the first nodef
66+
var node = model.LogicalNodes.FirstOrDefault(n => n.Name.ToLower() == boneName.ToLower());
67+
68+
if (node == null)
69+
{
70+
throw new Exception("Error, Unexpected, Node not found");
71+
}
72+
73+
// Get the translation sampler for the node
74+
var quaternionSampler = animation.FindRotationChannel(node).GetRotationSampler().CreateCurveSampler();
75+
76+
var outQuaternion = quaternionSampler.GetPoint(time);
77+
78+
return GlobalSceneTransforms.FlipQuaternion(outQuaternion, true);
79+
}
80+
81+
}
3682
internal class FramePoseMatrixCalculator
3783
{
3884
private readonly AnimationFile _animationFile;
@@ -83,13 +129,13 @@ private static void ValidDateSkeletonFile(AnimationFile file)
83129
throw new Exception($"No anim parts! Bone Count: {file.Bones.Length}");
84130

85131
if (file.AnimationParts[0].DynamicFrames.Count == 0)
86-
throw new Exception($"No anim frames, in part 0! Bone Count: {file.Bones.Length}, Anim Parts Count: {file.AnimationParts.Count}");
132+
throw new Exception($"No anim frames, in part 0! Bone Count: {file.Bones.Length}, Anim Parts Count: {file.AnimationParts.Count}");
87133

88134
if (file.AnimationParts[0].DynamicFrames[0].Quaternion.Count != file.Bones.Length)
89-
throw new Exception($"Not a valid skeleton file, doesn't contain quaternion values for all bones! Quat count frame 0: {file.AnimationParts[0].DynamicFrames[0].Quaternion.Count}, Bone count {file.Bones.Length}");
90-
135+
throw new Exception($"Not a valid skeleton file, doesn't contain quaternion values for all bones! Quat count frame 0: {file.AnimationParts[0].DynamicFrames[0].Quaternion.Count}, Bone count {file.Bones.Length}");
136+
91137
if (file.AnimationParts[0].DynamicFrames[0].Transforms.Count != file.Bones.Length)
92-
throw new Exception($"Not a valid skeleton file, doesn't contain translation values for all bones! Trans count frame 0: {file.AnimationParts[0].DynamicFrames[0].Transforms.Count}, Bone count {file.Bones.Length}");
138+
throw new Exception($"Not a valid skeleton file, doesn't contain translation values for all bones! Trans count frame 0: {file.AnimationParts[0].DynamicFrames[0].Transforms.Count}, Bone count {file.Bones.Length}");
93139
}
94140

95141
private void RebuildSkeletonGlobalMatrices(bool doMirror)
@@ -104,7 +150,7 @@ private void RebuildSkeletonGlobalMatrices(bool doMirror)
104150
_worldTransform[boneIndex] = transform;
105151
}
106152

107-
for (var i = 0; i < _worldTransform.Length; i++)
153+
for (var i = 0; i < _worldTransform.Length; i++)
108154
{
109155
var parentIndex = _animationFile.Bones[i].ParentId;
110156

0 commit comments

Comments
 (0)