Aucune description
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

QuaternionControl.cs 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. using UnityEngine.InputSystem.Layouts;
  2. using UnityEngine.InputSystem.LowLevel;
  3. using UnityEngine.InputSystem.Utilities;
  4. ////REVIEW: expose euler angle subcontrols?
  5. namespace UnityEngine.InputSystem.Controls
  6. {
  7. /// <summary>
  8. /// A generic input control reading quaternion (rotation) values.
  9. /// </summary>
  10. public class QuaternionControl : InputControl<Quaternion>
  11. {
  12. // Accessing these components as individual controls usually doesn't make too much sense,
  13. // but having these controls allows changing the state format on the quaternion without
  14. // requiring the control to explicitly support the various different storage formats.
  15. // Also, it allows putting processors on the individual components which may be necessary
  16. // to properly convert the source data.
  17. /// <summary>
  18. /// The X component of the quaternion.
  19. /// </summary>
  20. /// <value>Control representing the X component.</value>
  21. [InputControl(displayName = "X")]
  22. public AxisControl x { get; set; }
  23. /// <summary>
  24. /// The Y component of the quaternion.
  25. /// </summary>
  26. /// <value>Control representing the Y component.</value>
  27. [InputControl(displayName = "Y")]
  28. public AxisControl y { get; set; }
  29. /// <summary>
  30. /// The Z component of the quaternion.
  31. /// </summary>
  32. /// <value>Control representing the Z component.</value>
  33. [InputControl(displayName = "Z")]
  34. public AxisControl z { get; set; }
  35. /// <summary>
  36. /// The W component of the quaternion.
  37. /// </summary>
  38. /// <value>Control representing the W component.</value>
  39. [InputControl(displayName = "W")]
  40. public AxisControl w { get; set; }
  41. /// <summary>
  42. /// Default-initialize the control.
  43. /// </summary>
  44. public QuaternionControl()
  45. {
  46. m_StateBlock.sizeInBits = sizeof(float) * 4 * 8;
  47. m_StateBlock.format = InputStateBlock.FormatQuaternion;
  48. }
  49. /// <inheritdoc/>
  50. protected override void FinishSetup()
  51. {
  52. x = GetChildControl<AxisControl>("x");
  53. y = GetChildControl<AxisControl>("y");
  54. z = GetChildControl<AxisControl>("z");
  55. w = GetChildControl<AxisControl>("w");
  56. base.FinishSetup();
  57. }
  58. /// <inheritdoc/>
  59. public override unsafe Quaternion ReadUnprocessedValueFromState(void* statePtr)
  60. {
  61. switch (m_OptimizedControlDataType)
  62. {
  63. case InputStateBlock.kFormatQuaternion:
  64. return *(Quaternion*)((byte*)statePtr + (int)m_StateBlock.byteOffset);
  65. default:
  66. return new Quaternion(
  67. x.ReadValueFromStateWithCaching(statePtr),
  68. y.ReadValueFromStateWithCaching(statePtr),
  69. z.ReadValueFromStateWithCaching(statePtr),
  70. w.ReadUnprocessedValueFromStateWithCaching(statePtr));
  71. }
  72. }
  73. /// <inheritdoc/>
  74. public override unsafe void WriteValueIntoState(Quaternion value, void* statePtr)
  75. {
  76. switch (m_OptimizedControlDataType)
  77. {
  78. case InputStateBlock.kFormatQuaternion:
  79. *(Quaternion*)((byte*)statePtr + (int)m_StateBlock.byteOffset) = value;
  80. break;
  81. default:
  82. x.WriteValueIntoState(value.x, statePtr);
  83. y.WriteValueIntoState(value.y, statePtr);
  84. z.WriteValueIntoState(value.z, statePtr);
  85. w.WriteValueIntoState(value.w, statePtr);
  86. break;
  87. }
  88. }
  89. protected override FourCC CalculateOptimizedControlDataType()
  90. {
  91. if (
  92. m_StateBlock.sizeInBits == sizeof(float) * 4 * 8 &&
  93. m_StateBlock.bitOffset == 0 &&
  94. x.optimizedControlDataType == InputStateBlock.FormatFloat &&
  95. y.optimizedControlDataType == InputStateBlock.FormatFloat &&
  96. z.optimizedControlDataType == InputStateBlock.FormatFloat &&
  97. w.optimizedControlDataType == InputStateBlock.FormatFloat &&
  98. y.m_StateBlock.byteOffset == x.m_StateBlock.byteOffset + 4 &&
  99. z.m_StateBlock.byteOffset == x.m_StateBlock.byteOffset + 8 &&
  100. w.m_StateBlock.byteOffset == x.m_StateBlock.byteOffset + 12 &&
  101. // For some unknown reason ReadUnprocessedValueFromState here uses ReadValueFromState on x/y/z (but not w)
  102. // which means we can't optimize if there any processors on x/y/z
  103. x.m_ProcessorStack.length == 0 &&
  104. y.m_ProcessorStack.length == 0 &&
  105. z.m_ProcessorStack.length == 0
  106. )
  107. return InputStateBlock.FormatQuaternion;
  108. return InputStateBlock.FormatInvalid;
  109. }
  110. }
  111. }