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; } /// /// 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; /// /// Number of bones /// public int BoneCount; //TODO: Span /// /// Bones information (skeleton, BoneInfo *) /// public BoneInfo* Bones; //TODO: Span /// /// Bones base transformation (pose, Transform *) /// public Transform* BindPose; public readonly CBool IsValid => Raylib.IsModelValid(this); public static Model Load(string fileName) { return Raylib.LoadModel(fileName); } public static Model LoadFromMesh(Mesh mesh) { return Raylib.LoadModelFromMesh(mesh); } public readonly void Draw(Vector3 position) { Raylib.DrawModel(this, position, 1.0f, Color.White); } public readonly void Draw(Vector3 position, float scale) { Raylib.DrawModel(this, position, scale, Color.White); } public readonly void Draw(Vector3 position, float scale, Color color) { Raylib.DrawModel(this, position, scale, color); } public readonly void Draw(Vector3 position, Vector3 rotationAxis, float rotationAngle) { Raylib.DrawModelEx(this, position, rotationAxis, rotationAngle, Vector3.One, Color.White); } public readonly void Draw(Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale) { Raylib.DrawModelEx(this, position, rotationAxis, rotationAngle, scale, Color.White); } public readonly void Draw(Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color color) { Raylib.DrawModelEx(this, position, rotationAxis, rotationAngle, scale, color); } public readonly void DrawWires(Vector3 position, Color color) { Raylib.DrawModelWires(this, position, 1.0f, color); } public readonly void DrawWires(Vector3 position, float scale) { Raylib.DrawModelWires(this, position, scale, Color.White); } public readonly void DrawWires(Vector3 position, float scale, Color color) { Raylib.DrawModelWires(this, position, scale, color); } public readonly void DrawWires(Vector3 position, Vector3 rotationAxis, float rotationAngle, Color color) { Raylib.DrawModelWiresEx(this, position, rotationAxis, rotationAngle, Vector3.One, color); } public readonly void DrawWires(Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color color) { Raylib.DrawModelWiresEx(this, position, rotationAxis, rotationAngle, scale, color); } public readonly void DrawPoints(Vector3 position, Color color) { Raylib.DrawModelPoints(this, position, 1.0f, color); } public readonly void DrawPoints(Vector3 position, float scale, Color color) { Raylib.DrawModelPoints(this, position, scale, color); } public readonly void DrawPoints(Vector3 position, Vector3 rotationAxis, float rotationAngle, Color color) { Raylib.DrawModelPointsEx(this, position, rotationAxis, rotationAngle, Vector3.One, color); } public readonly void DrawPoints(Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color color) { Raylib.DrawModelPointsEx(this, position, rotationAxis, rotationAngle, scale, color); } public void Unload() { Raylib.UnloadModel(this); } } /// /// Model animation /// [StructLayout(LayoutKind.Sequential)] public unsafe struct ModelAnimation { /// /// Number of bones /// public readonly int BoneCount; /// /// Number of animation frames /// public readonly int FrameCount; /// /// Bones information (skeleton, BoneInfo *) /// public readonly BoneInfo* Bones; /// public ReadOnlySpan BoneInfo => new(Bones, BoneCount); /// /// Poses array by frame (Transform **) /// public readonly Transform** FramePoses; /// /// Animation name (char[32]) /// public fixed sbyte Name[32]; /// public readonly FramePosesCollection FramePosesColl => new FramePosesCollection(FramePoses, FrameCount, BoneCount); public struct FramePosesCollection { readonly Transform** _framePoses; readonly int _frameCount; readonly int _boneCount; public readonly FramePoses this[int index] => new FramePoses(_framePoses[index], _boneCount); public readonly Transform this[int index1, int index2] => new FramePoses(_framePoses[index1], _boneCount)[index2]; internal FramePosesCollection(Transform** framePoses, int frameCount, int boneCount) { this._framePoses = framePoses; this._frameCount = frameCount; this._boneCount = boneCount; } } public static ModelAnimation[] LoadAnimations(string fileName) { int count = 0; ModelAnimation* animations = Raylib.LoadModelAnimations(fileName, ref count); ModelAnimation[] output = new ModelAnimation[count]; for (int i = 0; i < count; i++) { output[i] = animations[i]; } return output; } public static void UnloadAnimations(ModelAnimation[] modelAnimations) { fixed (ModelAnimation* ptr = modelAnimations) { Raylib.UnloadModelAnimations(ptr, modelAnimations.Length); } } public void Unload() { Raylib.UnloadModelAnimation(this); } } public unsafe struct FramePoses { readonly Transform* _poses; readonly int _count; public ref Transform this[int index] => ref _poses[index]; internal FramePoses(Transform* poses, int count) { this._poses = poses; this._count = count; } }