123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- namespace Leap.Unity
- {
- public class CapsuleHand : IHandModel
- {
- public override ModelType HandModelType
- {
- get
- {
- return ModelType.Graphics;
- }
- }
- public override Chirality Handedness
- {
- get
- {
- return this.handedness;
- }
- set
- {
- }
- }
- public override bool SupportsEditorPersistence()
- {
- return true;
- }
- public override Hand GetLeapHand()
- {
- return this.hand_;
- }
- public override void SetLeapHand(Hand hand)
- {
- this.hand_ = hand;
- }
- private void OnValidate()
- {
- this._cylinderResolution = Mathf.Max(3, this._cylinderResolution);
- if (this._armRenderers != null)
- {
- this.updateArmVisibility();
- }
- }
- public override void InitHand()
- {
- if (this._material != null)
- {
- this.jointMat = new Material(this._material);
- this.jointMat.hideFlags = HideFlags.DontSaveInEditor;
- }
- if (this._serializedTransforms != null)
- {
- for (int i = 0; i < this._serializedTransforms.Count; i++)
- {
- Transform transform = this._serializedTransforms[i];
- if (transform != null)
- {
- UnityEngine.Object.DestroyImmediate(transform.gameObject);
- }
- }
- this._serializedTransforms.Clear();
- }
- else
- {
- this._serializedTransforms = new List<Transform>();
- }
- this._jointSpheres = new Transform[20];
- this._armRenderers = new List<Renderer>();
- this._cylinderTransforms = new List<Transform>();
- this._sphereATransforms = new List<Transform>();
- this._sphereBTransforms = new List<Transform>();
- this.createSpheres();
- this.createCylinders();
- this.updateArmVisibility();
- this._hasGeneratedMeshes = false;
- }
- public override void BeginHand()
- {
- base.BeginHand();
- if (this.hand_.IsLeft)
- {
- this.jointMat.color = CapsuleHand._leftColorList[CapsuleHand._leftColorIndex];
- CapsuleHand._leftColorIndex = (CapsuleHand._leftColorIndex + 1) % CapsuleHand._leftColorList.Length;
- }
- else
- {
- this.jointMat.color = CapsuleHand._rightColorList[CapsuleHand._rightColorIndex];
- CapsuleHand._rightColorIndex = (CapsuleHand._rightColorIndex + 1) % CapsuleHand._rightColorList.Length;
- }
- }
- public override void UpdateHand()
- {
- this.updateSpheres();
- if (this._showArm)
- {
- this.updateArm();
- }
- this.updateCylinders();
- }
- private void updateSpheres()
- {
- List<Finger> fingers = this.hand_.Fingers;
- for (int i = 0; i < fingers.Count; i++)
- {
- Finger finger = fingers[i];
- for (int j = 0; j < 4; j++)
- {
- int fingerJointIndex = this.getFingerJointIndex((int)finger.Type, j);
- Transform transform = this._jointSpheres[fingerJointIndex];
- transform.position = finger.Bone((Bone.BoneType)j).NextJoint.ToVector3();
- }
- }
- this.palmPositionSphere.position = this.hand_.PalmPosition.ToVector3();
- Vector3 position = this.hand_.PalmPosition.ToVector3();
- this.wristPositionSphere.position = position;
- Transform transform2 = this._jointSpheres[0];
- Vector3 inDirection = transform2.position - this.hand_.PalmPosition.ToVector3();
- this.mockThumbJointSphere.position = this.hand_.PalmPosition.ToVector3() + Vector3.Reflect(inDirection, this.hand_.Basis.xBasis.ToVector3());
- }
- private void updateArm()
- {
- Arm arm = this.hand_.Arm;
- Vector3 b = arm.Basis.xBasis.ToVector3() * arm.Width * 0.7f * 0.5f;
- Vector3 a = arm.WristPosition.ToVector3();
- Vector3 vector = arm.ElbowPosition.ToVector3();
- float d = Vector3.Distance(a, vector);
- a -= arm.Direction.ToVector3() * d * 0.05f;
- this.armFrontRight.position = a + b;
- this.armFrontLeft.position = a - b;
- this.armBackRight.position = vector + b;
- this.armBackLeft.position = vector - b;
- }
- private void updateCylinders()
- {
- for (int i = 0; i < this._cylinderTransforms.Count; i++)
- {
- Transform transform = this._cylinderTransforms[i];
- Transform transform2 = this._sphereATransforms[i];
- Transform transform3 = this._sphereBTransforms[i];
- Vector3 vector = transform2.position - transform3.position;
- if (!this._hasGeneratedMeshes)
- {
- MeshFilter component = transform.GetComponent<MeshFilter>();
- component.sharedMesh = this.generateCylinderMesh(vector.magnitude / base.transform.lossyScale.x);
- }
- transform.position = transform2.position;
- if (vector.sqrMagnitude > Mathf.Epsilon)
- {
- transform.LookAt(transform3);
- }
- }
- this._hasGeneratedMeshes = true;
- }
- private void updateArmVisibility()
- {
- for (int i = 0; i < this._armRenderers.Count; i++)
- {
- this._armRenderers[i].enabled = this._showArm;
- }
- }
- private void createSpheres()
- {
- List<Finger> fingers = this.hand_.Fingers;
- for (int i = 0; i < fingers.Count; i++)
- {
- Finger finger = fingers[i];
- for (int j = 0; j < 4; j++)
- {
- int fingerJointIndex = this.getFingerJointIndex((int)finger.Type, j);
- this._jointSpheres[fingerJointIndex] = this.createSphere("Joint", 0.008f, false);
- }
- }
- this.mockThumbJointSphere = this.createSphere("MockJoint", 0.008f, false);
- this.palmPositionSphere = this.createSphere("PalmPosition", 0.015f, false);
- this.wristPositionSphere = this.createSphere("WristPosition", 0.008f, false);
- this.armFrontLeft = this.createSphere("ArmFrontLeft", 0.008f, true);
- this.armFrontRight = this.createSphere("ArmFrontRight", 0.008f, true);
- this.armBackLeft = this.createSphere("ArmBackLeft", 0.008f, true);
- this.armBackRight = this.createSphere("ArmBackRight", 0.008f, true);
- }
- private void createCylinders()
- {
- for (int i = 0; i < 5; i++)
- {
- for (int j = 0; j < 3; j++)
- {
- int fingerJointIndex = this.getFingerJointIndex(i, j);
- int fingerJointIndex2 = this.getFingerJointIndex(i, j + 1);
- Transform jointA = this._jointSpheres[fingerJointIndex];
- Transform jointB = this._jointSpheres[fingerJointIndex2];
- this.createCylinder("Finger Joint", jointA, jointB, false);
- }
- }
- for (int k = 0; k < 4; k++)
- {
- int fingerJointIndex3 = this.getFingerJointIndex(k, 0);
- int fingerJointIndex4 = this.getFingerJointIndex(k + 1, 0);
- Transform jointA2 = this._jointSpheres[fingerJointIndex3];
- Transform jointB2 = this._jointSpheres[fingerJointIndex4];
- this.createCylinder("Hand Joints", jointA2, jointB2, false);
- }
- Transform jointA3 = this._jointSpheres[0];
- Transform jointA4 = this._jointSpheres[16];
- this.createCylinder("Hand Bottom", jointA3, this.mockThumbJointSphere, false);
- this.createCylinder("Hand Side", jointA4, this.mockThumbJointSphere, false);
- this.createCylinder("ArmFront", this.armFrontLeft, this.armFrontRight, true);
- this.createCylinder("ArmBack", this.armBackLeft, this.armBackRight, true);
- this.createCylinder("ArmLeft", this.armFrontLeft, this.armBackLeft, true);
- this.createCylinder("ArmRight", this.armFrontRight, this.armBackRight, true);
- }
- private int getFingerJointIndex(int fingerIndex, int jointIndex)
- {
- return fingerIndex * 4 + jointIndex;
- }
- private Transform createSphere(string name, float radius, bool isPartOfArm = false)
- {
- GameObject gameObject = new GameObject(name);
- this._serializedTransforms.Add(gameObject.transform);
- gameObject.AddComponent<MeshFilter>().mesh = this._sphereMesh;
- gameObject.AddComponent<MeshRenderer>().sharedMaterial = this.jointMat;
- gameObject.transform.parent = base.transform;
- gameObject.transform.localScale = Vector3.one * radius * 2f;
- gameObject.hideFlags = (HideFlags.HideInHierarchy | HideFlags.HideInInspector | HideFlags.DontSaveInEditor | HideFlags.DontSaveInBuild | HideFlags.DontUnloadUnusedAsset);
- gameObject.layer = base.gameObject.layer;
- if (isPartOfArm)
- {
- this._armRenderers.Add(gameObject.GetComponent<Renderer>());
- }
- return gameObject.transform;
- }
- private void createCylinder(string name, Transform jointA, Transform jointB, bool isPartOfArm = false)
- {
- GameObject gameObject = new GameObject(name);
- this._serializedTransforms.Add(gameObject.transform);
- gameObject.AddComponent<MeshFilter>();
- gameObject.AddComponent<MeshRenderer>().sharedMaterial = this._material;
- gameObject.transform.parent = base.transform;
- this._cylinderTransforms.Add(gameObject.transform);
- this._sphereATransforms.Add(jointA);
- this._sphereBTransforms.Add(jointB);
- gameObject.gameObject.layer = base.gameObject.layer;
- gameObject.hideFlags = (HideFlags.HideInHierarchy | HideFlags.HideInInspector | HideFlags.DontSaveInEditor | HideFlags.DontSaveInBuild | HideFlags.DontUnloadUnusedAsset);
- if (isPartOfArm)
- {
- this._armRenderers.Add(gameObject.GetComponent<Renderer>());
- }
- }
- private Mesh generateCylinderMesh(float length)
- {
- Mesh mesh = new Mesh();
- mesh.name = "GeneratedCylinder";
- mesh.hideFlags = HideFlags.DontSave;
- List<Vector3> list = new List<Vector3>();
- List<Color> list2 = new List<Color>();
- List<int> list3 = new List<int>();
- Vector3 zero = Vector3.zero;
- Vector3 a = Vector3.forward * length;
- for (int i = 0; i < this._cylinderResolution; i++)
- {
- float f = 6.28318548f * (float)i / (float)this._cylinderResolution;
- float x = 0.006f * Mathf.Cos(f);
- float y = 0.006f * Mathf.Sin(f);
- Vector3 b = new Vector3(x, y, 0f);
- list.Add((zero + b) * base.transform.lossyScale.x);
- list.Add((a + b) * base.transform.lossyScale.x);
- list2.Add(Color.white);
- list2.Add(Color.white);
- int count = list.Count;
- int num = this._cylinderResolution * 2;
- list3.Add(count % num);
- list3.Add((count + 2) % num);
- list3.Add((count + 1) % num);
- list3.Add((count + 2) % num);
- list3.Add((count + 3) % num);
- list3.Add((count + 1) % num);
- }
- mesh.SetVertices(list);
- mesh.SetIndices(list3.ToArray(), MeshTopology.Triangles, 0);
- mesh.RecalculateBounds();
- mesh.RecalculateNormals();
- mesh.UploadMeshData(true);
- return mesh;
- }
- private const int THUMB_BASE_INDEX = 0;
- private const int PINKY_BASE_INDEX = 16;
- private const float SPHERE_RADIUS = 0.008f;
- private const float CYLINDER_RADIUS = 0.006f;
- private const float PALM_RADIUS = 0.015f;
- private static int _leftColorIndex = 0;
- private static int _rightColorIndex = 0;
- private static Color[] _leftColorList = new Color[]
- {
- new Color(0f, 0f, 1f),
- new Color(0.2f, 0f, 0.4f),
- new Color(0f, 0.2f, 0.2f)
- };
- private static Color[] _rightColorList = new Color[]
- {
- new Color(1f, 0f, 0f),
- new Color(1f, 1f, 0f),
- new Color(1f, 0.5f, 0f)
- };
- [SerializeField]
- private Chirality handedness;
- [SerializeField]
- private bool _showArm = true;
- [SerializeField]
- private Material _material;
- [SerializeField]
- private Mesh _sphereMesh;
- [SerializeField]
- private int _cylinderResolution = 12;
- private bool _hasGeneratedMeshes;
- private Material jointMat;
- [SerializeField]
- [HideInInspector]
- private List<Transform> _serializedTransforms;
- private Transform[] _jointSpheres;
- private Transform mockThumbJointSphere;
- private Transform palmPositionSphere;
- private Transform wristPositionSphere;
- private List<Renderer> _armRenderers;
- private List<Transform> _cylinderTransforms;
- private List<Transform> _sphereATransforms;
- private List<Transform> _sphereBTransforms;
- private Transform armFrontLeft;
- private Transform armFrontRight;
- private Transform armBackLeft;
- private Transform armBackRight;
- private Hand hand_;
- }
- }
|