IKSolverVRBodyPart.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using UnityEngine;
  2. using System.Collections;
  3. using System;
  4. using RootMotion;
  5. namespace RootMotion.FinalIK {
  6. /// <summary>
  7. /// Hybrid %IK solver designed for mapping a character to a VR headset and 2 hand controllers.
  8. /// </summary>
  9. public partial class IKSolverVR: IKSolver {
  10. /// <summary>
  11. /// A base class for all IKSolverVR body parts.
  12. /// </summary>
  13. [System.Serializable]
  14. public abstract class BodyPart {
  15. protected abstract void OnRead(Vector3[] positions, Quaternion[] rotations, bool hasChest, bool hasNeck, bool hasShoulders, bool hasToes, bool hasLegs, int rootIndex, int index);
  16. public abstract void PreSolve();
  17. public abstract void Write(ref Vector3[] solvedPositions, ref Quaternion[] solvedRotations);
  18. public abstract void ApplyOffsets(float scale);
  19. public abstract void ResetOffsets();
  20. public float sqrMag { get; private set; }
  21. public float mag { get; private set; }
  22. [HideInInspector] public VirtualBone[] bones = new VirtualBone[0];
  23. protected bool initiated;
  24. protected Vector3 rootPosition;
  25. protected Quaternion rootRotation = Quaternion.identity;
  26. protected int index = -1;
  27. protected int LOD;
  28. public void SetLOD(int LOD)
  29. {
  30. this.LOD = LOD;
  31. }
  32. public void Read(Vector3[] positions, Quaternion[] rotations, bool hasChest, bool hasNeck, bool hasShoulders, bool hasToes, bool hasLegs, int rootIndex, int index) {
  33. this.index = index;
  34. rootPosition = positions[rootIndex];
  35. rootRotation = rotations[rootIndex];
  36. OnRead(positions, rotations, hasChest, hasNeck, hasShoulders, hasToes, hasLegs, rootIndex, index);
  37. mag = VirtualBone.PreSolve(ref bones);
  38. sqrMag = mag * mag;
  39. initiated = true;
  40. }
  41. public void MovePosition(Vector3 position) {
  42. Vector3 delta = position - bones[0].solverPosition;
  43. foreach (VirtualBone bone in bones) bone.solverPosition += delta;
  44. }
  45. public void MoveRotation(Quaternion rotation) {
  46. Quaternion delta = QuaTools.FromToRotation(bones[0].solverRotation, rotation);
  47. VirtualBone.RotateAroundPoint(bones, 0, bones[0].solverPosition, delta);
  48. }
  49. public void Translate(Vector3 position, Quaternion rotation) {
  50. MovePosition(position);
  51. MoveRotation(rotation);
  52. }
  53. public void TranslateRoot(Vector3 newRootPos, Quaternion newRootRot) {
  54. Vector3 deltaPosition = newRootPos - rootPosition;
  55. rootPosition = newRootPos;
  56. foreach (VirtualBone bone in bones) bone.solverPosition += deltaPosition;
  57. Quaternion deltaRotation = QuaTools.FromToRotation(rootRotation, newRootRot);
  58. rootRotation = newRootRot;
  59. VirtualBone.RotateAroundPoint(bones, 0, newRootPos, deltaRotation);
  60. }
  61. public void RotateTo(VirtualBone bone, Quaternion rotation, float weight = 1f) {
  62. if (weight <= 0f) return;
  63. Quaternion q = QuaTools.FromToRotation(bone.solverRotation, rotation);
  64. if (weight < 1f) q = Quaternion.Slerp(Quaternion.identity, q, weight);
  65. for (int i = 0; i < bones.Length; i++) {
  66. if (bones[i] == bone) {
  67. VirtualBone.RotateAroundPoint(bones, i, bones[i].solverPosition, q);
  68. return;
  69. }
  70. }
  71. }
  72. public void Visualize(Color color) {
  73. for (int i = 0; i < bones.Length - 1; i++) {
  74. Debug.DrawLine(bones[i].solverPosition, bones[i + 1].solverPosition, color);
  75. }
  76. }
  77. public void Visualize() {
  78. Visualize(Color.white);
  79. }
  80. }
  81. }
  82. }