EditCurveKeySelection.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. //-----------------------------------------------------------------------------
  2. // EditCurveKeySelection.cs
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Runtime.Serialization;
  10. using System.Text;
  11. using Microsoft.Xna.Framework;
  12. namespace Xna.Tools
  13. {
  14. /// <summary>
  15. /// This class contains EditCurveKey selction information.
  16. /// </summary>
  17. [Serializable]
  18. public class EditCurveKeySelection : Dictionary<long, EditCurveSelections>,
  19. IEquatable<EditCurveKeySelection>
  20. {
  21. #region Constructors.
  22. /// <summary>
  23. /// Create new instance of EditCurveKeySelection from EditCurve.
  24. /// </summary>
  25. /// <param name="curve"></param>
  26. /// <returns>New instance of EditCurveKeySelection</returns>
  27. public EditCurveKeySelection(ICollection<EditCurveKey> keys) : this()
  28. {
  29. foreach (EditCurveKey key in keys)
  30. {
  31. if ( key.Selection != EditCurveSelections.None )
  32. Select(key.Id, key.Selection);
  33. }
  34. }
  35. public EditCurveKeySelection()
  36. : base()
  37. {
  38. }
  39. protected EditCurveKeySelection(SerializationInfo info,
  40. StreamingContext context): base(info, context)
  41. {
  42. }
  43. #endregion
  44. #region Equality override methods.
  45. public override bool Equals(object obj)
  46. {
  47. bool isSame = false;
  48. EditCurveKeySelection other = obj as EditCurveKeySelection;
  49. if (other != null)
  50. isSame = Equals(other);
  51. return isSame;
  52. }
  53. public override int GetHashCode()
  54. {
  55. int hashCode = 0;
  56. foreach (long key in Keys)
  57. hashCode += key.GetHashCode() + this[key].GetHashCode();
  58. return hashCode;
  59. }
  60. public bool Equals(EditCurveKeySelection other)
  61. {
  62. if (other == null) return false;
  63. if (this.Count != other.Count) return false;
  64. foreach (long key in Keys)
  65. {
  66. if (!other.ContainsKey(key)) return false;
  67. if (this[key] != other[key]) return false;
  68. }
  69. return true;
  70. }
  71. #endregion
  72. /// <summary>
  73. /// Add CurveKey to selection.
  74. /// </summary>
  75. /// <param name="id">EditCurveKey id</param>
  76. /// <param name="slectTypes">slection type</param>
  77. public void Select(long id, EditCurveSelections selectTypes)
  78. {
  79. // Update selectTypes if it already in selection, otherwise,
  80. // just add to selection.
  81. if (ContainsKey(id))
  82. this[id] = this[id] | selectTypes;
  83. else
  84. Add(id, selectTypes);
  85. }
  86. /// <summary>
  87. /// Create clone of a selection.
  88. /// </summary>
  89. /// <param name="selection"></param>
  90. /// <returns></returns>
  91. public EditCurveKeySelection Clone()
  92. {
  93. EditCurveKeySelection newSelection = new EditCurveKeySelection();
  94. foreach (long keyId in Keys)
  95. newSelection.Add(keyId, this[keyId]);
  96. return newSelection;
  97. }
  98. /// <summary>
  99. /// Compare given EditCueveKey collection and this selection.
  100. /// </summary>
  101. /// <returns>It returns true if seleciton are same,
  102. /// otherwise it returns false.</returns>
  103. public bool CompareSelection(ICollection<EditCurveKey> editCurveKeys)
  104. {
  105. if (this.Count != editCurveKeys.Count) return false;
  106. foreach ( EditCurveKey key in editCurveKeys )
  107. {
  108. if (!ContainsKey(key.Id)) return false;
  109. if (this[key.Id] != key.Selection) return false;
  110. }
  111. return true;
  112. }
  113. /// <summary>
  114. /// Select intersected EditCurveKey.
  115. /// </summary>
  116. /// <param name="editCurveKeys">Selection target EditCurveKeys.</param>
  117. /// <param name="selectRegion">Select region in unit coordinate.</param>
  118. /// <param name="singleSelect">It select only one EditCurveKey
  119. /// if this value is true.</param>
  120. /// <returns>It returns true if any EditCurveKey selected;
  121. /// otherwise it returns false.</returns>
  122. public bool SelectKeys(ICollection<EditCurveKey> editCurveKeys,
  123. BoundingBox selectRegion, bool singleSelect)
  124. {
  125. bool selected = false;
  126. foreach (EditCurveKey key in editCurveKeys)
  127. {
  128. Vector3 p =
  129. new Vector3(key.OriginalKey.Position, key.OriginalKey.Value, 0);
  130. if (selectRegion.Contains(p) != ContainmentType.Disjoint)
  131. {
  132. Select(key.Id, EditCurveSelections.Key);
  133. selected = true;
  134. if (singleSelect) break;
  135. }
  136. }
  137. return selected;
  138. }
  139. /// <summary>
  140. /// Select intersected tangents.
  141. /// </summary>
  142. /// <param name="editCurveKeys">Selection target EditCurveKeys.</param>
  143. /// <param name="selectRegion">Select region in unit coordinate.</param>
  144. /// <param name="tangentLength">Tangent length in unit coordinate.</param>
  145. /// <param name="singleSelect">It select only one EditCurveKey
  146. /// if this value is true.</param>
  147. /// <returns>It returns true if any EditCurveKey selected;
  148. /// otherwise it returns false.</returns>
  149. public bool SelectTangents(ICollection<EditCurveKey> editCurveKeys,
  150. BoundingBox selectRegion, Vector2 tangentScale, bool singleSelect)
  151. {
  152. bool selected = false;
  153. foreach (EditCurveKey key in editCurveKeys)
  154. {
  155. CurveKey orgKey = key.OriginalKey;
  156. // User can't select stepped continuity key tangents.
  157. if (orgKey.Continuity == CurveContinuity.Step) continue;
  158. Vector3 rayOrigin = new Vector3(orgKey.Position, orgKey.Value, 0);
  159. for (int i = 0; i < 2; ++i)
  160. {
  161. float tsx = tangentScale.X;
  162. float tsy = tangentScale.Y;
  163. Vector3 dir = (i == 0) ?
  164. new Vector3(-tsx, -orgKey.TangentIn * tsy, 0) :
  165. new Vector3(tsx, orgKey.TangentOut * tsy, 0);
  166. float length = dir.Length();
  167. dir.Normalize();
  168. Ray ray = new Ray(rayOrigin, dir);
  169. Nullable<float> result;
  170. selectRegion.Intersects(ref ray, out result);
  171. if (result.HasValue && result.Value < length)
  172. {
  173. Select( key.Id, (i==0)?
  174. EditCurveSelections.TangentIn:
  175. EditCurveSelections.TangentOut);
  176. selected = true;
  177. if (singleSelect) break;
  178. }
  179. }
  180. }
  181. return selected;
  182. }
  183. /// <summary>
  184. /// Create new selection that result of toggle selection given two selections.
  185. /// </summary>
  186. /// <param name="selection">Current selection</param>
  187. /// <param name="newSelection">New selection</param>
  188. /// <returns>Toggle selection result.</returns>
  189. public static EditCurveKeySelection ToggleSelection(
  190. EditCurveKeySelection selection, EditCurveKeySelection newSelection)
  191. {
  192. EditCurveKeySelection result = selection.Clone();
  193. foreach (long key in newSelection.Keys)
  194. {
  195. EditCurveSelections s;
  196. if (result.TryGetValue(key, out s))
  197. {
  198. // Both selection contains same key, toggle selections value.
  199. s = s ^ newSelection[key];
  200. if (s != EditCurveSelections.None)
  201. result[key] = s;
  202. else
  203. result.Remove(key);
  204. }
  205. else
  206. {
  207. result.Add(key, newSelection[key]);
  208. }
  209. }
  210. return result;
  211. }
  212. }
  213. }