Skip to content

Commit 05bf345

Browse files
Merge branch 'kagenocookie:master' into master
2 parents 1e443cc + 4f6977e commit 05bf345

File tree

5 files changed

+121
-19
lines changed

5 files changed

+121
-19
lines changed

ContentEditor.App/Graphics/OpenGLRenderContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ public override (MeshHandle, ShapeMesh) CreateShapeMesh()
242242
foreach (var sub in group.Submeshes) {
243243
var newMesh = meshlist[meshIdx++].Clone();
244244
newMesh.Initialize(GL);
245-
handle.SetMaterialName(handle.Meshes.Count, meshFile.MaterialNames[sub.materialIndex]);
245+
handle.SetMaterialName(handle.Meshes.Count, sub.materialIndex >= meshFile.MaterialNames.Count ? "default" : meshFile.MaterialNames[sub.materialIndex]);
246246
handle.Bones = boneList;
247247
handle.Meshes.Add(newMesh);
248248
}

ContentEditor.App/Imgui/App/BundleManagementUI.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ private void ShowEditNativesPathPopup(object? entry, Bundle bundle)
459459
ImGui.SeparatorText("Edit Natives Path");
460460
ImGui.SetNextItemWidth(ImGui.CalcTextSize(target).X + 15);
461461
if (ImGui.InputText("##target", ref target, 512)) {
462-
d.Target = target;
462+
d.Target = target.ToLowerInvariant();
463463
}
464464
ImGui.SameLine();
465465
if (ImGui.Button($"{AppIcons.SI_Save}")) {

ContentEditor.App/Imgui/App/MeshViewer.cs

Lines changed: 103 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using ContentEditor.Editor;
99
using ContentPatcher;
1010
using ReeLib;
11+
using ReeLib.Common;
1112
using ReeLib.via;
1213

1314
namespace ContentEditor.App;
@@ -145,7 +146,7 @@ public void ChangeMesh(FileHandle newHandle)
145146
ChangeMesh();
146147
}
147148

148-
private void ChangeMesh()
149+
private void ChangeMesh(bool resetMdf = true)
149150
{
150151
meshPath = Handle.Filepath;
151152
if (!Handle.References.Contains(this)) Handle.References.Add(this);
@@ -156,11 +157,19 @@ private void ChangeMesh()
156157
}
157158
return;
158159
}
159-
TryGuessMdfFilepath();
160+
if (resetMdf) TryGuessMdfFilepath();
160161

161162
var meshComponent = previewGameobject?.GetComponent<MeshComponent>();
162-
meshComponent?.Transform.InvalidateTransform();
163-
meshComponent?.SetMesh(Handle, Handle);
163+
if (meshComponent != null) {
164+
165+
meshComponent.Transform.InvalidateTransform();
166+
if (!string.IsNullOrEmpty(mdfSource)) {
167+
isMDFUpdateRequest = true;
168+
UpdateMaterial(meshComponent);
169+
} else {
170+
meshComponent.SetMesh(Handle, Handle);
171+
}
172+
}
164173
if (mesh.HasAnimations && string.IsNullOrEmpty(animationSourceFile)) {
165174
animationSourceFile = Handle.Filepath;
166175
}
@@ -310,6 +319,12 @@ private bool ShowMenu(MeshComponent meshComponent)
310319
ImguiHelpers.VerticalSeparator();
311320
if (ImGui.MenuItem($"{AppIcons.SI_MeshViewerMeshGroup} Mesh Groups")) ImGui.OpenPopup("MeshGroups");
312321
if (ImGui.MenuItem($"{AppIcons.SI_FileType_MDF} Material")) ImGui.OpenPopup("Material");
322+
var mdfErrors = GetMdfErrors();
323+
if (mdfErrors != null) {
324+
using var _ = ImguiHelpers.OverrideStyleCol(ImGuiCol.Text, Colors.Warning);
325+
ImGui.MenuItem($"{AppIcons.SI_GenericWarning}");
326+
ImguiHelpers.Tooltip(mdfErrors);
327+
}
313328
if (ImGui.BeginMenu($"{AppIcons.SI_FileType_RCOL} RCOL")) {
314329
var rcolEdit = Scene!.Root.SetEditMode(previewGameobject.GetOrAddComponent<RequestSetColliderComponent>());
315330
rcolEdit?.DrawMainUI();
@@ -398,6 +413,26 @@ private void ShowMeshInfo()
398413
}
399414
}
400415

