mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-28 21:19:52 +01:00
texture discovery
This commit is contained in:
1 parent
62b629fe3a
commit
a348e005f7
6 files changed
+117
-9
No files matched your search
@@ -37,7 +37,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
chunk: [pages, api, media, models]
|
chunk: [pages, api, media, models, textures]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Free disk space
|
- name: Free disk space
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using BlitzKit.Game.Models;
|
using BlitzKit.Game.Models;
|
||||||
using CUE4Parse_Conversion;
|
using CUE4Parse_Conversion;
|
||||||
|
using CUE4Parse_Conversion.Materials;
|
||||||
using CUE4Parse_Conversion.Meshes;
|
using CUE4Parse_Conversion.Meshes;
|
||||||
using CUE4Parse_Conversion.Textures;
|
using CUE4Parse_Conversion.Textures;
|
||||||
using CUE4Parse_Conversion.UEFormat.Enums;
|
using CUE4Parse_Conversion.UEFormat.Enums;
|
||||||
using CUE4Parse.UE4.Assets.Exports;
|
using CUE4Parse.UE4.Assets.Exports;
|
||||||
using CUE4Parse.UE4.Assets.Exports.Engine;
|
using CUE4Parse.UE4.Assets.Exports.Engine;
|
||||||
|
using CUE4Parse.UE4.Assets.Exports.Material;
|
||||||
using CUE4Parse.UE4.Assets.Exports.StaticMesh;
|
using CUE4Parse.UE4.Assets.Exports.StaticMesh;
|
||||||
using CUE4Parse.UE4.Assets.Exports.Texture;
|
using CUE4Parse.UE4.Assets.Exports.Texture;
|
||||||
using CUE4Parse.UE4.Assets.Objects;
|
using CUE4Parse.UE4.Assets.Objects;
|
||||||
@@ -31,6 +33,80 @@ public partial class GameInterface
|
|||||||
files = [.. provider.Files.Keys];
|
files = [.. provider.Files.Keys];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly Dictionary<string, string> texturePaths = new();
|
||||||
|
|
||||||
|
public void DiscoverTextures(string[] tankTags)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Discovering textures...");
|
||||||
|
|
||||||
|
var options = new ExporterOptions() { TextureFormat = ETextureFormat.Jpeg };
|
||||||
|
|
||||||
|
foreach (var tag in tankTags)
|
||||||
|
{
|
||||||
|
var pda = provider.Discovered<UPrimaryDataAsset>(tag);
|
||||||
|
|
||||||
|
foreach (var group in tankPartPrefixes.Values)
|
||||||
|
{
|
||||||
|
var dataTable = pda.Get<UDataTable>(group);
|
||||||
|
|
||||||
|
foreach (var row in dataTable.RowMap.Values)
|
||||||
|
{
|
||||||
|
var visualData = row.Get<UObject>("VisualData");
|
||||||
|
var meshSettings = visualData.Get<FStructFallback>("MeshSettings");
|
||||||
|
|
||||||
|
foreach (var property in meshSettings.Properties)
|
||||||
|
{
|
||||||
|
if (meshSettings.TryGet<UStaticMesh>(property.Name.Text, out var mesh))
|
||||||
|
{
|
||||||
|
mesh.TryConvert(out var convertedMesh);
|
||||||
|
|
||||||
|
var lod0 = convertedMesh.LODs.Find(lod => !lod.SkipLod);
|
||||||
|
|
||||||
|
if (lod0 == null || lod0.Sections == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var section in lod0.Sections.Value)
|
||||||
|
{
|
||||||
|
if (section.Material == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var materialInterface = section.Material.Load<UMaterialInterface>();
|
||||||
|
|
||||||
|
if (materialInterface == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var materialData = new MaterialData() { Parameters = new() };
|
||||||
|
|
||||||
|
materialInterface.GetParams(materialData.Parameters, options.MaterialFormat);
|
||||||
|
|
||||||
|
foreach (var parameterTexture in materialData.Parameters.Textures)
|
||||||
|
{
|
||||||
|
if (MonoGltf.knownChannels.TryGetValue(parameterTexture.Key, out var channel))
|
||||||
|
{
|
||||||
|
var path = parameterTexture.Value.GetPathName();
|
||||||
|
var name = Path.GetFileNameWithoutExtension(path);
|
||||||
|
|
||||||
|
texturePaths[name] = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"Discovered {texturePaths.Count} textures");
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> Textures => [.. texturePaths.Keys];
|
||||||
|
|
||||||
public HashSet<string> Files => files;
|
public HashSet<string> Files => files;
|
||||||
|
|
||||||
public byte[] TankBigIcon(string tag)
|
public byte[] TankBigIcon(string tag)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class MonoGltf
|
|||||||
{
|
{
|
||||||
readonly SceneBuilder scene = new();
|
readonly SceneBuilder scene = new();
|
||||||
|
|
||||||
readonly Dictionary<string, KnownChannel> knownChannels = new()
|
public static readonly Dictionary<string, KnownChannel> knownChannels = new()
|
||||||
{
|
{
|
||||||
{ "BaseColor", KnownChannel.BaseColor },
|
{ "BaseColor", KnownChannel.BaseColor },
|
||||||
{ "Normal", KnownChannel.Normal },
|
{ "Normal", KnownChannel.Normal },
|
||||||
@@ -46,14 +46,14 @@ public class MonoGltf
|
|||||||
var options = new ExporterOptions() { TextureFormat = ETextureFormat.Jpeg };
|
var options = new ExporterOptions() { TextureFormat = ETextureFormat.Jpeg };
|
||||||
|
|
||||||
staticMesh.TryConvert(out var convertedMesh);
|
staticMesh.TryConvert(out var convertedMesh);
|
||||||
var lod =
|
var lod0 =
|
||||||
convertedMesh.LODs.Find(lod => !lod.SkipLod) ?? throw new Exception("Failed to find lod0");
|
convertedMesh.LODs.Find(lod => !lod.SkipLod) ?? throw new Exception("Failed to find lod0");
|
||||||
|
|
||||||
var emptyMaterial = new MaterialBuilder("empty_material");
|
var emptyMaterial = new MaterialBuilder("empty_material");
|
||||||
var materialMap = new Dictionary<string, MaterialBuilder>();
|
var materialMap = new Dictionary<string, MaterialBuilder>();
|
||||||
|
|
||||||
int sectionIndex = 0;
|
int sectionIndex = 0;
|
||||||
foreach (var section in lod.Sections.Value)
|
foreach (var section in lod0.Sections.Value)
|
||||||
{
|
{
|
||||||
var meshBuilder = new ConfiguredMeshBuilder();
|
var meshBuilder = new ConfiguredMeshBuilder();
|
||||||
MaterialBuilder materialBuilder;
|
MaterialBuilder materialBuilder;
|
||||||
@@ -100,15 +100,15 @@ public class MonoGltf
|
|||||||
var wedgeIndex = new int[3];
|
var wedgeIndex = new int[3];
|
||||||
for (var k = 0; k < wedgeIndex.Length; k++)
|
for (var k = 0; k < wedgeIndex.Length; k++)
|
||||||
{
|
{
|
||||||
wedgeIndex[k] = (int)lod.Indices.Value[section.FirstIndex + faceIndex * 3 + k];
|
wedgeIndex[k] = (int)lod0.Indices.Value[section.FirstIndex + faceIndex * 3 + k];
|
||||||
}
|
}
|
||||||
|
|
||||||
var vertex1 = lod.Verts[wedgeIndex[0]];
|
var vertex1 = lod0.Verts[wedgeIndex[0]];
|
||||||
var vertex2 = lod.Verts[wedgeIndex[1]];
|
var vertex2 = lod0.Verts[wedgeIndex[1]];
|
||||||
var vertex3 = lod.Verts[wedgeIndex[2]];
|
var vertex3 = lod0.Verts[wedgeIndex[2]];
|
||||||
|
|
||||||
var (v1, v2, v3) = PrepareTris(vertex1, vertex2, vertex3);
|
var (v1, v2, v3) = PrepareTris(vertex1, vertex2, vertex3);
|
||||||
var (c1, c2, c3) = PrepareUVsAndTexCoords(lod, vertex1, vertex2, vertex3, wedgeIndex);
|
var (c1, c2, c3) = PrepareUVsAndTexCoords(lod0, vertex1, vertex2, vertex3, wedgeIndex);
|
||||||
|
|
||||||
primitive.AddTriangle((v1, c1), (v2, c2), (v3, c3));
|
primitive.AddTriangle((v1, c1), (v2, c2), (v3, c3));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { assertSecret } from "@blitzkit/core";
|
import { assertSecret } from "@blitzkit/core";
|
||||||
import type { GameInterface } from "@blitzkit/game";
|
import type { GameInterface } from "@blitzkit/game";
|
||||||
import { clientUnmounted } from "./unmounted";
|
import { clientUnmounted } from "./unmounted";
|
||||||
|
import { api } from "../api/dynamic";
|
||||||
|
import { assertDiscoveryTag } from "./assertDiscoveryTag";
|
||||||
|
|
||||||
let _game: GameInterface | null = null;
|
let _game: GameInterface | null = null;
|
||||||
|
|
||||||
@@ -12,6 +14,17 @@ if (!clientUnmounted && import.meta.env.SSR) {
|
|||||||
assertSecret(import.meta.env.WOTB_USMAP),
|
assertSecret(import.meta.env.WOTB_USMAP),
|
||||||
"../../temp",
|
"../../temp",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const tankTags: string[] = [];
|
||||||
|
|
||||||
|
for (const item of api.metadata.group("TankEntity")) {
|
||||||
|
const assetDiscovery = item.BlitzStaticAssetsDiscovery();
|
||||||
|
const tag = assertDiscoveryTag(assetDiscovery);
|
||||||
|
|
||||||
|
tankTags.push(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
_game.discoverTextures(tankTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const game = _game;
|
export const game = _game;
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import type { APIContext } from "astro";
|
||||||
|
import { mixStaticPaths } from "../../astro/mixStaticPaths";
|
||||||
|
import { game } from "../../game/game";
|
||||||
|
import { getStaticPaths as _getStaticPaths } from "./_index";
|
||||||
|
|
||||||
|
export const getStaticPaths = mixStaticPaths(_getStaticPaths, () => {
|
||||||
|
return game!.textures.map((name) => ({ params: { name } }));
|
||||||
|
});
|
||||||
|
|
||||||
|
export function GET({ params }: APIContext<never, { name: string }>) {
|
||||||
|
return Response.json(params);
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import type { GetStaticPaths } from "astro";
|
||||||
|
import { isChunkEnabled } from "../../astro/isChunkEnabled";
|
||||||
|
|
||||||
|
export const getStaticPaths = (() => {
|
||||||
|
if (!isChunkEnabled("textures")) return [];
|
||||||
|
return [{ params: { textures: "textures" } }];
|
||||||
|
}) satisfies GetStaticPaths;
|
||||||
Reference in new issue
Block a user