Added Ufbx

This commit is contained in:
2026-03-14 18:29:18 +09:00
parent 254b08bc81
commit cce1cf7256
372 changed files with 11672 additions and 154 deletions

View File

@@ -6,7 +6,6 @@ using Misaki.HighPerformance.Mathematics;
namespace Ghost.Engine.Components;
[RequireComponent<LocalToWorld>]
public unsafe struct Camera : IComponent
{
public float nearClipPlane;

View File

@@ -7,7 +7,7 @@ namespace Ghost.Engine.Components;
public struct MeshInstance : IComponent
{
public Handle<Mesh> mesh;
public int materialPaletteIndex;
public Identifier<MaterialPalette> materialPalette;
public ShadowCastingMode shadowCastingMode;
public RenderingLayerMask renderingLayerMask;
public bool staticShadowCaster;

View File

@@ -34,7 +34,7 @@ public class RenderExtractionSystem : ISystem
var meshInstances = chunk.GetComponentData<MeshInstance>();
var localToWorlds = chunk.GetComponentData<LocalToWorld>();
for (int i = 0; i < chunk.Count; i++)
for (var i = 0; i < chunk.Count; i++)
{
ref readonly var meshInstance = ref meshInstances[i];
ref readonly var localToWorld = ref localToWorlds[i];
@@ -43,7 +43,7 @@ public class RenderExtractionSystem : ISystem
{
localToWorld = localToWorld.matrix,
mesh = meshInstance.mesh,
materialPaletteIndex = meshInstance.materialPaletteIndex,
materialPalette = meshInstance.materialPalette,
renderingLayerMask = meshInstance.renderingLayerMask,
}, 0);

View File

@@ -9,7 +9,7 @@ namespace Ghost.Entities;
public interface ISharedComponent;
public interface ISharedWarper
{
public int Index
int Index
{
get; set;
}
@@ -24,7 +24,7 @@ public struct Shared<T> : IComponent, ISharedWarper
}
}
internal unsafe sealed class SharedComponentStore : IDisposable
internal sealed unsafe class SharedComponentStore : IDisposable
{
private struct EntryInfo
{
@@ -88,7 +88,7 @@ internal unsafe sealed class SharedComponentStore : IDisposable
// If collision: fall through to insert (you may want a secondary structure).
}
int index = AllocateEntry(ref store);
var index = AllocateEntry(ref store);
var dst = (byte*)store.data.GetUnsafePtr() + (index * store.typeSize);
MemoryUtility.MemCpy(dst, data, (nuint)store.typeSize);
@@ -168,7 +168,7 @@ internal unsafe sealed class SharedComponentStore : IDisposable
}
// Remove from hash lookup (best-effort; collisions require more robust handling)
long key = ((long)componentTypeId << 32) ^ (uint)info.hashCode;
var key = ((long)componentTypeId << 32) ^ (uint)info.hashCode;
store.hashLookup.Remove(key);
// Push to free-list
@@ -226,16 +226,16 @@ internal unsafe sealed class SharedComponentStore : IDisposable
{
if (store.freeListHead != 0)
{
int idx = store.freeListHead;
var idx = store.freeListHead;
store.freeListHead = store.infos[idx].nextFree;
store.infos[idx].nextFree = -1;
return idx;
}
int newIndex = store.infos.Count;
var newIndex = store.infos.Count;
store.infos.Add(default);
int newByteCount = (newIndex + 1) * store.typeSize;
var newByteCount = (newIndex + 1) * store.typeSize;
store.data.Resize(newByteCount);
return newIndex;

View File

@@ -1167,7 +1167,7 @@ public unsafe partial struct EntityQuery
var it = _mask.writeAccess.GetIterator();
while (it.Next(out var id))
{
for (var i =0; i < 1; i++)
for (var i = 0; i < 1; i++)
{
if (id == runner.componentIDs[i])
{
@@ -1321,7 +1321,7 @@ public unsafe partial struct EntityQuery
var it = _mask.writeAccess.GetIterator();
while (it.Next(out var id))
{
for (var i =0; i < 1; i++)
for (var i = 0; i < 1; i++)
{
if (id == runner.componentIDs[i])
{
@@ -1501,7 +1501,7 @@ public unsafe partial struct EntityQuery
var it = _mask.writeAccess.GetIterator();
while (it.Next(out var id))
{
for (var i =0; i < 1; i++)
for (var i = 0; i < 1; i++)
{
if (id == runner.componentIDs[i])
{
@@ -1707,7 +1707,7 @@ public unsafe partial struct EntityQuery
var it = _mask.writeAccess.GetIterator();
while (it.Next(out var id))
{
for (var i =0; i < 1; i++)
for (var i = 0; i < 1; i++)
{
if (id == runner.componentIDs[i])
{
@@ -1939,7 +1939,7 @@ public unsafe partial struct EntityQuery
var it = _mask.writeAccess.GetIterator();
while (it.Next(out var id))
{
for (var i =0; i < 1; i++)
for (var i = 0; i < 1; i++)
{
if (id == runner.componentIDs[i])
{
@@ -2197,7 +2197,7 @@ public unsafe partial struct EntityQuery
var it = _mask.writeAccess.GetIterator();
while (it.Next(out var id))
{
for (var i =0; i < 1; i++)
for (var i = 0; i < 1; i++)
{
if (id == runner.componentIDs[i])
{
@@ -2481,7 +2481,7 @@ public unsafe partial struct EntityQuery
var it = _mask.writeAccess.GetIterator();
while (it.Next(out var id))
{
for (var i =0; i < 1; i++)
for (var i = 0; i < 1; i++)
{
if (id == runner.componentIDs[i])
{
@@ -2791,7 +2791,7 @@ public unsafe partial struct EntityQuery
var it = _mask.writeAccess.GetIterator();
while (it.Next(out var id))
{
for (var i =0; i < 1; i++)
for (var i = 0; i < 1; i++)
{
if (id == runner.componentIDs[i])
{

View File

@@ -138,11 +138,11 @@ public struct Vertex
{
public const int COUNT = 5;
public static readonly FixedText32 Position = new("POSITION");
public static readonly FixedText32 Normal = new("NORMAL");
public static readonly FixedText32 Tangent = new("TANGENT");
public static readonly FixedText32 Uv = new("TEXCOORD");
public static readonly FixedText32 Color = new("COLOR");
public static readonly FixedText32 Position = new("POSITION"u8);
public static readonly FixedText32 Normal = new("NORMAL"u8);
public static readonly FixedText32 Tangent = new("TANGENT"u8);
public static readonly FixedText32 Uv = new("TEXCOORD"u8);
public static readonly FixedText32 Color = new("COLOR"u8);
}
public float4 position;

View File

@@ -5,12 +5,18 @@ using System.Runtime.CompilerServices;
namespace Ghost.Graphics.Core;
public readonly struct MaterialPaletteInfo
public readonly struct MaterialPalette
{
public int MaterialCount
public readonly ReadOnlyUnsafeCollection<Handle<Material>> materials;
public unsafe MaterialPalette(Handle<Material>* pMaterials, int count)
{
get;
init;
materials = new ReadOnlyUnsafeCollection<Handle<Material>>(pMaterials, count);
}
public MaterialPalette(ReadOnlyUnsafeCollection<Handle<Material>> materials)
{
this.materials = materials;
}
}
@@ -47,14 +53,6 @@ internal sealed class MaterialPaletteStore : IDisposable
_entries = new UnsafeList<Entry>(initialCapacity + 1, Allocator.Persistent);
_lookup = new UnsafeHashMap<ulong, int>(initialCapacity * 2, Allocator.Persistent);
_freeListHead = 0;
_entries.Add(new Entry
{
materials = default,
refCount = int.MaxValue,
lookupHash = 0,
nextFree = -1,
});
}
~MaterialPaletteStore()
@@ -66,14 +64,14 @@ internal sealed class MaterialPaletteStore : IDisposable
{
if (_freeListHead != 0)
{
int index = _freeListHead;
var index = _freeListHead;
ref var entry = ref _entries[index];
_freeListHead = entry.nextFree;
entry.nextFree = -1;
return index;
}
int newIndex = _entries.Count;
var newIndex = _entries.Count;
_entries.Add(default);
return newIndex;
}
@@ -82,7 +80,7 @@ internal sealed class MaterialPaletteStore : IDisposable
{
const ulong offset = 14695981039346656037UL;
ulong hash = offset ^ seed;
var hash = offset ^ seed;
hash = Mix(hash, (ulong)materials.Length);
foreach (var material in materials)
@@ -112,7 +110,7 @@ internal sealed class MaterialPaletteStore : IDisposable
return 0;
}
ulong hash = ComputeLookupHash(materials, 0);
var hash = ComputeLookupHash(materials, 0);
while (_lookup.TryGetValue(hash, out var existingIndex))
{
ref var entry = ref _entries[existingIndex];
@@ -125,7 +123,7 @@ internal sealed class MaterialPaletteStore : IDisposable
hash = ComputeLookupHash(materials, hash);
}
int index = AllocateEntry();
var index = AllocateEntry();
ref var newEntry = ref _entries[index];
newEntry.lookupHash = hash;
newEntry.refCount = 1;
@@ -140,7 +138,7 @@ internal sealed class MaterialPaletteStore : IDisposable
newEntry.materials.Clear();
}
for (int i = 0; i < materials.Length; i++)
for (var i = 0; i < materials.Length; i++)
{
newEntry.materials.Add(materials[i]);
}
@@ -149,36 +147,29 @@ internal sealed class MaterialPaletteStore : IDisposable
return index;
}
public bool IsValid(int paletteIndex)
public bool IsValid(Identifier<MaterialPalette> paletteID)
{
if (paletteIndex == 0)
{
return true;
}
var paletteIndex = paletteID.Value;
return paletteIndex > 0
&& paletteIndex < _entries.Count
&& _entries[paletteIndex].IsActive;
}
public MaterialPaletteInfo GetInfo(int paletteIndex)
public MaterialPalette GetInfo(Identifier<MaterialPalette> paletteID)
{
ObjectDisposedException.ThrowIf(_disposed, this);
if (!IsValid(paletteIndex))
if (!IsValid(paletteID))
{
return default;
}
if (paletteIndex == 0)
if (paletteID == 0)
{
return default;
}
return new MaterialPaletteInfo
{
MaterialCount = _entries[paletteIndex].materials.Count,
};
return new MaterialPalette(_entries[paletteID].materials.AsReadOnly());
}
public Handle<Material> GetMaterial(int paletteIndex, int localMaterialIndex)
@@ -199,16 +190,16 @@ internal sealed class MaterialPaletteStore : IDisposable
return entry.materials[localMaterialIndex];
}
public void Release(int paletteIndex)
public void Release(Identifier<MaterialPalette> paletteID)
{
ObjectDisposedException.ThrowIf(_disposed, this);
if (paletteIndex == 0 || !IsValid(paletteIndex))
if (paletteID == 0 || !IsValid(paletteID))
{
return;
}
ref var entry = ref _entries[paletteIndex];
ref var entry = ref _entries[paletteID];
entry.refCount--;
if (entry.refCount > 0)
{
@@ -218,7 +209,7 @@ internal sealed class MaterialPaletteStore : IDisposable
_lookup.Remove(entry.lookupHash);
entry.materials.Clear();
entry.nextFree = _freeListHead;
_freeListHead = paletteIndex;
_freeListHead = paletteID;
}
public void Dispose()
@@ -228,7 +219,7 @@ internal sealed class MaterialPaletteStore : IDisposable
return;
}
for (int i = 0; i < _entries.Count; i++)
for (var i = 0; i < _entries.Count; i++)
{
_entries[i].Dispose();
}

View File

@@ -9,7 +9,7 @@ public struct RenderRecord
{
public float4x4 localToWorld;
public Handle<Mesh> mesh;
public int materialPaletteIndex;
public Identifier<MaterialPalette> materialPalette;
public RenderingLayerMask renderingLayerMask;
}
@@ -74,7 +74,7 @@ public struct RenderList : IDisposable
_threadLocalRecords = new UnsafeArray<UnsafeList<RenderRecord>>(maxLevelOfConcurrency, allocationHandle);
for (int i = 0; i < maxLevelOfConcurrency; i++)
for (var i = 0; i < maxLevelOfConcurrency; i++)
{
_threadLocalRecords[i] = new UnsafeList<RenderRecord>(capacity, allocationHandle);
}
@@ -114,7 +114,7 @@ public struct RenderList : IDisposable
public readonly void Clear()
{
ThrowIfNotCreated();
for (int i = 0; i < _threadLocalRecords.Length; i++)
for (var i = 0; i < _threadLocalRecords.Length; i++)
{
_threadLocalRecords[i].Clear();
}
@@ -134,7 +134,7 @@ public struct RenderList : IDisposable
}
var maxConcurrency = Math.Min(_threadLocalRecords.Length, other._threadLocalRecords.Length);
for (int i = 0; i < maxConcurrency; i++)
for (var i = 0; i < maxConcurrency; i++)
{
_threadLocalRecords[i].AddRange(other._threadLocalRecords[i].AsSpan());
}
@@ -142,7 +142,7 @@ public struct RenderList : IDisposable
if (other._threadLocalRecords.Length > _threadLocalRecords.Length)
{
// Add remaining records from other lists to the first list if other has more thread local lists than this
for (int i = _threadLocalRecords.Length; i < other._threadLocalRecords.Length; i++)
for (var i = _threadLocalRecords.Length; i < other._threadLocalRecords.Length; i++)
{
_threadLocalRecords[0].AddRange(other._threadLocalRecords[i].AsSpan());
}
@@ -156,7 +156,7 @@ public struct RenderList : IDisposable
return;
}
for (int i = 0; i < _threadLocalRecords.Length; i++)
for (var i = 0; i < _threadLocalRecords.Length; i++)
{
_threadLocalRecords[i].Dispose();
}

View File

@@ -4,8 +4,8 @@ namespace Ghost.Graphics.Core;
public struct RenderingLayerMask : IEquatable<RenderingLayerMask>
{
private static readonly Dictionary<string, uint> _layerNameToBit = new (32);
private static readonly Dictionary<uint, string> _bitToLayerName = new (32);
private static readonly Dictionary<string, uint> _layerNameToBit = new(32);
private static readonly Dictionary<uint, string> _bitToLayerName = new(32);
internal static void SetLayerName(int layerIndex, string name)
{

View File

@@ -41,7 +41,7 @@ public unsafe partial class GhostRenderPipeline : IRenderPipeline
public void Render(RenderContext ctx, ReadOnlySpan<RenderRequest> requests)
{
for (int i = 0; i < requests.Length; i++)
for (var i = 0; i < requests.Length; i++)
{
ref readonly var request = ref requests[i];

View File

@@ -81,27 +81,27 @@ public interface IResourceManager
/// <summary>
/// Determines whether the specified material palette index is valid.
/// </summary>
/// <param name="paletteIndex">The palette index to validate.</param>
bool HasMaterialPalette(int paletteIndex);
/// <param name="paletteID">The palette index to validate.</param>
bool HasMaterialPalette(Identifier<MaterialPalette> paletteID);
/// <summary>
/// Gets metadata for a material palette entry.
/// </summary>
/// <param name="paletteIndex">The palette index to query.</param>
MaterialPaletteInfo GetMaterialPaletteInfo(int paletteIndex);
/// <param name="paletteID">The palette index to query.</param>
MaterialPalette GetMaterialPaletteInfo(Identifier<MaterialPalette> paletteID);
/// <summary>
/// Gets a material handle from a palette entry by local material index.
/// </summary>
/// <param name="paletteIndex">The palette index to query.</param>
/// <param name="paletteID">The palette index to query.</param>
/// <param name="localMaterialIndex">The material slot inside the palette.</param>
Handle<Material> GetMaterialPaletteMaterial(int paletteIndex, int localMaterialIndex);
Handle<Material> GetMaterialPaletteMaterial(Identifier<MaterialPalette> paletteID, int localMaterialIndex);
/// <summary>
/// Releases a material palette reference previously returned by <see cref="GetOrCreateMaterialPalette(ReadOnlySpan{Handle{Material}})"/>.
/// </summary>
/// <param name="paletteIndex">The palette index to release.</param>
void ReleaseMaterialPalette(int paletteIndex);
/// <param name="paletteID">The palette index to release.</param>
void ReleaseMaterialPalette(Identifier<MaterialPalette> paletteID);
/// <summary>
/// Determines whether a shader with the specified identifier exists in the collection.
@@ -299,28 +299,28 @@ internal sealed class ResourceManager : IResourceManager, IDisposable
return _materialPalettes.InsertOrGet(materials);
}
public bool HasMaterialPalette(int paletteIndex)
public bool HasMaterialPalette(Identifier<MaterialPalette> paletteID)
{
ObjectDisposedException.ThrowIf(_disposed, this);
return _materialPalettes.IsValid(paletteIndex);
return _materialPalettes.IsValid(paletteID);
}
public MaterialPaletteInfo GetMaterialPaletteInfo(int paletteIndex)
public MaterialPalette GetMaterialPaletteInfo(Identifier<MaterialPalette> paletteID)
{
ObjectDisposedException.ThrowIf(_disposed, this);
return _materialPalettes.GetInfo(paletteIndex);
return _materialPalettes.GetInfo(paletteID);
}
public Handle<Material> GetMaterialPaletteMaterial(int paletteIndex, int localMaterialIndex)
public Handle<Material> GetMaterialPaletteMaterial(Identifier<MaterialPalette> paletteID, int localMaterialIndex)
{
ObjectDisposedException.ThrowIf(_disposed, this);
return _materialPalettes.GetMaterial(paletteIndex, localMaterialIndex);
return _materialPalettes.GetMaterial(paletteID, localMaterialIndex);
}
public void ReleaseMaterialPalette(int paletteIndex)
public void ReleaseMaterialPalette(Identifier<MaterialPalette> paletteID)
{
ObjectDisposedException.ThrowIf(_disposed, this);
_materialPalettes.Release(paletteIndex);
_materialPalettes.Release(paletteID);
}
public bool HasShader(Identifier<Shader> id)

View File

@@ -19,7 +19,7 @@ internal sealed class SwapChainRecord
{
while (true)
{
int current = Volatile.Read(ref _refCount);
var current = Volatile.Read(ref _refCount);
if (current == 0)
{
return false; // It's dead, let it go.
@@ -36,7 +36,7 @@ internal sealed class SwapChainRecord
{
while (true)
{
int current = Volatile.Read(ref _refCount);
var current = Volatile.Read(ref _refCount);
if (current == 0)
{
return false;