416+
private string? GetMdfErrors()
417+
{
418+
var meshComponent = previewGameobject?.GetComponent<MeshComponent>();
419+
if (meshComponent?.MeshHandle == null || mesh == null || string.IsNullOrEmpty(mdfSource)) return null;
420+
421+
if (mesh != null && meshComponent.MeshHandle?.Material != null) {
422+
var mdfMats = meshComponent.MeshHandle.Material.Materials;
423+
var matNames = mesh.NativeMesh.MaterialNames;
424+
var nameMismatch = matNames.Any(name => !mdfMats.Select(m => m.name).Contains(name));
425+
if (mdfMats.Count != mesh.NativeMesh.MaterialNames.Count) {
426+
return "Mesh material count does not match MDF2 material count. Textures won't display correctly ingame.\nEnsure that both counts match.";
427+
}
428+
if (nameMismatch) {
429+
return "Mesh references material names that are not present in the selected MDF2.";
430+
}
431+
}
432+
433+
return null;
434+
}
435+
401436
private void ShowMaterialSettings(MeshComponent meshComponent)
402437
{
403438
bool useHighRes = textureMode == TextureMode.HighRes;
@@ -422,6 +457,69 @@ private void ShowMaterialSettings(MeshComponent meshComponent)
422457
(v, p) => v.mdfSource = p ?? "");
423458
}
424459
mdfPickerContext.ShowUI();
460+
if (mesh != null && meshComponent.MeshHandle?.Material != null) {
461+
var mdfMats = meshComponent.MeshHandle.Material.Materials;
462+
var matNames = mesh.NativeMesh.MaterialNames;
463+
var nameMismatch = matNames.Any(name => !mdfMats.Select(m => m.name).Contains(name));
464+
var error = GetMdfErrors();
465+
if (error != null) {
466+
ImGui.TextColored(Colors.Warning, error);
467+
}
468+
469+
if (mesh.NativeMesh.MaterialNames.Count < mdfMats.Count && !string.IsNullOrEmpty(mdfSource)) {
470+
if (ImGui.Button("Add missing materials from selected MDF2")) {
471+
AlignMatNamesToMdf();
472+
}
473+
}
474+
475+
ImGui.SeparatorText("Material mapping");
476+
for (int i = 0; i < mesh.NativeMesh.MaterialNames.Count; i++) {
477+
var matName = mesh.NativeMesh.MaterialNames[i];
478+
if (ImGui.Button($"{AppIcons.SI_GenericDelete}##{i}")) {
479+
var i_backup = i--;
480+
UndoRedo.RecordCallback(null, () => matNames.RemoveAt(i_backup), () => matNames.Insert(i_backup, matName));
481+
UndoRedo.AttachCallbackToLastAction(UndoRedo.CallbackType.Both, ApplyMeshChanges);
482+
continue;
483+
}
484+
ImGui.SameLine();
485+
ImGui.Text(i.ToString());
486+
ImGui.SameLine();
487+
if (ImGui.InputText($"##{i}", ref matName, 48)) {
488+
var prevName = mesh.NativeMesh.MaterialNames[i];
489+
int i_backup = i;
490+
UndoRedo.RecordCallbackSetter(null, mesh.NativeMesh.MaterialNames, prevName, matName, (o, v) => o[i_backup] = v, $"MatName{i}_{Handle.Filepath}");
491+
UndoRedo.AttachCallbackToLastAction(UndoRedo.CallbackType.Both, ApplyMeshChanges);
492+
}
493+
}
494+
if (ImGui.Button($"{AppIcons.SI_GenericAdd}")) {
495+
var newName = "NewMaterial".GetUniqueName(s => matNames.Contains(s));
496+
UndoRedo.RecordCallback(null, () => matNames.Add(newName), () => matNames.Remove(newName));
497+
UndoRedo.AttachCallbackToLastAction(UndoRedo.CallbackType.Both, ApplyMeshChanges);
498+
}
499+
}
500+
}
501+
502+
private void ApplyMeshChanges()
503+
{
504+
Handle.Modified = true;
505+
ChangeMesh(false);
506+
}
507+
508+
private void AlignMatNamesToMdf()
509+
{
510+
var meshComponent = previewGameobject?.GetComponent<MeshComponent>();
511+
if (meshComponent?.MeshHandle == null || mesh == null) return;
512+
513+
var mdfMats = meshComponent.MeshHandle.Material.Materials;
514+
var matNames = mesh.NativeMesh.MaterialNames;
515+
if (matNames.Count < mdfMats.Count) {
516+
var missingMats = mdfMats.Select(m => m.name).Where(m => !matNames.Contains(m));
517+
foreach (var mat in missingMats) {
518+
if (matNames.Count >= mdfMats.Count) break;
519+
matNames.Add(mat);
520+
}
521+
}
522+
Handle.Modified = true;
425523
}
426524

