Refactor and enhance graphics and audio systems

Updated target frameworks to .NET 10.0 across multiple projects for compatibility with the latest features. Refactored namespaces and introduced new classes for shader descriptors, FMOD integration, and DirectX 12 utilities using TerraFX. Replaced `Win32` bindings with TerraFX equivalents for DirectX 12. Added a C# wrapper for FMOD Studio API, including DSP and error handling. Enhanced entity queries, component storage, and query filters for better performance and type safety. Introduced new test projects and updated the solution structure. Added `meshoptimizer` bindings and integrated `meshoptimizer_native.dll`. Improved code readability, maintainability, and performance.
This commit is contained in:
2025-10-09 05:16:28 +09:00
parent 01a850ff94
commit 682200cbf1
126 changed files with 25587 additions and 3247 deletions

View File

@@ -7,6 +7,6 @@ using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Ghost.Engine")]
[assembly: InternalsVisibleTo("Ghost.Editor.Core")]
[assembly: InternalsVisibleTo("Ghost.UnitTest")]
[assembly: InternalsVisibleTo("Ghost.Entities.Test")]
[assembly: EngineAssembly]

View File

@@ -663,9 +663,8 @@ internal struct ComponentStorage : IDisposable
return set.Value;
}
public UnsafeBitSet GetOrCreateMask(Type type)
public UnsafeBitSet GetOrCreateMask(TypeHandle typeHandle)
{
var typeHandle = TypeHandle.Get(type);
if (!_typeIDMap.TryGetValue(typeHandle, out var id))
{
id = GetTypeID(typeHandle);
@@ -684,6 +683,11 @@ internal struct ComponentStorage : IDisposable
return set.Value;
}
public UnsafeBitSet GetOrCreateMask(Type type)
{
return GetOrCreateMask(TypeHandle.Get(type));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly void RebuildExecutionList()
{

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>

View File

@@ -1,5 +1,7 @@
using Ghost.Core;
using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
using System.Runtime.CompilerServices;
namespace Ghost.Entities.Query;
@@ -27,63 +29,68 @@ internal struct QueryFilter()
public readonly UnsafeBitSet ComputeFilterBitMask(World world)
{
UnsafeBitSet? allMask = null;
UnsafeBitSet? anyMask = null;
UnsafeBitSet? absentMask = null;
UnsafeBitSet allMask = default;
UnsafeBitSet anyMask = default;
UnsafeBitSet absentMask = default;
using var scope = AllocationManager.CreateStackScope();
foreach (var typeHandle in _all)
{
var mask = world.ComponentStorage.GetOrCreateMask(typeHandle);
if (!allMask.HasValue)
if (!allMask.IsCreated)
{
allMask = new UnsafeBitSet(mask.Length);
allMask.Value.SetAll();
allMask = new UnsafeBitSet(mask.Length, Allocator.Stack, AllocationOption.Clear);
allMask.SetAll();
}
allMask &= mask;
allMask.AndOperation(mask);
}
foreach (var typeHandle in _any)
{
var mask = world.ComponentStorage.GetOrCreateMask(typeHandle);
if (!anyMask.HasValue)
if (!anyMask.IsCreated)
{
anyMask = new UnsafeBitSet(mask.Length);
anyMask = new UnsafeBitSet(mask.Length, Allocator.Stack, AllocationOption.Clear);
}
anyMask |= mask;
anyMask.OrOperation(mask);
}
foreach (var typeHandle in _absent)
{
var mask = world.ComponentStorage.GetOrCreateMask(typeHandle);
if (!absentMask.HasValue)
if (!absentMask.IsCreated)
{
absentMask = new UnsafeBitSet(mask.Length);
absentMask = new UnsafeBitSet(mask.Length, Allocator.Stack, AllocationOption.Clear);
}
absentMask |= mask;
absentMask.OrOperation(mask);
}
var result = new UnsafeBitSet(world.EntityManager.EntityCount);
var result = new UnsafeBitSet(world.EntityManager.EntityCount, Allocator.Persistent);
result.SetAll();
if (allMask.HasValue)
if (allMask.IsCreated)
{
result &= allMask.Value;
result.AndOperation(allMask);
allMask.Dispose();
}
if (anyMask.HasValue)
if (anyMask.IsCreated)
{
result &= anyMask.Value;
result.AndOperation(anyMask);
anyMask.Dispose();
}
if (absentMask.HasValue)
if (absentMask.IsCreated)
{
result &= ~absentMask.Value;
result.AndOperation(~absentMask);
absentMask.Dispose();
}
return result;

View File

@@ -36,7 +36,37 @@ public ref struct CompRef<T> : IQueryTypeParameter
IsValid = isValid;
}
public CompRef(ref T value) : this(ref value, true)
public CompRef(ref T value)
: this(ref value, true)
{
}
}
public ref struct CompRO<T> : IQueryTypeParameter
where T : IComponentData
{
internal readonly ref T _value;
public readonly ref T ValueRO
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref _value;
}
public readonly bool IsValid
{
get;
init;
}
public CompRO(ref T value, bool isValid)
{
_value = ref value;
IsValid = isValid;
}
public CompRO(ref T value)
: this(ref value, true)
{
}
}