using System;
using System.Numerics;
using System.Runtime.InteropServices;
namespace Raylib_cs;
///
/// Bone information
///
[StructLayout(LayoutKind.Sequential)]
public unsafe struct BoneInfo
{
///
/// Bone name (char[32])
///
public fixed sbyte Name[32];
///
/// Bone parent
///
public int Parent;
///
/// Bone name as string
///
public string NameToString()
{
fixed (sbyte* name = Name)
{
return Utf8StringUtils.GetUTF8String(name);
}
}
}
///
/// Skeleton, animation bones hierarchy
///
[StructLayout(LayoutKind.Sequential)]
public unsafe struct ModelSkeleton
{
///
/// Number of bones
///
public int BoneCount;
///
/// Bones information (skeleton)
///
public BoneInfo* Bones;
///
/// Bones base transformation (Transform[])
///
public Transform* BindPose;
public Span BindPoseAsSpan()
{
if (BindPose == null || BoneCount <= 0)
{
return Span.Empty;
}
return new Span(BindPose, BoneCount);
}
public Span BonesAsSpan()
{
if (Bones == null || BoneCount <= 0)
{
return Span.Empty;
}
return new Span(Bones, BoneCount);
}
}
// Note:
// Anim pose, an array of Transform[]
// typedef Transform *ModelAnimPose; It's just a pointer array.
///
/// Model type
///
[StructLayout(LayoutKind.Sequential)]
public unsafe struct Model
{
///
/// Local transform matrix
///
public Matrix4x4 Transform;
///
/// Number of meshes
///
public int MeshCount;
///
/// Number of materials
///
public int MaterialCount;
///
/// Meshes array (Mesh *)
///
public Mesh* Meshes;
///
/// Materials array (Material *)
///
public Material* Materials;
///
/// Mesh material number (int *)
///
public int* MeshMaterial;
///
/// Skeleton for animation
///
public ModelSkeleton Skeleton;
///
/// Current animation pose (Transform[])
///
public Transform* CurrentPose;
///
/// Bones animated transformation matrices
///
public Matrix4x4* BoneMatrices;
///
/// Meshes as span. Based on MeshCount length
///
public Span MeshesAsSpan()
{
if (Meshes == null || MeshCount <= 0)
{
return Span.Empty;
}
return new Span(Meshes, MeshCount);
}
///
/// Materials as span. Based on MaterialCount length
///
public Span MaterialsAsSpan()
{
if (Materials == null || MaterialCount <= 0)
{
return Span.Empty;
}
return new Span(Materials, MaterialCount);
}
///
/// Mesh material number as span. Based on MeshCount length
///
public Span MeshMaterialAsSpan()
{
if (MeshMaterial == null || MeshCount <= 0)
{
return Span.Empty;
}
return new Span(MeshMaterial, MeshCount);
}
///
/// Current animation pose as span. Based on Skeleton.BoneCount length
///
public Span CurrentPoseAsSpan()
{
if (CurrentPose == null || Skeleton.BoneCount <= 0)
{
return Span.Empty;
}
return new Span(CurrentPose, Skeleton.BoneCount);
}
///
/// Bones animated transformation matrices as span. Based on Skeleton.BoneCount length
///
public Span BoneMatricesAsSpan()
{
if (BoneMatrices == null || Skeleton.BoneCount <= 0)
{
return Span.Empty;
}
return new Span(BoneMatrices, Skeleton.BoneCount);
}
}
///
/// ModelAnimation, contains a full animation sequence
///
[StructLayout(LayoutKind.Sequential)]
public unsafe struct ModelAnimation
{
///
/// Animation name (char[32])
///
public fixed sbyte Name[32];
///
/// Number of bones
///
public readonly int BoneCount;
///
/// Number of animation key frames
///
public readonly int KeyFrameCount;
///
/// Animation sequence keyframe poses [keyframe][pose]
///
public Transform** KeyframePoses;
///
/// Animation sequence keyframe poses as span. Based on KeyFrameCount length
///
public Span GetKeyFramePoseAsSpan(int frame)
{
if (KeyframePoses == null || frame < 0 || frame >= KeyFrameCount)
{
return Span.Empty;
}
var pose = KeyframePoses[frame];
if (pose == null || BoneCount <= 0)
{
return Span.Empty;
}
return new Span(KeyframePoses[frame], KeyFrameCount);
}
///
/// Animation name as string
///
public string NameToString()
{
fixed (sbyte* name = Name)
{
return Utf8StringUtils.GetUTF8String(name);
}
}
}