427525
private void ShowImportExportMenu()
@@ -477,6 +575,7 @@ private void ShowImportExportMenu()
477575
Handle.Revert(Workspace);
478576
Handle.Modified = true;
479577
ChangeMesh();
578+
AlignMatNamesToMdf();
480579
}
481580
});
482581
}, lastImportSourcePath, fileExtension: FileFilters.MeshFilesAll);

ContentPatcher/Data/ResourceManager.cs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ public IEnumerable<KeyValuePair<long, IContentResource>> GetResourceInstances(st
330330

331331
if (fieldResource.FilePath == null) {
332332
// ignore - there's no file here
333-
} else if (openFiles.TryGetValue(fieldResource.FilePath, out var file)) {
333+
} else if (openFiles.TryGetValue(fieldResource.FilePath.ToLowerInvariant(), out var file)) {
334334
file.Modified = true;
335335
} else {
336336
throw new Exception("New resource file should've been opened, wtf?");
@@ -746,6 +746,7 @@ public bool TryResolveStreamingBufferFile(string streamingNativePath, string fil
746746
{
747747
var rawStream = workspace.Env.FindSingleFile(streamingNativePath, out var resolvedPath);
748748
if (rawStream != null && resolvedPath != null) {
749+
resolvedPath = resolvedPath.ToLowerInvariant();
749750
if (openFiles.TryGetValue(resolvedPath, out file)) {
750751
rawStream.Dispose();
751752
return true;
@@ -775,7 +776,7 @@ public bool TryResolveStreamingBufferFile(string streamingNativePath, string fil
775776
{
776777
filepath = filepath.NormalizeFilepath();
777778
nativePath ??= PreprocessNativeFilepath(filepath);
778-
if (openFiles.TryGetValue(nativePath ?? filepath, out var handle)) {
779+
if (openFiles.TryGetValue(nativePath ?? filepath.ToLowerInvariant(), out var handle)) {
779780
return handle;
780781
}
781782

@@ -786,13 +787,13 @@ public bool TryResolveStreamingBufferFile(string streamingNativePath, string fil
786787
{
787788
filepath = filepath.NormalizeFilepath();
788789
filepath = workspace.Env.PrependBasePath(filepath);
789-
if (activeBundle?.ResourceListing != null && Path.IsPathFullyQualified(filepath) && filepath.StartsWith(workspace.BundleManager.GetBundleFolder(activeBundle))) {
790+
if (activeBundle?.ResourceListing != null && Path.IsPathFullyQualified(filepath) && filepath.StartsWith(workspace.BundleManager.GetBundleFolder(activeBundle), StringComparison.InvariantCultureIgnoreCase)) {
790791
var localPath = Path.GetRelativePath(workspace.BundleManager.GetBundleFolder(activeBundle), filepath);
791792
if (activeBundle.ResourceListing.TryGetValue(localPath, out var resourceList)) {
792793
return resourceList.Target;
793794
}
794795
}
795-
return filepath.IsNativePath() ? filepath : null;
796+
return filepath.IsNativePath() ? filepath.ToLowerInvariant() : null;
796797
}
797798

798799
private FileHandle? ReadFileResource(string filepath, string? nativePath, bool includeActiveBundle)
@@ -805,7 +806,7 @@ public bool TryResolveStreamingBufferFile(string streamingNativePath, string fil
805806
handle = CreateFileHandleInternal(filepath, nativePath, file);
806807
if (handle == null) return null;
807808

808-
openFiles.TryAdd(handle.NativePath ?? handle.Filepath, handle);
809+
openFiles.TryAdd(handle.NativePath ?? handle.Filepath.ToLowerInvariant(), handle);
809810
return handle;
810811
}
811812

@@ -839,7 +840,7 @@ public bool TryResolveStreamingBufferFile(string streamingNativePath, string fil
839840
}
840841

841842
if (handle == null) return null;
842-
openFiles.TryAdd(handle.NativePath ?? handle.Filepath, handle);
843+
openFiles.TryAdd(handle.NativePath ?? handle.Filepath.ToLowerInvariant(), handle);
843844
return handle;
844845
}
845846

@@ -933,7 +934,7 @@ public bool CanLoadFile(string filepath)
933934
return null;
934935
}
935936

936-
openFiles[filename] = handle;
937+
openFiles[filename.ToLowerInvariant()] = handle;
937938
handle.Resource = newFileResource;
938939
handle.DiffHandler = loader.CreateDiffHandler();
939940
return handle;
@@ -1019,7 +1020,7 @@ public FileHandle CreateFileHandle(string filepath, string? nativePath, Stream s
10191020
if (handle == null) {
10201021
throw new NotSupportedException();
10211022
}
1022-
string filekey = handle.NativePath ?? handle.Filepath;
1023+
string filekey = handle.NativePath ?? handle.Filepath.ToLowerInvariant();
10231024
if (keepFileReference && !openFiles.TryAdd(filekey, handle)) {
10241025
var prev = openFiles[filekey];
10251026
CloseFile(prev);
@@ -1069,7 +1070,7 @@ public FileHandle GetBaseFile(string filepath)
10691070
public void MarkFileResourceModified(string filepath, bool markModified)
10701071
{
10711072
filepath = PreprocessNativeFilepath(filepath) ?? filepath;
1072-
if (openFiles.TryGetValue(filepath, out var fileResource)) {
1073+
if (openFiles.TryGetValue(filepath.ToLowerInvariant(), out var fileResource)) {
10731074
fileResource.Modified = markModified;
10741075
}
10751076
}
@@ -1082,7 +1083,7 @@ public void MarkFileResourceModified(string filepath, bool markModified)
10821083
public TFileType? GetOpenFile<TFileType>(string filepath, bool markModified = false) where TFileType : BaseFile
10831084
{
10841085
filepath = PreprocessNativeFilepath(filepath) ?? filepath;
1085-
if (openFiles?.TryGetValue(filepath, out var handle) == true) {
1086+
if (openFiles?.TryGetValue(filepath.ToLowerInvariant(), out var handle) == true) {
10861087
var file = handle.GetFile<TFileType>();
10871088
if (markModified) {
10881089
handle.Modified = true;
@@ -1107,7 +1108,7 @@ public IEnumerable<FileHandle> GetModifiedResourceFiles()
11071108

11081109
public void CloseFile(FileHandle file)
11091110
{
1110-
if (!openFiles.Remove(file.Filepath, out _) && file.NativePath != null) {
1111+
if (!openFiles.Remove(file.Filepath.ToLowerInvariant(), out _) && file.NativePath != null) {
11111112
openFiles.Remove(file.NativePath, out _);
11121113
}
11131114
foreach (var rf in file.References) {
@@ -1120,7 +1121,9 @@ public void CloseAllFiles()
11201121
{
11211122
var files = openFiles.Keys.ToList();
11221123
foreach (var file in files) {
1123-
CloseFile(openFiles[file]);
1124+
if (openFiles.TryGetValue(file, out var fh)) {
1125+
CloseFile(fh);
1126+
}
11241127
}
11251128
}
11261129

RE-Engine-Lib

0 commit comments

Comments
 (0)