feat(wrapper): span-based interop, resource API refactor
Refactored native wrappers to use ReadOnlySpan<T> for pointer parameters, improving .NET safety and interop. Enhanced wrapper generator with $TYPE and prefix/suffix-based parameter remapping. Added platform-specific native library loading for meshoptimizer, nvtt, and ufbx. Updated D3D12GraphicsEngineFactory for native DLL resolution and removed redundant logic from UnitTestApp. Changed RenderGraphBuilder's resource extraction API to use QueryTextureExtraction/QueryBufferExtraction with explicit handles and flags. Removed IRenderer and D3D12Renderer, moving RenderContext to RenderPipeline. Improved mesh loading, resource management, and updated test shader conventions. Updated project references, build settings, and added launchSettings.json for tooling. BREAKING CHANGE: Native wrapper APIs now use ReadOnlySpan<T> instead of pointers. RenderGraphBuilder resource extraction API has changed. IRenderer and D3D12Renderer have been removed.
This commit is contained in:
@@ -241,11 +241,11 @@ public class AntlrShaderCompiler
|
|||||||
{
|
{
|
||||||
"disabled" => ZTest.Disabled,
|
"disabled" => ZTest.Disabled,
|
||||||
"less" => ZTest.Less,
|
"less" => ZTest.Less,
|
||||||
"lessequal" => ZTest.LessEqual,
|
"less_equal" => ZTest.LessEqual,
|
||||||
"equal" => ZTest.Equal,
|
"equal" => ZTest.Equal,
|
||||||
"greaterequal" => ZTest.GreaterEqual,
|
"greater_equal" => ZTest.GreaterEqual,
|
||||||
"greater" => ZTest.Greater,
|
"greater" => ZTest.Greater,
|
||||||
"notequal" => ZTest.NotEqual,
|
"not_equal" => ZTest.NotEqual,
|
||||||
"always" => ZTest.Always,
|
"always" => ZTest.Always,
|
||||||
_ => ZTest.Disabled
|
_ => ZTest.Disabled
|
||||||
};
|
};
|
||||||
@@ -269,7 +269,7 @@ public class AntlrShaderCompiler
|
|||||||
"alpha" => Blend.Alpha,
|
"alpha" => Blend.Alpha,
|
||||||
"additive" => Blend.Additive,
|
"additive" => Blend.Additive,
|
||||||
"multiply" => Blend.Multiply,
|
"multiply" => Blend.Multiply,
|
||||||
"premultipliedalpha" => Blend.PremultipliedAlpha,
|
"premultiplied_alpha" => Blend.PremultipliedAlpha,
|
||||||
_ => Blend.Opaque
|
_ => Blend.Opaque
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public sealed partial class ContextFlyout : MenuFlyout
|
|||||||
Opening += ContextFlyout_Opening;
|
Opening += ContextFlyout_Opening;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively sorts nodes and calculates folder groups
|
// Recursively sorts nodes and calculates folder pGroups
|
||||||
private static void PrepareNodes(List<MenuNode> nodes)
|
private static void PrepareNodes(List<MenuNode> nodes)
|
||||||
{
|
{
|
||||||
if (nodes.Count == 0)
|
if (nodes.Count == 0)
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ public partial class DockingLayout : Control
|
|||||||
targetGroup = FindFirstDockGroup(RootModule as DockContainer);
|
targetGroup = FindFirstDockGroup(RootModule as DockContainer);
|
||||||
if (targetGroup == null)
|
if (targetGroup == null)
|
||||||
{
|
{
|
||||||
// Root is not a container, or contains no groups. Wrap it.
|
// Root is not a container, or contains no pGroups. Wrap it.
|
||||||
var newGroup = new DockGroup();
|
var newGroup = new DockGroup();
|
||||||
newGroup.AddChild(document);
|
newGroup.AddChild(document);
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
<IsAotCompatible>True</IsAotCompatible>
|
<IsAotCompatible>True</IsAotCompatible>
|
||||||
<DefineConstants>$(DefineConstants);MHP_ENABLE_SAFETY_CHECKS;MHP_ENABLE_STACKTRACE</DefineConstants>
|
<DefineConstants>$(DefineConstants);MHP_ENABLE_SAFETY_CHECKS</DefineConstants>
|
||||||
<IsTrimmable>True</IsTrimmable>
|
<IsTrimmable>True</IsTrimmable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Misaki.HighPerformance" Version="1.0.6" />
|
<PackageReference Include="Misaki.HighPerformance" Version="1.0.6" />
|
||||||
<PackageReference Include="Misaki.HighPerformance.Jobs" Version="1.5.6" />
|
<PackageReference Include="Misaki.HighPerformance.Jobs" Version="1.5.8" />
|
||||||
<PackageReference Include="Misaki.HighPerformance.LowLevel" Version="1.6.3">
|
<PackageReference Include="Misaki.HighPerformance.LowLevel" Version="1.6.3">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Ghost.Core;
|
using Ghost.Core;
|
||||||
using Ghost.Entities;
|
using Ghost.Entities;
|
||||||
using Ghost.Graphics.Core;
|
using Ghost.Graphics.Core;
|
||||||
|
using Ghost.Graphics.RenderPipeline;
|
||||||
using Ghost.Graphics.RHI;
|
using Ghost.Graphics.RHI;
|
||||||
using Misaki.HighPerformance.Mathematics;
|
using Misaki.HighPerformance.Mathematics;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,4 @@ global using static TerraFX.Interop.DirectX.DirectX;
|
|||||||
global using static TerraFX.Interop.DirectX.DXGI;
|
global using static TerraFX.Interop.DirectX.DXGI;
|
||||||
global using static TerraFX.Interop.Windows.Windows;
|
global using static TerraFX.Interop.Windows.Windows;
|
||||||
|
|
||||||
using System.Runtime.Versioning;
|
[assembly: System.Runtime.Versioning.SupportedOSPlatform("windows10.0.19041.0")]
|
||||||
|
|
||||||
[assembly: SupportedOSPlatform("windows10.0.19041.0")]
|
|
||||||
@@ -7,11 +7,38 @@ using Ghost.Graphics.Core;
|
|||||||
using Ghost.Graphics.RHI;
|
using Ghost.Graphics.RHI;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.Loader;
|
||||||
|
|
||||||
namespace Ghost.Graphics.D3D12;
|
namespace Ghost.Graphics.D3D12;
|
||||||
|
|
||||||
public static class D3D12GraphicsEngineFactory
|
public static class D3D12GraphicsEngineFactory
|
||||||
{
|
{
|
||||||
|
static D3D12GraphicsEngineFactory()
|
||||||
|
{
|
||||||
|
var currentDir = AppContext.BaseDirectory;
|
||||||
|
var platform = OperatingSystem.IsWindows() ? "win" :
|
||||||
|
OperatingSystem.IsLinux() ? "linux" :
|
||||||
|
OperatingSystem.IsMacOS() ? "osx" : "unknown";
|
||||||
|
var arch = Environment.Is64BitProcess ? "x64" : "x86";
|
||||||
|
var nativeDllDir = Path.Combine(currentDir, "runtimes", platform + "-" + arch, "native");
|
||||||
|
|
||||||
|
AssemblyLoadContext.Default.ResolvingUnmanagedDll += (assembly, libraryName) =>
|
||||||
|
{
|
||||||
|
if (libraryName == "dxcompiler")
|
||||||
|
{
|
||||||
|
NativeLibrary.TryLoad(Path.Combine(nativeDllDir, "dxil.dll"), out _);
|
||||||
|
|
||||||
|
if (NativeLibrary.TryLoad(Path.Combine(nativeDllDir, "dxcompiler.dll"), out var dxcHandle))
|
||||||
|
{
|
||||||
|
return dxcHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IntPtr.Zero;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static IGraphicsEngine Create(GraphicsEngineDesc desc)
|
public static IGraphicsEngine Create(GraphicsEngineDesc desc)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
using Ghost.Core;
|
|
||||||
using Ghost.Graphics.RHI;
|
|
||||||
|
|
||||||
namespace Ghost.Graphics.D3D12;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// D3D12 implementation of the renderer interface using RHI abstractions
|
|
||||||
/// </summary>
|
|
||||||
internal class D3D12Renderer : IRenderer
|
|
||||||
{
|
|
||||||
private readonly D3D12GraphicsEngine _graphicsEngine;
|
|
||||||
private readonly ICommandBuffer _commandBuffer;
|
|
||||||
|
|
||||||
private bool _disposed;
|
|
||||||
|
|
||||||
public IRenderOutput? RenderOutput
|
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Func<RenderContext, Error>? RenderFunc
|
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public D3D12Renderer(D3D12GraphicsEngine graphicsEngine)
|
|
||||||
{
|
|
||||||
_graphicsEngine = graphicsEngine;
|
|
||||||
_commandBuffer = _graphicsEngine.CreateCommandBuffer(CommandBufferType.Graphics);
|
|
||||||
}
|
|
||||||
|
|
||||||
~D3D12Renderer()
|
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result Render(ICommandAllocator commandAllocator)
|
|
||||||
{
|
|
||||||
if (RenderFunc is null)
|
|
||||||
{
|
|
||||||
return Result.Success(); // No render function set, skip rendering.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RenderOutput is null)
|
|
||||||
{
|
|
||||||
return Result.Failure("Render target strategy is not set.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var target = RenderOutput.GetRenderTarget();
|
|
||||||
if (target.IsInvalid)
|
|
||||||
{
|
|
||||||
return Result.Failure("Render target is invalid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
_commandBuffer.Begin(commandAllocator);
|
|
||||||
RenderOutput.BeginRender(_commandBuffer);
|
|
||||||
|
|
||||||
var ctx = new RenderContext();
|
|
||||||
var error = RenderFunc.Invoke(ctx);
|
|
||||||
if (error != Error.None)
|
|
||||||
{
|
|
||||||
_commandBuffer.End();
|
|
||||||
return Result.Failure(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderOutput.EndRender(_commandBuffer);
|
|
||||||
var r = _commandBuffer.End();
|
|
||||||
if (r.IsFailure)
|
|
||||||
{
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
_graphicsEngine.Device.GraphicsQueue.Submit(_commandBuffer);
|
|
||||||
RenderOutput.Present();
|
|
||||||
|
|
||||||
return Result.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
//// TODO: A proper render graph integration.
|
|
||||||
//private Error RenderScene(Handle<Texture> target, ViewportDesc viewport, ScissorRectDesc rect)
|
|
||||||
//{
|
|
||||||
// // NOTE: Testing only.
|
|
||||||
// var ctx = new RenderingContext(_graphicsEngine, _commandBuffer);
|
|
||||||
// if (_frameIndex == 0)
|
|
||||||
// {
|
|
||||||
// _pass.Initialize(ref ctx);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //_commandBuffer.BeginRenderPass(rtDesc, depthDesc, false);
|
|
||||||
// _commandBuffer.SetViewport(viewport);
|
|
||||||
// _commandBuffer.SetScissorRect(rect);
|
|
||||||
|
|
||||||
// _renderGraph.Reset();
|
|
||||||
|
|
||||||
// var backBuffer = _renderGraph.ImportTexture(target, "Back Buffer");
|
|
||||||
// _pass.Build(_renderGraph, backBuffer);
|
|
||||||
|
|
||||||
// // Create view state from viewport
|
|
||||||
// var viewState = new ViewState((uint)viewport.Width, (uint)viewport.Height);
|
|
||||||
|
|
||||||
// // Compile with view state
|
|
||||||
// _renderGraph.Compile(in viewState);
|
|
||||||
// _renderGraph.Execute(_commandBuffer);
|
|
||||||
|
|
||||||
// //_commandBuffer.EndRenderPass();
|
|
||||||
// _frameIndex++;
|
|
||||||
|
|
||||||
// return Error.None;
|
|
||||||
//}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (_disposed)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_commandBuffer.Dispose();
|
|
||||||
|
|
||||||
_disposed = true;
|
|
||||||
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -487,7 +487,7 @@ internal static unsafe class D3D12Utility
|
|||||||
public static D3D12_RASTERIZER_DESC D3D12_RASTERIZER_DESC_CREATE(
|
public static D3D12_RASTERIZER_DESC D3D12_RASTERIZER_DESC_CREATE(
|
||||||
D3D12_FILL_MODE fillMode,
|
D3D12_FILL_MODE fillMode,
|
||||||
D3D12_CULL_MODE cullMode,
|
D3D12_CULL_MODE cullMode,
|
||||||
bool frontCounterClockwise = false,
|
bool frontCounterClockwise = true,
|
||||||
int depthBias = D3D12_DEFAULT_DEPTH_BIAS,
|
int depthBias = D3D12_DEFAULT_DEPTH_BIAS,
|
||||||
float depthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP,
|
float depthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP,
|
||||||
float slopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
|
float slopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
using Ghost.Core;
|
|
||||||
|
|
||||||
namespace Ghost.Graphics.RHI;
|
|
||||||
|
|
||||||
public readonly struct RenderContext
|
|
||||||
{
|
|
||||||
public ICommandBuffer CommandBuffer { get; init; }
|
|
||||||
public ICommandQueue GraphicsQueue { get; init; }
|
|
||||||
public ICommandQueue ComputeQueue { get; init; }
|
|
||||||
public ICommandQueue CopyQueue { get; init; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: We may don't need this anymore. We Use RenderExtractionSystem to extract render data from entities and pass them to IRenderPipeline to render.
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// High-level renderer interface that uses RHI abstractions
|
|
||||||
/// </summary>
|
|
||||||
public interface IRenderer : IDisposable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the render output target for this renderer.
|
|
||||||
/// </summary>
|
|
||||||
IRenderOutput? RenderOutput
|
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The function that performs the actual rendering operations. Skip rendering if this is null.
|
|
||||||
/// </summary>
|
|
||||||
Func<RenderContext, Error>? RenderFunc
|
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Renders a frame
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="commandAllocator">Command allocator to use for rendering</param>
|
|
||||||
/// <returns>Result of the rendering operation</returns>
|
|
||||||
Result Render(ICommandAllocator commandAllocator);
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
using Ghost.Core;
|
using Ghost.Core;
|
||||||
using Ghost.Graphics.RHI;
|
using Ghost.Graphics.RHI;
|
||||||
using Ghost.Graphics.Utilities;
|
using Ghost.Graphics.Utilities;
|
||||||
|
using Misaki.HighPerformance.Jobs;
|
||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
using Misaki.HighPerformance.LowLevel.Collections;
|
using Misaki.HighPerformance.LowLevel.Collections;
|
||||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
|
||||||
using Misaki.HighPerformance.Mathematics;
|
using Misaki.HighPerformance.Mathematics;
|
||||||
using Misaki.HighPerformance.Mathematics.Geometry;
|
using Misaki.HighPerformance.Mathematics.Geometry;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
@@ -246,6 +246,7 @@ public struct Mesh : IResourceReleasable
|
|||||||
private static unsafe int MeshletOutputCallback(void* context, ClodGroup group, ReadOnlyUnsafeCollection<ClodCluster> clusters)
|
private static unsafe int MeshletOutputCallback(void* context, ClodGroup group, ReadOnlyUnsafeCollection<ClodCluster> clusters)
|
||||||
{
|
{
|
||||||
var mesh = (Mesh*)context;
|
var mesh = (Mesh*)context;
|
||||||
|
|
||||||
ref var data = ref mesh->_meshletData;
|
ref var data = ref mesh->_meshletData;
|
||||||
|
|
||||||
// Ensure lists are initialized
|
// Ensure lists are initialized
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Ghost.Core;
|
using Ghost.Core;
|
||||||
|
using Ghost.Graphics.RenderPipeline;
|
||||||
using Ghost.Graphics.RHI;
|
using Ghost.Graphics.RHI;
|
||||||
using Misaki.HighPerformance.Mathematics;
|
using Misaki.HighPerformance.Mathematics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ using Ghost.Core;
|
|||||||
using Ghost.Graphics.RHI;
|
using Ghost.Graphics.RHI;
|
||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
using Misaki.HighPerformance.LowLevel.Collections;
|
using Misaki.HighPerformance.LowLevel.Collections;
|
||||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
|
||||||
using Misaki.HighPerformance.Mathematics;
|
|
||||||
|
|
||||||
namespace Ghost.Graphics.Core;
|
namespace Ghost.Graphics.Core;
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,16 @@ public enum AccessFlags : byte
|
|||||||
ReadWrite = Read | Write,
|
ReadWrite = Read | Write,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum ResourceExtractionFlags : byte
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// Releases the old resource after extraction.
|
||||||
|
/// </summary>
|
||||||
|
ReleaseAfterExtract = 1 << 0,
|
||||||
|
}
|
||||||
|
|
||||||
public interface IRenderGraphBuilder : IDisposable
|
public interface IRenderGraphBuilder : IDisposable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -33,17 +43,6 @@ public interface IRenderGraphBuilder : IDisposable
|
|||||||
/// <returns>An identifier for the newly created texture resource.</returns>
|
/// <returns>An identifier for the newly created texture resource.</returns>
|
||||||
Identifier<RGTexture> CreateTexture(in RGTextureDesc desc, string name);
|
Identifier<RGTexture> CreateTexture(in RGTextureDesc desc, string name);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates multiple texture resources based on the specified desc.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Those textures will be used as multi buffering in the render graph automaticlly and not aliasable with other resources.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="desc">A structure that defines the properties and configuration of the texture to create.</param>
|
|
||||||
/// <param name="name">The base name of the texture resources. The actual name for each texture will be generated by appending an index to this base name.</param>
|
|
||||||
/// <param name="textureIDs">A span to receive the identifiers for the newly created texture resources. The length of the span determines how many textures will be created.</param>
|
|
||||||
void CreateTextures(in RGTextureDesc desc, string name, Span<Identifier<RGTexture>> textureIDs);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new buffer resource based on the specified desc.
|
/// Creates a new buffer resource based on the specified desc.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -52,17 +51,6 @@ public interface IRenderGraphBuilder : IDisposable
|
|||||||
/// <returns>An identifier for the newly created buffer resource.</returns>
|
/// <returns>An identifier for the newly created buffer resource.</returns>
|
||||||
Identifier<RGBuffer> CreateBuffer(in BufferDesc desc, string name);
|
Identifier<RGBuffer> CreateBuffer(in BufferDesc desc, string name);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates multiple buffer resources based on the specified desc.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Those buffers will be used as multi buffering in the render graph automaticlly and not aliasable with other resources.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="desc">A structure that defines the properties and configuration of the buffer to create.</param>
|
|
||||||
/// <param name="name">The base name of the buffer resources. The actual name for each buffer will be generated by appending an index to this base name.</param>
|
|
||||||
/// <param name="bufferIDs">A span to receive the identifiers for the newly created buffer resources. The length of the span determines how many buffers will be created.</param>
|
|
||||||
void CreateBuffers(in BufferDesc desc, string name, Span<Identifier<RGBuffer>> bufferIDs);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers the specified texture for use in the current render graph pass with the given access mode.
|
/// Registers the specified texture for use in the current render graph pass with the given access mode.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -83,16 +71,16 @@ public interface IRenderGraphBuilder : IDisposable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extracts the actual texture resource associated with the given identifier for use in outside of the render graph execution context.
|
/// Extracts the actual texture resource associated with the given identifier for use in outside of the render graph execution context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="texture">The identifier of the texture to be extracted.</param>
|
/// <param name="src">The identifier of the texture to be extracted.</param>
|
||||||
/// <returns>A handle to the actual texture resource that can be used outside of the render graph execution context.</returns>
|
/// <param name="dst">A handle to receive the actual GPU texture resource.</param>
|
||||||
Handle<GPUTexture> ExtractTexture(Identifier<RGTexture> texture);
|
void QueryTextureExtraction(Identifier<RGTexture> src, Handle<GPUTexture> dst, ResourceExtractionFlags flags = ResourceExtractionFlags.ReleaseAfterExtract);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extracts the actual buffer resource associated with the given identifier for use in outside of the render graph execution context.
|
/// Extracts the actual buffer resource associated with the given identifier for use in outside of the render graph execution context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="buffer">The identifier of the buffer to be extracted.</param>
|
/// <param name="src">The identifier of the buffer to be extracted.</param>
|
||||||
/// <returns>A handle to the actual buffer resource that can be used outside of the render graph execution context.</returns>
|
/// <param name="dst">A handle to receive the actual GPU buffer resource.</param>
|
||||||
Handle<GPUBuffer> ExtractBuffer(Identifier<RGBuffer> buffer);
|
void QueryBufferExtraction(Identifier<RGBuffer> src, Handle<GPUBuffer> dst, ResourceExtractionFlags flags = ResourceExtractionFlags.ReleaseAfterExtract);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IRasterRenderGraphBuilder : IRenderGraphBuilder
|
public interface IRasterRenderGraphBuilder : IRenderGraphBuilder
|
||||||
@@ -244,18 +232,6 @@ internal class RenderGraphBuilder : IRasterRenderGraphBuilder, IComputeRenderGra
|
|||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateTextures(in RGTextureDesc desc, string name, Span<Identifier<RGTexture>> textureIDs)
|
|
||||||
{
|
|
||||||
// TODO: Create multiple textures, mark them as no aliasable, and add them to the resource registry and current pass.
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CreateBuffers(in BufferDesc desc, string name, Span<Identifier<RGBuffer>> bufferIDs)
|
|
||||||
{
|
|
||||||
// TODO: Create multiple buffers, mark them as no aliasable, and add them to the resource registry and current pass.
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Identifier<RGTexture> UseTexture(Identifier<RGTexture> texture, AccessFlags flags)
|
public Identifier<RGTexture> UseTexture(Identifier<RGTexture> texture, AccessFlags flags)
|
||||||
{
|
{
|
||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
@@ -268,13 +244,13 @@ internal class RenderGraphBuilder : IRasterRenderGraphBuilder, IComputeRenderGra
|
|||||||
return UseResource(buffer.AsResource(), flags, RenderGraphResourceType.Buffer).AsBuffer();
|
return UseResource(buffer.AsResource(), flags, RenderGraphResourceType.Buffer).AsBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement ExtractTexture and ExtractBuffer to allow users to get the actual GPU resources for use outside of the render graph execution context.
|
// TODO: Implement QueryTextureExtraction and QueryBufferExtraction to allow users to get the actual GPU resources for use outside of the render graph execution context.
|
||||||
public Handle<GPUTexture> ExtractTexture(Identifier<RGTexture> texture)
|
public void QueryTextureExtraction(Identifier<RGTexture> src, Handle<GPUTexture> dst, ResourceExtractionFlags flags = ResourceExtractionFlags.ReleaseAfterExtract)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Handle<GPUBuffer> ExtractBuffer(Identifier<RGBuffer> buffer)
|
public void QueryBufferExtraction(Identifier<RGBuffer> src, Handle<GPUBuffer> dst, ResourceExtractionFlags flags = ResourceExtractionFlags.ReleaseAfterExtract)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,14 @@ using Ghost.Graphics.RHI;
|
|||||||
|
|
||||||
namespace Ghost.Graphics.RenderPipeline;
|
namespace Ghost.Graphics.RenderPipeline;
|
||||||
|
|
||||||
|
public readonly struct RenderContext
|
||||||
|
{
|
||||||
|
public ICommandBuffer CommandBuffer { get; init; }
|
||||||
|
public ICommandQueue GraphicsQueue { get; init; }
|
||||||
|
public ICommandQueue ComputeQueue { get; init; }
|
||||||
|
public ICommandQueue CopyQueue { get; init; }
|
||||||
|
}
|
||||||
|
|
||||||
public interface IRenderPipelineSettings
|
public interface IRenderPipelineSettings
|
||||||
{
|
{
|
||||||
IRenderPipeline CreatePipeline(RenderSystem renderSystem);
|
IRenderPipeline CreatePipeline(RenderSystem renderSystem);
|
||||||
|
|||||||
@@ -205,7 +205,8 @@ public sealed class ResourceManager : IDisposable
|
|||||||
{
|
{
|
||||||
Debug.Assert(!_disposed);
|
Debug.Assert(!_disposed);
|
||||||
|
|
||||||
if (!_meshes.TryGetElementAt(handle.ID, handle.Generation, out var mesh))
|
ref var mesh = ref _meshes.GetElementReferenceAt(handle.ID, handle.Generation, out var exist);
|
||||||
|
if (!exist)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -249,7 +250,7 @@ public sealed class ResourceManager : IDisposable
|
|||||||
{
|
{
|
||||||
Debug.Assert(!_disposed);
|
Debug.Assert(!_disposed);
|
||||||
|
|
||||||
var material = _materials.GetElementReferenceAt(handle.ID, handle.Generation, out var exist);
|
ref var material = ref _materials.GetElementReferenceAt(handle.ID, handle.Generation, out var exist);
|
||||||
if (!exist)
|
if (!exist)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -359,7 +360,7 @@ public sealed class ResourceManager : IDisposable
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var shader = _shaders[id.Value];
|
ref var shader = ref _shaders[id.Value];
|
||||||
shader.ReleaseResource(_resourceDatabase);
|
shader.ReleaseResource(_resourceDatabase);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,17 +403,17 @@ public sealed class ResourceManager : IDisposable
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var mesh in _meshes)
|
foreach (ref var mesh in _meshes)
|
||||||
{
|
{
|
||||||
mesh.ReleaseResource(_resourceDatabase);
|
mesh.ReleaseResource(_resourceDatabase);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var material in _materials)
|
foreach (ref var material in _materials)
|
||||||
{
|
{
|
||||||
material.ReleaseResource(_resourceDatabase);
|
material.ReleaseResource(_resourceDatabase);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var shader in _shaders)
|
foreach (ref var shader in _shaders)
|
||||||
{
|
{
|
||||||
shader.ReleaseResource(_resourceDatabase);
|
shader.ReleaseResource(_resourceDatabase);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ shader "MyShader/Standard"
|
|||||||
{
|
{
|
||||||
pipeline
|
pipeline
|
||||||
{
|
{
|
||||||
ztest = disabled;
|
ztest = less_equal;
|
||||||
zwrite = off;
|
zwrite = on;
|
||||||
cull = off;
|
cull = back;
|
||||||
blend = opaque;
|
blend = opaque;
|
||||||
color_mask = all;
|
color_mask = all;
|
||||||
}
|
}
|
||||||
@@ -34,6 +34,7 @@ shader "MyShader/Standard"
|
|||||||
{
|
{
|
||||||
float4 position : SV_POSITION;
|
float4 position : SV_POSITION;
|
||||||
float4 color : COLOR;
|
float4 color : COLOR;
|
||||||
|
float3 normal : NORMAL;
|
||||||
float2 uv : TEXCOORD0;
|
float2 uv : TEXCOORD0;
|
||||||
nointerpolation uint meshletID : MESHLET_ID;
|
nointerpolation uint meshletID : MESHLET_ID;
|
||||||
};
|
};
|
||||||
@@ -78,6 +79,7 @@ shader "MyShader/Standard"
|
|||||||
// outVerts[groupThreadID.x].position = v.position.xyz;
|
// outVerts[groupThreadID.x].position = v.position.xyz;
|
||||||
|
|
||||||
outVerts[groupThreadID.x].color = v.color;
|
outVerts[groupThreadID.x].color = v.color;
|
||||||
|
outVerts[groupThreadID.x].normal = normalize(mul((float3x3)instanceData.localToWorld, v.normal));
|
||||||
outVerts[groupThreadID.x].uv = v.uv;
|
outVerts[groupThreadID.x].uv = v.uv;
|
||||||
outVerts[groupThreadID.x].meshletID = groupID.x;
|
outVerts[groupThreadID.x].meshletID = groupID.x;
|
||||||
}
|
}
|
||||||
@@ -110,13 +112,14 @@ shader "MyShader/Standard"
|
|||||||
// float4 blendedColor = (color1 + color2 + color3 + color4) * 0.25f;
|
// float4 blendedColor = (color1 + color2 + color3 + color4) * 0.25f;
|
||||||
// return perMaterialData.color * blendedColor + input.color;
|
// return perMaterialData.color * blendedColor + input.color;
|
||||||
|
|
||||||
uint hash = PCGHash(input.meshletID);
|
// uint hash = PCGHash(input.meshletID);
|
||||||
|
//
|
||||||
float r = float((hash & 0xFF0000u) >> 16) / 255.0;
|
// float r = float((hash & 0xFF0000u) >> 16) / 255.0;
|
||||||
float g = float((hash & 0x00FF00u) >> 8) / 255.0;
|
// float g = float((hash & 0x00FF00u) >> 8) / 255.0;
|
||||||
float b = float((hash & 0x0000FFu)) / 255.0;
|
// float b = float((hash & 0x0000FFu)) / 255.0;
|
||||||
|
//
|
||||||
return float4(r, g, b, 1.0);
|
// return float4(r, g, b, 1.0);
|
||||||
|
return float4(input.normal, 1.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ public partial class EntityQueryTest : ITest
|
|||||||
{
|
{
|
||||||
_world.Dispose();
|
_world.Dispose();
|
||||||
_jobScheduler.Dispose();
|
_jobScheduler.Dispose();
|
||||||
JobScheduler.ReleaseTempAllocator();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public unsafe partial class TestRenderPipeline : IRenderPipeline
|
|||||||
{
|
{
|
||||||
private class MeshletDebugPassData
|
private class MeshletDebugPassData
|
||||||
{
|
{
|
||||||
|
public Identifier<RGTexture> depth;
|
||||||
public Identifier<RGTexture> backbuffer;
|
public Identifier<RGTexture> backbuffer;
|
||||||
public RenderList renderList;
|
public RenderList renderList;
|
||||||
public Handle<Material> material;
|
public Handle<Material> material;
|
||||||
@@ -202,7 +203,7 @@ public unsafe partial class TestRenderPipeline : IRenderPipeline
|
|||||||
|
|
||||||
var m_11 = 1.0f / math.tan(vfovF * 0.5f);
|
var m_11 = 1.0f / math.tan(vfovF * 0.5f);
|
||||||
var m_00 = m_11 / aspectScreen;
|
var m_00 = m_11 / aspectScreen;
|
||||||
var m_22 = -request.view.farClipPlane / (request.view.farClipPlane - request.view.nearClipPlane);
|
var m_22 = request.view.farClipPlane / (request.view.farClipPlane - request.view.nearClipPlane);
|
||||||
var m_23 = -(request.view.farClipPlane * request.view.nearClipPlane) / (request.view.farClipPlane - request.view.nearClipPlane);
|
var m_23 = -(request.view.farClipPlane * request.view.nearClipPlane) / (request.view.farClipPlane - request.view.nearClipPlane);
|
||||||
|
|
||||||
var projectionMatrix = new float4x4
|
var projectionMatrix = new float4x4
|
||||||
@@ -210,7 +211,7 @@ public unsafe partial class TestRenderPipeline : IRenderPipeline
|
|||||||
m_00, 0, 0, 0,
|
m_00, 0, 0, 0,
|
||||||
0, m_11, 0, 0,
|
0, m_11, 0, 0,
|
||||||
0, 0, m_22, m_23,
|
0, 0, m_22, m_23,
|
||||||
0, 0, -1, 0
|
0, 0, 1, 0
|
||||||
);
|
);
|
||||||
|
|
||||||
//var vp = math.mul(projectionMatrix, viewMatrix);
|
//var vp = math.mul(projectionMatrix, viewMatrix);
|
||||||
@@ -341,12 +342,13 @@ public unsafe partial class TestRenderPipeline : IRenderPipeline
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIX: We still not change our root signature layout yet.
|
|
||||||
|
|
||||||
private void MeshletDebugPass(Identifier<RGTexture> backbuffer, RenderList renderList, uint globalIndex, uint viewIndex, uint instanceBuffer)
|
private void MeshletDebugPass(Identifier<RGTexture> backbuffer, RenderList renderList, uint globalIndex, uint viewIndex, uint instanceBuffer)
|
||||||
{
|
{
|
||||||
using (var builder = _renderGraph.AddRasterRenderPass<MeshletDebugPassData>("Meshlet Debug Pass", out var passData))
|
using (var builder = _renderGraph.AddRasterRenderPass<MeshletDebugPassData>("Meshlet Debug Pass", out var passData))
|
||||||
{
|
{
|
||||||
|
var depth = builder.CreateTexture(RGTextureDesc.RelativeDepth(1.0f), "Depth Texture");
|
||||||
|
|
||||||
|
passData.depth = depth;
|
||||||
passData.backbuffer = backbuffer;
|
passData.backbuffer = backbuffer;
|
||||||
passData.renderList = renderList;
|
passData.renderList = renderList;
|
||||||
passData.globalIndex = globalIndex;
|
passData.globalIndex = globalIndex;
|
||||||
@@ -355,6 +357,8 @@ public unsafe partial class TestRenderPipeline : IRenderPipeline
|
|||||||
passData.material = _meshletMaterial;
|
passData.material = _meshletMaterial;
|
||||||
|
|
||||||
builder.SetColorAttachment(backbuffer, 0);
|
builder.SetColorAttachment(backbuffer, 0);
|
||||||
|
builder.SetDepthAttachment(depth);
|
||||||
|
|
||||||
builder.SetRenderFunc<MeshletDebugPassData>(static (data, ctx)=>
|
builder.SetRenderFunc<MeshletDebugPassData>(static (data, ctx)=>
|
||||||
{
|
{
|
||||||
ctx.SetGlobalData(data.globalIndex, data.viewIndex);
|
ctx.SetGlobalData(data.globalIndex, data.viewIndex);
|
||||||
|
|||||||
@@ -25,40 +25,12 @@ public partial class UnitTestApp : Application
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void LoadDll()
|
|
||||||
{
|
|
||||||
var currentDir = AppContext.BaseDirectory;
|
|
||||||
var platform = OperatingSystem.IsWindows() ? "win" :
|
|
||||||
OperatingSystem.IsLinux() ? "linux" :
|
|
||||||
OperatingSystem.IsMacOS() ? "osx" : "unknown";
|
|
||||||
var arch = Environment.Is64BitProcess ? "x64" : "x86";
|
|
||||||
var nativeDllDir = Path.Combine(currentDir, "runtimes", platform + "-" + arch, "native");
|
|
||||||
if (Directory.Exists(nativeDllDir))
|
|
||||||
{
|
|
||||||
foreach (var dll in Directory.EnumerateFiles(nativeDllDir, "*.dll"))
|
|
||||||
{
|
|
||||||
NativeLibrary.Load(dll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//NativeLibrary.SetDllImportResolver(typeof(UnitTestApp).Assembly, (libraryName, assembly, searchPath) =>
|
|
||||||
//{
|
|
||||||
// if (libraryName == "dxcompiler")
|
|
||||||
// {
|
|
||||||
// NativeLibrary.Load(Path.Combine(nativeDllDir, "dxil.dll"));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return IntPtr.Zero;
|
|
||||||
//});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when the application is launched.
|
/// Invoked when the application is launched.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="args">Details about the launch request and process.</param>
|
/// <param name="args">Details about the launch request and process.</param>
|
||||||
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
||||||
{
|
{
|
||||||
LoadDll();
|
|
||||||
|
|
||||||
_window = new GraphicsTestWindow();
|
_window = new GraphicsTestWindow();
|
||||||
_window.Activate();
|
_window.Activate();
|
||||||
|
|
||||||
|
|||||||
@@ -80,15 +80,15 @@ internal static class MeshUtility
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var maxScratchIndices = (uint)(pMesh->max_face_triangles * 3u);
|
var maxScratchIndices = (int)(pMesh->max_face_triangles * 3u);
|
||||||
|
|
||||||
using var triIndicesArray = new UnsafeArray<uint>((int)maxScratchIndices, scope1.AllocationHandle);
|
using var triIndicesArray = new UnsafeArray<uint>(maxScratchIndices, scope1.AllocationHandle);
|
||||||
|
|
||||||
for (var j = 0u; j < pMesh->num_faces; j++)
|
for (var j = 0u; j < pMesh->num_faces; j++)
|
||||||
{
|
{
|
||||||
var face = pMesh->faces.data[j];
|
var face = pMesh->faces.data[j];
|
||||||
|
|
||||||
var numTris = UfbxApi.TriangulateFace((uint*)triIndicesArray.GetUnsafePtr(), maxScratchIndices, pMesh, face);
|
var numTris = UfbxApi.TriangulateFace(triIndicesArray.AsSpan(0, maxScratchIndices), pMesh, face);
|
||||||
|
|
||||||
var totalIndices = numTris * 3;
|
var totalIndices = numTris * 3;
|
||||||
for (var k = 0; k < totalIndices; k++)
|
for (var k = 0; k < totalIndices; k++)
|
||||||
@@ -147,13 +147,13 @@ internal static class MeshUtility
|
|||||||
vertex_size = (nuint)sizeof(Vertex)
|
vertex_size = (nuint)sizeof(Vertex)
|
||||||
};
|
};
|
||||||
|
|
||||||
var numUniqueVertices = stream.GenerateIndices(1, (uint*)weldedIndices.GetUnsafePtr(), (nuint)weldedIndices.Count, null, &error);
|
var numUniqueVertices = UfbxApi.GenerateIndices([stream], weldedIndices, null, &error);
|
||||||
if (numUniqueVertices == 0 && error.type != ufbx_error_type.UFBX_ERROR_NONE)
|
if (numUniqueVertices == 0 && error.type != ufbx_error_type.UFBX_ERROR_NONE)
|
||||||
{
|
{
|
||||||
return Result.Failure($"Welding failed: {error.description}");
|
return Result.Failure($"Welding failed: {error.description}");
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshOptApi.OptimizeVertexCache((uint*)cachedIndices.GetUnsafePtr(), (uint*)weldedIndices.GetUnsafePtr(), numIndices, numIndices);
|
MeshOptApi.OptimizeVertexCache((uint*)cachedIndices.GetUnsafePtr(), (uint*)weldedIndices.GetUnsafePtr(), numIndices, numUniqueVertices);
|
||||||
|
|
||||||
vertices = new UnsafeList<Vertex>((int)numUniqueVertices, allocator);
|
vertices = new UnsafeList<Vertex>((int)numUniqueVertices, allocator);
|
||||||
indices = new UnsafeList<uint>((int)numIndices, allocator);
|
indices = new UnsafeList<uint>((int)numIndices, allocator);
|
||||||
@@ -165,11 +165,11 @@ internal static class MeshUtility
|
|||||||
MemoryUtility.MemCpy(indices.GetUnsafePtr(), cachedIndices.GetUnsafePtr(), numIndices * sizeof(uint));
|
MemoryUtility.MemCpy(indices.GetUnsafePtr(), cachedIndices.GetUnsafePtr(), numIndices * sizeof(uint));
|
||||||
indices.UnsafeSetCount((int)numIndices);
|
indices.UnsafeSetCount((int)numIndices);
|
||||||
|
|
||||||
if (needComputeNormals)
|
//if (needComputeNormals)
|
||||||
{
|
//{
|
||||||
MeshBuilder.ComputeNormal(vertices, indices);
|
// MeshBuilder.ComputeNormal(vertices, indices);
|
||||||
MeshBuilder.ComputeTangents(vertices, indices);
|
// MeshBuilder.ComputeTangents(vertices, indices);
|
||||||
}
|
//}
|
||||||
|
|
||||||
return Result.Success();
|
return Result.Success();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Ghost.Graphics.Utilities;
|
|||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Controls;
|
using Microsoft.UI.Xaml.Controls;
|
||||||
using Microsoft.UI.Xaml.Media;
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
using Misaki.HighPerformance.Jobs;
|
||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
using Misaki.HighPerformance.Mathematics;
|
using Misaki.HighPerformance.Mathematics;
|
||||||
|
|
||||||
@@ -19,6 +20,7 @@ public sealed partial class GraphicsTestWindow : Window
|
|||||||
{
|
{
|
||||||
private RenderSystem? _renderSystem;
|
private RenderSystem? _renderSystem;
|
||||||
private ISwapChain? _swapChain;
|
private ISwapChain? _swapChain;
|
||||||
|
private JobScheduler _jobScheduler;
|
||||||
private World? _world;
|
private World? _world;
|
||||||
|
|
||||||
private Handle<Mesh> _meshHandle;
|
private Handle<Mesh> _meshHandle;
|
||||||
@@ -43,6 +45,8 @@ public sealed partial class GraphicsTestWindow : Window
|
|||||||
};
|
};
|
||||||
|
|
||||||
AllocationManager.Initialize(opts);
|
AllocationManager.Initialize(opts);
|
||||||
|
|
||||||
|
_jobScheduler = new JobScheduler(Environment.ProcessorCount - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GraphicsTestWindow_Activated(object sender, WindowActivatedEventArgs e)
|
private void GraphicsTestWindow_Activated(object sender, WindowActivatedEventArgs e)
|
||||||
@@ -75,7 +79,7 @@ public sealed partial class GraphicsTestWindow : Window
|
|||||||
_renderSystem.Start();
|
_renderSystem.Start();
|
||||||
|
|
||||||
// ECS Setup
|
// ECS Setup
|
||||||
_world = World.Create();
|
_world = World.Create(_jobScheduler);
|
||||||
_world.AddService(_renderSystem);
|
_world.AddService(_renderSystem);
|
||||||
|
|
||||||
// Add Systems
|
// Add Systems
|
||||||
@@ -105,7 +109,7 @@ public sealed partial class GraphicsTestWindow : Window
|
|||||||
|
|
||||||
_world.EntityManager.SetComponent(cameraEntity, new LocalToWorld
|
_world.EntityManager.SetComponent(cameraEntity, new LocalToWorld
|
||||||
{
|
{
|
||||||
matrix = float4x4.TRS(new float3(0.0f, 1.0f, 5.0f), quaternion.EulerXYZ(new float3(0, 0, 0)), new float3(1.0f, 1.0f, 1.0f))
|
matrix = float4x4.TRS(new float3(0.0f, 1.0f, -5.0f), quaternion.EulerXYZ(new float3(0, 0, 0)), float3.one)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create Mesh Entity
|
// Create Mesh Entity
|
||||||
@@ -158,6 +162,7 @@ public sealed partial class GraphicsTestWindow : Window
|
|||||||
_renderSystem?.ResourceManager.ReleaseMesh(_meshHandle);
|
_renderSystem?.ResourceManager.ReleaseMesh(_meshHandle);
|
||||||
|
|
||||||
_swapChain?.Dispose();
|
_swapChain?.Dispose();
|
||||||
|
_jobScheduler.Dispose();
|
||||||
_renderSystem?.Dispose();
|
_renderSystem?.Dispose();
|
||||||
|
|
||||||
AllocationManager.Dispose();
|
AllocationManager.Dispose();
|
||||||
|
|||||||
@@ -1,9 +1,33 @@
|
|||||||
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ghost.MeshOptimizer
|
namespace Ghost.MeshOptimizer
|
||||||
{
|
{
|
||||||
public static unsafe partial class Api
|
public static unsafe partial class Api
|
||||||
{
|
{
|
||||||
|
static Api()
|
||||||
|
{
|
||||||
|
NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), (libraryName, assembly, searchPath) =>
|
||||||
|
{
|
||||||
|
if (libraryName != "meshoptimizer")
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
var platform = OperatingSystem.IsWindows() ? "win" :
|
||||||
|
OperatingSystem.IsLinux() ? "linux" :
|
||||||
|
OperatingSystem.IsMacOS() ? "osx" : "unknown";
|
||||||
|
var ext = OperatingSystem.IsWindows() ? ".dll" :
|
||||||
|
OperatingSystem.IsLinux() ? ".so" :
|
||||||
|
OperatingSystem.IsMacOS() ? ".dylib" : "";
|
||||||
|
|
||||||
|
var arch = Environment.Is64BitProcess ? "x64" : "x86";
|
||||||
|
var nativeDllDir = Path.Combine("./runtimes", platform + "-" + arch, "native");
|
||||||
|
|
||||||
|
return NativeLibrary.Load(Path.Combine(nativeDllDir, libraryName + ext));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[DllImport("meshoptimizer", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
[DllImport("meshoptimizer", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||||
[return: NativeTypeName("size_t")]
|
[return: NativeTypeName("size_t")]
|
||||||
public static extern nuint meshopt_generateVertexRemap([NativeTypeName("unsigned int *")] uint* destination, [NativeTypeName("const unsigned int *")] uint* indices, [NativeTypeName("size_t")] nuint index_count, [NativeTypeName("const void *")] void* vertices, [NativeTypeName("size_t")] nuint vertex_count, [NativeTypeName("size_t")] nuint vertex_size);
|
public static extern nuint meshopt_generateVertexRemap([NativeTypeName("unsigned int *")] uint* destination, [NativeTypeName("const unsigned int *")] uint* indices, [NativeTypeName("size_t")] nuint index_count, [NativeTypeName("const void *")] void* vertices, [NativeTypeName("size_t")] nuint vertex_count, [NativeTypeName("size_t")] nuint vertex_size);
|
||||||
|
|||||||
@@ -1,9 +1,28 @@
|
|||||||
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ghost.Nvtt
|
namespace Ghost.Nvtt
|
||||||
{
|
{
|
||||||
public static unsafe partial class Api
|
public static unsafe partial class Api
|
||||||
{
|
{
|
||||||
|
static Api()
|
||||||
|
{
|
||||||
|
NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), (libraryName, assembly, searchPath) =>
|
||||||
|
{
|
||||||
|
var platform = OperatingSystem.IsWindows() ? "win" :
|
||||||
|
OperatingSystem.IsLinux() ? "linux" :
|
||||||
|
OperatingSystem.IsMacOS() ? "osx" : "unknown";
|
||||||
|
var ext = OperatingSystem.IsWindows() ? ".dll" :
|
||||||
|
OperatingSystem.IsLinux() ? ".so" :
|
||||||
|
OperatingSystem.IsMacOS() ? ".dylib" : "";
|
||||||
|
|
||||||
|
var arch = Environment.Is64BitProcess ? "x64" : "x86";
|
||||||
|
var nativeDllDir = Path.Combine("./runtimes", platform + "-" + arch, "native");
|
||||||
|
|
||||||
|
return NativeLibrary.Load(Path.Combine(nativeDllDir, libraryName + ext));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[DllImport("nvtt", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
[DllImport("nvtt", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||||
public static extern NvttBoolean nvttIsCudaSupported();
|
public static extern NvttBoolean nvttIsCudaSupported();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using static Ghost.Ufbx.ufbx_aperture_format;
|
using static Ghost.Ufbx.ufbx_aperture_format;
|
||||||
using static Ghost.Ufbx.ufbx_aperture_mode;
|
using static Ghost.Ufbx.ufbx_aperture_mode;
|
||||||
@@ -167,6 +168,29 @@ namespace Ghost.Ufbx
|
|||||||
|
|
||||||
public const int UFBX_BAKE_STEP_HANDLING_COUNT = (int)(UFBX_BAKE_STEP_HANDLING_IGNORE + 1);
|
public const int UFBX_BAKE_STEP_HANDLING_COUNT = (int)(UFBX_BAKE_STEP_HANDLING_IGNORE + 1);
|
||||||
|
|
||||||
|
static Api()
|
||||||
|
{
|
||||||
|
NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), (libraryName, assembly, searchPath) =>
|
||||||
|
{
|
||||||
|
if (libraryName != "ufbx")
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
var platform = OperatingSystem.IsWindows() ? "win" :
|
||||||
|
OperatingSystem.IsLinux() ? "linux" :
|
||||||
|
OperatingSystem.IsMacOS() ? "osx" : "unknown";
|
||||||
|
var ext = OperatingSystem.IsWindows() ? ".dll" :
|
||||||
|
OperatingSystem.IsLinux() ? ".so" :
|
||||||
|
OperatingSystem.IsMacOS() ? ".dylib" : "";
|
||||||
|
|
||||||
|
var arch = Environment.Is64BitProcess ? "x64" : "x86";
|
||||||
|
var nativeDllDir = Path.Combine("./runtimes", platform + "-" + arch, "native");
|
||||||
|
|
||||||
|
return NativeLibrary.Load(Path.Combine(nativeDllDir, libraryName + ext));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[DllImport("ufbx", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
[DllImport("ufbx", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||||
[return: NativeTypeName("_Bool")]
|
[return: NativeTypeName("_Bool")]
|
||||||
public static extern bool ufbx_is_thread_safe();
|
public static extern bool ufbx_is_thread_safe();
|
||||||
|
|||||||
@@ -257,13 +257,67 @@ public unsafe partial struct UfbxApi
|
|||||||
/// From: <see cref="Api.ufbx_triangulate_face(uint*, nuint, ufbx_mesh*, ufbx_face)" />
|
/// From: <see cref="Api.ufbx_triangulate_face(uint*, nuint, ufbx_mesh*, ufbx_face)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public static uint TriangulateFace(uint* indices, nuint num_indices, ufbx_mesh* mesh, ufbx_face face)
|
public static uint TriangulateFace(ReadOnlySpan<uint> indices, ufbx_mesh* mesh, ufbx_face face)
|
||||||
{
|
{
|
||||||
return Api.ufbx_triangulate_face(
|
fixed (uint* pindices = indices)
|
||||||
indices,
|
{
|
||||||
num_indices,
|
return Api.ufbx_triangulate_face(
|
||||||
mesh,
|
(uint*)pindices,
|
||||||
face);
|
(nuint)indices.Length,
|
||||||
|
mesh,
|
||||||
|
face);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// From: <see cref="Api.ufbx_topo_next_vertex_edge(ufbx_topo_edge*, nuint, uint)" />
|
||||||
|
/// </summary>
|
||||||
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static uint TopoNextVertexEdge(ReadOnlySpan<ufbx_topo_edge> topo, uint index)
|
||||||
|
{
|
||||||
|
fixed (ufbx_topo_edge* ptopo = topo)
|
||||||
|
{
|
||||||
|
return Api.ufbx_topo_next_vertex_edge(
|
||||||
|
(ufbx_topo_edge*)ptopo,
|
||||||
|
(nuint)topo.Length,
|
||||||
|
index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// From: <see cref="Api.ufbx_topo_prev_vertex_edge(ufbx_topo_edge*, nuint, uint)" />
|
||||||
|
/// </summary>
|
||||||
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static uint TopoPrevVertexEdge(ReadOnlySpan<ufbx_topo_edge> topo, uint index)
|
||||||
|
{
|
||||||
|
fixed (ufbx_topo_edge* ptopo = topo)
|
||||||
|
{
|
||||||
|
return Api.ufbx_topo_prev_vertex_edge(
|
||||||
|
(ufbx_topo_edge*)ptopo,
|
||||||
|
(nuint)topo.Length,
|
||||||
|
index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// From: <see cref="Api.ufbx_generate_indices(ufbx_vertex_stream*, nuint, uint*, nuint, ufbx_allocator_opts*, ufbx_error*)" />
|
||||||
|
/// </summary>
|
||||||
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static nuint GenerateIndices(ReadOnlySpan<ufbx_vertex_stream> streams, ReadOnlySpan<uint> indices, ufbx_allocator_opts* allocator, ufbx_error* error)
|
||||||
|
{
|
||||||
|
fixed (ufbx_vertex_stream* pstreams = streams)
|
||||||
|
{
|
||||||
|
fixed (uint* pindices = indices)
|
||||||
|
{
|
||||||
|
return Api.ufbx_generate_indices(
|
||||||
|
(ufbx_vertex_stream*)pstreams,
|
||||||
|
(nuint)streams.Length,
|
||||||
|
(uint*)pindices,
|
||||||
|
(nuint)indices.Length,
|
||||||
|
allocator,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -21,12 +21,15 @@ public unsafe partial struct ufbx_blend_deformer
|
|||||||
/// From: <see cref="Api.ufbx_add_blend_vertex_offsets(ufbx_blend_deformer*, Misaki.HighPerformance.Mathematics.float3*, nuint, float)" />
|
/// From: <see cref="Api.ufbx_add_blend_vertex_offsets(ufbx_blend_deformer*, Misaki.HighPerformance.Mathematics.float3*, nuint, float)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public void AddBlendVertexOffsets(Misaki.HighPerformance.Mathematics.float3* vertices, nuint num_vertices, float weight)
|
public void AddBlendVertexOffsets(ReadOnlySpan<Misaki.HighPerformance.Mathematics.float3> vertices, float weight)
|
||||||
{
|
{
|
||||||
Api.ufbx_add_blend_vertex_offsets(
|
fixed (Misaki.HighPerformance.Mathematics.float3* pvertices = vertices)
|
||||||
(ufbx_blend_deformer*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
vertices,
|
Api.ufbx_add_blend_vertex_offsets(
|
||||||
num_vertices,
|
(ufbx_blend_deformer*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
weight);
|
(Misaki.HighPerformance.Mathematics.float3*)pvertices,
|
||||||
|
(nuint)vertices.Length,
|
||||||
|
weight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,12 +32,15 @@ public unsafe partial struct ufbx_blend_shape
|
|||||||
/// From: <see cref="Api.ufbx_add_blend_shape_vertex_offsets(ufbx_blend_shape*, Misaki.HighPerformance.Mathematics.float3*, nuint, float)" />
|
/// From: <see cref="Api.ufbx_add_blend_shape_vertex_offsets(ufbx_blend_shape*, Misaki.HighPerformance.Mathematics.float3*, nuint, float)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public void AddVertexOffsets(Misaki.HighPerformance.Mathematics.float3* vertices, nuint num_vertices, float weight)
|
public void AddVertexOffsets(ReadOnlySpan<Misaki.HighPerformance.Mathematics.float3> vertices, float weight)
|
||||||
{
|
{
|
||||||
Api.ufbx_add_blend_shape_vertex_offsets(
|
fixed (Misaki.HighPerformance.Mathematics.float3* pvertices = vertices)
|
||||||
(ufbx_blend_shape*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
vertices,
|
Api.ufbx_add_blend_shape_vertex_offsets(
|
||||||
num_vertices,
|
(ufbx_blend_shape*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
weight);
|
(Misaki.HighPerformance.Mathematics.float3*)pvertices,
|
||||||
|
(nuint)vertices.Length,
|
||||||
|
weight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,27 +10,33 @@ public unsafe partial struct ufbx_cache_channel
|
|||||||
/// From: <see cref="Api.ufbx_sample_geometry_cache_real(ufbx_cache_channel*, double, float*, nuint, ufbx_geometry_cache_data_opts*)" />
|
/// From: <see cref="Api.ufbx_sample_geometry_cache_real(ufbx_cache_channel*, double, float*, nuint, ufbx_geometry_cache_data_opts*)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public nuint SampleGeometryCacheReal(double time, float* data, nuint num_data, ufbx_geometry_cache_data_opts* opts)
|
public nuint SampleGeometryCacheReal(double time, ReadOnlySpan<float> data, ufbx_geometry_cache_data_opts* opts)
|
||||||
{
|
{
|
||||||
return Api.ufbx_sample_geometry_cache_real(
|
fixed (float* pdata = data)
|
||||||
(ufbx_cache_channel*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
time,
|
return Api.ufbx_sample_geometry_cache_real(
|
||||||
data,
|
(ufbx_cache_channel*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
num_data,
|
time,
|
||||||
opts);
|
(float*)pdata,
|
||||||
|
(nuint)data.Length,
|
||||||
|
opts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// From: <see cref="Api.ufbx_sample_geometry_cache_vec3(ufbx_cache_channel*, double, Misaki.HighPerformance.Mathematics.float3*, nuint, ufbx_geometry_cache_data_opts*)" />
|
/// From: <see cref="Api.ufbx_sample_geometry_cache_vec3(ufbx_cache_channel*, double, Misaki.HighPerformance.Mathematics.float3*, nuint, ufbx_geometry_cache_data_opts*)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public nuint SampleGeometryCacheVec3(double time, Misaki.HighPerformance.Mathematics.float3* data, nuint num_data, ufbx_geometry_cache_data_opts* opts)
|
public nuint SampleGeometryCacheVec3(double time, ReadOnlySpan<Misaki.HighPerformance.Mathematics.float3> data, ufbx_geometry_cache_data_opts* opts)
|
||||||
{
|
{
|
||||||
return Api.ufbx_sample_geometry_cache_vec3(
|
fixed (Misaki.HighPerformance.Mathematics.float3* pdata = data)
|
||||||
(ufbx_cache_channel*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
time,
|
return Api.ufbx_sample_geometry_cache_vec3(
|
||||||
data,
|
(ufbx_cache_channel*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
num_data,
|
time,
|
||||||
opts);
|
(Misaki.HighPerformance.Mathematics.float3*)pdata,
|
||||||
|
(nuint)data.Length,
|
||||||
|
opts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,25 +10,31 @@ public unsafe partial struct ufbx_cache_frame
|
|||||||
/// From: <see cref="Api.ufbx_read_geometry_cache_real(ufbx_cache_frame*, float*, nuint, ufbx_geometry_cache_data_opts*)" />
|
/// From: <see cref="Api.ufbx_read_geometry_cache_real(ufbx_cache_frame*, float*, nuint, ufbx_geometry_cache_data_opts*)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public nuint ReadGeometryCacheReal(float* data, nuint num_data, ufbx_geometry_cache_data_opts* opts)
|
public nuint ReadGeometryCacheReal(ReadOnlySpan<float> data, ufbx_geometry_cache_data_opts* opts)
|
||||||
{
|
{
|
||||||
return Api.ufbx_read_geometry_cache_real(
|
fixed (float* pdata = data)
|
||||||
(ufbx_cache_frame*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
data,
|
return Api.ufbx_read_geometry_cache_real(
|
||||||
num_data,
|
(ufbx_cache_frame*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
opts);
|
(float*)pdata,
|
||||||
|
(nuint)data.Length,
|
||||||
|
opts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// From: <see cref="Api.ufbx_read_geometry_cache_vec3(ufbx_cache_frame*, Misaki.HighPerformance.Mathematics.float3*, nuint, ufbx_geometry_cache_data_opts*)" />
|
/// From: <see cref="Api.ufbx_read_geometry_cache_vec3(ufbx_cache_frame*, Misaki.HighPerformance.Mathematics.float3*, nuint, ufbx_geometry_cache_data_opts*)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public nuint ReadGeometryCacheVec3(Misaki.HighPerformance.Mathematics.float3* data, nuint num_data, ufbx_geometry_cache_data_opts* opts)
|
public nuint ReadGeometryCacheVec3(ReadOnlySpan<Misaki.HighPerformance.Mathematics.float3> data, ufbx_geometry_cache_data_opts* opts)
|
||||||
{
|
{
|
||||||
return Api.ufbx_read_geometry_cache_vec3(
|
fixed (Misaki.HighPerformance.Mathematics.float3* pdata = data)
|
||||||
(ufbx_cache_frame*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
data,
|
return Api.ufbx_read_geometry_cache_vec3(
|
||||||
num_data,
|
(ufbx_cache_frame*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
opts);
|
(Misaki.HighPerformance.Mathematics.float3*)pdata,
|
||||||
|
(nuint)data.Length,
|
||||||
|
opts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,42 +21,57 @@ public unsafe partial struct ufbx_mesh : System.IDisposable
|
|||||||
/// From: <see cref="Api.ufbx_compute_topology(ufbx_mesh*, ufbx_topo_edge*, nuint)" />
|
/// From: <see cref="Api.ufbx_compute_topology(ufbx_mesh*, ufbx_topo_edge*, nuint)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public void ComputeTopology(ufbx_topo_edge* topo, nuint num_topo)
|
public void ComputeTopology(ReadOnlySpan<ufbx_topo_edge> topo)
|
||||||
{
|
{
|
||||||
Api.ufbx_compute_topology(
|
fixed (ufbx_topo_edge* ptopo = topo)
|
||||||
(ufbx_mesh*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
topo,
|
Api.ufbx_compute_topology(
|
||||||
num_topo);
|
(ufbx_mesh*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
|
(ufbx_topo_edge*)ptopo,
|
||||||
|
(nuint)topo.Length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// From: <see cref="Api.ufbx_generate_normal_mapping(ufbx_mesh*, ufbx_topo_edge*, nuint, uint*, nuint, bool)" />
|
/// From: <see cref="Api.ufbx_generate_normal_mapping(ufbx_mesh*, ufbx_topo_edge*, nuint, uint*, nuint, bool)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public nuint GenerateNormalMapping(ufbx_topo_edge* topo, nuint num_topo, uint* normal_indices, nuint num_normal_indices, bool assume_smooth)
|
public nuint GenerateNormalMapping(ReadOnlySpan<ufbx_topo_edge> topo, ReadOnlySpan<uint> normal_indices, bool assume_smooth)
|
||||||
{
|
{
|
||||||
return Api.ufbx_generate_normal_mapping(
|
fixed (ufbx_topo_edge* ptopo = topo)
|
||||||
(ufbx_mesh*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
topo,
|
fixed (uint* pnormal_indices = normal_indices)
|
||||||
num_topo,
|
{
|
||||||
normal_indices,
|
return Api.ufbx_generate_normal_mapping(
|
||||||
num_normal_indices,
|
(ufbx_mesh*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
assume_smooth);
|
(ufbx_topo_edge*)ptopo,
|
||||||
|
(nuint)topo.Length,
|
||||||
|
(uint*)pnormal_indices,
|
||||||
|
(nuint)normal_indices.Length,
|
||||||
|
assume_smooth);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// From: <see cref="Api.ufbx_compute_normals(ufbx_mesh*, ufbx_vertex_vec3*, uint*, nuint, Misaki.HighPerformance.Mathematics.float3*, nuint)" />
|
/// From: <see cref="Api.ufbx_compute_normals(ufbx_mesh*, ufbx_vertex_vec3*, uint*, nuint, Misaki.HighPerformance.Mathematics.float3*, nuint)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public void ComputeNormals(ufbx_vertex_vec3* positions, uint* normal_indices, nuint num_normal_indices, Misaki.HighPerformance.Mathematics.float3* normals, nuint num_normals)
|
public void ComputeNormals(ufbx_vertex_vec3* positions, ReadOnlySpan<uint> normal_indices, ReadOnlySpan<Misaki.HighPerformance.Mathematics.float3> normals)
|
||||||
{
|
{
|
||||||
Api.ufbx_compute_normals(
|
fixed (uint* pnormal_indices = normal_indices)
|
||||||
(ufbx_mesh*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
positions,
|
fixed (Misaki.HighPerformance.Mathematics.float3* pnormals = normals)
|
||||||
normal_indices,
|
{
|
||||||
num_normal_indices,
|
Api.ufbx_compute_normals(
|
||||||
normals,
|
(ufbx_mesh*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
num_normals);
|
positions,
|
||||||
|
(uint*)pnormal_indices,
|
||||||
|
(nuint)normal_indices.Length,
|
||||||
|
(Misaki.HighPerformance.Mathematics.float3*)pnormals,
|
||||||
|
(nuint)normals.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -10,14 +10,20 @@ public unsafe partial struct ufbx_nurbs_basis
|
|||||||
/// From: <see cref="Api.ufbx_evaluate_nurbs_basis(ufbx_nurbs_basis*, float, float*, nuint, float*, nuint)" />
|
/// From: <see cref="Api.ufbx_evaluate_nurbs_basis(ufbx_nurbs_basis*, float, float*, nuint, float*, nuint)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public nuint Evaluate(float u, float* weights, nuint num_weights, float* derivatives, nuint num_derivatives)
|
public nuint Evaluate(float u, ReadOnlySpan<float> weights, ReadOnlySpan<float> derivatives)
|
||||||
{
|
{
|
||||||
return Api.ufbx_evaluate_nurbs_basis(
|
fixed (float* pweights = weights)
|
||||||
(ufbx_nurbs_basis*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
u,
|
fixed (float* pderivatives = derivatives)
|
||||||
weights,
|
{
|
||||||
num_weights,
|
return Api.ufbx_evaluate_nurbs_basis(
|
||||||
derivatives,
|
(ufbx_nurbs_basis*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
num_derivatives);
|
u,
|
||||||
|
(float*)pweights,
|
||||||
|
(nuint)weights.Length,
|
||||||
|
(float*)pderivatives,
|
||||||
|
(nuint)derivatives.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,53 +23,65 @@ public unsafe partial struct ufbx_panic
|
|||||||
/// From: <see cref="Api.ufbx_catch_triangulate_face(ufbx_panic*, uint*, nuint, ufbx_mesh*, ufbx_face)" />
|
/// From: <see cref="Api.ufbx_catch_triangulate_face(ufbx_panic*, uint*, nuint, ufbx_mesh*, ufbx_face)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public uint CatchTriangulateFace(uint* indices, nuint num_indices, ufbx_mesh* mesh, ufbx_face face)
|
public uint CatchTriangulateFace(ReadOnlySpan<uint> indices, ufbx_mesh* mesh, ufbx_face face)
|
||||||
{
|
{
|
||||||
return Api.ufbx_catch_triangulate_face(
|
fixed (uint* pindices = indices)
|
||||||
(ufbx_panic*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
indices,
|
return Api.ufbx_catch_triangulate_face(
|
||||||
num_indices,
|
(ufbx_panic*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
mesh,
|
(uint*)pindices,
|
||||||
face);
|
(nuint)indices.Length,
|
||||||
|
mesh,
|
||||||
|
face);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// From: <see cref="Api.ufbx_catch_compute_topology(ufbx_panic*, ufbx_mesh*, ufbx_topo_edge*, nuint)" />
|
/// From: <see cref="Api.ufbx_catch_compute_topology(ufbx_panic*, ufbx_mesh*, ufbx_topo_edge*, nuint)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public void CatchComputeTopology(ufbx_mesh* mesh, ufbx_topo_edge* topo, nuint num_topo)
|
public void CatchComputeTopology(ufbx_mesh* mesh, ReadOnlySpan<ufbx_topo_edge> topo)
|
||||||
{
|
{
|
||||||
Api.ufbx_catch_compute_topology(
|
fixed (ufbx_topo_edge* ptopo = topo)
|
||||||
(ufbx_panic*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
mesh,
|
Api.ufbx_catch_compute_topology(
|
||||||
topo,
|
(ufbx_panic*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
num_topo);
|
mesh,
|
||||||
|
(ufbx_topo_edge*)ptopo,
|
||||||
|
(nuint)topo.Length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// From: <see cref="Api.ufbx_catch_topo_next_vertex_edge(ufbx_panic*, ufbx_topo_edge*, nuint, uint)" />
|
/// From: <see cref="Api.ufbx_catch_topo_next_vertex_edge(ufbx_panic*, ufbx_topo_edge*, nuint, uint)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public uint CatchTopoNextVertexEdge(ufbx_topo_edge* topo, nuint num_topo, uint index)
|
public uint CatchTopoNextVertexEdge(ReadOnlySpan<ufbx_topo_edge> topo, uint index)
|
||||||
{
|
{
|
||||||
return Api.ufbx_catch_topo_next_vertex_edge(
|
fixed (ufbx_topo_edge* ptopo = topo)
|
||||||
(ufbx_panic*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
topo,
|
return Api.ufbx_catch_topo_next_vertex_edge(
|
||||||
num_topo,
|
(ufbx_panic*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
index);
|
(ufbx_topo_edge*)ptopo,
|
||||||
|
(nuint)topo.Length,
|
||||||
|
index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// From: <see cref="Api.ufbx_catch_topo_prev_vertex_edge(ufbx_panic*, ufbx_topo_edge*, nuint, uint)" />
|
/// From: <see cref="Api.ufbx_catch_topo_prev_vertex_edge(ufbx_panic*, ufbx_topo_edge*, nuint, uint)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public uint CatchTopoPrevVertexEdge(ufbx_topo_edge* topo, nuint num_topo, uint index)
|
public uint CatchTopoPrevVertexEdge(ReadOnlySpan<ufbx_topo_edge> topo, uint index)
|
||||||
{
|
{
|
||||||
return Api.ufbx_catch_topo_prev_vertex_edge(
|
fixed (ufbx_topo_edge* ptopo = topo)
|
||||||
(ufbx_panic*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
topo,
|
return Api.ufbx_catch_topo_prev_vertex_edge(
|
||||||
num_topo,
|
(ufbx_panic*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
index);
|
(ufbx_topo_edge*)ptopo,
|
||||||
|
(nuint)topo.Length,
|
||||||
|
index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -88,32 +100,44 @@ public unsafe partial struct ufbx_panic
|
|||||||
/// From: <see cref="Api.ufbx_catch_generate_normal_mapping(ufbx_panic*, ufbx_mesh*, ufbx_topo_edge*, nuint, uint*, nuint, bool)" />
|
/// From: <see cref="Api.ufbx_catch_generate_normal_mapping(ufbx_panic*, ufbx_mesh*, ufbx_topo_edge*, nuint, uint*, nuint, bool)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public nuint CatchGenerateNormalMapping(ufbx_mesh* mesh, ufbx_topo_edge* topo, nuint num_topo, uint* normal_indices, nuint num_normal_indices, bool assume_smooth)
|
public nuint CatchGenerateNormalMapping(ufbx_mesh* mesh, ReadOnlySpan<ufbx_topo_edge> topo, ReadOnlySpan<uint> normal_indices, bool assume_smooth)
|
||||||
{
|
{
|
||||||
return Api.ufbx_catch_generate_normal_mapping(
|
fixed (ufbx_topo_edge* ptopo = topo)
|
||||||
(ufbx_panic*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
mesh,
|
fixed (uint* pnormal_indices = normal_indices)
|
||||||
topo,
|
{
|
||||||
num_topo,
|
return Api.ufbx_catch_generate_normal_mapping(
|
||||||
normal_indices,
|
(ufbx_panic*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
num_normal_indices,
|
mesh,
|
||||||
assume_smooth);
|
(ufbx_topo_edge*)ptopo,
|
||||||
|
(nuint)topo.Length,
|
||||||
|
(uint*)pnormal_indices,
|
||||||
|
(nuint)normal_indices.Length,
|
||||||
|
assume_smooth);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// From: <see cref="Api.ufbx_catch_compute_normals(ufbx_panic*, ufbx_mesh*, ufbx_vertex_vec3*, uint*, nuint, Misaki.HighPerformance.Mathematics.float3*, nuint)" />
|
/// From: <see cref="Api.ufbx_catch_compute_normals(ufbx_panic*, ufbx_mesh*, ufbx_vertex_vec3*, uint*, nuint, Misaki.HighPerformance.Mathematics.float3*, nuint)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public void CatchComputeNormals(ufbx_mesh* mesh, ufbx_vertex_vec3* positions, uint* normal_indices, nuint num_normal_indices, Misaki.HighPerformance.Mathematics.float3* normals, nuint num_normals)
|
public void CatchComputeNormals(ufbx_mesh* mesh, ufbx_vertex_vec3* positions, ReadOnlySpan<uint> normal_indices, ReadOnlySpan<Misaki.HighPerformance.Mathematics.float3> normals)
|
||||||
{
|
{
|
||||||
Api.ufbx_catch_compute_normals(
|
fixed (uint* pnormal_indices = normal_indices)
|
||||||
(ufbx_panic*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
mesh,
|
fixed (Misaki.HighPerformance.Mathematics.float3* pnormals = normals)
|
||||||
positions,
|
{
|
||||||
normal_indices,
|
Api.ufbx_catch_compute_normals(
|
||||||
num_normal_indices,
|
(ufbx_panic*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
normals,
|
mesh,
|
||||||
num_normals);
|
positions,
|
||||||
|
(uint*)pnormal_indices,
|
||||||
|
(nuint)normal_indices.Length,
|
||||||
|
(Misaki.HighPerformance.Mathematics.float3*)pnormals,
|
||||||
|
(nuint)normals.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -204,11 +204,14 @@ public unsafe partial struct ufbx_props
|
|||||||
/// From: <see cref="Api.ufbx_find_prop_concat(ufbx_props*, ufbx_string*, nuint)" />
|
/// From: <see cref="Api.ufbx_find_prop_concat(ufbx_props*, ufbx_string*, nuint)" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
public ufbx_prop* FindPropConcat(ufbx_string* parts, nuint num_parts)
|
public ufbx_prop* FindPropConcat(ReadOnlySpan<ufbx_string> parts)
|
||||||
{
|
{
|
||||||
return Api.ufbx_find_prop_concat(
|
fixed (ufbx_string* pparts = parts)
|
||||||
(ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
{
|
||||||
parts,
|
return Api.ufbx_find_prop_concat(
|
||||||
num_parts);
|
(ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
||||||
|
(ufbx_string*)pparts,
|
||||||
|
(nuint)parts.Length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
// <auto-generated>
|
|
||||||
// This file is generated by Ghost.NativeWrapperGen. Do not edit manually.
|
|
||||||
// </auto-generated>
|
|
||||||
|
|
||||||
namespace Ghost.Ufbx;
|
|
||||||
|
|
||||||
public unsafe partial struct ufbx_topo_edge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// From: <see cref="Api.ufbx_topo_next_vertex_edge(ufbx_topo_edge*, nuint, uint)" />
|
|
||||||
/// </summary>
|
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
|
||||||
public uint TopoNextVertexEdge(nuint num_topo, uint index)
|
|
||||||
{
|
|
||||||
return Api.ufbx_topo_next_vertex_edge(
|
|
||||||
(ufbx_topo_edge*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
|
||||||
num_topo,
|
|
||||||
index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// From: <see cref="Api.ufbx_topo_prev_vertex_edge(ufbx_topo_edge*, nuint, uint)" />
|
|
||||||
/// </summary>
|
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
|
||||||
public uint TopoPrevVertexEdge(nuint num_topo, uint index)
|
|
||||||
{
|
|
||||||
return Api.ufbx_topo_prev_vertex_edge(
|
|
||||||
(ufbx_topo_edge*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
|
||||||
num_topo,
|
|
||||||
index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
// <auto-generated>
|
|
||||||
// This file is generated by Ghost.NativeWrapperGen. Do not edit manually.
|
|
||||||
// </auto-generated>
|
|
||||||
|
|
||||||
namespace Ghost.Ufbx;
|
|
||||||
|
|
||||||
public unsafe partial struct ufbx_vertex_stream
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// From: <see cref="Api.ufbx_generate_indices(ufbx_vertex_stream*, nuint, uint*, nuint, ufbx_allocator_opts*, ufbx_error*)" />
|
|
||||||
/// </summary>
|
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
|
||||||
public nuint GenerateIndices(nuint num_streams, uint* indices, nuint num_indices, ufbx_allocator_opts* allocator, ufbx_error* error)
|
|
||||||
{
|
|
||||||
return Api.ufbx_generate_indices(
|
|
||||||
(ufbx_vertex_stream*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this),
|
|
||||||
num_streams,
|
|
||||||
indices,
|
|
||||||
num_indices,
|
|
||||||
allocator,
|
|
||||||
error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -40,8 +40,10 @@ public sealed class RemapConfig
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class DerivesFromConfig
|
public sealed class DerivesFromConfig
|
||||||
{
|
{
|
||||||
|
/// <summary>The prefix of the sibling parameter name to consume (e.g. "name_").</summary>
|
||||||
|
public string ParamPrefix { get; init; } = string.Empty;
|
||||||
/// <summary>The suffix of the sibling parameter name to consume (e.g. "_len").</summary>
|
/// <summary>The suffix of the sibling parameter name to consume (e.g. "_len").</summary>
|
||||||
public required string ParamSuffix { get; init; }
|
public string ParamSuffix { get; init; } = string.Empty;
|
||||||
/// <summary>Expression to pass in place of the consumed parameter. $arg is replaced with the source param name.</summary>
|
/// <summary>Expression to pass in place of the consumed parameter. $arg is replaced with the source param name.</summary>
|
||||||
public required string Expr { get; init; }
|
public required string Expr { get; init; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,18 +140,36 @@ public sealed class WrapperGeneratorEmitter
|
|||||||
{
|
{
|
||||||
foreach (var condition in conditions)
|
foreach (var condition in conditions)
|
||||||
{
|
{
|
||||||
// Handle parameterised conditions before the switch.
|
var inverseCondition = false;
|
||||||
if (condition.StartsWith("NAME_CONDITION(", StringComparison.Ordinal) &&
|
|
||||||
condition.EndsWith(')'))
|
var conditionSpan = condition.AsSpan();
|
||||||
|
if (conditionSpan[0] == '!')
|
||||||
{
|
{
|
||||||
var pattern = condition["NAME_CONDITION(".Length..^1];
|
inverseCondition = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var remainingCondition = conditionSpan[(inverseCondition ? 1 : 0)..].Trim();
|
||||||
|
|
||||||
|
// Handle parameterised conditions before the switch.
|
||||||
|
if (remainingCondition.StartsWith("NAME_CONDITION(", StringComparison.Ordinal) &&
|
||||||
|
remainingCondition.EndsWith(')'))
|
||||||
|
{
|
||||||
|
var pattern = remainingCondition["NAME_CONDITION(".Length..^1];
|
||||||
|
|
||||||
// $TSelf → full struct name (e.g. "NvttSurface")
|
// $TSelf → full struct name (e.g. "NvttSurface")
|
||||||
// $TBare → struct name with the library prefix stripped (e.g. "Surface")
|
// $TBare → struct name with the library prefix stripped (e.g. "Surface")
|
||||||
var bareName = StripPrefix(targetStructName, config.NativeTypePrefix);
|
var bareName = StripPrefix(targetStructName, config.NativeTypePrefix);
|
||||||
var resolvedPattern = pattern
|
var resolvedPattern = pattern.ToString()
|
||||||
.Replace("$TBare", bareName, StringComparison.Ordinal)
|
.Replace("$TBare", bareName, StringComparison.Ordinal)
|
||||||
.Replace("$TSelf", targetStructName, StringComparison.Ordinal);
|
.Replace("$TSelf", targetStructName, StringComparison.Ordinal);
|
||||||
if (!Regex.IsMatch(func.Name, resolvedPattern, RegexOptions.IgnoreCase))
|
|
||||||
|
var match = Regex.IsMatch(func.Name, resolvedPattern, RegexOptions.IgnoreCase);
|
||||||
|
if (inverseCondition)
|
||||||
|
{
|
||||||
|
match = !match;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -159,13 +177,13 @@ public sealed class WrapperGeneratorEmitter
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (condition)
|
switch (remainingCondition)
|
||||||
{
|
{
|
||||||
case "SELF_PTR":
|
case "SELF_PTR":
|
||||||
if (func.Parameters.Count == 0 ||
|
if (func.Parameters.Count == 0 ||
|
||||||
resolver.TryGetBindingStructName(func.Parameters[0].TypeName) is null)
|
resolver.TryGetBindingStructName(func.Parameters[0].TypeName) is null)
|
||||||
{
|
{
|
||||||
return false;
|
return inverseCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -174,7 +192,7 @@ public sealed class WrapperGeneratorEmitter
|
|||||||
if (func.Parameters.Count > 0 &&
|
if (func.Parameters.Count > 0 &&
|
||||||
resolver.TryGetBindingStructName(func.Parameters[0].TypeName) is not null)
|
resolver.TryGetBindingStructName(func.Parameters[0].TypeName) is not null)
|
||||||
{
|
{
|
||||||
return false;
|
return inverseCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -182,7 +200,7 @@ public sealed class WrapperGeneratorEmitter
|
|||||||
case "RETURN_BINDING_TYPE":
|
case "RETURN_BINDING_TYPE":
|
||||||
if (resolver.TryGetBindingStructName(func.ReturnType) is null)
|
if (resolver.TryGetBindingStructName(func.ReturnType) is null)
|
||||||
{
|
{
|
||||||
return false;
|
return inverseCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -190,7 +208,7 @@ public sealed class WrapperGeneratorEmitter
|
|||||||
case "VOID_RETURN":
|
case "VOID_RETURN":
|
||||||
if (!string.Equals(func.ReturnType, "void", StringComparison.Ordinal))
|
if (!string.Equals(func.ReturnType, "void", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
return false;
|
return inverseCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -466,7 +484,7 @@ public sealed class WrapperGeneratorEmitter
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var expectedSiblingName = param.Name + remap.DerivesFrom.ParamSuffix;
|
var expectedSiblingName = remap.DerivesFrom.ParamPrefix + param.Name + remap.DerivesFrom.ParamSuffix;
|
||||||
for (var j = i + 1; j < func.Parameters.Count; j++)
|
for (var j = i + 1; j < func.Parameters.Count; j++)
|
||||||
{
|
{
|
||||||
if (string.Equals(func.Parameters[j].Name, expectedSiblingName, StringComparison.Ordinal))
|
if (string.Equals(func.Parameters[j].Name, expectedSiblingName, StringComparison.Ordinal))
|
||||||
@@ -522,17 +540,17 @@ public sealed class WrapperGeneratorEmitter
|
|||||||
var convertBack = matchedRemap.Adapter.ConvertBack;
|
var convertBack = matchedRemap.Adapter.ConvertBack;
|
||||||
var publicParam = new PublicParam
|
var publicParam = new PublicParam
|
||||||
{
|
{
|
||||||
PublicType = matchedRemap.Dst,
|
PublicType = matchedRemap.Dst.Replace("$TYPE", param.RawTypeName),
|
||||||
PublicName = param.Name,
|
PublicName = param.Name,
|
||||||
WrapCall = convertBack.WrapCall,
|
WrapCall = convertBack.WrapCall.Replace("$TYPE", param.RawTypeName),
|
||||||
PassAs = convertBack.PassAs,
|
PassAs = convertBack.PassAs.Replace("$TYPE", param.RawTypeName),
|
||||||
};
|
};
|
||||||
publicParams.Add(publicParam);
|
publicParams.Add(publicParam);
|
||||||
allNativeParams.Add(new NativeParamInfo
|
allNativeParams.Add(new NativeParamInfo
|
||||||
{
|
{
|
||||||
NativeName = param.Name,
|
NativeName = param.Name,
|
||||||
PublicName = param.Name,
|
PublicName = param.Name,
|
||||||
PassAs = convertBack.PassAs,
|
PassAs = convertBack.PassAs.Replace("$TYPE", param.RawTypeName),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -581,7 +599,8 @@ public sealed class WrapperGeneratorEmitter
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.Equals(remap.Src, param.TypeName, StringComparison.Ordinal))
|
var src = remap.Src.Replace("$TYPE", param.RawTypeName);
|
||||||
|
if (!string.Equals(src, param.TypeName, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ public sealed class NativeParameter
|
|||||||
{
|
{
|
||||||
public required string Name { get; init; }
|
public required string Name { get; init; }
|
||||||
public required string TypeName { get; init; }
|
public required string TypeName { get; init; }
|
||||||
|
|
||||||
|
private string? _rawTypeName;
|
||||||
|
public string RawTypeName => _rawTypeName ??= TypeName.TrimEnd('*', '&');
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class NativeMember
|
public sealed class NativeMember
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"Ghost.NativeWrapperGen": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"commandLineArgs": "--config \"F:/csharp/GhostEngine/src/Tools/Ghost.NativeWrapperGen/configs/ufbx.json\" --input \"F:/csharp/GhostEngine/src/ThridParty/Ghost.Ufbx/Generated\" --output \"F:/csharp/GhostEngine/src/ThridParty/Ghost.Ufbx/Wrapper\""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,13 +17,31 @@
|
|||||||
"dst": "ReadOnlySpan<byte>",
|
"dst": "ReadOnlySpan<byte>",
|
||||||
"scope": [ "parameter" ],
|
"scope": [ "parameter" ],
|
||||||
"filter": [ ".*name", ".*filename", ".*path", ".*prop$" ],
|
"filter": [ ".*name", ".*filename", ".*path", ".*prop$" ],
|
||||||
"derivesFrom": { "paramSuffix": "_len", "expr": "(nuint)$arg.Length" },
|
"derivesFrom": {
|
||||||
|
"paramSuffix": "_len",
|
||||||
|
"expr": "(nuint)$arg.Length"
|
||||||
|
},
|
||||||
"adapter": {
|
"adapter": {
|
||||||
"convertBack": {
|
"convertBack": {
|
||||||
"wrapCall": "fixed (byte* p$arg = $arg) { $CALL }",
|
"wrapCall": "fixed (byte* p$arg = $arg) { $CALL }",
|
||||||
"passAs": "(sbyte*)p$arg"
|
"passAs": "(sbyte*)p$arg"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "$TYPE*",
|
||||||
|
"dst": "ReadOnlySpan<$TYPE>",
|
||||||
|
"scope": [ "parameter" ],
|
||||||
|
"derivesFrom": {
|
||||||
|
"paramPrefix": "num_",
|
||||||
|
"expr": "(nuint)$arg.Length"
|
||||||
|
},
|
||||||
|
"adapter": {
|
||||||
|
"convertBack": {
|
||||||
|
"wrapCall": "fixed ($TYPE* p$arg = $arg) { $CALL }",
|
||||||
|
"passAs": "($TYPE*)p$arg"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -57,14 +75,13 @@
|
|||||||
// Instance method: first param is T* of a known binding struct → method on T
|
// Instance method: first param is T* of a known binding struct → method on T
|
||||||
"comment": "First param is T* of a known binding struct → instance method on T",
|
"comment": "First param is T* of a known binding struct → instance method on T",
|
||||||
"filter": "EXTERN_API",
|
"filter": "EXTERN_API",
|
||||||
"conditions": [ "SELF_PTR" ],
|
"conditions": [ "SELF_PTR", "!NAME_CONDITION(ufbx_generate_indices)", "!NAME_CONDITION(ufbx_topo_next_vertex_edge)", "!NAME_CONDITION(ufbx_topo_prev_vertex_edge)" ],
|
||||||
"targetType": "FIRST_PARAM_TYPE",
|
"targetType": "FIRST_PARAM_TYPE",
|
||||||
"apply": {
|
"apply": {
|
||||||
"type": "INSTANCE_METHOD",
|
"type": "INSTANCE_METHOD",
|
||||||
"opts": {
|
"opts": {
|
||||||
"removeFirstParam": true,
|
"removeFirstParam": true,
|
||||||
"passAs": "($TSelf*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this)",
|
"passAs": "($TSelf*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref this)",
|
||||||
// Change "ufbx_free_scene" to "free"
|
|
||||||
"name": {
|
"name": {
|
||||||
"remove": [
|
"remove": [
|
||||||
"PREFIX",
|
"PREFIX",
|
||||||
|
|||||||
Reference in New Issue
Block a user