﻿/************************************************************
 * Copyright (C), 2015-2025, BEIJING FOHEART Tech. Co., Ltd.
 * FileName:motionVenusSDKManaged.cs
 * Author:MaoxiaoHu
 * History:
 * -----------
 * V1.1.0
 * MaoxiaoHu 22/2/21        
 * 对应motionVenusSDK.h v3.1.0版本。
 * 将motionVenusSDK.h 中的结构体枚举等重新定义，
 * 确保在调用C++接口时进行正确的类型封送。
 * 测试版本Unity 2020.2.6.f1 64位
 * -----------
 ***********************************************************/
using System.Runtime.InteropServices;

namespace FOHEART_Mocap
{
    public enum SuitType : byte
    {
        WirelessSuit,
        wiredSuit,
    };

    /*固定定义为一字节的枚举类型*/
    public enum StreamFormat_TypeDef : byte
    {
        StreamFormat_Binary,/*数据流格式为二进制流*/
        StreamFormat_String/*数据流格式为可读字符串*/
    };

    /*固定定义为一字节的枚举类型*/
    public enum SkeletonPosition_TypeDef : byte
    {
        SkeletonPosition_None,
        SkeletonPosition_Meter
    };

    /*固定定义为一字节的枚举类型*/
    public enum SensorAttitude_TypeDef : byte
    {
        SensorAttitude_None,
        SensorAttitude_Euler,
        SensorAttitude_Quat
    };

    public enum SensorAccel_TypeDef : byte
    {
        SensorAccel_None,
        SensorAccel_g
    };
    
    public enum SensorLAccel_TypeDef : byte
    {
        SensorLAccel_None,
        SensorLAccel_g
    };

    public enum SensorGyro_TypeDef : byte
    {
        SensorGyro_None,
        SensorGyro_degreePerSecond
    };

    public enum SensorMag_TypeDef : byte
    {
        SensorMag_None,
        SensorMag_mGauss
    };

    /*固定定义为一字节的枚举类型*/
    public enum SkeletonAttitude_TypeDef : byte
    {
        SkeletonAttitude_None,/*不包含骨骼的旋转角度*/
        SkeletonAttitude_Euler,/*骨骼的旋转角度以欧拉角格式表示 单位是Degree*/
        SkeletonAttitude_Quat/*骨骼的旋转角度以四元数格式表示*/
    };

    /*固定定义为一字节的枚举类型*/
    public enum SkeletonCoordinate_TypeDef : byte
    {
        SkeletonCoordinate_Relative,/*骨骼旋转系为本地坐标系 即当前骨骼相对于其父骨骼的旋转*/
        SkeletonCoordinate_Global/*骨骼旋转系为全局坐标系 即当前骨骼相对于世界坐标系的旋转*/
    };

    /*固定定义为一字节的枚举类型*/
    public enum ChannelOrder : byte
    {
        XYZ,
        XZY,
        YXZ,
        YZX,
        ZXY,
        ZYX,
        CHANNEL_ORDER_MAX
    };

    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct _stream_header_managed
    {
        public ushort protocolVersion;/*协议的版本*/
        public byte AvatarNameLength; /*当前演员的名称长度*/

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public byte[] AvatarName;/*对应MotionVenus左侧设备列表中演员名称*/

        public uint suitNumber;       /*当前设备的序列号，与接收器背面粘贴的序列号一致*/
        public SuitType suitType;          /*设备类型 现在默认是0*/
        public uint frameNumber;         /*帧序号，从0开始累加，每秒100帧*/
        public byte bodySkeletonCount;         /*人体躯干骨骼的数量 默认为23*/
        public byte leftFigureSkeletonCount;/*左手指骨的骨骼数量 默认为15*/
        public byte rightFigureSkeletonCount;/*右手指骨的骨骼数量 默认为15*/

        /*
	当前数据流的格式 二进制或字符串 对应设置为MotionVenus软件工具栏->选项->插件->转发规则->自定义->数据流
	*/
        public StreamFormat_TypeDef streamFormat;
        /*
        是否包含53段骨骼位置
        对应设置为MotionVenus软件工具栏->选项->插件->转发规则->自定义->人体骨骼->骨骼坐标
        */
        public SkeletonPosition_TypeDef skeletonPosition;
        /*
        是否包含53段骨骼的旋转角度，以及角度的表示方法
        对应设置为MotionVenus软件工具栏->选项->插件->转发规则->自定义->人体骨骼->旋转
        */
        public SkeletonAttitude_TypeDef skeletonAttitude;
        /*
        如果包含53段骨骼的旋转角度，规定骨骼旋转系
        对应设置为MotionVenus软件工具栏->选项->插件->转发规则->自定义->人体骨骼->骨骼旋转系
        */
        public SkeletonCoordinate_TypeDef skeletonCoordinate;
        /*
        如果发送的角度是欧拉角 设定四元数转换为欧拉角时候的旋转顺序
        对应设置为MotionVenus软件工具栏->选项->插件->转发规则->自定义->旋转顺序
        */
        public ChannelOrder channelOrder;
        /*
        是否包含传感器原始的角度，如果包含，指定角度的表示方法（欧拉角或四元数）
        对应设置为MotionVenus软件工具栏->选项->插件->转发规则->自定义->传感器->旋转
        */
        public SensorAttitude_TypeDef sensorAttitude;
        /*
        是否包含传感器原始的加速度
        对应设置为MotionVenus软件工具栏->选项->插件->转发规则->自定义->传感器->加速度
        */
        public SensorAccel_TypeDef sensorAccel;
        /*
        是否包含传感器原始的线性加速度
        对应设置为MotionVenus软件工具栏->选项->插件->转发规则->自定义->传感器->线性加速度
        */
        public SensorLAccel_TypeDef sensorLAccel;
        /*
        是否包含传感器原始的角速度
        对应设置为MotionVenus软件工具栏->选项->插件->转发规则->自定义->传感器->角速度
        */
        public SensorGyro_TypeDef sensorGyro;
        /*
        是否包含传感器原始的磁力值
        对应设置为MotionVenus软件工具栏->选项->插件->转发规则->自定义->传感器->磁力值
        */
        public SensorMag_TypeDef sensorMag;

        public float hipHeight;
        public byte unity3D_SkeletonTemplate;
        public byte unrealEngine_SkeletonTemplate;
        public byte motionBuilder_SkeletonTemplate;
        public byte blender_SkeletonTemplate;
        public byte c4d_SkeletonTemplate;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
        public byte[] otherEngineSkeletonTemplate;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public byte[] idColorRGB;

        // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        // public byte isContainSkeletonEulerBias;

        //  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        // public float[] thumb0AddEuler;

        // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        // public float[] armAddEuler;

        public byte leftHandAction;
        public byte rightHandAction;
    };

