mirror of
https://github.com/4sval/FModel.git
synced 2026-03-22 01:34:37 -05:00
cost less export check
This commit is contained in:
parent
7431ef5592
commit
73fffc5545
|
|
@ -1 +1 @@
|
|||
Subproject commit 095d8457e2e4a2fb307b9ac688420ed30b6207bf
|
||||
Subproject commit ff03587d77e77bb7f7c9b927a38d87e3bdbaa07c
|
||||
|
|
@ -2,20 +2,22 @@ using System;
|
|||
using System.Runtime.CompilerServices;
|
||||
using CUE4Parse.UE4.Assets.Exports;
|
||||
using FModel.Creator.Bases;
|
||||
using FModel.Creator.Bases.BB;
|
||||
using FModel.Creator.Bases.FN;
|
||||
using FModel.Creator.Bases.MV;
|
||||
using FModel.Creator.Bases.SB;
|
||||
|
||||
namespace FModel.Creator;
|
||||
|
||||
public class CreatorPackage : IDisposable
|
||||
{
|
||||
private UObject _object;
|
||||
private string _pkgName;
|
||||
private string _exportType;
|
||||
private Lazy<UObject> _object;
|
||||
private EIconStyle _style;
|
||||
|
||||
public CreatorPackage(UObject uObject, EIconStyle style)
|
||||
public CreatorPackage(string packageName, string exportType, Lazy<UObject> uObject, EIconStyle style)
|
||||
{
|
||||
_pkgName = packageName;
|
||||
_exportType = exportType;
|
||||
_object = uObject;
|
||||
_style = style;
|
||||
}
|
||||
|
|
@ -30,7 +32,7 @@ public class CreatorPackage : IDisposable
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryConstructCreator(out UCreator creator)
|
||||
{
|
||||
switch (_object.ExportType)
|
||||
switch (_exportType)
|
||||
{
|
||||
// Fortnite
|
||||
case "AthenaConsumableEmoteItemDefinition":
|
||||
|
|
@ -145,16 +147,16 @@ public class CreatorPackage : IDisposable
|
|||
case "FortVehicleCosmeticsItemDefinition_EngineAudio":
|
||||
creator = _style switch
|
||||
{
|
||||
EIconStyle.Cataba => new BaseCommunity(_object, _style, "Cataba"),
|
||||
_ => new BaseIcon(_object, _style)
|
||||
EIconStyle.Cataba => new BaseCommunity(_object.Value, _style, "Cataba"),
|
||||
_ => new BaseIcon(_object.Value, _style)
|
||||
};
|
||||
return true;
|
||||
case "JunoAthenaCharacterItemOverrideDefinition":
|
||||
case "JunoAthenaDanceItemOverrideDefinition":
|
||||
creator = new BaseJuno(_object, _style);
|
||||
creator = new BaseJuno(_object.Value, _style);
|
||||
return true;
|
||||
case "FortTandemCharacterData":
|
||||
creator = new BaseTandem(_object, _style);
|
||||
creator = new BaseTandem(_object.Value, _style);
|
||||
return true;
|
||||
case "FortTrapItemDefinition":
|
||||
case "FortSpyTechItemDefinition":
|
||||
|
|
@ -166,26 +168,25 @@ public class CreatorPackage : IDisposable
|
|||
case "FortWeaponMeleeDualWieldItemDefinition":
|
||||
case "FortCreativeWeaponRangedItemDefinition":
|
||||
case "Daybreak_LevelExitVehicle_PartItemDefinition_C":
|
||||
creator = new BaseIconStats(_object, _style);
|
||||
creator = new BaseIconStats(_object.Value, _style);
|
||||
return true;
|
||||
case "FortItemSeriesDefinition":
|
||||
creator = new BaseSeries(_object, _style);
|
||||
creator = new BaseSeries(_object.Value, _style);
|
||||
return true;
|
||||
case "MaterialInstanceConstant"
|
||||
when _object.Owner != null &&
|
||||
(_object.Owner.Name.Contains("/MI_OfferImages/", StringComparison.OrdinalIgnoreCase) ||
|
||||
_object.Owner.Name.EndsWith($"/RenderSwitch_Materials/{_object.Name}", StringComparison.OrdinalIgnoreCase) ||
|
||||
_object.Owner.Name.EndsWith($"/MI_BPTile/{_object.Name}", StringComparison.OrdinalIgnoreCase)):
|
||||
creator = new BaseMaterialInstance(_object, _style);
|
||||
when _pkgName.Contains("/MI_OfferImages/", StringComparison.OrdinalIgnoreCase) ||
|
||||
_pkgName.Contains("/RenderSwitch_Materials/", StringComparison.OrdinalIgnoreCase) ||
|
||||
_pkgName.Contains("/MI_BPTile/", StringComparison.OrdinalIgnoreCase):
|
||||
creator = new BaseMaterialInstance(_object.Value, _style);
|
||||
return true;
|
||||
case "AthenaItemShopOfferDisplayData":
|
||||
creator = new BaseOfferDisplayData(_object, _style);
|
||||
creator = new BaseOfferDisplayData(_object.Value, _style);
|
||||
return true;
|
||||
case "FortMtxOfferData":
|
||||
creator = new BaseMtxOffer(_object, _style);
|
||||
creator = new BaseMtxOffer(_object.Value, _style);
|
||||
return true;
|
||||
case "FortPlaylistAthena":
|
||||
creator = new BasePlaylist(_object, _style);
|
||||
creator = new BasePlaylist(_object.Value, _style);
|
||||
return true;
|
||||
case "FortFeatItemDefinition":
|
||||
case "FortQuestItemDefinition":
|
||||
|
|
@ -193,17 +194,17 @@ public class CreatorPackage : IDisposable
|
|||
case "FortQuestItemDefinition_Campaign":
|
||||
case "AthenaDailyQuestDefinition":
|
||||
case "FortUrgentQuestItemDefinition":
|
||||
creator = new Bases.FN.BaseQuest(_object, _style);
|
||||
creator = new Bases.FN.BaseQuest(_object.Value, _style);
|
||||
return true;
|
||||
case "FortCompendiumItemDefinition":
|
||||
case "FortChallengeBundleItemDefinition":
|
||||
creator = new BaseBundle(_object, _style);
|
||||
creator = new BaseBundle(_object.Value, _style);
|
||||
return true;
|
||||
// case "AthenaSeasonItemDefinition":
|
||||
// creator = new BaseSeason(_object, _style);
|
||||
// return true;
|
||||
case "FortItemAccessTokenType":
|
||||
creator = new BaseItemAccessToken(_object, _style);
|
||||
creator = new BaseItemAccessToken(_object.Value, _style);
|
||||
return true;
|
||||
case "FortCreativeOption":
|
||||
case "PlaylistUserOptionEnum":
|
||||
|
|
@ -217,14 +218,14 @@ public class CreatorPackage : IDisposable
|
|||
case "PlaylistUserTintedIconIntEnum":
|
||||
case "PlaylistUserOptionPrimaryAsset":
|
||||
case "PlaylistUserOptionCollisionProfileEnum":
|
||||
creator = new BaseUserControl(_object, _style);
|
||||
creator = new BaseUserControl(_object.Value, _style);
|
||||
return true;
|
||||
// PandaGame
|
||||
case "CharacterData":
|
||||
creator = new BaseFighter(_object, _style);
|
||||
creator = new BaseFighter(_object.Value, _style);
|
||||
return true;
|
||||
case "PerkGroup":
|
||||
creator = new BasePerkGroup(_object, _style);
|
||||
creator = new BasePerkGroup(_object.Value, _style);
|
||||
return true;
|
||||
case "StatTrackingBundleData":
|
||||
case "HydraSyncedDataAsset":
|
||||
|
|
@ -237,10 +238,10 @@ public class CreatorPackage : IDisposable
|
|||
case "TauntData":
|
||||
case "SkinData":
|
||||
case "PerkData":
|
||||
creator = new BasePandaIcon(_object, _style);
|
||||
creator = new BasePandaIcon(_object.Value, _style);
|
||||
return true;
|
||||
case "QuestData":
|
||||
creator = new Bases.MV.BaseQuest(_object, _style);
|
||||
creator = new Bases.MV.BaseQuest(_object.Value, _style);
|
||||
return true;
|
||||
default:
|
||||
creator = null;
|
||||
|
|
@ -248,7 +249,7 @@ public class CreatorPackage : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
public override string ToString() => $"{_object.ExportType} | {_style}";
|
||||
public override string ToString() => $"{_exportType} | {_style}";
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@ using CUE4Parse.UE4.Wwise;
|
|||
|
||||
using CUE4Parse_Conversion;
|
||||
using CUE4Parse_Conversion.Sounds;
|
||||
|
||||
using CUE4Parse.UE4.Assets;
|
||||
using CUE4Parse.UE4.Objects.UObject;
|
||||
using EpicManifestParser;
|
||||
using EpicManifestParser.UE;
|
||||
using EpicManifestParser.ZlibngDotNetDecompressor;
|
||||
|
|
@ -620,13 +621,16 @@ public class CUE4ParseViewModel : ViewModel
|
|||
case "uasset":
|
||||
case "umap":
|
||||
{
|
||||
var exports = Provider.LoadAllObjects(fullPath);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(exports, Formatting.Indented), saveProperties, updateUi);
|
||||
if (HasFlag(bulk, EBulkType.Properties)) break; // do not search for viewable exports if we are dealing with jsons
|
||||
|
||||
foreach (var e in exports)
|
||||
var pkg = Provider.LoadPackage(fullPath);
|
||||
if (saveProperties || updateUi)
|
||||
{
|
||||
if (CheckExport(cancellationToken, e, bulk))
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(pkg.GetExports(), Formatting.Indented), saveProperties, updateUi);
|
||||
if (saveProperties) break; // do not search for viewable exports if we are dealing with jsons
|
||||
}
|
||||
|
||||
for (var i = 0; i < pkg.ExportMapLength; i++)
|
||||
{
|
||||
if (CheckExport(cancellationToken, pkg, i, bulk))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -807,25 +811,30 @@ public class CUE4ParseViewModel : ViewModel
|
|||
TabControl.AddTab(fullPath.SubstringAfterLast('/'), fullPath.SubstringBeforeLast('/'), parentExportType);
|
||||
TabControl.SelectedTab.ScrollTrigger = objectName;
|
||||
|
||||
var exports = Provider.LoadAllObjects(fullPath);
|
||||
var pkg = Provider.LoadPackage(fullPath);
|
||||
TabControl.SelectedTab.Highlighter = AvalonExtensions.HighlighterSelector(""); // json
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(exports, Formatting.Indented), false, false);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(pkg.GetExports(), Formatting.Indented), false, false);
|
||||
|
||||
foreach (var e in exports)
|
||||
for (var i = 0; i < pkg.ExportMapLength; i++)
|
||||
{
|
||||
if (CheckExport(cancellationToken, e))
|
||||
if (CheckExport(cancellationToken, pkg, i))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckExport(CancellationToken cancellationToken, UObject export, EBulkType bulk = EBulkType.None) // return true once you wanna stop searching for exports
|
||||
private bool CheckExport(CancellationToken cancellationToken, IPackage pkg, int index, EBulkType bulk = EBulkType.None) // return true once you wanna stop searching for exports
|
||||
{
|
||||
var isNone = bulk == EBulkType.None;
|
||||
var updateUi = !HasFlag(bulk, EBulkType.Auto);
|
||||
var saveTextures = HasFlag(bulk, EBulkType.Textures);
|
||||
switch (export)
|
||||
|
||||
var pointer = new FPackageIndex(pkg, index + 1).ResolvedObject;
|
||||
if (pointer?.Object is null) return false;
|
||||
|
||||
var dummy = ((AbstractUePackage) pkg).ConstructObject(pointer.Class?.Object?.Value as UStruct, pkg);
|
||||
switch (dummy)
|
||||
{
|
||||
case UVerseDigest verseDigest when isNone:
|
||||
case UVerseDigest when isNone && pointer.Object.Value is UVerseDigest verseDigest:
|
||||
{
|
||||
if (!TabControl.CanAddTabs) return false;
|
||||
|
||||
|
|
@ -834,20 +843,21 @@ public class CUE4ParseViewModel : ViewModel
|
|||
TabControl.SelectedTab.SetDocumentText(verseDigest.ReadableCode, false, false);
|
||||
return true;
|
||||
}
|
||||
case UTexture texture when isNone || saveTextures:
|
||||
case UTexture when (isNone || saveTextures) && pointer.Object.Value is UTexture texture:
|
||||
{
|
||||
TabControl.SelectedTab.AddImage(texture, saveTextures, updateUi);
|
||||
return false;
|
||||
}
|
||||
case USvgAsset svgasset when isNone || saveTextures:
|
||||
case USvgAsset when (isNone || saveTextures) && pointer.Object.Value is USvgAsset svgasset:
|
||||
{
|
||||
const int size = 512;
|
||||
var data = svgasset.GetOrDefault<byte[]>("SvgData");
|
||||
var sourceFile = svgasset.GetOrDefault<string>("SourceFile");
|
||||
using var stream = new MemoryStream(data) { Position = 0 };
|
||||
var svg = new SkiaSharp.Extended.Svg.SKSvg(new SKSize(512, 512));
|
||||
var svg = new SkiaSharp.Extended.Svg.SKSvg(new SKSize(size, size));
|
||||
svg.Load(stream);
|
||||
|
||||
var bitmap = new SKBitmap(512, 512);
|
||||
var bitmap = new SKBitmap(size, size);
|
||||
using (var canvas = new SKCanvas(bitmap))
|
||||
using (var paint = new SKPaint { IsAntialias = true, FilterQuality = SKFilterQuality.Medium })
|
||||
{
|
||||
|
|
@ -857,11 +867,10 @@ public class CUE4ParseViewModel : ViewModel
|
|||
if (saveTextures)
|
||||
{
|
||||
var fileName = sourceFile.SubstringAfterLast('/');
|
||||
var t = new TabImage(fileName, false, bitmap);
|
||||
var path = Path.Combine(UserSettings.Default.TextureDirectory,
|
||||
UserSettings.Default.KeepDirectoryStructure ? TabControl.SelectedTab.Directory : "", fileName!).Replace('\\', '/');
|
||||
|
||||
System.IO.Directory.CreateDirectory(path.SubstringBeforeLast('/'));
|
||||
Directory.CreateDirectory(path.SubstringBeforeLast('/'));
|
||||
|
||||
using var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read);
|
||||
fs.Write(data, 0, data.Length);
|
||||
|
|
@ -892,9 +901,9 @@ public class CUE4ParseViewModel : ViewModel
|
|||
case USoundWave when isNone:
|
||||
{
|
||||
var shouldDecompress = UserSettings.Default.CompressedAudioMode == ECompressedAudio.PlayDecompressed;
|
||||
export.Decode(shouldDecompress, out var audioFormat, out var data);
|
||||
pointer.Object.Value.Decode(shouldDecompress, out var audioFormat, out var data);
|
||||
var hasAf = !string.IsNullOrEmpty(audioFormat);
|
||||
if (data == null || !hasAf || export.Owner == null)
|
||||
if (data == null || !hasAf)
|
||||
{
|
||||
if (hasAf) FLogger.Append(ELog.Warning, () => FLogger.Text($"Unsupported audio format '{audioFormat}'", Constants.WHITE, true));
|
||||
return false;
|
||||
|
|
@ -916,16 +925,16 @@ public class CUE4ParseViewModel : ViewModel
|
|||
case USkeletalMesh when isNone && UserSettings.Default.PreviewSkeletalMeshes:
|
||||
case USkeleton when isNone && UserSettings.Default.SaveSkeletonAsMesh:
|
||||
case UMaterialInstance when isNone && UserSettings.Default.PreviewMaterials && !ModelIsOverwritingMaterial &&
|
||||
!(Provider.InternalGameName.Equals("FortniteGame", StringComparison.OrdinalIgnoreCase) && export.Owner != null &&
|
||||
(export.Owner.Name.Contains("/MI_OfferImages/", StringComparison.OrdinalIgnoreCase) ||
|
||||
export.Owner.Name.EndsWith($"/RenderSwitch_Materials/{export.Name}", StringComparison.OrdinalIgnoreCase) ||
|
||||
export.Owner.Name.EndsWith($"/MI_BPTile/{export.Name}", StringComparison.OrdinalIgnoreCase))):
|
||||
!(Provider.InternalGameName.Equals("FortniteGame", StringComparison.OrdinalIgnoreCase) &&
|
||||
(pkg.Name.Contains("/MI_OfferImages/", StringComparison.OrdinalIgnoreCase) ||
|
||||
pkg.Name.Contains("/RenderSwitch_Materials/", StringComparison.OrdinalIgnoreCase) ||
|
||||
pkg.Name.Contains("/MI_BPTile/", StringComparison.OrdinalIgnoreCase))):
|
||||
{
|
||||
if (SnooperViewer.TryLoadExport(cancellationToken, export))
|
||||
if (SnooperViewer.TryLoadExport(cancellationToken, dummy, pointer.Object))
|
||||
SnooperViewer.Run();
|
||||
return true;
|
||||
}
|
||||
case UMaterialInstance m when isNone && ModelIsOverwritingMaterial:
|
||||
case UMaterialInstance when isNone && ModelIsOverwritingMaterial && pointer.Object.Value is UMaterialInstance m:
|
||||
{
|
||||
SnooperViewer.Renderer.Swap(m);
|
||||
SnooperViewer.Run();
|
||||
|
|
@ -935,7 +944,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
case UAnimMontage when isNone && ModelIsWaitingAnimation:
|
||||
case UAnimComposite when isNone && ModelIsWaitingAnimation:
|
||||
{
|
||||
SnooperViewer.Renderer.Animate(export);
|
||||
SnooperViewer.Renderer.Animate(pointer.Object);
|
||||
SnooperViewer.Run();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -947,19 +956,19 @@ public class CUE4ParseViewModel : ViewModel
|
|||
case UAnimMontage when HasFlag(bulk, EBulkType.Animations):
|
||||
case UAnimComposite when HasFlag(bulk, EBulkType.Animations):
|
||||
{
|
||||
SaveExport(export, updateUi);
|
||||
SaveExport(pointer.Object.Value, updateUi);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (!isNone && !saveTextures) return false;
|
||||
|
||||
using var package = new CreatorPackage(export, UserSettings.Default.CosmeticStyle);
|
||||
if (!package.TryConstructCreator(out var creator))
|
||||
using var cPackage = new CreatorPackage(pkg.Name, dummy.ExportType, pointer.Object, UserSettings.Default.CosmeticStyle);
|
||||
if (!cPackage.TryConstructCreator(out var creator))
|
||||
return false;
|
||||
|
||||
creator.ParseForInfo();
|
||||
TabControl.SelectedTab.AddImage(export.Name, false, creator.Draw(), saveTextures, updateUi);
|
||||
TabControl.SelectedTab.AddImage(pointer.Object.Value.Name, false, creator.Draw(), saveTextures, updateUi);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,33 +77,33 @@ public class Renderer : IDisposable
|
|||
Color = VertexColor.Default;
|
||||
}
|
||||
|
||||
public void Load(CancellationToken cancellationToken, UObject export)
|
||||
public void Load(CancellationToken cancellationToken, UObject dummy, Lazy<UObject> export)
|
||||
{
|
||||
ShowLights = false;
|
||||
Color = VertexColor.Default;
|
||||
_saveCameraMode = export is not UWorld and not UBlueprintGeneratedClass;
|
||||
switch (export)
|
||||
_saveCameraMode = dummy is not UWorld and not UBlueprintGeneratedClass;
|
||||
switch (dummy)
|
||||
{
|
||||
case UStaticMesh st:
|
||||
case UStaticMesh when export.Value is UStaticMesh st:
|
||||
LoadStaticMesh(st);
|
||||
break;
|
||||
case USkeletalMesh sk:
|
||||
case USkeletalMesh when export.Value is USkeletalMesh sk:
|
||||
LoadSkeletalMesh(sk);
|
||||
break;
|
||||
case USkeleton skel:
|
||||
case USkeleton when export.Value is USkeleton skel:
|
||||
LoadSkeleton(skel);
|
||||
break;
|
||||
case UMaterialInstance mi:
|
||||
case UMaterialInstance when export.Value is UMaterialInstance mi:
|
||||
LoadMaterialInstance(mi);
|
||||
break;
|
||||
case UWorld wd:
|
||||
case UWorld when export.Value is UWorld wd:
|
||||
LoadWorld(cancellationToken, wd, Transform.Identity);
|
||||
break;
|
||||
case UBlueprintGeneratedClass bp:
|
||||
case UBlueprintGeneratedClass when export.Value is UBlueprintGeneratedClass bp:
|
||||
LoadJunoWorld(cancellationToken, bp, Transform.Identity);
|
||||
Color = VertexColor.Colors;
|
||||
break;
|
||||
case UPaperSprite ps:
|
||||
case UPaperSprite when export.Value is UPaperSprite ps:
|
||||
LoadPaperSprite(ps);
|
||||
break;
|
||||
}
|
||||
|
|
@ -119,7 +119,7 @@ public class Renderer : IDisposable
|
|||
Application.Current.Dispatcher.Invoke(() => model.Materials[section.MaterialIndex].Setup(Options, model.UvCount));
|
||||
}
|
||||
|
||||
public void Animate(UObject anim) => Animate(anim, Options.SelectedModel);
|
||||
public void Animate(Lazy<UObject> anim) => Animate(anim.Value, Options.SelectedModel);
|
||||
private void Animate(UObject anim, FGuid guid)
|
||||
{
|
||||
if (!Options.TryGetModel(guid, out var m) || m is not SkeletalModel model)
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ public class Snooper : GameWindow
|
|||
_init = false;
|
||||
}
|
||||
|
||||
public bool TryLoadExport(CancellationToken cancellationToken, UObject export)
|
||||
public bool TryLoadExport(CancellationToken cancellationToken, UObject dummy, Lazy<UObject> export)
|
||||
{
|
||||
Renderer.Load(cancellationToken, export);
|
||||
Renderer.Load(cancellationToken, dummy, export);
|
||||
return Renderer.Options.Models.Count > 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user