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