WeightData.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. using UnityEngine;
  2. using UnityEngine.Assertions;
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. #if UNITY_EDITOR
  7. namespace VoxelImporter
  8. {
  9. [Serializable]
  10. public class WeightData : ISerializationCallbackReceiver
  11. {
  12. [Serializable, System.Diagnostics.DebuggerDisplay("Weight({weightXYZ}, {weight_XYZ}, {weightX_YZ}, {weightXY_Z}, {weight_X_YZ}, {weight_XY_Z}, {weightX_Y_Z}, {weight_X_Y_Z})")]
  13. public class VoxelWeight
  14. {
  15. public float weightXYZ;
  16. public float weight_XYZ;
  17. public float weightX_YZ;
  18. public float weightXY_Z;
  19. public float weight_X_YZ;
  20. public float weight_XY_Z;
  21. public float weightX_Y_Z;
  22. public float weight_X_Y_Z;
  23. public bool HasValue()
  24. {
  25. return weightXYZ != 0f || weight_XYZ != 0f || weightX_YZ != 0f || weightXY_Z != 0f || weight_X_YZ != 0f || weight_XY_Z != 0f || weightX_Y_Z != 0f || weight_X_Y_Z != 0f;
  26. }
  27. public void SetWeight(float weight)
  28. {
  29. weightXYZ = weight;
  30. weight_XYZ = weight;
  31. weightX_YZ = weight;
  32. weightXY_Z = weight;
  33. weight_X_YZ = weight;
  34. weight_XY_Z = weight;
  35. weightX_Y_Z = weight;
  36. weight_X_Y_Z = weight;
  37. }
  38. public void SetWeight(VoxelSkinnedAnimationObject.VoxelVertexIndex index, float weight)
  39. {
  40. switch (index)
  41. {
  42. case VoxelBase.VoxelVertexIndex.XYZ: weightXYZ = weight; break;
  43. case VoxelBase.VoxelVertexIndex._XYZ: weight_XYZ = weight; break;
  44. case VoxelBase.VoxelVertexIndex.X_YZ: weightX_YZ = weight; break;
  45. case VoxelBase.VoxelVertexIndex.XY_Z: weightXY_Z = weight; break;
  46. case VoxelBase.VoxelVertexIndex._X_YZ: weight_X_YZ = weight; break;
  47. case VoxelBase.VoxelVertexIndex._XY_Z: weight_XY_Z = weight; break;
  48. case VoxelBase.VoxelVertexIndex.X_Y_Z: weightX_Y_Z = weight; break;
  49. case VoxelBase.VoxelVertexIndex._X_Y_Z: weight_X_Y_Z = weight; break;
  50. default: Assert.IsTrue(false); break;
  51. }
  52. }
  53. public float GetWeight(VoxelSkinnedAnimationObject.VoxelVertexIndex index)
  54. {
  55. switch (index)
  56. {
  57. case VoxelBase.VoxelVertexIndex.XYZ: return weightXYZ;
  58. case VoxelBase.VoxelVertexIndex._XYZ: return weight_XYZ;
  59. case VoxelBase.VoxelVertexIndex.X_YZ: return weightX_YZ;
  60. case VoxelBase.VoxelVertexIndex.XY_Z: return weightXY_Z;
  61. case VoxelBase.VoxelVertexIndex._X_YZ: return weight_X_YZ;
  62. case VoxelBase.VoxelVertexIndex._XY_Z: return weight_XY_Z;
  63. case VoxelBase.VoxelVertexIndex.X_Y_Z: return weightX_Y_Z;
  64. case VoxelBase.VoxelVertexIndex._X_Y_Z: return weight_X_Y_Z;
  65. default: Assert.IsTrue(false); return 0f;
  66. }
  67. }
  68. }
  69. public void OnBeforeSerialize()
  70. {
  71. }
  72. public void OnAfterDeserialize()
  73. {
  74. #region repair
  75. if (weightKeys.Count < weightValues.Count)
  76. {
  77. weightValues.RemoveRange(weightKeys.Count, weightValues.Count - weightKeys.Count);
  78. }
  79. else if(weightKeys.Count > weightValues.Count)
  80. {
  81. weightKeys.RemoveRange(weightValues.Count, weightKeys.Count - weightValues.Count);
  82. }
  83. #endregion
  84. {
  85. IntVector3 max = IntVector3.zero;
  86. for (int i = 0; i < weightKeys.Count; i++)
  87. {
  88. max = IntVector3.Max(max, weightKeys[i]);
  89. }
  90. indexTable = new DataTable3<int>(max.x, max.y, max.z);
  91. }
  92. for (int i = 0; i < weightKeys.Count; i++)
  93. {
  94. if (indexTable.Contains(weightKeys[i]))
  95. {
  96. weightKeys.RemoveAt(i);
  97. weightValues.RemoveAt(i);
  98. i--;
  99. continue;
  100. }
  101. indexTable.Set(weightKeys[i], i);
  102. }
  103. }
  104. public void SetWeight(IntVector3 pos, VoxelWeight weight)
  105. {
  106. if(!indexTable.Contains(pos))
  107. {
  108. indexTable.Set(pos, weightKeys.Count);
  109. weightKeys.Add(pos);
  110. weightValues.Add(weight);
  111. }
  112. else
  113. {
  114. var index = indexTable.Get(pos);
  115. Assert.IsTrue(weightKeys[index] == pos);
  116. weightValues[index] = weight;
  117. }
  118. }
  119. public void RemoveWeight(IntVector3 pos)
  120. {
  121. if (indexTable.Contains(pos))
  122. {
  123. var index = indexTable.Get(pos);
  124. if(index < weightKeys.Count - 1)
  125. {
  126. weightKeys[index] = weightKeys[weightKeys.Count - 1];
  127. weightValues[index] = weightValues[weightValues.Count - 1];
  128. indexTable.Set(weightKeys[weightKeys.Count - 1], index);
  129. weightKeys.RemoveAt(weightKeys.Count - 1);
  130. weightValues.RemoveAt(weightValues.Count - 1);
  131. }
  132. else
  133. {
  134. weightKeys.RemoveAt(index);
  135. weightValues.RemoveAt(index);
  136. }
  137. indexTable.Remove(pos);
  138. }
  139. }
  140. public VoxelWeight GetWeight(IntVector3 pos)
  141. {
  142. if (!indexTable.Contains(pos)) return null;
  143. var index = indexTable.Get(pos);
  144. Assert.IsTrue(weightKeys[index] == pos);
  145. return weightValues[index];
  146. }
  147. public void ClearWeight()
  148. {
  149. indexTable.Clear();
  150. weightKeys.Clear();
  151. weightValues.Clear();
  152. }
  153. public void AllAction(Action<IntVector3, VoxelWeight> action)
  154. {
  155. for (int i = 0; i < weightKeys.Count; i++)
  156. {
  157. if (weightValues[i] != null)
  158. {
  159. action(weightKeys[i], weightValues[i]);
  160. }
  161. }
  162. }
  163. private DataTable3<int> indexTable = new DataTable3<int>();
  164. [SerializeField]
  165. private List<IntVector3> weightKeys = new List<IntVector3>();
  166. [SerializeField]
  167. private List<VoxelWeight> weightValues = new List<VoxelWeight>();
  168. }
  169. }
  170. #endif