Textures in primary content extraction

This commit is contained in:
ds5678 2024-07-20 09:03:10 -07:00
parent 89402cdfce
commit 862004ef35
5 changed files with 118 additions and 2 deletions

View File

@ -3,6 +3,7 @@ using AssetRipper.Import.Logging;
using AssetRipper.SourceGenerated.Classes.ClassID_117;
using AssetRipper.SourceGenerated.Classes.ClassID_187;
using AssetRipper.SourceGenerated.Classes.ClassID_188;
using AssetRipper.SourceGenerated.Classes.ClassID_189;
using AssetRipper.SourceGenerated.Classes.ClassID_28;
using AssetRipper.SourceGenerated.Classes.ClassID_89;
using AssetRipper.SourceGenerated.Enums;
@ -21,6 +22,24 @@ namespace AssetRipper.Export.Modules.Textures
{
public static class TextureConverter
{
public static bool TryConvertToBitmap(IImageTexture texture, out DirectBitmap bitmap)
{
return texture switch
{
ICubemapArray cubemapArray => TryConvertToBitmap(cubemapArray, out bitmap),
ITexture2DArray texture2DArray => TryConvertToBitmap(texture2DArray, out bitmap),
ITexture3D texture3D => TryConvertToBitmap(texture3D, out bitmap),
ITexture2D texture2D => TryConvertToBitmap(texture2D, out bitmap),
_ => ReturnFalse(out bitmap),
};
static bool ReturnFalse(out DirectBitmap bitmap)
{
bitmap = DirectBitmap.Empty;
return false;
}
}
public static bool TryConvertToBitmap(ITexture3D texture, out DirectBitmap bitmap)
{
byte[] buffer = texture.GetImageData();

View File

@ -1,9 +1,11 @@
using AssetRipper.Assets;
using AssetRipper.Assets.Bundles;
using AssetRipper.Export.Modules.Textures;
using AssetRipper.Export.PrimaryContent.Audio;
using AssetRipper.Export.PrimaryContent.DeletedAssets;
using AssetRipper.Export.PrimaryContent.Models;
using AssetRipper.Export.PrimaryContent.Scripts;
using AssetRipper.Export.PrimaryContent.Textures;
using AssetRipper.Import.Configuration;
using AssetRipper.Import.Logging;
using AssetRipper.Processing;
@ -12,6 +14,7 @@ using AssetRipper.SourceGenerated.Classes.ClassID_115;
using AssetRipper.SourceGenerated.Classes.ClassID_128;
using AssetRipper.SourceGenerated.Classes.ClassID_152;
using AssetRipper.SourceGenerated.Classes.ClassID_156;
using AssetRipper.SourceGenerated.Classes.ClassID_189;
using AssetRipper.SourceGenerated.Classes.ClassID_2;
using AssetRipper.SourceGenerated.Classes.ClassID_238;
using AssetRipper.SourceGenerated.Classes.ClassID_3;
@ -68,6 +71,8 @@ public sealed class PrimaryContentExporter
RegisterHandler<IAudioClip>(new AudioContentExtractor());
RegisterHandler<IImageTexture>(new TextureExporter(ImageExportFormat.Png));
RegisterHandler<IMonoScript>(new ScriptContentExtractor(gameData.AssemblyManager));
// Deleted assets

View File

@ -0,0 +1,54 @@
using AssetRipper.Assets;
using AssetRipper.Export.Modules.Textures;
using AssetRipper.SourceGenerated.Classes.ClassID_189;
using AssetRipper.SourceGenerated.Extensions;
namespace AssetRipper.Export.PrimaryContent.Textures;
public sealed class TextureExporter : IContentExtractor
{
public ImageExportFormat ImageFormat { get; }
public TextureExporter(ImageExportFormat imageFormat)
{
ImageFormat = imageFormat;
}
public bool TryCreateCollection(IUnityObjectBase asset, [NotNullWhen(true)] out ExportCollectionBase? exportCollection)
{
if (asset is IImageTexture texture && texture.CheckAssetIntegrity())
{
exportCollection = new ImageExportCollection(this, texture);
return true;
}
else
{
exportCollection = null;
return false;
}
}
public bool Export(IUnityObjectBase asset, string path)
{
if (TextureConverter.TryConvertToBitmap((IImageTexture)asset, out DirectBitmap bitmap))
{
using FileStream stream = File.Create(path);
bitmap.Save(stream, ImageFormat);
return true;
}
else
{
return false;
}
}
private sealed class ImageExportCollection : SingleExportCollection<IImageTexture>
{
private ImageExportFormat ExportFormat => ((TextureExporter)ContentExtractor).ImageFormat;
protected override string ExportExtension => ExportFormat.GetFileExtension();
public ImageExportCollection(IContentExtractor contentExtractor, IImageTexture asset) : base(contentExtractor, asset)
{
}
}
}

View File

@ -5,7 +5,7 @@ using AssetRipper.Import.Logging;
using AssetRipper.SourceGenerated.Classes.ClassID_117;
using AssetRipper.SourceGenerated.Classes.ClassID_187;
using AssetRipper.SourceGenerated.Classes.ClassID_188;
using AssetRipper.SourceGenerated.Classes.ClassID_28;
using AssetRipper.SourceGenerated.Classes.ClassID_189;
using AssetRipper.SourceGenerated.Extensions;
using AssetRipper.SourceGenerated.Subclasses.StreamingInfo;
@ -24,7 +24,7 @@ public sealed class TextureArrayAssetExporter : BinaryAssetExporter
{
exportCollection = asset switch
{
ITexture2D texture when texture.CheckAssetIntegrity() => new TextureArrayAssetExportCollection(this, texture),
IImageTexture texture when texture.CheckAssetIntegrity() && texture.MainAsset is null => new TextureArrayAssetExportCollection(this, texture),
_ => null,
};
return exportCollection is not null;

View File

@ -0,0 +1,38 @@
using AssetRipper.SourceGenerated.Classes.ClassID_189;
namespace AssetRipper.SourceGenerated.Extensions;
public static class ImageTextureExtensions
{
public static byte[] GetImageData(this IImageTexture texture)
{
if (texture.ImageData_C189.Length > 0)
{
return texture.ImageData_C189;
}
else if (texture.Has_StreamData_C189() && texture.StreamData_C189.IsSet())
{
return texture.StreamData_C189.GetContent(texture.Collection);
}
else
{
return [];
}
}
public static bool CheckAssetIntegrity(this IImageTexture texture)
{
if (texture.ImageData_C189.Length > 0)
{
return true;
}
else if (texture.Has_StreamData_C189())
{
return texture.StreamData_C189.CheckIntegrity(texture.Collection);
}
else
{
return false;
}
}
}