This commit is contained in:
tresabhi committed 2026-06-08 20:14:55 -05:00
1 parent a878a7a143
commit c86b269cf2
3 files changed
+36 -32

No files matched your search

+1 -1
View File
@@ -146,7 +146,7 @@ public partial class GameInterface
var gltf = new MonoGltf(mesh); var gltf = new MonoGltf(mesh);
return gltf.Write($"{tag}/${part}"); return gltf.Write($"{tag}/{part}");
} }
catch (Exception e) catch (Exception e)
{ {
+32 -22
View File
@@ -30,8 +30,7 @@ using ConfiguredMeshBuilder = MeshBuilder<
public class MonoGltf public class MonoGltf
{ {
readonly SceneBuilder scene; readonly SceneBuilder scene = new();
readonly Dictionary<string, Dictionary<KnownChannel, string>> textureMap = [];
readonly Dictionary<string, KnownChannel> knownChannels = new() readonly Dictionary<string, KnownChannel> knownChannels = new()
{ {
@@ -40,23 +39,23 @@ public class MonoGltf
{ "RMAO", KnownChannel.MetallicRoughness }, { "RMAO", KnownChannel.MetallicRoughness },
// { "CDE", ?? }, // { "CDE", ?? },
}; };
readonly string stubTexture = "../../stub/stupid.png";
public MonoGltf(UStaticMesh staticMesh) public MonoGltf(UStaticMesh staticMesh)
{ {
scene = new(staticMesh.Name);
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 lod =
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");
MaterialBuilder emptyMaterial = new("empty_material"); var emptyMaterial = new MaterialBuilder("empty_material");
Dictionary<string, MaterialBuilder> materialMap = []; var materialMap = new Dictionary<string, MaterialBuilder>();
int sectionIndex = 0; int sectionIndex = 0;
foreach (var section in lod.Sections.Value) foreach (var section in lod.Sections.Value)
{ {
ConfiguredMeshBuilder meshBuilder = new($"{staticMesh.Name}_section_{sectionIndex}"); var meshBuilder = new ConfiguredMeshBuilder();
MaterialBuilder materialBuilder; MaterialBuilder materialBuilder;
if (section.Material == null || section.MaterialName == null) if (section.Material == null || section.MaterialName == null)
@@ -73,27 +72,23 @@ public class MonoGltf
var materialData = new MaterialData() { Parameters = new() }; var materialData = new MaterialData() { Parameters = new() };
materialInterface.GetParams(materialData.Parameters, options.MaterialFormat); materialInterface.GetParams(materialData.Parameters, options.MaterialFormat);
materialBuilder = new(section.MaterialName); materialBuilder = new();
var textures = new Dictionary<KnownChannel, string>();
materialMap.Add(section.MaterialName, materialBuilder); materialMap.Add(section.MaterialName, materialBuilder);
textureMap.Add(section.MaterialName, textures);
foreach (var parameterTexture in materialData.Parameters.Textures) foreach (var parameterTexture in materialData.Parameters.Textures)
{ {
if (knownChannels.TryGetValue(parameterTexture.Key, out var channel)) if (knownChannels.TryGetValue(parameterTexture.Key, out var channel))
{ {
materialBuilder.WithChannelImage(channel, "../../stub/stupid.png"); var texture = parameterTexture.Value;
var name = Path.GetFileNameWithoutExtension(texture.GetPathName());
var path = $"textures/{name}.webp";
// var texture = parameterTexture.Value; materialBuilder.WithChannelImage(channel, stubTexture);
// var name = Path.GetFileNameWithoutExtension(texture.GetPathName()); materialBuilder.GetChannel(channel).Texture.PrimaryImage.Name = path;
// textures.Add(channel, name);
} }
else else
{ {
// Console.WriteLine($"Unsupported texture type: {parameterTexture.Key}"); Console.WriteLine($"Unsupported texture type: {parameterTexture.Key}");
} }
} }
} }
@@ -124,6 +119,19 @@ public class MonoGltf
public byte[] Write(string name) public byte[] Write(string name)
{ {
var model = scene.ToGltf2();
model.Asset.Copyright = null;
model.Asset.Generator = null;
var mappedTextures = new Dictionary<MemoryImage, string>();
foreach (var image in model.LogicalImages)
{
mappedTextures[image.Content] = image.Name!;
image.Name = null;
}
var stream = new MemoryStream(); var stream = new MemoryStream();
var context = WriteContext var context = WriteContext
.CreateFromStream(stream) .CreateFromStream(stream)
@@ -133,11 +141,10 @@ public class MonoGltf
ImageWriting = ResourceWriteMode.SatelliteFile, ImageWriting = ResourceWriteMode.SatelliteFile,
ImageWriteCallback = (context, assetName, image) => ImageWriteCallback = (context, assetName, image) =>
{ {
return "/textures/my-ass.png"; return mappedTextures[image];
}, },
} }
); );
var model = scene.ToGltf2();
context.WriteBinarySchema2(name, model); context.WriteBinarySchema2(name, model);
@@ -150,17 +157,17 @@ public class MonoGltf
VertexPositionNormalTangent VertexPositionNormalTangent
) PrepareTris(CMeshVertex vert1, CMeshVertex vert2, CMeshVertex vert3) ) PrepareTris(CMeshVertex vert1, CMeshVertex vert2, CMeshVertex vert3)
{ {
VertexPositionNormalTangent v1 = new( var v1 = new VertexPositionNormalTangent(
SwapYZ(vert1.Position * 0.01f), SwapYZ(vert1.Position * 0.01f),
SwapYZAndNormalize((FVector)vert1.Normal), SwapYZAndNormalize((FVector)vert1.Normal),
SwapYZAndNormalize((Vector4)vert1.Tangent) SwapYZAndNormalize((Vector4)vert1.Tangent)
); );
VertexPositionNormalTangent v2 = new( var v2 = new VertexPositionNormalTangent(
SwapYZ(vert2.Position * 0.01f), SwapYZ(vert2.Position * 0.01f),
SwapYZAndNormalize((FVector)vert2.Normal), SwapYZAndNormalize((FVector)vert2.Normal),
SwapYZAndNormalize((Vector4)vert2.Tangent) SwapYZAndNormalize((Vector4)vert2.Tangent)
); );
VertexPositionNormalTangent v3 = new( var v3 = new VertexPositionNormalTangent(
SwapYZ(vert3.Position * 0.01f), SwapYZ(vert3.Position * 0.01f),
SwapYZAndNormalize((FVector)vert3.Normal), SwapYZAndNormalize((FVector)vert3.Normal),
SwapYZAndNormalize((Vector4)vert3.Tangent) SwapYZAndNormalize((Vector4)vert3.Tangent)
@@ -223,9 +230,11 @@ public class MonoGltf
) )
{ {
var (uvs1, uvs2, uvs3) = PrepareUVs(vert1, vert2, vert3, uvs, indices); var (uvs1, uvs2, uvs3) = PrepareUVs(vert1, vert2, vert3, uvs, indices);
var c1 = new VertexColorXTextureX((Vector4)colors[indices[0]] / 255, uvs1); var c1 = new VertexColorXTextureX((Vector4)colors[indices[0]] / 255, uvs1);
var c2 = new VertexColorXTextureX((Vector4)colors[indices[1]] / 255, uvs2); var c2 = new VertexColorXTextureX((Vector4)colors[indices[1]] / 255, uvs2);
var c3 = new VertexColorXTextureX((Vector4)colors[indices[2]] / 255, uvs3); var c3 = new VertexColorXTextureX((Vector4)colors[indices[2]] / 255, uvs3);
return (c1, c2, c3); return (c1, c2, c3);
} }
@@ -240,6 +249,7 @@ public class MonoGltf
var uvs1 = new List<Vector2>() { (Vector2)vert1.UV }; var uvs1 = new List<Vector2>() { (Vector2)vert1.UV };
var uvs2 = new List<Vector2>() { (Vector2)vert2.UV }; var uvs2 = new List<Vector2>() { (Vector2)vert2.UV };
var uvs3 = new List<Vector2>() { (Vector2)vert3.UV }; var uvs3 = new List<Vector2>() { (Vector2)vert3.UV };
foreach (var uv in uvs) foreach (var uv in uvs)
{ {
uvs1.Add((Vector2)uv[indices[0]]); uvs1.Add((Vector2)uv[indices[0]]);
@@ -30,20 +30,14 @@ export const getStaticPaths = mixStaticPaths(_getStaticPaths, async () => {
return paths; return paths;
}); });
type KnownChannel = "BaseColor" | "Normal" | "MetallicRoughness";
interface MappedGltf {
Json: string;
TextureMap: Record<string, Record<KnownChannel, string>>;
}
export async function GET({ export async function GET({
params, params,
}: APIContext<never, { id: string; part: string }>) { }: APIContext<never, { id: string; part: string }>) {
const item = api.metadata.item(params.id); const item = api.metadata.item(params.id);
const assetDiscovery = item.BlitzStaticAssetsDiscovery(); const assetDiscovery = item.BlitzStaticAssetsDiscovery();
const tag = assertDiscoveryTag(assetDiscovery); const tag = assertDiscoveryTag(assetDiscovery);
const part = game!.tankPart(tag, params.part); const bytes = game!.tankPart(tag, params.part);
const array = new Uint8Array(bytes);
return Response.json(part); return new Response(array);
} }