    /*
    人体单段骨骼的数据定义 ，与本段骨骼所有相关的数据都存储在里面
    */
    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct _SingleSkeleton_managed
    {
        FoheartSkeletonName.kinemHumanHandsSkeleton32Index skeletonIndex;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public byte[] skeletonName;
        /*
        下面三个为一组 输出为手指32段骨骼的位置与旋转信息
        坐标系为：MotionVenus软件3D界面左下角坐标系（右手）
        */
        /*人体骨骼的起始点位置坐标 单位是米*/
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public float[] position_meter;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public float[] quat_xyzw;/*人体骨骼的旋转四元数，顺序为xyzw 由设置决定是本地坐标系或者全局坐标系*/
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public float[] euler_degree;/*人体骨骼的旋转欧拉角，单位是角度 由设置决定是本地坐标系或者全局坐标系*/

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public float[] euler_biasDegree;
        /* 
            下面六个为一组 输出为佩戴在人体上的传感器原始数据
            坐标系为：现实世界中传感器自身的坐标系（参考磁北），导光柱指向方向为+y 与导光柱右侧垂直为+x 垂直指向传感器正面上方为+z
        */
        /*传感器原始输出四元数，顺序为xyzw*/
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public float[] sensorQuat_xyzw;
        /*传感器原始输出欧拉角，单位是角度*/
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public float[] sensorEuler_degree;
        /*传感器原始输出加速度，单位是g*/
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public float[] sensorAccel_g;
        /*传感器原始输出线性加速度，单位是g*/
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public float[] sensorLAccel_g;
        /*传感器原始输出角速度，单位是degree/second */
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public float[] sensorGyro_DegreePerSecond;
        /*传感器原始输出磁力值，单位是毫高斯*/
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public float[] sensorMag_mGauss;
    };
    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct _KHS53PosAttitude_managed
    {
        /*
            包含当前帧的一些信息
        */
        public _stream_header_managed hdr;

        /*
            人体53段骨骼的数据，角度、位置等等
        */
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 53)]
        public _SingleSkeleton_managed[] skeletons;

        /*
	        数据来源的IP地址
	        例如 192.168.3.21
	    */
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public byte[] remoteIP;
        /*数据来源的端口号*/
        public uint remotePort;

        public uint sdkVersion;
    };

    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct _KHHS32PosAttitude_managed
    {
        /*
            包含当前帧的一些信息
        */
        public _stream_header_managed hdr;

        /*
            人体53段骨骼的数据，角度、位置等等
        */
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
        public _SingleSkeleton_managed[] skeletons;

        /*
	        数据来源的IP地址
	        例如 192.168.3.21
	    */
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public byte[] remoteIP;
        /*数据来源的端口号*/
        public uint remotePort;

        public uint sdkVersion;
    };
}