mirror of
https://github.com/sampletext32/ParkanPlayground.git
synced 2026-08-15 02:57:49 +04:00
fix textures UV. drop leftovers. properly map material_lo.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
using System.Buffers.Binary;
|
using System.Buffers.Binary;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Common;
|
||||||
|
|
||||||
namespace MaterialLib;
|
namespace MaterialLib;
|
||||||
|
|
||||||
@@ -168,28 +169,3 @@ public static class MaterialParser
|
|||||||
return $"Интерполируется: {string.Join(", ", parts)} | Остальные компоненты копируются (Flags: 0x{(int)target:X})";
|
return $"Интерполируется: {string.Join(", ", parts)} | Остальные компоненты копируются (Flags: 0x{(int)target:X})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper extensions
|
|
||||||
internal static class StreamExtensions
|
|
||||||
{
|
|
||||||
public static float ReadFloatLittleEndian(this Stream stream)
|
|
||||||
{
|
|
||||||
Span<byte> buffer = stackalloc byte[4];
|
|
||||||
stream.ReadExactly(buffer);
|
|
||||||
return BinaryPrimitives.ReadSingleLittleEndian(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ushort ReadUInt16LittleEndian(this Stream stream)
|
|
||||||
{
|
|
||||||
Span<byte> buffer = stackalloc byte[2];
|
|
||||||
stream.ReadExactly(buffer);
|
|
||||||
return BinaryPrimitives.ReadUInt16LittleEndian(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static uint ReadUInt32LittleEndian(this Stream stream)
|
|
||||||
{
|
|
||||||
Span<byte> buffer = stackalloc byte[4];
|
|
||||||
stream.ReadExactly(buffer);
|
|
||||||
return BinaryPrimitives.ReadUInt32LittleEndian(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -104,11 +104,6 @@ public static class Msh0x01
|
|||||||
ushort FallbackKey0x08,
|
ushort FallbackKey0x08,
|
||||||
ushort[] Msh02SlotIndicesByStateAndLOD)
|
ushort[] Msh02SlotIndicesByStateAndLOD)
|
||||||
{
|
{
|
||||||
public bool IsRoot => ParentIndexOrLink == ushort.MaxValue;
|
|
||||||
|
|
||||||
public int ParentIndexOrMinusOne =>
|
|
||||||
ParentIndexOrLink == ushort.MaxValue ? -1 : ParentIndexOrLink;
|
|
||||||
|
|
||||||
public ushort ResolveSlotIndex(int state, int lod = 0)
|
public ushort ResolveSlotIndex(int state, int lod = 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -129,26 +124,6 @@ public static class Msh0x01
|
|||||||
? Msh02SlotIndicesByStateAndLOD[index]
|
? Msh02SlotIndicesByStateAndLOD[index]
|
||||||
: ushort.MaxValue;
|
: ushort.MaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasGeometrySlot(int lod, int group = 0) =>
|
|
||||||
ResolveSlotIndex(lod, group) != ushort.MaxValue;
|
|
||||||
|
|
||||||
public int CountLodsForGroup(int group = 0)
|
|
||||||
{
|
|
||||||
var count = 0;
|
|
||||||
|
|
||||||
for (var lod = 0; lod < StateCount; lod++)
|
|
||||||
{
|
|
||||||
if (!HasGeometrySlot(lod, group))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-12
@@ -38,21 +38,25 @@ public static class Msh0x0D
|
|||||||
return data
|
return data
|
||||||
.Chunk(ElementSize)
|
.Chunk(ElementSize)
|
||||||
.Select(x => new Batch(
|
.Select(x => new Batch(
|
||||||
(BatchFlags)BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(0x00)),
|
Flags: (BatchFlags)BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(0x00)),
|
||||||
BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(0x02)),
|
MaterialIndexHi: BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(0x02)),
|
||||||
BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(0x04)),
|
MaterialIndexLo: x.AsSpan(0x04)[0],
|
||||||
BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(0x06)),
|
LightmapIndex: x.AsSpan(0x05)[0],
|
||||||
BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(0x08)),
|
LocalBatchIndex: BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(0x06)),
|
||||||
BinaryPrimitives.ReadUInt32LittleEndian(x.AsSpan(0x0A)),
|
IndexCount0x06: BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(0x08)),
|
||||||
BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(0x0E)),
|
IndexStart0x06: BinaryPrimitives.ReadUInt32LittleEndian(x.AsSpan(0x0A)),
|
||||||
BinaryPrimitives.ReadUInt32LittleEndian(x.AsSpan(0x10))))
|
VertexCount0x03: BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(0x0E)),
|
||||||
|
BaseVertex0x03: BinaryPrimitives.ReadUInt16LittleEndian(x.AsSpan(0x10))
|
||||||
|
)
|
||||||
|
)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>MSH batch 0x0D, sizeof 0x14.</summary>
|
/// <summary>MSH batch 0x0D, sizeof 0x14.</summary>
|
||||||
/// <param name="Flags">[0x00..0x02] Флаги batch.</param>
|
/// <param name="Flags">[0x00..0x02] Флаги batch.</param>
|
||||||
/// <param name="MaterialIndex">[0x02..0x04] Индекс material slot. Может быть overridden CAniMesh::forced_material_index.</param>
|
/// <param name="MaterialIndexHi">[0x02..0x04] Индекс material slot. Может быть overridden CAniMesh::forced_material_index.</param>
|
||||||
/// <param name="Opaque04">[0x04..0x06] Opaque. В GetBatchRenderData попадает в packed field вместе с material/lightmap данными.</param>
|
/// <param name="MaterialIndexLo">[0x04..0x05] Индекс материала</param>
|
||||||
|
/// <param name="LightmapIndex">[0x05..0x06] Индекс карты освещения</param>
|
||||||
/// <param name="LocalBatchIndex">[0x06..0x08] Локальный batch index. В GetBatchRenderData складывается с MSH_piece.local_index_base / batch base.</param>
|
/// <param name="LocalBatchIndex">[0x06..0x08] Локальный batch index. В GetBatchRenderData складывается с MSH_piece.local_index_base / batch base.</param>
|
||||||
/// <param name="IndexCount0x06">[0x08..0x0A] Количество индексов из component 0x06.</param>
|
/// <param name="IndexCount0x06">[0x08..0x0A] Количество индексов из component 0x06.</param>
|
||||||
/// <param name="IndexStart0x06">[0x0A..0x0E] Первый индекс в component 0x06.</param>
|
/// <param name="IndexStart0x06">[0x0A..0x0E] Первый индекс в component 0x06.</param>
|
||||||
@@ -60,8 +64,9 @@ public static class Msh0x0D
|
|||||||
/// <param name="BaseVertex0x03">[0x10..0x14] Base vertex в vertex streams, включая position stream 0x03.</param>
|
/// <param name="BaseVertex0x03">[0x10..0x14] Base vertex в vertex streams, включая position stream 0x03.</param>
|
||||||
public readonly record struct Batch(
|
public readonly record struct Batch(
|
||||||
BatchFlags Flags,
|
BatchFlags Flags,
|
||||||
ushort MaterialIndex,
|
ushort MaterialIndexHi,
|
||||||
ushort Opaque04,
|
byte MaterialIndexLo,
|
||||||
|
byte LightmapIndex,
|
||||||
ushort LocalBatchIndex,
|
ushort LocalBatchIndex,
|
||||||
ushort IndexCount0x06,
|
ushort IndexCount0x06,
|
||||||
uint IndexStart0x06,
|
uint IndexStart0x06,
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ public sealed class MshConverter
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine($"# batch {batchIndex}, material {batch.MaterialIndex}, flags {batch.Flags}");
|
writer.WriteLine($"# batch {batchIndex}, material {batch.MaterialIndexLo}, flags {batch.Flags}");
|
||||||
|
|
||||||
for (var i = 0; i + 2 < batch.IndexCount0x06; i += 3)
|
for (var i = 0; i + 2 < batch.IndexCount0x06; i += 3)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public static class MshRestPoseBuilder
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Convert.ToInt32(node.ParentIndexOrMinusOne);
|
return Convert.ToInt32(node.ParentIndexOrLink);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public static class MshViewportLoader
|
|||||||
var outIndices = new List<uint>();
|
var outIndices = new List<uint>();
|
||||||
var batchTriangleCount = 0;
|
var batchTriangleCount = 0;
|
||||||
|
|
||||||
var material = materialLibrary.FindMaterial(batch.MaterialIndex) ?? ViewportMaterial.Untextured;
|
var material = materialLibrary.FindMaterial(batch.MaterialIndexLo) ?? ViewportMaterial.Untextured;
|
||||||
var vertexColor = material.HasTexture ? Vector3.One : debugColor;
|
var vertexColor = material.HasTexture ? Vector3.One : debugColor;
|
||||||
|
|
||||||
for (var i = 0; i + 2 < batch.IndexCount0x06; i += 3)
|
for (var i = 0; i + 2 < batch.IndexCount0x06; i += 3)
|
||||||
@@ -183,7 +183,7 @@ public static class MshViewportLoader
|
|||||||
return Vector2.Zero;
|
return Vector2.Zero;
|
||||||
|
|
||||||
var uv = uvs[vertexIndex];
|
var uv = uvs[vertexIndex];
|
||||||
return new Vector2(uv.U / 1024.0f, 1.0f - uv.V / 1024.0f);
|
return new Vector2(uv.U / 1024.0f, uv.V / 1024.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vector3 ToNumericsVector3(Common.Vector3 position)
|
private static Vector3 ToNumericsVector3(Common.Vector3 position)
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ public sealed class WeaMaterialLibrary
|
|||||||
|
|
||||||
foreach (var materialRef in materialRefs)
|
foreach (var materialRef in materialRefs)
|
||||||
{
|
{
|
||||||
var texture = TryLoadMaterialTexture(gl, materialFs, parseResult.Archive, materialRef.Name);
|
var texture = TryLoadMaterialTexture(gl, materialFs, parseResult.Archive, materialRef.Name, out var texm);
|
||||||
result[materialRef.Id] = texture != null
|
result[materialRef.Id] = texture != null
|
||||||
? new ViewportMaterial(materialRef.Name, texture.Value)
|
? new ViewportMaterial(materialRef.Name, texture.Value, texm)
|
||||||
: new ViewportMaterial(materialRef.Name);
|
: new ViewportMaterial(materialRef.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,9 +194,10 @@ public sealed class WeaMaterialLibrary
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static uint? TryLoadMaterialTexture(
|
private static uint? TryLoadMaterialTexture(
|
||||||
GL gl, FileStream materialFs, NResArchive materialArchive, string materialName
|
GL gl, FileStream materialFs, NResArchive materialArchive, string materialName, out TexmFile? texm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
texm = null;
|
||||||
var entry = FindMaterialEntry(materialArchive, materialName);
|
var entry = FindMaterialEntry(materialArchive, materialName);
|
||||||
if (entry == null)
|
if (entry == null)
|
||||||
return null;
|
return null;
|
||||||
@@ -235,6 +236,7 @@ public sealed class WeaMaterialLibrary
|
|||||||
if (texmResult.TexmFile == null)
|
if (texmResult.TexmFile == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
texm = texmResult.TexmFile;
|
||||||
var rgba = texmResult.TexmFile.GetRgba32BytesFromMipmap(0, out var width, out var height);
|
var rgba = texmResult.TexmFile.GetRgba32BytesFromMipmap(0, out var width, out var height);
|
||||||
return ViewportTextureLoader.CreateRgbaTexture(gl, rgba, width, height);
|
return ViewportTextureLoader.CreateRgbaTexture(gl, rgba, width, height);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using TexmLib;
|
||||||
|
|
||||||
namespace NResUI.Rendering.Viewport;
|
namespace NResUI.Rendering.Viewport;
|
||||||
|
|
||||||
public sealed class ViewportMaterial
|
public sealed class ViewportMaterial
|
||||||
@@ -6,10 +8,13 @@ public sealed class ViewportMaterial
|
|||||||
public uint TextureHandle { get; }
|
public uint TextureHandle { get; }
|
||||||
public bool HasTexture => TextureHandle != 0;
|
public bool HasTexture => TextureHandle != 0;
|
||||||
|
|
||||||
public ViewportMaterial(string name, uint textureHandle = 0)
|
public TexmFile? Texm { get; }
|
||||||
|
|
||||||
|
public ViewportMaterial(string name, uint textureHandle = 0, TexmFile? texm = null)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
TextureHandle = textureHandle;
|
TextureHandle = textureHandle;
|
||||||
|
Texm = texm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ViewportMaterial Untextured { get; } = new("Untextured");
|
public static ViewportMaterial Untextured { get; } = new("Untextured");
|
||||||
|
|||||||
+2
-2
@@ -277,9 +277,9 @@ public record class TexmFile(
|
|||||||
// swap endianess back
|
// swap endianess back
|
||||||
// (rawPixel[0], rawPixel[1], rawPixel[2], rawPixel[3]) = (rawPixel[3], rawPixel[2], rawPixel[1], rawPixel[0]);
|
// (rawPixel[0], rawPixel[1], rawPixel[2], rawPixel[3]) = (rawPixel[3], rawPixel[2], rawPixel[1], rawPixel[0]);
|
||||||
|
|
||||||
var r = rawPixel[0];
|
var b = rawPixel[0];
|
||||||
var g = rawPixel[1];
|
var g = rawPixel[1];
|
||||||
var b = rawPixel[2];
|
var r = rawPixel[2];
|
||||||
var a = rawPixel[3];
|
var a = rawPixel[3];
|
||||||
|
|
||||||
result[i + 0] = r;
|
result[i + 0] = r;
|
||||||
|
|||||||
Reference in New Issue
Block a user