Added ufbx warper

This commit is contained in:
2026-03-15 02:19:40 +09:00
parent cce1cf7256
commit 3e4084c42a
232 changed files with 10989 additions and 55 deletions

View File

@@ -1,5 +1,5 @@
using Ghost.Nvtt;
using Ghost.Nvtt.Warper;
using Ghost.Nvtt.Wrapper;
using Misaki.HighPerformance.Image;
using System.IO.Hashing;
using System.Runtime.CompilerServices;

View File

@@ -47,4 +47,7 @@
<Deploy />
</Project>
</Folder>
<Folder Name="/Tools/">
<Project Path="Tools/Ghost.NativeWrapperGen/Ghost.NativeWrapperGen.csproj" />
</Folder>
</Solution>

View File

@@ -1,5 +1,5 @@
using Ghost.Nvtt;
using Ghost.Nvtt.Warper;
using Ghost.Nvtt.Wrapper;
using Ghost.Test.Core;
namespace Ghost.MicroTest;

View File

@@ -1,12 +1,9 @@
using Ghost.Test.Core;
using Ghost.Ufbx;
using System.Diagnostics;
using System.Text;
using static Ghost.Ufbx.Api;
namespace Ghost.MicroTest;
internal unsafe class UfbxBindingTest : ITest
internal class UfbxBindingTest : ITest
{
private static ReadOnlySpan<byte> TestFilePath => "F:/c/Third Parties/ufbx/data/blender_340_z_up_7400_binary.fbx"u8;
@@ -16,37 +13,60 @@ internal unsafe class UfbxBindingTest : ITest
public void Run()
{
ufbx_load_opts opts = default;
ufbx_error error;
ufbx_scene* pScene;
// Smoke-test LoadOpts heap-pointer shape (construct, set, read back, dispose)
using var opts = new LoadOpts();
opts.IgnoreAnimation = true;
opts.IgnoreEmbedded = true;
var path = TestFilePath;
fixed (byte* p = path)
{
pScene = ufbx_load_file((sbyte*)p, &opts, &error);
}
// Load scene using the safe high-level wrapper (no unsafe, no fixed blocks)
using var scene = Scene.LoadFile(TestFilePath, opts);
if (pScene == null)
// Enumerate nodes using the wrapper's NodeList (ref struct, no allocation)
for (var i = 0; i < scene.Nodes.Count; i++)
{
Debug.Fail($"Failed to load scene: {Encoding.UTF8.GetString((byte*)error.description.data, (int)error.description.length)}");
}
for (nuint i = 0; i < pScene->nodes.count; i++)
{
var node = pScene->nodes.data[i];
if (node->is_root)
var node = scene.Nodes[i];
if (node.IsRoot)
{
continue;
}
Console.WriteLine($"Object: {Encoding.UTF8.GetString((byte*)node->name.data, (int)node->name.length)}");
if (node->mesh != null)
// node.Name is a string property — no manual ToString() needed
Console.WriteLine($"Object: {node.Name}");
if (node.HasMesh)
{
Console.WriteLine($"-> mesh with {node->mesh->faces.count} faces");
Console.WriteLine($"-> mesh with {node.Mesh.NumFaces} faces");
}
}
ufbx_free_scene(pScene);
// Find a node by name using the new instance method (no unsafe, no fixed)
var rootNode = scene.FindNode("RootNode"u8);
if (!rootNode.IsNull)
{
Console.WriteLine($"Found root node: {rootNode.Name}");
}
// Find a material by name
var material = scene.FindMaterial("Material"u8);
if (!material.IsNull)
{
Console.WriteLine($"Found material: {material.Name}");
// Find a prop on the material's props using the instance method
var prop = material.Props.FindProp("DiffuseColor"u8);
if (!prop.IsNull)
{
Console.WriteLine($" DiffuseColor prop type: {prop.Type}");
}
}
// Find an anim stack
var animStack = scene.FindAnimStack("Take 001"u8);
if (!animStack.IsNull)
{
Console.WriteLine($"Found anim stack: {animStack.Name}");
}
Console.WriteLine("Done.");
}
public void Cleanup()

View File

@@ -1,4 +1,4 @@
namespace Ghost.Nvtt.Warper;
namespace Ghost.Nvtt.Wrapper;
/// <summary>
/// Wrapper around an nvtt batch list — a list of (surface, face, mipmap,

View File

@@ -1,4 +1,4 @@
namespace Ghost.Nvtt.Warper;
namespace Ghost.Nvtt.Wrapper;
/// <summary>
/// Controls how a surface is compressed - format, quality, pixel layout and

View File

@@ -1,4 +1,4 @@
namespace Ghost.Nvtt.Warper;
namespace Ghost.Nvtt.Wrapper;
/// <summary>
/// Wrapper around the nvtt compression context — the central object that drives

View File

@@ -1,4 +1,4 @@
namespace Ghost.Nvtt.Warper;
namespace Ghost.Nvtt.Wrapper;
/// <summary>
/// Wrapper around an nvtt cube-map surface (six faces, optional mip chain).

View File

@@ -1,6 +1,6 @@
using System.Runtime.InteropServices;
namespace Ghost.Nvtt.Warper;
namespace Ghost.Nvtt.Wrapper;
/// <summary>
/// Static helpers wrapping global nvtt functions (version, CUDA detection,

View File

@@ -1,7 +1,7 @@
using System.Runtime.CompilerServices;
using System.Text;
namespace Ghost.Nvtt.Warper;
namespace Ghost.Nvtt.Wrapper;
/// <summary>
/// Internal helpers for converting between managed and unmanaged types.

View File

@@ -1,6 +1,6 @@
using System.Runtime.InteropServices;
namespace Ghost.Nvtt.Warper;
namespace Ghost.Nvtt.Wrapper;
/// <summary>
/// Configures where compressed data is written and how it is formatted.

View File

@@ -1,4 +1,4 @@
namespace Ghost.Nvtt.Warper;
namespace Ghost.Nvtt.Wrapper;
/// <summary>
/// Wrapper around a single 2-D / 3-D / cube-face image surface used as input

View File

@@ -1,4 +1,4 @@
namespace Ghost.Nvtt.Warper;
namespace Ghost.Nvtt.Wrapper;
/// <summary>
/// Wrapper around an nvtt surface set — a collection of faces and mip levels

View File

@@ -1,4 +1,4 @@
namespace Ghost.Nvtt.Warper;
namespace Ghost.Nvtt.Wrapper;
/// <summary>
/// Wraps an nvtt timing context that records per-operation wall-clock times.

View File

@@ -1,3 +1,4 @@
using System;
using System.Runtime.InteropServices;
using static Ghost.Ufbx.ufbx_aperture_format;
using static Ghost.Ufbx.ufbx_aperture_mode;
@@ -418,7 +419,8 @@ namespace Ghost.Ufbx
public static extern Misaki.HighPerformance.Mathematics.float3 ufbx_evaluate_baked_vec3(ufbx_baked_vec3_list keyframes, double time);
[DllImport("ufbx", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ufbx_quat ufbx_evaluate_baked_quat(ufbx_baked_quat_list keyframes, double time);
[return: NativeTypeName("ufbx_quat")]
public static extern Misaki.HighPerformance.Mathematics.quaternion ufbx_evaluate_baked_quat(ufbx_baked_quat_list keyframes, double time);
[DllImport("ufbx", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ufbx_bone_pose* ufbx_get_bone_pose([NativeTypeName("const ufbx_pose *")] ufbx_pose* pose, [NativeTypeName("const ufbx_node *")] ufbx_node* node);
@@ -457,30 +459,35 @@ namespace Ghost.Ufbx
[DllImport("ufbx", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("ufbx_real")]
public static extern float ufbx_quat_dot(ufbx_quat a, ufbx_quat b);
public static extern float ufbx_quat_dot([NativeTypeName("ufbx_quat")] Misaki.HighPerformance.Mathematics.quaternion a, [NativeTypeName("ufbx_quat")] Misaki.HighPerformance.Mathematics.quaternion b);
[DllImport("ufbx", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ufbx_quat ufbx_quat_mul(ufbx_quat a, ufbx_quat b);
[return: NativeTypeName("ufbx_quat")]
public static extern Misaki.HighPerformance.Mathematics.quaternion ufbx_quat_mul([NativeTypeName("ufbx_quat")] Misaki.HighPerformance.Mathematics.quaternion a, [NativeTypeName("ufbx_quat")] Misaki.HighPerformance.Mathematics.quaternion b);
[DllImport("ufbx", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ufbx_quat ufbx_quat_normalize(ufbx_quat q);
[return: NativeTypeName("ufbx_quat")]
public static extern Misaki.HighPerformance.Mathematics.quaternion ufbx_quat_normalize([NativeTypeName("ufbx_quat")] Misaki.HighPerformance.Mathematics.quaternion q);
[DllImport("ufbx", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ufbx_quat ufbx_quat_fix_antipodal(ufbx_quat q, ufbx_quat reference);
[return: NativeTypeName("ufbx_quat")]
public static extern Misaki.HighPerformance.Mathematics.quaternion ufbx_quat_fix_antipodal([NativeTypeName("ufbx_quat")] Misaki.HighPerformance.Mathematics.quaternion q, [NativeTypeName("ufbx_quat")] Misaki.HighPerformance.Mathematics.quaternion reference);
[DllImport("ufbx", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ufbx_quat ufbx_quat_slerp(ufbx_quat a, ufbx_quat b, [NativeTypeName("ufbx_real")] float t);
[return: NativeTypeName("ufbx_quat")]
public static extern Misaki.HighPerformance.Mathematics.quaternion ufbx_quat_slerp([NativeTypeName("ufbx_quat")] Misaki.HighPerformance.Mathematics.quaternion a, [NativeTypeName("ufbx_quat")] Misaki.HighPerformance.Mathematics.quaternion b, [NativeTypeName("ufbx_real")] float t);
[DllImport("ufbx", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("ufbx_vec3")]
public static extern Misaki.HighPerformance.Mathematics.float3 ufbx_quat_rotate_vec3(ufbx_quat q, [NativeTypeName("ufbx_vec3")] Misaki.HighPerformance.Mathematics.float3 v);
public static extern Misaki.HighPerformance.Mathematics.float3 ufbx_quat_rotate_vec3([NativeTypeName("ufbx_quat")] Misaki.HighPerformance.Mathematics.quaternion q, [NativeTypeName("ufbx_vec3")] Misaki.HighPerformance.Mathematics.float3 v);
[DllImport("ufbx", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("ufbx_vec3")]
public static extern Misaki.HighPerformance.Mathematics.float3 ufbx_quat_to_euler(ufbx_quat q, ufbx_rotation_order order);
public static extern Misaki.HighPerformance.Mathematics.float3 ufbx_quat_to_euler([NativeTypeName("ufbx_quat")] Misaki.HighPerformance.Mathematics.quaternion q, ufbx_rotation_order order);
[DllImport("ufbx", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ufbx_quat ufbx_euler_to_quat([NativeTypeName("ufbx_vec3")] Misaki.HighPerformance.Mathematics.float3 v, ufbx_rotation_order order);
[return: NativeTypeName("ufbx_quat")]
public static extern Misaki.HighPerformance.Mathematics.quaternion ufbx_euler_to_quat([NativeTypeName("ufbx_vec3")] Misaki.HighPerformance.Mathematics.float3 v, ufbx_rotation_order order);
[DllImport("ufbx", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("ufbx_matrix")]

View File

@@ -4,7 +4,8 @@ namespace Ghost.Ufbx
{
public double time;
public ufbx_quat value;
[NativeTypeName("ufbx_quat")]
public Misaki.HighPerformance.Mathematics.quaternion value;
public ufbx_baked_key_flags flags;
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

View File

@@ -1,3 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

View File

@@ -1,3 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

View File

@@ -1,3 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

View File

@@ -111,7 +111,8 @@ namespace Ghost.Ufbx
public ufbx_mirror_axis handedness_conversion_axis;
public ufbx_quat root_rotation;
[NativeTypeName("ufbx_quat")]
public Misaki.HighPerformance.Mathematics.quaternion root_rotation;
[NativeTypeName("ufbx_real")]
public float root_scale;

View File

@@ -66,12 +66,14 @@ namespace Ghost.Ufbx
[NativeTypeName("ufbx_vec3")]
public Misaki.HighPerformance.Mathematics.float3 adjust_pre_translation;
public ufbx_quat adjust_pre_rotation;
[NativeTypeName("ufbx_quat")]
public Misaki.HighPerformance.Mathematics.quaternion adjust_pre_rotation;
[NativeTypeName("ufbx_real")]
public float adjust_pre_scale;
public ufbx_quat adjust_post_rotation;
[NativeTypeName("ufbx_quat")]
public Misaki.HighPerformance.Mathematics.quaternion adjust_post_rotation;
[NativeTypeName("ufbx_real")]
public float adjust_post_scale;

View File

@@ -1,3 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

View File

@@ -1,3 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

View File

@@ -5,7 +5,8 @@ namespace Ghost.Ufbx
[NativeTypeName("ufbx_vec3")]
public Misaki.HighPerformance.Mathematics.float3 translation;
public ufbx_quat rotation;
[NativeTypeName("ufbx_quat")]
public Misaki.HighPerformance.Mathematics.quaternion rotation;
[NativeTypeName("ufbx_vec3")]
public Misaki.HighPerformance.Mathematics.float3 scale;

View File

@@ -19,11 +19,6 @@
<PackageReference Include="Misaki.HighPerformance.Mathematics" Version="1.3.1" />
</ItemGroup>
<ItemGroup>
<Folder Include="Warper\" />
<Folder Include="runtimes\win-x64\native\" />
</ItemGroup>
<ItemGroup>
<None Update="runtimes\win-x64\native\ufbx.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

View File

@@ -0,0 +1,47 @@
using System.Runtime.InteropServices;
namespace Ghost.Ufbx;
public unsafe partial class LoadOpts
{
public partial cstring ObjMtlPath
{
get => _objMtlPath;
set
{
_objMtlPath.Dispose();
_objMtlPath = new cstring(value);
_ptr->obj_mtl_path = new ufbx_string
{
data = (sbyte*)_objMtlPath.ptr,
length = (nuint)_objMtlPath.length,
};
}
}
public partial cstring Filename
{
get => _filename;
set
{
_filename.Dispose();
_filename = new cstring(value);
_ptr->filename = new ufbx_string
{
data = (sbyte*)_filename.ptr,
length = (nuint)_filename.length,
};
}
}
public partial void Dispose()
{
_objMtlPath.Dispose();
_filename.Dispose();
if (_csAlloc && _ptr != null)
{
NativeMemory.Free(_ptr);
_ptr = null;
}
}
}

View File

@@ -0,0 +1,25 @@
using System.Text;
namespace Ghost.Ufbx;
public static unsafe class UfbxErrorExtensions
{
/// <summary>
/// Formats a ufbx_error into a human-readable string using ufbx_format_error.
/// Allocates a 2KB stack buffer; the result is truncated if the message exceeds that.
/// </summary>
public static string FormatError(ref this ufbx_error error)
{
const int BufferSize = 2048;
Span<byte> buffer = stackalloc byte[BufferSize];
fixed (ufbx_error* pError = &error)
fixed (byte* pBuffer = buffer)
{
var len = Api.ufbx_format_error((sbyte*)pBuffer, (nuint)BufferSize, pError);
if (len == 0)
return string.Empty;
// ufbx_format_error returns the number of characters written (excluding null terminator)
return Encoding.UTF8.GetString(buffer[..(int)len]);
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ghost.Ufbx;
public unsafe struct Allocator
{
private ufbx_allocator* _ptr;
internal Allocator(ufbx_allocator* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public void* User => _ptr->user;
internal ufbx_allocator* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,25 @@
namespace Ghost.Ufbx;
public unsafe struct AllocatorOpts
{
private ufbx_allocator_opts* _ptr;
internal AllocatorOpts(ufbx_allocator_opts* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public Allocator Allocator => new((ufbx_allocator*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->allocator));
public nuint MemoryLimit => _ptr->memory_limit;
public nuint AllocationLimit => _ptr->allocation_limit;
public nuint HugeThreshold => _ptr->huge_threshold;
public nuint MaxChunkSize => _ptr->max_chunk_size;
internal ufbx_allocator_opts* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,91 @@
namespace Ghost.Ufbx;
public unsafe ref struct Anim
{
private ufbx_anim* _ptr;
internal Anim(ufbx_anim* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ufbx_prop EvaluatePropLen(Element element, sbyte* name, nuint nameLen, double time)
{
return Api.ufbx_evaluate_prop_len(_ptr, element.GetUnsafePtr(), name, nameLen, time);
}
public ufbx_prop EvaluateProp(Element element, sbyte* name, double time)
{
return Api.ufbx_evaluate_prop(_ptr, element.GetUnsafePtr(), name, time);
}
public ufbx_prop EvaluatePropFlagsLen(Element element, sbyte* name, nuint nameLen, double time, uint flags)
{
return Api.ufbx_evaluate_prop_flags_len(_ptr, element.GetUnsafePtr(), name, nameLen, time, flags);
}
public ufbx_prop EvaluatePropFlags(Element element, sbyte* name, double time, uint flags)
{
return Api.ufbx_evaluate_prop_flags(_ptr, element.GetUnsafePtr(), name, time, flags);
}
public ufbx_props EvaluateProps(Element element, double time, Prop buffer, nuint bufferSize)
{
return Api.ufbx_evaluate_props(_ptr, element.GetUnsafePtr(), time, buffer.GetUnsafePtr(), bufferSize);
}
public ufbx_props EvaluatePropsFlags(Element element, double time, Prop buffer, nuint bufferSize, uint flags)
{
return Api.ufbx_evaluate_props_flags(_ptr, element.GetUnsafePtr(), time, buffer.GetUnsafePtr(), bufferSize, flags);
}
public ufbx_transform EvaluateTransform(Node node, double time)
{
return Api.ufbx_evaluate_transform(_ptr, node.GetUnsafePtr(), time);
}
public ufbx_transform EvaluateTransformFlags(Node node, double time, uint flags)
{
return Api.ufbx_evaluate_transform_flags(_ptr, node.GetUnsafePtr(), time, flags);
}
public float EvaluateBlendWeight(BlendChannel channel, double time)
{
return Api.ufbx_evaluate_blend_weight(_ptr, channel.GetUnsafePtr(), time);
}
public float EvaluateBlendWeightFlags(BlendChannel channel, double time, uint flags)
{
return Api.ufbx_evaluate_blend_weight_flags(_ptr, channel.GetUnsafePtr(), time, flags);
}
public void FreeAnim()
{
Api.ufbx_free_anim(_ptr);
}
public void RetainAnim()
{
Api.ufbx_retain_anim(_ptr);
}
public double TimeBegin => _ptr->time_begin;
public double TimeEnd => _ptr->time_end;
public AnimLayerList Layers => new(_ptr->layers.data, _ptr->layers.count);
public ReadOnlySpan<float> OverrideLayerWeights => _ptr->override_layer_weights.data == null ? ReadOnlySpan<float>.Empty : new ReadOnlySpan<float>(_ptr->override_layer_weights.data, checked((int)_ptr->override_layer_weights.count));
public ReadOnlySpan<ufbx_prop_override> PropOverrides => _ptr->prop_overrides.data == null ? ReadOnlySpan<ufbx_prop_override>.Empty : new ReadOnlySpan<ufbx_prop_override>(_ptr->prop_overrides.data, checked((int)_ptr->prop_overrides.count));
public ReadOnlySpan<ufbx_transform_override> TransformOverrides => _ptr->transform_overrides.data == null ? ReadOnlySpan<ufbx_transform_override>.Empty : new ReadOnlySpan<ufbx_transform_override>(_ptr->transform_overrides.data, checked((int)_ptr->transform_overrides.count));
public bool IgnoreConnections => _ptr->ignore_connections;
public bool Custom => _ptr->custom;
internal ufbx_anim* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,50 @@
namespace Ghost.Ufbx;
public unsafe struct AnimCurve
{
private ufbx_anim_curve* _ptr;
internal AnimCurve(ufbx_anim_curve* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public float EvaluateCurve(double time, float defaultValue)
{
return Api.ufbx_evaluate_curve(_ptr, time, defaultValue);
}
public float EvaluateCurveFlags(double time, float defaultValue, uint flags)
{
return Api.ufbx_evaluate_curve_flags(_ptr, time, defaultValue, flags);
}
public ReadOnlySpan<ufbx_keyframe> Keyframes => _ptr->keyframes.data == null ? ReadOnlySpan<ufbx_keyframe>.Empty : new ReadOnlySpan<ufbx_keyframe>(_ptr->keyframes.data, checked((int)_ptr->keyframes.count));
public Extrapolation PreExtrapolation => new((ufbx_extrapolation*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->pre_extrapolation));
public Extrapolation PostExtrapolation => new((ufbx_extrapolation*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->post_extrapolation));
public float MinValue => _ptr->min_value;
public float MaxValue => _ptr->max_value;
public double MinTime => _ptr->min_time;
public double MaxTime => _ptr->max_time;
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_anim_curve* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct AnimCurveList
{
private readonly ufbx_anim_curve** _data;
public int Count { get; }
internal AnimCurveList(ufbx_anim_curve** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public AnimCurve this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_anim_curve** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_anim_curve** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public AnimCurve Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,60 @@
namespace Ghost.Ufbx;
public unsafe struct AnimLayer
{
private ufbx_anim_layer* _ptr;
internal AnimLayer(ufbx_anim_layer* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public AnimProp FindAnimPropLen(Element element, sbyte* prop, nuint propLen)
{
return new(Api.ufbx_find_anim_prop_len(_ptr, element.GetUnsafePtr(), prop, propLen));
}
public AnimProp FindAnimProp(Element element, sbyte* prop)
{
return new(Api.ufbx_find_anim_prop(_ptr, element.GetUnsafePtr(), prop));
}
public ufbx_anim_prop_list FindAnimProps(Element element)
{
return Api.ufbx_find_anim_props(_ptr, element.GetUnsafePtr());
}
public float Weight => _ptr->weight;
public bool WeightIsAnimated => _ptr->weight_is_animated;
public bool Blended => _ptr->blended;
public bool Additive => _ptr->additive;
public bool ComposeRotation => _ptr->compose_rotation;
public bool ComposeScale => _ptr->compose_scale;
public AnimValueList AnimValues => new(_ptr->anim_values.data, _ptr->anim_values.count);
public ReadOnlySpan<ufbx_anim_prop> AnimProps => _ptr->anim_props.data == null ? ReadOnlySpan<ufbx_anim_prop>.Empty : new ReadOnlySpan<ufbx_anim_prop>(_ptr->anim_props.data, checked((int)_ptr->anim_props.count));
public bool HasAnim => _ptr->anim != null;
public Anim Anim => _ptr->anim != null ? new(_ptr->anim) : throw new InvalidOperationException("Anim is null.");
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_anim_layer* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct AnimLayerList
{
private readonly ufbx_anim_layer** _data;
public int Count { get; }
internal AnimLayerList(ufbx_anim_layer** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public AnimLayer this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_anim_layer** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_anim_layer** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public AnimLayer Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,27 @@
namespace Ghost.Ufbx;
public unsafe struct AnimOpts
{
private ufbx_anim_opts* _ptr;
internal AnimOpts(ufbx_anim_opts* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ReadOnlySpan<uint> LayerIds => _ptr->layer_ids.data == null ? ReadOnlySpan<uint>.Empty : new ReadOnlySpan<uint>(_ptr->layer_ids.data, checked((int)_ptr->layer_ids.count));
public ReadOnlySpan<float> OverrideLayerWeights => _ptr->override_layer_weights.data == null ? ReadOnlySpan<float>.Empty : new ReadOnlySpan<float>(_ptr->override_layer_weights.data, checked((int)_ptr->override_layer_weights.count));
public ReadOnlySpan<ufbx_prop_override_desc> PropOverrides => _ptr->prop_overrides.data == null ? ReadOnlySpan<ufbx_prop_override_desc>.Empty : new ReadOnlySpan<ufbx_prop_override_desc>(_ptr->prop_overrides.data, checked((int)_ptr->prop_overrides.count));
public ReadOnlySpan<ufbx_transform_override> TransformOverrides => _ptr->transform_overrides.data == null ? ReadOnlySpan<ufbx_transform_override>.Empty : new ReadOnlySpan<ufbx_transform_override>(_ptr->transform_overrides.data, checked((int)_ptr->transform_overrides.count));
public bool IgnoreConnections => _ptr->ignore_connections;
public AllocatorOpts ResultAllocator => new((ufbx_allocator_opts*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->result_allocator));
internal ufbx_anim_opts* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,24 @@
namespace Ghost.Ufbx;
public unsafe struct AnimProp
{
private ufbx_anim_prop* _ptr;
internal AnimProp(ufbx_anim_prop* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public bool HasElement => _ptr->element != null;
public Element Element => _ptr->element != null ? new(_ptr->element) : throw new InvalidOperationException("Element is null.");
public ReadOnlySpan<byte> PropNameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->prop_name);
public string PropName => NativeWrapperHelpers.GetString(_ptr->prop_name);
public bool HasAnimValue => _ptr->anim_value != null;
public AnimValue AnimValue => _ptr->anim_value != null ? new(_ptr->anim_value) : throw new InvalidOperationException("AnimValue is null.");
internal ufbx_anim_prop* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,35 @@
namespace Ghost.Ufbx;
public unsafe struct AnimStack
{
private ufbx_anim_stack* _ptr;
internal AnimStack(ufbx_anim_stack* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public double TimeBegin => _ptr->time_begin;
public double TimeEnd => _ptr->time_end;
public AnimLayerList Layers => new(_ptr->layers.data, _ptr->layers.count);
public bool HasAnim => _ptr->anim != null;
public Anim Anim => _ptr->anim != null ? new(_ptr->anim) : throw new InvalidOperationException("Anim is null.");
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_anim_stack* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct AnimStackList
{
private readonly ufbx_anim_stack** _data;
public int Count { get; }
internal AnimStackList(ufbx_anim_stack** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public AnimStack this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_anim_stack** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_anim_stack** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public AnimStack Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,48 @@
namespace Ghost.Ufbx;
public unsafe struct AnimValue
{
private ufbx_anim_value* _ptr;
internal AnimValue(ufbx_anim_value* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public float EvaluateAnimValueReal(double time)
{
return Api.ufbx_evaluate_anim_value_real(_ptr, time);
}
public Misaki.HighPerformance.Mathematics.float3 EvaluateAnimValueVec3(double time)
{
return Api.ufbx_evaluate_anim_value_vec3(_ptr, time);
}
public float EvaluateAnimValueRealFlags(double time, uint flags)
{
return Api.ufbx_evaluate_anim_value_real_flags(_ptr, time, flags);
}
public Misaki.HighPerformance.Mathematics.float3 EvaluateAnimValueVec3Flags(double time, uint flags)
{
return Api.ufbx_evaluate_anim_value_vec3_flags(_ptr, time, flags);
}
public Misaki.HighPerformance.Mathematics.float3 DefaultValue => _ptr->default_value;
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_anim_value* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct AnimValueList
{
private readonly ufbx_anim_value** _data;
public int Count { get; }
internal AnimValueList(ufbx_anim_value** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public AnimValue this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_anim_value** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_anim_value** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public AnimValue Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,24 @@
namespace Ghost.Ufbx;
public unsafe struct Application
{
private ufbx_application* _ptr;
internal Application(ufbx_application* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ReadOnlySpan<byte> VendorBytes => NativeWrapperHelpers.AsByteSpan(_ptr->vendor);
public string Vendor => NativeWrapperHelpers.GetString(_ptr->vendor);
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public ReadOnlySpan<byte> VersionBytes => NativeWrapperHelpers.AsByteSpan(_ptr->version);
public string Version => NativeWrapperHelpers.GetString(_ptr->version);
internal ufbx_application* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,43 @@
namespace Ghost.Ufbx;
public unsafe struct AudioClip
{
private ufbx_audio_clip* _ptr;
internal AudioClip(ufbx_audio_clip* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ReadOnlySpan<byte> FilenameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->filename);
public string Filename => NativeWrapperHelpers.GetString(_ptr->filename);
public ReadOnlySpan<byte> AbsoluteFilenameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->absolute_filename);
public string AbsoluteFilename => NativeWrapperHelpers.GetString(_ptr->absolute_filename);
public ReadOnlySpan<byte> RelativeFilenameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->relative_filename);
public string RelativeFilename => NativeWrapperHelpers.GetString(_ptr->relative_filename);
public ReadOnlySpan<byte> RawFilename => NativeWrapperHelpers.AsSpan(_ptr->raw_filename);
public ReadOnlySpan<byte> RawAbsoluteFilename => NativeWrapperHelpers.AsSpan(_ptr->raw_absolute_filename);
public ReadOnlySpan<byte> RawRelativeFilename => NativeWrapperHelpers.AsSpan(_ptr->raw_relative_filename);
public ReadOnlySpan<byte> Content => NativeWrapperHelpers.AsSpan(_ptr->content);
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_audio_clip* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct AudioClipList
{
private readonly ufbx_audio_clip** _data;
public int Count { get; }
internal AudioClipList(ufbx_audio_clip** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public AudioClip this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_audio_clip** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_audio_clip** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public AudioClip Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,28 @@
namespace Ghost.Ufbx;
public unsafe struct AudioLayer
{
private ufbx_audio_layer* _ptr;
internal AudioLayer(ufbx_audio_layer* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public AudioClipList Clips => new(_ptr->clips.data, _ptr->clips.count);
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_audio_layer* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct AudioLayerList
{
private readonly ufbx_audio_layer** _data;
public int Count { get; }
internal AudioLayerList(ufbx_audio_layer** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public AudioLayer this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_audio_layer** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_audio_layer** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public AudioLayer Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,53 @@
namespace Ghost.Ufbx;
public unsafe struct BakeOpts
{
private ufbx_bake_opts* _ptr;
internal BakeOpts(ufbx_bake_opts* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public AllocatorOpts TempAllocator => new((ufbx_allocator_opts*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->temp_allocator));
public AllocatorOpts ResultAllocator => new((ufbx_allocator_opts*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->result_allocator));
public bool TrimStartTime => _ptr->trim_start_time;
public double ResampleRate => _ptr->resample_rate;
public double MinimumSampleRate => _ptr->minimum_sample_rate;
public double MaximumSampleRate => _ptr->maximum_sample_rate;
public bool BakeTransformProps => _ptr->bake_transform_props;
public bool SkipNodeTransforms => _ptr->skip_node_transforms;
public bool NoResampleRotation => _ptr->no_resample_rotation;
public bool IgnoreLayerWeightAnimation => _ptr->ignore_layer_weight_animation;
public nuint MaxKeyframeSegments => _ptr->max_keyframe_segments;
public ufbx_bake_step_handling StepHandling => _ptr->step_handling;
public double StepCustomDuration => _ptr->step_custom_duration;
public double StepCustomEpsilon => _ptr->step_custom_epsilon;
public uint EvaluateFlags => _ptr->evaluate_flags;
public bool KeyReductionEnabled => _ptr->key_reduction_enabled;
public bool KeyReductionRotation => _ptr->key_reduction_rotation;
public double KeyReductionThreshold => _ptr->key_reduction_threshold;
public nuint KeyReductionPasses => _ptr->key_reduction_passes;
internal ufbx_bake_opts* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,61 @@
namespace Ghost.Ufbx;
public unsafe struct BakedAnim
{
private ufbx_baked_anim* _ptr;
internal BakedAnim(ufbx_baked_anim* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public void RetainBakedAnim()
{
Api.ufbx_retain_baked_anim(_ptr);
}
public void FreeBakedAnim()
{
Api.ufbx_free_baked_anim(_ptr);
}
public BakedNode FindBakedNodeByTypedId(uint typedId)
{
return new(Api.ufbx_find_baked_node_by_typed_id(_ptr, typedId));
}
public BakedNode FindBakedNode(Node node)
{
return new(Api.ufbx_find_baked_node(_ptr, node.GetUnsafePtr()));
}
public BakedElement FindBakedElementByElementId(uint elementId)
{
return new(Api.ufbx_find_baked_element_by_element_id(_ptr, elementId));
}
public BakedElement FindBakedElement(Element element)
{
return new(Api.ufbx_find_baked_element(_ptr, element.GetUnsafePtr()));
}
public ReadOnlySpan<ufbx_baked_node> Nodes => _ptr->nodes.data == null ? ReadOnlySpan<ufbx_baked_node>.Empty : new ReadOnlySpan<ufbx_baked_node>(_ptr->nodes.data, checked((int)_ptr->nodes.count));
public ReadOnlySpan<ufbx_baked_element> Elements => _ptr->elements.data == null ? ReadOnlySpan<ufbx_baked_element>.Empty : new ReadOnlySpan<ufbx_baked_element>(_ptr->elements.data, checked((int)_ptr->elements.count));
public double PlaybackTimeBegin => _ptr->playback_time_begin;
public double PlaybackTimeEnd => _ptr->playback_time_end;
public double PlaybackDuration => _ptr->playback_duration;
public double KeyTimeMin => _ptr->key_time_min;
public double KeyTimeMax => _ptr->key_time_max;
public BakedAnimMetadata Metadata => new((ufbx_baked_anim_metadata*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->metadata));
internal ufbx_baked_anim* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,23 @@
namespace Ghost.Ufbx;
public unsafe struct BakedAnimMetadata
{
private ufbx_baked_anim_metadata* _ptr;
internal BakedAnimMetadata(ufbx_baked_anim_metadata* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public nuint ResultMemoryUsed => _ptr->result_memory_used;
public nuint TempMemoryUsed => _ptr->temp_memory_used;
public nuint ResultAllocs => _ptr->result_allocs;
public nuint TempAllocs => _ptr->temp_allocs;
internal ufbx_baked_anim_metadata* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,19 @@
namespace Ghost.Ufbx;
public unsafe struct BakedElement
{
private ufbx_baked_element* _ptr;
internal BakedElement(ufbx_baked_element* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public uint ElementId => _ptr->element_id;
public ReadOnlySpan<ufbx_baked_prop> Props => _ptr->props.data == null ? ReadOnlySpan<ufbx_baked_prop>.Empty : new ReadOnlySpan<ufbx_baked_prop>(_ptr->props.data, checked((int)_ptr->props.count));
internal ufbx_baked_element* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,31 @@
namespace Ghost.Ufbx;
public unsafe struct BakedNode
{
private ufbx_baked_node* _ptr;
internal BakedNode(ufbx_baked_node* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public uint TypedId => _ptr->typed_id;
public uint ElementId => _ptr->element_id;
public bool ConstantTranslation => _ptr->constant_translation;
public bool ConstantRotation => _ptr->constant_rotation;
public bool ConstantScale => _ptr->constant_scale;
public ReadOnlySpan<ufbx_baked_vec3> TranslationKeys => _ptr->translation_keys.data == null ? ReadOnlySpan<ufbx_baked_vec3>.Empty : new ReadOnlySpan<ufbx_baked_vec3>(_ptr->translation_keys.data, checked((int)_ptr->translation_keys.count));
public ReadOnlySpan<ufbx_baked_quat> RotationKeys => _ptr->rotation_keys.data == null ? ReadOnlySpan<ufbx_baked_quat>.Empty : new ReadOnlySpan<ufbx_baked_quat>(_ptr->rotation_keys.data, checked((int)_ptr->rotation_keys.count));
public ReadOnlySpan<ufbx_baked_vec3> ScaleKeys => _ptr->scale_keys.data == null ? ReadOnlySpan<ufbx_baked_vec3>.Empty : new ReadOnlySpan<ufbx_baked_vec3>(_ptr->scale_keys.data, checked((int)_ptr->scale_keys.count));
internal ufbx_baked_node* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,22 @@
namespace Ghost.Ufbx;
public unsafe struct BakedProp
{
private ufbx_baked_prop* _ptr;
internal BakedProp(ufbx_baked_prop* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public bool ConstantValue => _ptr->constant_value;
public ReadOnlySpan<ufbx_baked_vec3> Keys => _ptr->keys.data == null ? ReadOnlySpan<ufbx_baked_vec3>.Empty : new ReadOnlySpan<ufbx_baked_vec3>(_ptr->keys.data, checked((int)_ptr->keys.count));
internal ufbx_baked_prop* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,21 @@
namespace Ghost.Ufbx;
public unsafe struct BakedQuat
{
private ufbx_baked_quat* _ptr;
internal BakedQuat(ufbx_baked_quat* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public double Time => _ptr->time;
public Misaki.HighPerformance.Mathematics.quaternion Value => _ptr->value;
public ufbx_baked_key_flags Flags => _ptr->flags;
internal ufbx_baked_quat* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,21 @@
namespace Ghost.Ufbx;
public unsafe struct BakedVec3
{
private ufbx_baked_vec3* _ptr;
internal BakedVec3(ufbx_baked_vec3* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public double Time => _ptr->time;
public Misaki.HighPerformance.Mathematics.float3 Value => _ptr->value;
public ufbx_baked_key_flags Flags => _ptr->flags;
internal ufbx_baked_vec3* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,33 @@
namespace Ghost.Ufbx;
public unsafe struct BlendChannel
{
private ufbx_blend_channel* _ptr;
internal BlendChannel(ufbx_blend_channel* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public float Weight => _ptr->weight;
public ReadOnlySpan<ufbx_blend_keyframe> Keyframes => _ptr->keyframes.data == null ? ReadOnlySpan<ufbx_blend_keyframe>.Empty : new ReadOnlySpan<ufbx_blend_keyframe>(_ptr->keyframes.data, checked((int)_ptr->keyframes.count));
public bool HasTargetShape => _ptr->target_shape != null;
public BlendShape TargetShape => _ptr->target_shape != null ? new(_ptr->target_shape) : throw new InvalidOperationException("TargetShape is null.");
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_blend_channel* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct BlendChannelList
{
private readonly ufbx_blend_channel** _data;
public int Count { get; }
internal BlendChannelList(ufbx_blend_channel** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public BlendChannel this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_blend_channel** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_blend_channel** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public BlendChannel Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,38 @@
namespace Ghost.Ufbx;
public unsafe struct BlendDeformer
{
private ufbx_blend_deformer* _ptr;
internal BlendDeformer(ufbx_blend_deformer* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public Misaki.HighPerformance.Mathematics.float3 GetBlendVertexOffset(nuint vertex)
{
return Api.ufbx_get_blend_vertex_offset(_ptr, vertex);
}
public void AddBlendVertexOffsets(Misaki.HighPerformance.Mathematics.float3* vertices, nuint numVertices, float weight)
{
Api.ufbx_add_blend_vertex_offsets(_ptr, vertices, numVertices, weight);
}
public BlendChannelList Channels => new(_ptr->channels.data, _ptr->channels.count);
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_blend_deformer* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct BlendDeformerList
{
private readonly ufbx_blend_deformer** _data;
public int Count { get; }
internal BlendDeformerList(ufbx_blend_deformer** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public BlendDeformer this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_blend_deformer** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_blend_deformer** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public BlendDeformer Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,22 @@
namespace Ghost.Ufbx;
public unsafe struct BlendKeyframe
{
private ufbx_blend_keyframe* _ptr;
internal BlendKeyframe(ufbx_blend_keyframe* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public bool HasShape => _ptr->shape != null;
public BlendShape Shape => _ptr->shape != null ? new(_ptr->shape) : throw new InvalidOperationException("Shape is null.");
public float TargetWeight => _ptr->target_weight;
public float EffectiveWeight => _ptr->effective_weight;
internal ufbx_blend_keyframe* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,51 @@
namespace Ghost.Ufbx;
public unsafe struct BlendShape
{
private ufbx_blend_shape* _ptr;
internal BlendShape(ufbx_blend_shape* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public uint GetBlendShapeOffsetIndex(nuint vertex)
{
return Api.ufbx_get_blend_shape_offset_index(_ptr, vertex);
}
public Misaki.HighPerformance.Mathematics.float3 GetBlendShapeVertexOffset(nuint vertex)
{
return Api.ufbx_get_blend_shape_vertex_offset(_ptr, vertex);
}
public void AddBlendShapeVertexOffsets(Misaki.HighPerformance.Mathematics.float3* vertices, nuint numVertices, float weight)
{
Api.ufbx_add_blend_shape_vertex_offsets(_ptr, vertices, numVertices, weight);
}
public nuint NumOffsets => _ptr->num_offsets;
public ReadOnlySpan<uint> OffsetVertices => _ptr->offset_vertices.data == null ? ReadOnlySpan<uint>.Empty : new ReadOnlySpan<uint>(_ptr->offset_vertices.data, checked((int)_ptr->offset_vertices.count));
public ReadOnlySpan<Misaki.HighPerformance.Mathematics.float3> PositionOffsets => _ptr->position_offsets.data == null ? ReadOnlySpan<Misaki.HighPerformance.Mathematics.float3>.Empty : new ReadOnlySpan<Misaki.HighPerformance.Mathematics.float3>(_ptr->position_offsets.data, checked((int)_ptr->position_offsets.count));
public ReadOnlySpan<Misaki.HighPerformance.Mathematics.float3> NormalOffsets => _ptr->normal_offsets.data == null ? ReadOnlySpan<Misaki.HighPerformance.Mathematics.float3>.Empty : new ReadOnlySpan<Misaki.HighPerformance.Mathematics.float3>(_ptr->normal_offsets.data, checked((int)_ptr->normal_offsets.count));
public ReadOnlySpan<float> OffsetWeights => _ptr->offset_weights.data == null ? ReadOnlySpan<float>.Empty : new ReadOnlySpan<float>(_ptr->offset_weights.data, checked((int)_ptr->offset_weights.count));
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_blend_shape* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct BlendShapeList
{
private readonly ufbx_blend_shape** _data;
public int Count { get; }
internal BlendShapeList(ufbx_blend_shape** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public BlendShape this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_blend_shape** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_blend_shape** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public BlendShape Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,34 @@
namespace Ghost.Ufbx;
public unsafe struct Bone
{
private ufbx_bone* _ptr;
internal Bone(ufbx_bone* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public float Radius => _ptr->radius;
public float RelativeLength => _ptr->relative_length;
public bool IsRoot => _ptr->is_root;
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
public NodeList Instances => new(_ptr->instances.data, _ptr->instances.count);
internal ufbx_bone* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct BoneList
{
private readonly ufbx_bone** _data;
public int Count { get; }
internal BoneList(ufbx_bone** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public Bone this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_bone** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_bone** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public Bone Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,22 @@
namespace Ghost.Ufbx;
public unsafe struct BonePose
{
private ufbx_bone_pose* _ptr;
internal BonePose(ufbx_bone_pose* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public bool HasBoneNode => _ptr->bone_node != null;
public Node BoneNode => _ptr->bone_node != null ? new(_ptr->bone_node) : throw new InvalidOperationException("BoneNode is null.");
public Misaki.HighPerformance.Mathematics.float3x4 BoneToWorld => _ptr->bone_to_world;
public Misaki.HighPerformance.Mathematics.float3x4 BoneToParent => _ptr->bone_to_parent;
internal ufbx_bone_pose* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,39 @@
namespace Ghost.Ufbx;
public unsafe struct CacheChannel
{
private ufbx_cache_channel* _ptr;
internal CacheChannel(ufbx_cache_channel* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public nuint SampleGeometryCacheReal(double time, float* data, nuint numData, GeometryCacheDataOpts opts)
{
return Api.ufbx_sample_geometry_cache_real(_ptr, time, data, numData, opts.GetUnsafePtr());
}
public nuint SampleGeometryCacheVec3(double time, Misaki.HighPerformance.Mathematics.float3* data, nuint numData, GeometryCacheDataOpts opts)
{
return Api.ufbx_sample_geometry_cache_vec3(_ptr, time, data, numData, opts.GetUnsafePtr());
}
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public ufbx_cache_interpretation Interpretation => _ptr->interpretation;
public ReadOnlySpan<byte> InterpretationNameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->interpretation_name);
public string InterpretationName => NativeWrapperHelpers.GetString(_ptr->interpretation_name);
public ReadOnlySpan<ufbx_cache_frame> Frames => _ptr->frames.data == null ? ReadOnlySpan<ufbx_cache_frame>.Empty : new ReadOnlySpan<ufbx_cache_frame>(_ptr->frames.data, checked((int)_ptr->frames.count));
public ufbx_mirror_axis MirrorAxis => _ptr->mirror_axis;
public float ScaleFactor => _ptr->scale_factor;
internal ufbx_cache_channel* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,38 @@
namespace Ghost.Ufbx;
public unsafe struct CacheDeformer
{
private ufbx_cache_deformer* _ptr;
internal CacheDeformer(ufbx_cache_deformer* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ReadOnlySpan<byte> ChannelBytes => NativeWrapperHelpers.AsByteSpan(_ptr->channel);
public string Channel => NativeWrapperHelpers.GetString(_ptr->channel);
public bool HasFile => _ptr->file != null;
public CacheFile File => _ptr->file != null ? new(_ptr->file) : throw new InvalidOperationException("File is null.");
public bool HasExternalCache => _ptr->external_cache != null;
public GeometryCache ExternalCache => _ptr->external_cache != null ? new(_ptr->external_cache) : throw new InvalidOperationException("ExternalCache is null.");
public bool HasExternalChannel => _ptr->external_channel != null;
public CacheChannel ExternalChannel => _ptr->external_channel != null ? new(_ptr->external_channel) : throw new InvalidOperationException("ExternalChannel is null.");
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_cache_deformer* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct CacheDeformerList
{
private readonly ufbx_cache_deformer** _data;
public int Count { get; }
internal CacheDeformerList(ufbx_cache_deformer** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public CacheDeformer this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_cache_deformer** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_cache_deformer** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public CacheDeformer Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,46 @@
namespace Ghost.Ufbx;
public unsafe struct CacheFile
{
private ufbx_cache_file* _ptr;
internal CacheFile(ufbx_cache_file* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ReadOnlySpan<byte> FilenameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->filename);
public string Filename => NativeWrapperHelpers.GetString(_ptr->filename);
public ReadOnlySpan<byte> AbsoluteFilenameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->absolute_filename);
public string AbsoluteFilename => NativeWrapperHelpers.GetString(_ptr->absolute_filename);
public ReadOnlySpan<byte> RelativeFilenameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->relative_filename);
public string RelativeFilename => NativeWrapperHelpers.GetString(_ptr->relative_filename);
public ReadOnlySpan<byte> RawFilename => NativeWrapperHelpers.AsSpan(_ptr->raw_filename);
public ReadOnlySpan<byte> RawAbsoluteFilename => NativeWrapperHelpers.AsSpan(_ptr->raw_absolute_filename);
public ReadOnlySpan<byte> RawRelativeFilename => NativeWrapperHelpers.AsSpan(_ptr->raw_relative_filename);
public ufbx_cache_file_format Format => _ptr->format;
public bool HasExternalCache => _ptr->external_cache != null;
public GeometryCache ExternalCache => _ptr->external_cache != null ? new(_ptr->external_cache) : throw new InvalidOperationException("ExternalCache is null.");
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_cache_file* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct CacheFileList
{
private readonly ufbx_cache_file** _data;
public int Count { get; }
internal CacheFileList(ufbx_cache_file** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public CacheFile this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_cache_file** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_cache_file** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public CacheFile Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,51 @@
namespace Ghost.Ufbx;
public unsafe struct CacheFrame
{
private ufbx_cache_frame* _ptr;
internal CacheFrame(ufbx_cache_frame* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public nuint ReadGeometryCacheReal(float* data, nuint numData, GeometryCacheDataOpts opts)
{
return Api.ufbx_read_geometry_cache_real(_ptr, data, numData, opts.GetUnsafePtr());
}
public nuint ReadGeometryCacheVec3(Misaki.HighPerformance.Mathematics.float3* data, nuint numData, GeometryCacheDataOpts opts)
{
return Api.ufbx_read_geometry_cache_vec3(_ptr, data, numData, opts.GetUnsafePtr());
}
public ReadOnlySpan<byte> ChannelBytes => NativeWrapperHelpers.AsByteSpan(_ptr->channel);
public string Channel => NativeWrapperHelpers.GetString(_ptr->channel);
public double Time => _ptr->time;
public ReadOnlySpan<byte> FilenameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->filename);
public string Filename => NativeWrapperHelpers.GetString(_ptr->filename);
public ufbx_cache_file_format FileFormat => _ptr->file_format;
public ufbx_mirror_axis MirrorAxis => _ptr->mirror_axis;
public float ScaleFactor => _ptr->scale_factor;
public ufbx_cache_data_format DataFormat => _ptr->data_format;
public ufbx_cache_data_encoding DataEncoding => _ptr->data_encoding;
public ulong DataOffset => _ptr->data_offset;
public uint DataCount => _ptr->data_count;
public uint DataElementBytes => _ptr->data_element_bytes;
public ulong DataTotalBytes => _ptr->data_total_bytes;
internal ufbx_cache_frame* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,68 @@
namespace Ghost.Ufbx;
public unsafe struct Camera
{
private ufbx_camera* _ptr;
internal Camera(ufbx_camera* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ufbx_projection_mode ProjectionMode => _ptr->projection_mode;
public bool ResolutionIsPixels => _ptr->resolution_is_pixels;
public Misaki.HighPerformance.Mathematics.float2 Resolution => _ptr->resolution;
public Misaki.HighPerformance.Mathematics.float2 FieldOfViewDeg => _ptr->field_of_view_deg;
public Misaki.HighPerformance.Mathematics.float2 FieldOfViewTan => _ptr->field_of_view_tan;
public float OrthographicExtent => _ptr->orthographic_extent;
public Misaki.HighPerformance.Mathematics.float2 OrthographicSize => _ptr->orthographic_size;
public Misaki.HighPerformance.Mathematics.float2 ProjectionPlane => _ptr->projection_plane;
public float AspectRatio => _ptr->aspect_ratio;
public float NearPlane => _ptr->near_plane;
public float FarPlane => _ptr->far_plane;
public CoordinateAxes ProjectionAxes => new((ufbx_coordinate_axes*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->projection_axes));
public ufbx_aspect_mode AspectMode => _ptr->aspect_mode;
public ufbx_aperture_mode ApertureMode => _ptr->aperture_mode;
public ufbx_gate_fit GateFit => _ptr->gate_fit;
public ufbx_aperture_format ApertureFormat => _ptr->aperture_format;
public float FocalLengthMm => _ptr->focal_length_mm;
public Misaki.HighPerformance.Mathematics.float2 FilmSizeInch => _ptr->film_size_inch;
public Misaki.HighPerformance.Mathematics.float2 ApertureSizeInch => _ptr->aperture_size_inch;
public float SqueezeRatio => _ptr->squeeze_ratio;
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
public NodeList Instances => new(_ptr->instances.data, _ptr->instances.count);
internal ufbx_camera* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct CameraList
{
private readonly ufbx_camera** _data;
public int Count { get; }
internal CameraList(ufbx_camera** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public Camera this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_camera** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_camera** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public Camera Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,28 @@
namespace Ghost.Ufbx;
public unsafe struct CameraSwitcher
{
private ufbx_camera_switcher* _ptr;
internal CameraSwitcher(ufbx_camera_switcher* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
public NodeList Instances => new(_ptr->instances.data, _ptr->instances.count);
internal ufbx_camera_switcher* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct CameraSwitcherList
{
private readonly ufbx_camera_switcher** _data;
public int Count { get; }
internal CameraSwitcherList(ufbx_camera_switcher** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public CameraSwitcher this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_camera_switcher** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_camera_switcher** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public CameraSwitcher Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,26 @@
namespace Ghost.Ufbx;
public unsafe struct Character
{
private ufbx_character* _ptr;
internal Character(ufbx_character* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_character* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct CharacterList
{
private readonly ufbx_character** _data;
public int Count { get; }
internal CharacterList(ufbx_character** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public Character this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_character** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_character** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public Character Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ghost.Ufbx;
public unsafe struct CloseMemoryCb
{
private ufbx_close_memory_cb* _ptr;
internal CloseMemoryCb(ufbx_close_memory_cb* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public void* User => _ptr->user;
internal ufbx_close_memory_cb* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,22 @@
namespace Ghost.Ufbx;
public unsafe struct ColorSet
{
private ufbx_color_set* _ptr;
internal ColorSet(ufbx_color_set* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public uint Index => _ptr->index;
public VertexVec4 VertexColor => new((ufbx_vertex_vec4*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->vertex_color));
internal ufbx_color_set* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,27 @@
namespace Ghost.Ufbx;
public unsafe struct Connection
{
private ufbx_connection* _ptr;
internal Connection(ufbx_connection* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public bool HasSrc => _ptr->src != null;
public Element Src => _ptr->src != null ? new(_ptr->src) : throw new InvalidOperationException("Src is null.");
public bool HasDst => _ptr->dst != null;
public Element Dst => _ptr->dst != null ? new(_ptr->dst) : throw new InvalidOperationException("Dst is null.");
public ReadOnlySpan<byte> SrcPropBytes => NativeWrapperHelpers.AsByteSpan(_ptr->src_prop);
public string SrcProp => NativeWrapperHelpers.GetString(_ptr->src_prop);
public ReadOnlySpan<byte> DstPropBytes => NativeWrapperHelpers.AsByteSpan(_ptr->dst_prop);
public string DstProp => NativeWrapperHelpers.GetString(_ptr->dst_prop);
internal ufbx_connection* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,59 @@
namespace Ghost.Ufbx;
public unsafe struct Constraint
{
private ufbx_constraint* _ptr;
internal Constraint(ufbx_constraint* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ufbx_constraint_type Type => _ptr->type;
public ReadOnlySpan<byte> TypeNameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->type_name);
public string TypeName => NativeWrapperHelpers.GetString(_ptr->type_name);
public bool HasNode => _ptr->node != null;
public Node Node => _ptr->node != null ? new(_ptr->node) : throw new InvalidOperationException("Node is null.");
public ReadOnlySpan<ufbx_constraint_target> Targets => _ptr->targets.data == null ? ReadOnlySpan<ufbx_constraint_target>.Empty : new ReadOnlySpan<ufbx_constraint_target>(_ptr->targets.data, checked((int)_ptr->targets.count));
public float Weight => _ptr->weight;
public bool Active => _ptr->active;
public Transform TransformOffset => new((ufbx_transform*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->transform_offset));
public Misaki.HighPerformance.Mathematics.float3 AimVector => _ptr->aim_vector;
public ufbx_constraint_aim_up_type AimUpType => _ptr->aim_up_type;
public bool HasAimUpNode => _ptr->aim_up_node != null;
public Node AimUpNode => _ptr->aim_up_node != null ? new(_ptr->aim_up_node) : throw new InvalidOperationException("AimUpNode is null.");
public Misaki.HighPerformance.Mathematics.float3 AimUpVector => _ptr->aim_up_vector;
public bool HasIkEffector => _ptr->ik_effector != null;
public Node IkEffector => _ptr->ik_effector != null ? new(_ptr->ik_effector) : throw new InvalidOperationException("IkEffector is null.");
public bool HasIkEndNode => _ptr->ik_end_node != null;
public Node IkEndNode => _ptr->ik_end_node != null ? new(_ptr->ik_end_node) : throw new InvalidOperationException("IkEndNode is null.");
public Misaki.HighPerformance.Mathematics.float3 IkPoleVector => _ptr->ik_pole_vector;
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_constraint* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct ConstraintList
{
private readonly ufbx_constraint** _data;
public int Count { get; }
internal ConstraintList(ufbx_constraint** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public Constraint this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_constraint** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_constraint** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public Constraint Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,22 @@
namespace Ghost.Ufbx;
public unsafe struct ConstraintTarget
{
private ufbx_constraint_target* _ptr;
internal ConstraintTarget(ufbx_constraint_target* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public bool HasNode => _ptr->node != null;
public Node Node => _ptr->node != null ? new(_ptr->node) : throw new InvalidOperationException("Node is null.");
public float Weight => _ptr->weight;
public Transform Transform => new((ufbx_transform*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->transform));
internal ufbx_constraint_target* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,21 @@
namespace Ghost.Ufbx;
public unsafe struct CoordinateAxes
{
private ufbx_coordinate_axes* _ptr;
internal CoordinateAxes(ufbx_coordinate_axes* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ufbx_coordinate_axis Right => _ptr->right;
public ufbx_coordinate_axis Up => _ptr->up;
public ufbx_coordinate_axis Front => _ptr->front;
internal ufbx_coordinate_axes* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,21 @@
namespace Ghost.Ufbx;
public unsafe struct CurvePoint
{
private ufbx_curve_point* _ptr;
internal CurvePoint(ufbx_curve_point* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public bool Valid => _ptr->valid;
public Misaki.HighPerformance.Mathematics.float3 Position => _ptr->position;
public Misaki.HighPerformance.Mathematics.float3 Derivative => _ptr->derivative;
internal ufbx_curve_point* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,34 @@
namespace Ghost.Ufbx;
public unsafe struct DisplayLayer
{
private ufbx_display_layer* _ptr;
internal DisplayLayer(ufbx_display_layer* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public NodeList Nodes => new(_ptr->nodes.data, _ptr->nodes.count);
public bool Visible => _ptr->visible;
public bool Frozen => _ptr->frozen;
public Misaki.HighPerformance.Mathematics.float3 UiColor => _ptr->ui_color;
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
internal ufbx_display_layer* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct DisplayLayerList
{
private readonly ufbx_display_layer** _data;
public int Count { get; }
internal DisplayLayerList(ufbx_display_layer** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public DisplayLayer this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_display_layer** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_display_layer** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public DisplayLayer Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,72 @@
namespace Ghost.Ufbx;
public unsafe struct DomNode
{
private ufbx_dom_node* _ptr;
internal DomNode(ufbx_dom_node* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public DomNode DomFindLen(sbyte* name, nuint nameLen)
{
return new(Api.ufbx_dom_find_len(_ptr, name, nameLen));
}
public DomNode DomFind(sbyte* name)
{
return new(Api.ufbx_dom_find(_ptr, name));
}
public bool DomIsArray()
{
return Api.ufbx_dom_is_array(_ptr);
}
public nuint DomArraySize()
{
return Api.ufbx_dom_array_size(_ptr);
}
public ufbx_int32_list DomAsInt32List()
{
return Api.ufbx_dom_as_int32_list(_ptr);
}
public ufbx_int64_list DomAsInt64List()
{
return Api.ufbx_dom_as_int64_list(_ptr);
}
public ufbx_float_list DomAsFloatList()
{
return Api.ufbx_dom_as_float_list(_ptr);
}
public ufbx_double_list DomAsDoubleList()
{
return Api.ufbx_dom_as_double_list(_ptr);
}
public ufbx_real_list DomAsRealList()
{
return Api.ufbx_dom_as_real_list(_ptr);
}
public ufbx_blob_list DomAsBlobList()
{
return Api.ufbx_dom_as_blob_list(_ptr);
}
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public DomNodeList Children => new(_ptr->children.data, _ptr->children.count);
public ReadOnlySpan<ufbx_dom_value> Values => _ptr->values.data == null ? ReadOnlySpan<ufbx_dom_value>.Empty : new ReadOnlySpan<ufbx_dom_value>(_ptr->values.data, checked((int)_ptr->values.count));
internal ufbx_dom_node* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct DomNodeList
{
private readonly ufbx_dom_node** _data;
public int Count { get; }
internal DomNodeList(ufbx_dom_node** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public DomNode this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_dom_node** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_dom_node** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public DomNode Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,26 @@
namespace Ghost.Ufbx;
public unsafe struct DomValue
{
private ufbx_dom_value* _ptr;
internal DomValue(ufbx_dom_value* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ufbx_dom_value_type Type => _ptr->type;
public ReadOnlySpan<byte> ValueStrBytes => NativeWrapperHelpers.AsByteSpan(_ptr->value_str);
public string ValueStr => NativeWrapperHelpers.GetString(_ptr->value_str);
public ReadOnlySpan<byte> ValueBlob => NativeWrapperHelpers.AsSpan(_ptr->value_blob);
public long ValueInt => _ptr->value_int;
public double ValueFloat => _ptr->value_float;
internal ufbx_dom_value* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,19 @@
namespace Ghost.Ufbx;
public unsafe struct Edge
{
private ufbx_edge* _ptr;
internal Edge(ufbx_edge* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public uint A => _ptr->a;
public uint B => _ptr->b;
internal ufbx_edge* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,263 @@
namespace Ghost.Ufbx;
public unsafe ref struct Element
{
private ufbx_element* _ptr;
internal Element(ufbx_element* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public Element GetPropElement(Prop prop, ufbx_element_type type)
{
return new(Api.ufbx_get_prop_element(_ptr, prop.GetUnsafePtr(), type));
}
public Element FindPropElementLen(sbyte* name, nuint nameLen, ufbx_element_type type)
{
return new(Api.ufbx_find_prop_element_len(_ptr, name, nameLen, type));
}
public Element FindPropElement(sbyte* name, ufbx_element_type type)
{
return new(Api.ufbx_find_prop_element(_ptr, name, type));
}
public Unknown AsUnknown()
{
return new(Api.ufbx_as_unknown(_ptr));
}
public Node AsNode()
{
return new(Api.ufbx_as_node(_ptr));
}
public Mesh AsMesh()
{
return new(Api.ufbx_as_mesh(_ptr));
}
public Light AsLight()
{
return new(Api.ufbx_as_light(_ptr));
}
public Camera AsCamera()
{
return new(Api.ufbx_as_camera(_ptr));
}
public Bone AsBone()
{
return new(Api.ufbx_as_bone(_ptr));
}
public Empty AsEmpty()
{
return new(Api.ufbx_as_empty(_ptr));
}
public LineCurve AsLineCurve()
{
return new(Api.ufbx_as_line_curve(_ptr));
}
public NurbsCurve AsNurbsCurve()
{
return new(Api.ufbx_as_nurbs_curve(_ptr));
}
public NurbsSurface AsNurbsSurface()
{
return new(Api.ufbx_as_nurbs_surface(_ptr));
}
public NurbsTrimSurface AsNurbsTrimSurface()
{
return new(Api.ufbx_as_nurbs_trim_surface(_ptr));
}
public NurbsTrimBoundary AsNurbsTrimBoundary()
{
return new(Api.ufbx_as_nurbs_trim_boundary(_ptr));
}
public ProceduralGeometry AsProceduralGeometry()
{
return new(Api.ufbx_as_procedural_geometry(_ptr));
}
public StereoCamera AsStereoCamera()
{
return new(Api.ufbx_as_stereo_camera(_ptr));
}
public CameraSwitcher AsCameraSwitcher()
{
return new(Api.ufbx_as_camera_switcher(_ptr));
}
public Marker AsMarker()
{
return new(Api.ufbx_as_marker(_ptr));
}
public LodGroup AsLodGroup()
{
return new(Api.ufbx_as_lod_group(_ptr));
}
public SkinDeformer AsSkinDeformer()
{
return new(Api.ufbx_as_skin_deformer(_ptr));
}
public SkinCluster AsSkinCluster()
{
return new(Api.ufbx_as_skin_cluster(_ptr));
}
public BlendDeformer AsBlendDeformer()
{
return new(Api.ufbx_as_blend_deformer(_ptr));
}
public BlendChannel AsBlendChannel()
{
return new(Api.ufbx_as_blend_channel(_ptr));
}
public BlendShape AsBlendShape()
{
return new(Api.ufbx_as_blend_shape(_ptr));
}
public CacheDeformer AsCacheDeformer()
{
return new(Api.ufbx_as_cache_deformer(_ptr));
}
public CacheFile AsCacheFile()
{
return new(Api.ufbx_as_cache_file(_ptr));
}
public Material AsMaterial()
{
return new(Api.ufbx_as_material(_ptr));
}
public Texture AsTexture()
{
return new(Api.ufbx_as_texture(_ptr));
}
public Video AsVideo()
{
return new(Api.ufbx_as_video(_ptr));
}
public Shader AsShader()
{
return new(Api.ufbx_as_shader(_ptr));
}
public ShaderBinding AsShaderBinding()
{
return new(Api.ufbx_as_shader_binding(_ptr));
}
public AnimStack AsAnimStack()
{
return new(Api.ufbx_as_anim_stack(_ptr));
}
public AnimLayer AsAnimLayer()
{
return new(Api.ufbx_as_anim_layer(_ptr));
}
public AnimValue AsAnimValue()
{
return new(Api.ufbx_as_anim_value(_ptr));
}
public AnimCurve AsAnimCurve()
{
return new(Api.ufbx_as_anim_curve(_ptr));
}
public DisplayLayer AsDisplayLayer()
{
return new(Api.ufbx_as_display_layer(_ptr));
}
public SelectionSet AsSelectionSet()
{
return new(Api.ufbx_as_selection_set(_ptr));
}
public SelectionNode AsSelectionNode()
{
return new(Api.ufbx_as_selection_node(_ptr));
}
public Character AsCharacter()
{
return new(Api.ufbx_as_character(_ptr));
}
public Constraint AsConstraint()
{
return new(Api.ufbx_as_constraint(_ptr));
}
public AudioLayer AsAudioLayer()
{
return new(Api.ufbx_as_audio_layer(_ptr));
}
public AudioClip AsAudioClip()
{
return new(Api.ufbx_as_audio_clip(_ptr));
}
public Pose AsPose()
{
return new(Api.ufbx_as_pose(_ptr));
}
public MetadataObject AsMetadataObject()
{
return new(Api.ufbx_as_metadata_object(_ptr));
}
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
public NodeList Instances => new(_ptr->instances.data, _ptr->instances.count);
public ufbx_element_type Type => _ptr->type;
public ReadOnlySpan<ufbx_connection> ConnectionsSrc => _ptr->connections_src.data == null ? ReadOnlySpan<ufbx_connection>.Empty : new ReadOnlySpan<ufbx_connection>(_ptr->connections_src.data, checked((int)_ptr->connections_src.count));
public ReadOnlySpan<ufbx_connection> ConnectionsDst => _ptr->connections_dst.data == null ? ReadOnlySpan<ufbx_connection>.Empty : new ReadOnlySpan<ufbx_connection>(_ptr->connections_dst.data, checked((int)_ptr->connections_dst.count));
public bool HasDomNode => _ptr->dom_node != null;
public DomNode DomNode => _ptr->dom_node != null ? new(_ptr->dom_node) : throw new InvalidOperationException("DomNode is null.");
public bool HasScene => _ptr->scene != null;
public Scene Scene => _ptr->scene != null ? new(_ptr->scene) : throw new InvalidOperationException("Scene is null.");
internal ufbx_element* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct ElementList
{
private readonly ufbx_element** _data;
public int Count { get; }
internal ElementList(ufbx_element** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public Element this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_element** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_element** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public Element Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,28 @@
namespace Ghost.Ufbx;
public unsafe struct Empty
{
private ufbx_empty* _ptr;
internal Empty(ufbx_empty* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public Element Element => new((ufbx_element*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->element));
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
public Props Props => new((ufbx_props*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->props));
public uint ElementId => _ptr->element_id;
public uint TypedId => _ptr->typed_id;
public NodeList Instances => new(_ptr->instances.data, _ptr->instances.count);
internal ufbx_empty* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,52 @@
namespace Ghost.Ufbx;
public unsafe readonly ref struct EmptyList
{
private readonly ufbx_empty** _data;
public int Count { get; }
internal EmptyList(ufbx_empty** data, nuint count)
{
_data = data;
Count = checked((int)count);
}
public Empty this[int index]
{
get
{
NativeWrapperHelpers.ThrowIfOutOfRange(index, Count);
return new(_data[index]);
}
}
public Enumerator GetEnumerator() => new(_data, Count);
public unsafe ref struct Enumerator
{
private readonly ufbx_empty** _data;
private readonly int _count;
private int _index;
internal Enumerator(ufbx_empty** data, int count)
{
_data = data;
_count = count;
_index = -1;
}
public Empty Current => new(_data[_index]);
public bool MoveNext()
{
var next = _index + 1;
if (next >= _count)
{
return false;
}
_index = next;
return true;
}
}
}

View File

@@ -0,0 +1,24 @@
namespace Ghost.Ufbx;
public unsafe struct Error
{
private ufbx_error* _ptr;
internal Error(ufbx_error* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ufbx_error_type Type => _ptr->type;
public ReadOnlySpan<byte> DescriptionBytes => NativeWrapperHelpers.AsByteSpan(_ptr->description);
public string Description => NativeWrapperHelpers.GetString(_ptr->description);
public uint StackSize => _ptr->stack_size;
public nuint InfoLength => _ptr->info_length;
internal ufbx_error* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,23 @@
namespace Ghost.Ufbx;
public unsafe struct ErrorFrame
{
private ufbx_error_frame* _ptr;
internal ErrorFrame(ufbx_error_frame* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public uint SourceLine => _ptr->source_line;
public ReadOnlySpan<byte> FunctionBytes => NativeWrapperHelpers.AsByteSpan(_ptr->function);
public string Function => NativeWrapperHelpers.GetString(_ptr->function);
public ReadOnlySpan<byte> DescriptionBytes => NativeWrapperHelpers.AsByteSpan(_ptr->description);
public string Description => NativeWrapperHelpers.GetString(_ptr->description);
internal ufbx_error_frame* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,29 @@
namespace Ghost.Ufbx;
public unsafe struct EvaluateOpts
{
private ufbx_evaluate_opts* _ptr;
internal EvaluateOpts(ufbx_evaluate_opts* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public AllocatorOpts TempAllocator => new((ufbx_allocator_opts*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->temp_allocator));
public AllocatorOpts ResultAllocator => new((ufbx_allocator_opts*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->result_allocator));
public bool EvaluateSkinning => _ptr->evaluate_skinning;
public bool EvaluateCaches => _ptr->evaluate_caches;
public uint EvaluateFlags => _ptr->evaluate_flags;
public bool LoadExternalFiles => _ptr->load_external_files;
public OpenFileCb OpenFileCb => new((ufbx_open_file_cb*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref _ptr->open_file_cb));
internal ufbx_evaluate_opts* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,19 @@
namespace Ghost.Ufbx;
public unsafe struct Extrapolation
{
private ufbx_extrapolation* _ptr;
internal Extrapolation(ufbx_extrapolation* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public ufbx_extrapolation_mode Mode => _ptr->mode;
public int RepeatCount => _ptr->repeat_count;
internal ufbx_extrapolation* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,19 @@
namespace Ghost.Ufbx;
public unsafe struct Face
{
private ufbx_face* _ptr;
internal Face(ufbx_face* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public uint IndexBegin => _ptr->index_begin;
public uint NumIndices => _ptr->num_indices;
internal ufbx_face* GetUnsafePtr() => _ptr;
}

View File

@@ -0,0 +1,20 @@
namespace Ghost.Ufbx;
public unsafe struct FaceGroup
{
private ufbx_face_group* _ptr;
internal FaceGroup(ufbx_face_group* ptr)
{
_ptr = ptr;
}
public bool IsNull => _ptr == null;
public int Id => _ptr->id;
public ReadOnlySpan<byte> NameBytes => NativeWrapperHelpers.AsByteSpan(_ptr->name);
public string Name => NativeWrapperHelpers.GetString(_ptr->name);
internal ufbx_face_group* GetUnsafePtr() => _ptr;
}

Some files were not shown because too many files have changed in this diff Show More