diff --git a/Samples~/Hand Driver Demo/HandDriver/Scenes.meta b/Samples~/Hand Driver Demo/HandDriver/Scenes.meta index 838b3a8..b51161a 100644 --- a/Samples~/Hand Driver Demo/HandDriver/Scenes.meta +++ b/Samples~/Hand Driver Demo/HandDriver/Scenes.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d5af45222e699f84e97cbe0f5a9e4275 +guid: 74936e8bf9a4b144f91a9ae99cb9b6a5 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Samples~/Hand Driver Demo/HandDriver/Scripts.meta b/Samples~/Hand Driver Demo/HandDriver/Scripts.meta index 209eb9f..ef937d7 100644 --- a/Samples~/Hand Driver Demo/HandDriver/Scripts.meta +++ b/Samples~/Hand Driver Demo/HandDriver/Scripts.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: dd6c8c2fb003c044bbafdfd19b405601 +guid: ca9f7a4701b0fa14d88c58c3b79ab9de folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Samples~/Hand Driver Demo/HandDriver/Scripts/HandDriver.cs b/Samples~/Hand Driver Demo/HandDriver/Scripts/HandDriver.cs new file mode 100644 index 0000000..c257070 --- /dev/null +++ b/Samples~/Hand Driver Demo/HandDriver/Scripts/HandDriver.cs @@ -0,0 +1,698 @@ +using NaughtyAttributes; +using System.Collections.Generic; +using TouchSocket.Core; +using UnityEngine; + +public class HandDriver : MonoBehaviour +{ + public Network Network; + + public enum HandType + { + Left, + Right + } + + public enum Axis + { + x, + y, + z, + x_n, + y_n, + z_n + } + + public string CharacterName = string.Empty; + public HandType Hand; + private Dictionary _originQuaternionDic; + + public Transform Thumb1; + public Transform Thumb2; + public Transform Thumb3; + + public Transform Index1; + public Transform Index2; + public Transform Index3; + + public Transform Middle1; + public Transform Middle2; + public Transform Middle3; + + public Transform Ring1; + public Transform Ring2; + public Transform Ring3; + + public Transform Pinky1; + public Transform Pinky2; + public Transform Pinky3; + + public Transform Wrist; + + [Header("[Axis OffSet]")] + public Axis Pitch = Axis.x; + + public Axis Roll = Axis.y; + + public Axis Yaw = Axis.z; + + [Header("[IMU(On/Off)]")] public bool HasIMU = false; + + [Header("[Thumb Root Coefficient]")] [Range(0, 1)] public float coefficient = 0.6f; + + [Header("[Thumb Root OffSet]")] public Vector3 Thumb1Offset; + + [Header("[App Options]")] + public bool NeedRealTransfrom; + + //[HideInInspector] + public bool UsingNetwork; + + public bool UsingAndroidService; + + [Header("[Vector3 Angles]")] + public Vector3 thumb1; + public Vector3 thumb2; + public Vector3 thumb3; + + public Vector3 index1; + public Vector3 index2; + public Vector3 index3; + + public Vector3 middle1; + public Vector3 middle2; + public Vector3 middle3; + + public Vector3 ring1; + public Vector3 ring2; + public Vector3 ring3; + + public Vector3 pinky1; + public Vector3 pinky2; + public Vector3 pinky3; + + [Header("[Controller Values]")] + public float Joy_X; + public float Joy_Y; + public bool Button_A; + public bool Button_B; + public bool Button_Joystick; + public bool Button_Menu; + public InputData inputData = new(); + + [Header("[Vibration Control]")] + public string SendBackIP; + public VibrationData vibrationData; + + [BoxGroup("Vibrator 1"), Min(0), Label("Million Second")] + public int Duration1 = 20; + [BoxGroup("Vibrator 1"), Range(4, 10)] + public int Amplitude1 = 4; + [Button] + public void Vibrator_1Active() + { + if (Network == null) return; + SingleVirbator[] Virbators; + if (Hand == HandType.Left) + { + Virbators = new SingleVirbator[2] + { + new SingleVirbator(1, Duration1, Amplitude1), + new SingleVirbator() + }; + vibrationData = new VibrationData(Virbators); + } + else + { + Virbators = new SingleVirbator[2] + { + new SingleVirbator(), + new SingleVirbator(1, Duration1, Amplitude1), + }; + vibrationData = new VibrationData(Virbators); + } + Network.SendVibrationMsg(CharacterName, SendBackIP, vibrationData); + } + + [BoxGroup("Vibrator 2"), Min(0), Label("Million Second")] + public int Duration2 = 20; + [BoxGroup("Vibrator 2"), Range(4, 10)] + public int Amplitude2 = 4; + [Button] + public void Vibrator_2Active() + { + if (Network == null) return; + SingleVirbator[] Virbators; + if (Hand == HandType.Left) + { + Virbators = new SingleVirbator[2] + { + new SingleVirbator(2, Duration2, Amplitude2), + new SingleVirbator() + }; + vibrationData = new VibrationData(Virbators); + } + else + { + Virbators = new SingleVirbator[2] + { + new SingleVirbator(), + new SingleVirbator(2, Duration2, Amplitude2), + }; + vibrationData = new VibrationData(Virbators); + } + Network.SendVibrationMsg(CharacterName, SendBackIP, vibrationData); + } + [Button] + public void BothActiveWithVibrator_1Parameters() + { + if (Network == null) return; + SingleVirbator[] Virbators; + if (Hand == HandType.Left) + { + Virbators = new SingleVirbator[2] + { + new SingleVirbator(3, Duration1, Amplitude1), + new SingleVirbator() + }; + vibrationData = new VibrationData(Virbators); + } + else + { + Virbators = new SingleVirbator[2] + { + new SingleVirbator(), + new SingleVirbator(3, Duration1, Amplitude1), + }; + vibrationData = new VibrationData(Virbators); + } + Network.SendVibrationMsg(CharacterName, SendBackIP, vibrationData); + } + + + // Start is called before the first frame update + void Start() + { + if (GameObject.Find("Network") == null && (UsingAndroidService || UsingNetwork)) + { + GameObject network = new GameObject("Network"); + network.AddComponent(); + Network = GameObject.Find("Network").GetComponent(); + } + else if (UsingAndroidService || UsingNetwork) + { + Network = GameObject.Find("Network").GetComponent(); + } + + _originQuaternionDic = new Dictionary(); + InitJoints(); + + if (string.IsNullOrEmpty(SendBackIP) || UsingAndroidService) + { + SendBackIP = "127.0.0.1"; + } + + var Virbators = new SingleVirbator[2] + { + new SingleVirbator(0, 0, 1), + new SingleVirbator(0, 0, 1) + }; + + vibrationData = new VibrationData(Virbators); + + if(UsingAndroidService) + { + CharacterName = "AndroidService"; + } + } + + private void InitJoints() + { + _originQuaternionDic.AddOrUpdate(Thumb1.name, Thumb1.localRotation); + _originQuaternionDic.AddOrUpdate(Thumb2.name, Thumb2.localRotation); + _originQuaternionDic.AddOrUpdate(Thumb3.name, Thumb3.localRotation); + + _originQuaternionDic.AddOrUpdate(Index1.name, Index1.localRotation); + _originQuaternionDic.AddOrUpdate(Index2.name, Index2.localRotation); + _originQuaternionDic.AddOrUpdate(Index3.name, Index3.localRotation); + + _originQuaternionDic.AddOrUpdate(Middle1.name, Middle1.localRotation); + _originQuaternionDic.AddOrUpdate(Middle2.name, Middle2.localRotation); + _originQuaternionDic.AddOrUpdate(Middle3.name, Middle3.localRotation); + + _originQuaternionDic.AddOrUpdate(Ring1.name, Ring1.localRotation); + _originQuaternionDic.AddOrUpdate(Ring2.name, Ring2.localRotation); + _originQuaternionDic.AddOrUpdate(Ring3.name, Ring3.localRotation); + + _originQuaternionDic.AddOrUpdate(Pinky1.name, Pinky1.localRotation); + _originQuaternionDic.AddOrUpdate(Pinky2.name, Pinky2.localRotation); + _originQuaternionDic.AddOrUpdate(Pinky3.name, Pinky3.localRotation); + + _originQuaternionDic.AddOrUpdate(Wrist.name, Wrist.localRotation); + } + + private void Rotate(Transform tran, float angle, Axis angleType) + { + if (!NeedRealTransfrom) return; + + float angleX = 0; + float angleY = 0; + float angleZ = 0; + + switch (angleType) + { + case Axis.x_n: + angleX = -angle; + break; + case Axis.y_n: + angleY = -angle; + break; + case Axis.z_n: + angleZ = -angle; + break; + case Axis.x: + angleX = angle; + break; + case Axis.y: + angleY = angle; + break; + case Axis.z: + angleZ = angle; + break; + } + + tran.Rotate(angleX, angleY, angleZ); + } + + private Vector3 ConvertAngleToVec3(Vector3 current, float angle, Axis angleType) + { + float angleX = 0; + float angleY = 0; + float angleZ = 0; + + switch (angleType) + { + case Axis.x_n: + angleX = -angle; + break; + case Axis.y_n: + angleY = -angle; + break; + case Axis.z_n: + angleZ = -angle; + break; + case Axis.x: + angleX = angle; + break; + case Axis.y: + angleY = angle; + break; + case Axis.z: + angleZ = angle; + break; + } + + return current + new Vector3(angleX, angleY, angleZ); + } + + private void ResetRotation(Transform trans) + { + if (_originQuaternionDic.TryGetValue(trans.name, out Quaternion rot)) + { + trans.localRotation = rot; + } + } + + public void GetVec3Value(Vector3[] value) + { + thumb1 = value[0]; + thumb2 = value[1]; + thumb3 = value[2]; + + index1 = value[3]; + index2 = value[4]; + index3 = value[5]; + + middle1 = value[6]; + middle2 = value[7]; + middle3 = value[8]; + + ring1 = value[9]; + ring2 = value[10]; + ring3 = value[11]; + + pinky1 = value[12]; + pinky2 = value[13]; + pinky3 = value[14]; + } + + // Update is called once per frame + void Update() + { + if (UsingNetwork || UsingAndroidService) + { + UpdateThumb(); + UpdateIndex(); + UpdateMiddle(); + UpdateRing(); + UpdatePinky(); + + UpdateWrist(); + UpdateController(); + } + } + + private void UpdateWrist() + { + if (HasIMU) + { + if (Hand == HandType.Left) + { + Quaternion quat_r = new Quaternion( + Network.Convert2Angle(CharacterName, "l26"),//x + Network.Convert2Angle(CharacterName, "l25"),//y + Network.Convert2Angle(CharacterName, "l27"),//z + Network.Convert2Angle(CharacterName, "l24"));//w + ResetRotation(Wrist); + quat_r = ConvertQuaternion(quat_r); + Wrist.rotation = quat_r; + } + else + { + Quaternion quat_r = new Quaternion(Network.Convert2Angle(CharacterName, "r26"), + Network.Convert2Angle(CharacterName, "r25"), + Network.Convert2Angle(CharacterName, "r27"), Network.Convert2Angle(CharacterName, "r24")); + ResetRotation(Wrist); + quat_r = ConvertQuaternion(quat_r); + Wrist.rotation = quat_r; + } + } + } + + private void UpdateController() + { + if (Hand == HandType.Left) + { + Joy_X = Network.Convert2Angle(CharacterName, "l_joyX"); + Joy_Y = Network.Convert2Angle(CharacterName, "l_joyY"); + Button_A = Network.Convert2Bool(CharacterName, "l_aButton"); + Button_B = Network.Convert2Bool(CharacterName, "l_bButton"); + Button_Joystick = Network.Convert2Bool(CharacterName, "l_joyButton"); + Button_Menu = Network.Convert2Bool(CharacterName, "l_menu"); + inputData.joyX = Joy_X; + inputData.joyY = Joy_Y; + inputData.aButton = Button_A; + inputData.bButton = Button_B; + inputData.joyButton = Button_Joystick; + inputData.menu = Button_Menu; + } + else + { + Joy_X = Network.Convert2Angle(CharacterName, "r_joyX"); + Joy_Y = Network.Convert2Angle(CharacterName, "r_joyY"); + Button_A = Network.Convert2Bool(CharacterName, "r_aButton"); + Button_B = Network.Convert2Bool(CharacterName, "r_bButton"); + Button_Joystick = Network.Convert2Bool(CharacterName, "r_joyButton"); + Button_Menu = Network.Convert2Bool(CharacterName, "r_menu"); + inputData.joyX = Joy_X; + inputData.joyY = Joy_Y; + inputData.aButton = Button_A; + inputData.bButton = Button_B; + inputData.joyButton = Button_Joystick; + inputData.menu = Button_Menu; + } + } + + //z轴朝上的右手坐标系 四元数 转换为 Y轴朝上的左手坐标系 四元数 + private Quaternion ConvertQuaternion(Quaternion quat) + { + Quaternion quat_r = new Quaternion(quat.x, quat.y, quat.z, quat.w); + quat_r = Quaternion.Euler(quat_r.eulerAngles.z, -quat_r.eulerAngles.x, quat_r.eulerAngles.y); + return quat_r; + } + + private void UpdateThumb() + { + if (NeedRealTransfrom) + { + ResetRotation(Thumb1); + ResetRotation(Thumb2); + ResetRotation(Thumb3); + } + if (Hand == HandType.Left) + { + var thumb3Pitch = Network.Convert2Angle(CharacterName, "l0"); + var thumb2Pitch = Network.Convert2Angle(CharacterName, "l1"); + var thumb1Pitch = Network.Convert2Angle(CharacterName, "l2") * coefficient + Thumb1Offset.y; + var thumb1Yaw = Network.Convert2Angle(CharacterName, "l3") + Thumb1Offset.z; + var thumb1Roll = Network.Convert2Angle(CharacterName, "l20") + Thumb1Offset.x; + + thumb3 = ConvertAngleToVec3(Vector3.zero, thumb3Pitch, Pitch); + thumb2 = ConvertAngleToVec3(Vector3.zero, thumb2Pitch, Pitch); + thumb1 = ConvertAngleToVec3(Vector3.zero, thumb1Pitch, Pitch); + thumb1 = ConvertAngleToVec3(thumb1, thumb1Yaw, Yaw); + thumb1 = ConvertAngleToVec3(thumb1, thumb1Roll, Roll); + + Rotate(Thumb3, thumb3Pitch, Pitch); + Rotate(Thumb2, thumb2Pitch, Pitch); + Rotate(Thumb1, thumb1Pitch, Pitch); + Rotate(Thumb1, thumb1Yaw, Yaw); + Rotate(Thumb1, thumb1Roll, Roll); + } + else + { + + var thumb3Pitch = Network.Convert2Angle(CharacterName, "r0"); + var thumb2Pitch = Network.Convert2Angle(CharacterName, "r1"); + var thumb1Pitch = Network.Convert2Angle(CharacterName, "r2") * coefficient + Thumb1Offset.y; + var thumb1Yaw = Network.Convert2Angle(CharacterName, "r3") + Thumb1Offset.z; + var thumb1Roll = Network.Convert2Angle(CharacterName, "r20") + Thumb1Offset.x; + + thumb3 = ConvertAngleToVec3(Vector3.zero, thumb3Pitch, Pitch); + thumb2 = ConvertAngleToVec3(Vector3.zero, thumb2Pitch, Pitch); + thumb1 = ConvertAngleToVec3(Vector3.zero, thumb1Pitch, Pitch); + thumb1 = ConvertAngleToVec3(thumb1, thumb1Yaw, Yaw); + thumb1 = ConvertAngleToVec3(thumb1, thumb1Roll, Roll); + + Rotate(Thumb3, thumb3Pitch, Pitch); + Rotate(Thumb2, thumb2Pitch, Pitch); + Rotate(Thumb1, thumb1Pitch, Pitch); + Rotate(Thumb1, thumb1Yaw, Yaw); + Rotate(Thumb1, thumb1Roll, Roll); + } + } + + private void UpdateIndex() + { + if (NeedRealTransfrom) + { + ResetRotation(Index1); + ResetRotation(Index2); + ResetRotation(Index3); + } + if (Hand == HandType.Left) + { + var index3Pitch = Network.Convert2Angle(CharacterName, "l4"); + var index2Pitch = Network.Convert2Angle(CharacterName, "l5"); + var index1Pitch = Network.Convert2Angle(CharacterName, "l6"); + var index1Yaw = Network.Convert2Angle(CharacterName, "l7"); + var index1Roll = Network.Convert2Angle(CharacterName, "l21"); + + index3 = ConvertAngleToVec3(Vector3.zero, index3Pitch, Pitch); + index2 = ConvertAngleToVec3(Vector3.zero, index2Pitch, Pitch); + index1 = ConvertAngleToVec3(Vector3.zero, index1Pitch, Pitch); + index1 = ConvertAngleToVec3(index1, index1Yaw, Yaw); + index1 = ConvertAngleToVec3(index1, index1Roll, Roll); + + Rotate(Index3, index3Pitch, Pitch); + Rotate(Index2, index2Pitch, Pitch); + Rotate(Index1, index1Pitch, Pitch); + Rotate(Index1, index1Yaw, Yaw); + Rotate(Index1, index1Roll, Roll); + } + else + { + var index3Pitch = Network.Convert2Angle(CharacterName, "r4"); + var index2Pitch = Network.Convert2Angle(CharacterName, "r5"); + var index1Pitch = Network.Convert2Angle(CharacterName, "r6"); + var index1Yaw = Network.Convert2Angle(CharacterName, "r7"); + var index1Roll = Network.Convert2Angle(CharacterName, "r21"); + + index3 = ConvertAngleToVec3(Vector3.zero, index3Pitch, Pitch); + index2 = ConvertAngleToVec3(Vector3.zero, index2Pitch, Pitch); + index1 = ConvertAngleToVec3(Vector3.zero, index1Pitch, Pitch); + index1 = ConvertAngleToVec3(index1, index1Yaw, Yaw); + index1 = ConvertAngleToVec3(index1, index1Roll, Roll); + + Rotate(Index3, index3Pitch, Pitch); + Rotate(Index2, index2Pitch, Pitch); + Rotate(Index1, index1Pitch, Pitch); + Rotate(Index1, index1Yaw, Yaw); + Rotate(Index1, index1Roll, Roll); + } + } + + private void UpdateMiddle() + { + if (NeedRealTransfrom) + { + ResetRotation(Middle1); + ResetRotation(Middle2); + ResetRotation(Middle3); + } + if (Hand == HandType.Left) + { + var middle3Pitch = Network.Convert2Angle(CharacterName, "l8"); + var middle2Pitch = Network.Convert2Angle(CharacterName, "l9"); + var middle1Pitch = Network.Convert2Angle(CharacterName, "l10"); + var middle1Yaw = Network.Convert2Angle(CharacterName, "l11"); + + middle3 = ConvertAngleToVec3(Vector3.zero, middle3Pitch, Pitch); + middle2 = ConvertAngleToVec3(Vector3.zero, middle2Pitch, Pitch); + middle1 = ConvertAngleToVec3(Vector3.zero, middle1Pitch, Pitch); + middle1 = ConvertAngleToVec3(middle1, middle1Yaw, Yaw); + + Rotate(Middle3, middle3Pitch, Pitch); + Rotate(Middle2, middle2Pitch, Pitch); + Rotate(Middle1, middle1Pitch, Pitch); + Rotate(Middle1, middle1Yaw, Yaw); + } + else + { + var middle3Pitch = Network.Convert2Angle(CharacterName, "r8"); + var middle2Pitch = Network.Convert2Angle(CharacterName, "r9"); + var middle1Pitch = Network.Convert2Angle(CharacterName, "r10"); + var middle1Yaw = Network.Convert2Angle(CharacterName, "r11"); + + middle3 = ConvertAngleToVec3(Vector3.zero, middle3Pitch, Pitch); + middle2 = ConvertAngleToVec3(Vector3.zero, middle2Pitch, Pitch); + middle1 = ConvertAngleToVec3(Vector3.zero, middle1Pitch, Pitch); + middle1 = ConvertAngleToVec3(middle1, middle1Yaw, Yaw); + + Rotate(Middle3, middle3Pitch, Pitch); + Rotate(Middle2, middle2Pitch, Pitch); + Rotate(Middle1, middle1Pitch, Pitch); + Rotate(Middle1, middle1Yaw, Yaw); + } + } + + private void UpdateRing() + { + if (NeedRealTransfrom) + { + ResetRotation(Ring1); + ResetRotation(Ring2); + ResetRotation(Ring3); + } + if (Hand == HandType.Left) + { + var ring3Pitch = Network.Convert2Angle(CharacterName, "l12"); + var ring2Pitch = Network.Convert2Angle(CharacterName, "l13"); + var ring1Pitch = Network.Convert2Angle(CharacterName, "l14"); + var ring1Yaw = Network.Convert2Angle(CharacterName, "l15"); + + ring3 = ConvertAngleToVec3(Vector3.zero, ring3Pitch, Pitch); + ring2 = ConvertAngleToVec3(Vector3.zero, ring2Pitch, Pitch); + ring1 = ConvertAngleToVec3(Vector3.zero, ring1Pitch, Pitch); + ring1 = ConvertAngleToVec3(ring1, ring1Yaw, Yaw); + + Rotate(Ring3, ring3Pitch, Pitch); + Rotate(Ring2, ring2Pitch, Pitch); + Rotate(Ring1, ring1Pitch, Pitch); + Rotate(Ring1, ring1Yaw, Yaw); + } + else + { + var ring3Pitch = Network.Convert2Angle(CharacterName, "r12"); + var ring2Pitch = Network.Convert2Angle(CharacterName, "r13"); + var ring1Pitch = Network.Convert2Angle(CharacterName, "r14"); + var ring1Yaw = Network.Convert2Angle(CharacterName, "r15"); + + ring3 = ConvertAngleToVec3(Vector3.zero, ring3Pitch, Pitch); + ring2 = ConvertAngleToVec3(Vector3.zero, ring2Pitch, Pitch); + ring1 = ConvertAngleToVec3(Vector3.zero, ring1Pitch, Pitch); + ring1 = ConvertAngleToVec3(ring1, ring1Yaw, Yaw); + + Rotate(Ring3, ring3Pitch, Pitch); + Rotate(Ring2, ring2Pitch, Pitch); + Rotate(Ring1, ring1Pitch, Pitch); + Rotate(Ring1, ring1Yaw, Yaw); + } + } + + private void UpdatePinky() + { + if (NeedRealTransfrom) + { + ResetRotation(Pinky1); + ResetRotation(Pinky2); + ResetRotation(Pinky3); + } + if (Hand == HandType.Left) + { + var pinky3Pitch = Network.Convert2Angle(CharacterName, "l16"); + var pinky2Pitch = Network.Convert2Angle(CharacterName, "l17"); + var pinky1Pitch = Network.Convert2Angle(CharacterName, "l18"); + var pinky1Yaw = Network.Convert2Angle(CharacterName, "l19"); + var pinky1Roll = Network.Convert2Angle(CharacterName, "l22"); + + pinky3 = ConvertAngleToVec3(Vector3.zero, pinky3Pitch, Pitch); + pinky2 = ConvertAngleToVec3(Vector3.zero, pinky2Pitch, Pitch); + pinky1 = ConvertAngleToVec3(Vector3.zero, pinky1Pitch, Pitch); + pinky1 = ConvertAngleToVec3(pinky1, pinky1Yaw, Yaw); + pinky1 = ConvertAngleToVec3(pinky1, pinky1Roll, Roll); + + Rotate(Pinky3, pinky3Pitch, Pitch); + Rotate(Pinky2, pinky2Pitch, Pitch); + Rotate(Pinky1, pinky1Pitch, Pitch); + Rotate(Pinky1, pinky1Yaw, Yaw); + Rotate(Pinky1, pinky1Roll, Roll); + } + else + { + var pinky3Pitch = Network.Convert2Angle(CharacterName, "r16"); + var pinky2Pitch = Network.Convert2Angle(CharacterName, "r17"); + var pinky1Pitch = Network.Convert2Angle(CharacterName, "r18"); + var pinky1Yaw = Network.Convert2Angle(CharacterName, "r19"); + var pinky1Roll = Network.Convert2Angle(CharacterName, "r22"); + + pinky3 = ConvertAngleToVec3(Vector3.zero, pinky3Pitch, Pitch); + pinky2 = ConvertAngleToVec3(Vector3.zero, pinky2Pitch, Pitch); + pinky1 = ConvertAngleToVec3(Vector3.zero, pinky1Pitch, Pitch); + pinky1 = ConvertAngleToVec3(pinky1, pinky1Yaw, Yaw); + pinky1 = ConvertAngleToVec3(pinky1, pinky1Roll, Roll); + + Rotate(Pinky3, pinky3Pitch, Pitch); + Rotate(Pinky2, pinky2Pitch, Pitch); + Rotate(Pinky1, pinky1Pitch, Pitch); + Rotate(Pinky1, pinky1Yaw, Yaw); + Rotate(Pinky1, pinky1Roll, Roll); + } + } + + public void ServiceVibrationControl(int VirbatorIndex = 1, int DurationSecond = 20, int Strength = 10) + { + if (Network == null || !UsingAndroidService) return; + + SingleVirbator[] Virbators; + if (Hand == HandType.Left) + { + Virbators = new SingleVirbator[2] + { + new SingleVirbator(VirbatorIndex, DurationSecond, Strength), + new SingleVirbator() + }; + vibrationData = new VibrationData(Virbators); + } + else + { + Virbators = new SingleVirbator[2] + { + new SingleVirbator(), + new SingleVirbator(VirbatorIndex, DurationSecond, Strength), + }; + vibrationData = new VibrationData(Virbators); + } + Network.SendVibrationMsg("AndroidService", "127.0.0.1", vibrationData); + } +} \ No newline at end of file diff --git a/Samples~/Hand Driver Demo/HandDriver/Scripts/HandDriver.cs.meta b/Samples~/Hand Driver Demo/HandDriver/Scripts/HandDriver.cs.meta new file mode 100644 index 0000000..f4e3eb4 --- /dev/null +++ b/Samples~/Hand Driver Demo/HandDriver/Scripts/HandDriver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ff3bfb33faef00d40880dd5952fd19e9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Hand Driver Demo/HandDriver/Scripts/InputData.cs b/Samples~/Hand Driver Demo/HandDriver/Scripts/InputData.cs new file mode 100644 index 0000000..69d5f99 --- /dev/null +++ b/Samples~/Hand Driver Demo/HandDriver/Scripts/InputData.cs @@ -0,0 +1,35 @@ +//Struct InputData is a struct that contains all of the button, finger, and linear inputs. This is what's sent to the driver via the named pipe. +public struct InputData +{ + + public float joyX; //range: -1 -> 1 + public float joyY; //range: -1 -> 1 + public bool joyButton; + public bool trgButton; + public bool aButton; + public bool bButton; + public bool grab; + //public bool pinch; + public bool menu; + //public bool calibrate; + public bool trackpad_touch; + public float trgValue; //range: 0 -> 1 + + //constructor that uses a 1d array for flexion. + public InputData(float joyX, float joyY, bool joyButton, bool trgButton, + bool aButton, bool bButton, bool grab, bool pinch, bool menu, bool calibrate, float trgValue,bool trackpad_touch) + { + this.joyX = joyX; + this.joyY = joyY; + this.joyButton = joyButton; + this.trgButton = trgButton; + this.aButton = aButton; + this.bButton = bButton; + this.grab = grab; + //this.pinch = pinch; + this.menu = menu; + //this.calibrate = calibrate; + this.trgValue = trgValue; + this.trackpad_touch = trackpad_touch; + } +} diff --git a/Samples~/Hand Driver Demo/HandDriver/Scripts/InputData.cs.meta b/Samples~/Hand Driver Demo/HandDriver/Scripts/InputData.cs.meta new file mode 100644 index 0000000..2e5d61d --- /dev/null +++ b/Samples~/Hand Driver Demo/HandDriver/Scripts/InputData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 704298a683566b5449b0b21443685ded +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Hand Driver Demo/HandDriver/Scripts/Network.cs b/Samples~/Hand Driver Demo/HandDriver/Scripts/Network.cs new file mode 100644 index 0000000..4ea7b45 --- /dev/null +++ b/Samples~/Hand Driver Demo/HandDriver/Scripts/Network.cs @@ -0,0 +1,207 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Concurrent; +using System.IO; +using System.Net; +using System.Text; +using TouchSocket.Core; +using TouchSocket.Sockets; +using UnityEngine; + +public class Network : MonoBehaviour +{ + + public int Port = 5555; + + private UdpSession _udpClient; + + private ConcurrentDictionary> _deviceReadMessages; + + private StreamWriter writer; + private string _txtPath; + void Start() + { + _txtPath = Application.dataPath + "stream.data"; + _deviceReadMessages = new ConcurrentDictionary>(); + _udpClient = new UdpSession(); + + _udpClient.Received += ReceiveMsg; + + _udpClient.Setup(new TouchSocketConfig() + .SetBindIPHost(new IPHost(Port)) + .SetUdpDataHandlingAdapter(() => new NormalUdpDataHandlingAdapter())) + .Start(); + + Debug.Log("UDP Client Start!!"); + + } + + + private void WriteIntoTxt(string message) + { + FileInfo file = new FileInfo(_txtPath); + if (!file.Exists) + { + writer = file.CreateText(); + } + else + { + writer = file.AppendText(); + } + + writer.WriteLine(message); + writer.Flush(); + writer.Dispose(); + writer.Close(); + } + + private void ReceiveMsg(EndPoint endpoint, ByteBlock byteblock, IRequestInfo requestinfo) + { + string msg = Encoding.UTF8.GetString(byteblock.Buffer, 0, byteblock.Len); + Debug.Log(msg); + //WriteIntoTxt(msg); + JObject obj = JObject.Parse(msg); + var jps = obj.Properties(); + foreach (var jp in jps) + { + string role_name = jp.Name; + + JToken token = obj.GetValue(role_name); + JArray array = token["Parameter"] as JArray; + ConcurrentDictionary _deviceMsg = new ConcurrentDictionary(); + for (int i = 0; i < array.Count; i++) + { + JObject obj1 = array[i] as JObject; + string key = obj1.GetValue("Name").ToString(); + string value = obj1.GetValue("Value").ToString(); + _deviceMsg.TryAdd(key, value); + } + if (_deviceReadMessages.ContainsKey(role_name)) + { + _deviceReadMessages[role_name] = _deviceMsg; + } + else + { + _deviceReadMessages.TryAdd(role_name, _deviceMsg); + } + + } + //JToken token = obj.GetValue("Device1_"+Port); + //JArray array = token["Parameter"] as JArray; + //for (int i = 0; i < array.Count; i++) + //{ + // JObject obj1 = array[i] as JObject; + // string key = obj1.GetValue("Name").ToString(); + // string value = obj1.GetValue("Value").ToString(); + // _device1ReadMessages.AddOrUpdate(key, value); + //} + + //JToken token2 = obj.GetValue("Device2_"+Port); + //JArray array2 = token2["Parameter"] as JArray; + //for (int i = 0; i < array.Count; i++) + //{ + // JObject obj1 = array2[i] as JObject; + // string key = obj1.GetValue("Name").ToString(); + // string value = obj1.GetValue("Value").ToString(); + // _device2ReadMessages.AddOrUpdate(key, value); + //} + } + + // Update is called once per frame + void Update() + { + + } + + public float Convert2Angle(string role_name, string key) + { + float angle = 0; + if (!string.IsNullOrEmpty(role_name)) + { + if (!_deviceReadMessages.ContainsKey(role_name)) + { + return 0; + } + string str = _deviceReadMessages[role_name][key]; + + if (!string.IsNullOrEmpty(str)) + { + angle = Single.Parse(str); + } + } + return angle; + } + + public bool Convert2Bool(string role_name, string key) + { + bool flag = false; + if (!string.IsNullOrEmpty(role_name)) + { + if (!_deviceReadMessages.ContainsKey(role_name)) + { + return false; + } + string str = _deviceReadMessages[role_name][key]; + + if (!string.IsNullOrEmpty(str)) + { + flag = bool.Parse(str); + } + } + return flag; + } + + public void SendVibrationMsg(string RoleName, string IP, VibrationData data) + { + var json_role = new JObject(); + var json_one = new JObject(); + var parameterArrayLeft = new JArray(); + var parameterArrayRight = new JArray(); + + var _Lpara_active = new JObject(); + _Lpara_active.Add("Name", "Vibrators"); + _Lpara_active.Add("Value", data.Virbators[0].ActiveCommand); + + var _Lpara_duration = new JObject(); + _Lpara_duration.Add("Name", "Duration"); + _Lpara_duration.Add("Value", data.Virbators[0].Duration); + + var _Lpara_amplitude = new JObject(); + _Lpara_amplitude.Add("Name", "Amplitude"); + _Lpara_amplitude.Add("Value", data.Virbators[0].Amplitude); + + parameterArrayLeft.Add(_Lpara_active); + parameterArrayLeft.Add(_Lpara_duration); + parameterArrayLeft.Add(_Lpara_amplitude); + + var _Rpara_active = new JObject(); + _Rpara_active.Add("Name", "Vibrators"); + _Rpara_active.Add("Value", data.Virbators[1].ActiveCommand); + + var _Rpara_duration = new JObject(); + _Rpara_duration.Add("Name", "Duration"); + _Rpara_duration.Add("Value", data.Virbators[1].Duration); + + var _Rpara_amplitude = new JObject(); + _Rpara_amplitude.Add("Name", "Amplitude"); + _Rpara_amplitude.Add("Value", data.Virbators[1].Amplitude); + + parameterArrayRight.Add(_Rpara_active); + parameterArrayRight.Add(_Rpara_duration); + parameterArrayRight.Add(_Rpara_amplitude); + + json_one.Add("LeftHand", parameterArrayLeft); + json_one.Add("RightHand", parameterArrayRight); + json_role.Add(RoleName, json_one); + + Debug.Log(json_role.ToJson()); + _udpClient.Send(new IPEndPoint(IPAddress.Parse(IP), 8920), Encoding.UTF8.GetBytes(json_role.ToJson())); + } + + private void OnDestroy() + { + _udpClient.Received -= ReceiveMsg; + _udpClient.Stop(); + _udpClient.Dispose(); + } +} diff --git a/Samples~/Hand Driver Demo/HandDriver/Scripts/Network.cs.meta b/Samples~/Hand Driver Demo/HandDriver/Scripts/Network.cs.meta new file mode 100644 index 0000000..3b9d158 --- /dev/null +++ b/Samples~/Hand Driver Demo/HandDriver/Scripts/Network.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d694a138ada737547be655b517ff143b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Hand Driver Demo/HandDriver/Scripts/VibrationData.cs b/Samples~/Hand Driver Demo/HandDriver/Scripts/VibrationData.cs new file mode 100644 index 0000000..ceec53f --- /dev/null +++ b/Samples~/Hand Driver Demo/HandDriver/Scripts/VibrationData.cs @@ -0,0 +1,33 @@ + +public struct SingleVirbator +{ + public int ActiveCommand; + public int Duration; + public int Amplitude; + + public SingleVirbator(int command = 1, int duration = 0, int amplitude = 4) + { + command = command < 1 ? 1 : command > 3 ? 3 : command; + duration = duration < 0 ? 0 : duration; + amplitude = amplitude < 4 ? 4 : amplitude > 10 ? 10 : amplitude; + + ActiveCommand = command; + Duration = duration; + Amplitude = amplitude; + } +} + +public class VibrationData +{ + public SingleVirbator[] Virbators = new SingleVirbator[2]; + + public VibrationData(SingleVirbator[] virbators) + { + if (virbators.Length != 2) return; + + for (int i = 0; i < virbators.Length; i++) + { + Virbators[i] = virbators[i]; + } + } +} diff --git a/Samples~/Hand Driver Demo/HandDriver/Scripts/VibrationData.cs.meta b/Samples~/Hand Driver Demo/HandDriver/Scripts/VibrationData.cs.meta new file mode 100644 index 0000000..62d7e9d --- /dev/null +++ b/Samples~/Hand Driver Demo/HandDriver/Scripts/VibrationData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1fe0a761cd51ae048b2fd88ac356edf4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: