Brak opisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CurveDataSource.cs 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. using UnityEngine.Timeline;
  6. namespace UnityEditor.Timeline
  7. {
  8. enum CurveChangeType
  9. {
  10. None,
  11. CurveModified,
  12. CurveAddedOrRemoved
  13. }
  14. abstract class CurveDataSource
  15. {
  16. public static CurveDataSource Create(IRowGUI trackGUI)
  17. {
  18. if (trackGUI.asset is AnimationTrack)
  19. return new InfiniteClipCurveDataSource(trackGUI);
  20. return new TrackParametersCurveDataSource(trackGUI);
  21. }
  22. public static CurveDataSource Create(TimelineClipGUI clipGUI)
  23. {
  24. if (clipGUI.clip.animationClip != null)
  25. return new ClipAnimationCurveDataSource(clipGUI);
  26. return new ClipParametersCurveDataSource(clipGUI);
  27. }
  28. int? m_ID = null;
  29. public int id
  30. {
  31. get
  32. {
  33. if (!m_ID.HasValue)
  34. m_ID = CreateHashCode();
  35. return m_ID.Value;
  36. }
  37. }
  38. readonly IRowGUI m_TrackGUI;
  39. protected CurveDataSource(IRowGUI trackGUI)
  40. {
  41. m_TrackGUI = trackGUI;
  42. }
  43. public abstract AnimationClip animationClip { get; }
  44. public abstract float start { get; }
  45. public abstract float timeScale { get; }
  46. public abstract string groupingName { get; }
  47. // Applies changes from the visual curve in the curve wrapper back to the animation clips
  48. public virtual void ApplyCurveChanges(IEnumerable<CurveWrapper> updatedCurves)
  49. {
  50. Undo.RegisterCompleteObjectUndo(animationClip, "Edit Clip Curve");
  51. foreach (CurveWrapper c in updatedCurves)
  52. {
  53. if (c.curve.length > 0)
  54. AnimationUtility.SetEditorCurve(animationClip, c.binding, c.curve);
  55. else
  56. RemoveCurves(new[] { c.binding });
  57. c.changed = false;
  58. }
  59. }
  60. /// <summary>The clip version is a value that will change when a curve gets updated.
  61. /// it's used to detect when an animation clip has been changed externally </summary>
  62. /// <returns>A versioning value indicating the state of the curve. If the curve is updated externally this value will change. </returns>
  63. public virtual UInt64 GetClipVersion()
  64. {
  65. return animationClip.ClipVersion();
  66. }
  67. /// <summary>Call this method to check if the underlying clip has changed</summary>
  68. /// <param name="curveVersion">A versioning value. This will be updated to the latest version</param>
  69. /// <returns>A value indicating how the clip has changed</returns>
  70. public virtual CurveChangeType UpdateExternalChanges(ref UInt64 curveVersion)
  71. {
  72. return animationClip.GetChangeType(ref curveVersion);
  73. }
  74. public virtual string ModifyPropertyDisplayName(string path, string propertyName) => propertyName;
  75. public virtual void RemoveCurves(IEnumerable<EditorCurveBinding> bindings)
  76. {
  77. Undo.RegisterCompleteObjectUndo(animationClip, "Remove Curve(s)");
  78. foreach (var binding in bindings)
  79. {
  80. if (binding.isPPtrCurve)
  81. AnimationUtility.SetObjectReferenceCurve(animationClip, binding, null);
  82. else
  83. AnimationUtility.SetEditorCurve(animationClip, binding, null);
  84. }
  85. }
  86. public Rect GetBackgroundRect(WindowState state)
  87. {
  88. var trackRect = m_TrackGUI.boundingRect;
  89. return new Rect(
  90. state.timeAreaTranslation.x + trackRect.xMin,
  91. trackRect.y,
  92. (float)state.editSequence.asset.duration * state.timeAreaScale.x,
  93. trackRect.height
  94. );
  95. }
  96. public List<CurveWrapper> GenerateWrappers(IEnumerable<EditorCurveBinding> bindings)
  97. {
  98. var wrappers = new List<CurveWrapper>(bindings.Count());
  99. int curveWrapperId = 0;
  100. foreach (EditorCurveBinding b in bindings)
  101. {
  102. // General configuration
  103. var wrapper = new CurveWrapper
  104. {
  105. id = curveWrapperId++,
  106. binding = b,
  107. groupId = -1,
  108. hidden = false,
  109. readOnly = false,
  110. getAxisUiScalarsCallback = () => new Vector2(1, 1)
  111. };
  112. // Specific configuration
  113. ConfigureCurveWrapper(wrapper);
  114. wrappers.Add(wrapper);
  115. }
  116. return wrappers;
  117. }
  118. protected virtual void ConfigureCurveWrapper(CurveWrapper wrapper)
  119. {
  120. wrapper.color = CurveUtility.GetPropertyColor(wrapper.binding.propertyName);
  121. wrapper.renderer = new NormalCurveRenderer(AnimationUtility.GetEditorCurve(animationClip, wrapper.binding));
  122. wrapper.renderer.SetCustomRange(0.0f, animationClip.length);
  123. }
  124. protected virtual int CreateHashCode()
  125. {
  126. return m_TrackGUI.asset.GetHashCode();
  127. }
  128. }
  129. class ClipAnimationCurveDataSource : CurveDataSource
  130. {
  131. static readonly string k_GroupingName = L10n.Tr("Animated Values");
  132. readonly TimelineClipGUI m_ClipGUI;
  133. public ClipAnimationCurveDataSource(TimelineClipGUI clipGUI) : base(clipGUI.parent)
  134. {
  135. m_ClipGUI = clipGUI;
  136. }
  137. public override AnimationClip animationClip
  138. {
  139. get { return m_ClipGUI.clip.animationClip; }
  140. }
  141. public override float start
  142. {
  143. get { return (float)m_ClipGUI.clip.FromLocalTimeUnbound(0.0); }
  144. }
  145. public override float timeScale
  146. {
  147. get { return (float)m_ClipGUI.clip.timeScale; }
  148. }
  149. public override string groupingName
  150. {
  151. get { return k_GroupingName; }
  152. }
  153. protected override int CreateHashCode()
  154. {
  155. return base.CreateHashCode().CombineHash(m_ClipGUI.clip.GetHashCode());
  156. }
  157. public override string ModifyPropertyDisplayName(string path, string propertyName)
  158. {
  159. if (!AnimatedPropertyUtility.IsMaterialProperty(propertyName))
  160. return propertyName;
  161. var track = m_ClipGUI.clip.GetParentTrack();
  162. if (track == null)
  163. return propertyName;
  164. var gameObjectBinding = TimelineUtility.GetSceneGameObject(TimelineEditor.inspectedDirector, track);
  165. if (gameObjectBinding == null)
  166. return propertyName;
  167. if (!string.IsNullOrEmpty(path))
  168. {
  169. var transform = gameObjectBinding.transform.Find(path);
  170. if (transform == null)
  171. return propertyName;
  172. gameObjectBinding = transform.gameObject;
  173. }
  174. return AnimatedPropertyUtility.RemapMaterialName(gameObjectBinding, propertyName);
  175. }
  176. }
  177. class ClipParametersCurveDataSource : CurveDataSource
  178. {
  179. static readonly string k_GroupingName = L10n.Tr("Clip Properties");
  180. readonly TimelineClipGUI m_ClipGUI;
  181. readonly CurvesProxy m_CurvesProxy;
  182. private int m_ClipDirtyVersion;
  183. public ClipParametersCurveDataSource(TimelineClipGUI clipGUI) : base(clipGUI.parent)
  184. {
  185. m_ClipGUI = clipGUI;
  186. m_CurvesProxy = new CurvesProxy(clipGUI.clip);
  187. }
  188. public override AnimationClip animationClip
  189. {
  190. get { return m_CurvesProxy.curves; }
  191. }
  192. public override UInt64 GetClipVersion()
  193. {
  194. return sourceAnimationClip.ClipVersion();
  195. }
  196. public override CurveChangeType UpdateExternalChanges(ref ulong curveVersion)
  197. {
  198. if (m_ClipGUI == null || m_ClipGUI.clip == null)
  199. return CurveChangeType.None;
  200. var changeType = sourceAnimationClip.GetChangeType(ref curveVersion);
  201. if (changeType != CurveChangeType.None)
  202. {
  203. m_CurvesProxy.ApplyExternalChangesToProxy();
  204. }
  205. else if (m_ClipDirtyVersion != m_ClipGUI.clip.DirtyIndex)
  206. {
  207. m_CurvesProxy.UpdateProxyCurves();
  208. if (changeType == CurveChangeType.None)
  209. changeType = CurveChangeType.CurveModified;
  210. }
  211. m_ClipDirtyVersion = m_ClipGUI.clip.DirtyIndex;
  212. return changeType;
  213. }
  214. public override float start
  215. {
  216. get { return (float)m_ClipGUI.clip.FromLocalTimeUnbound(0.0); }
  217. }
  218. public override float timeScale
  219. {
  220. get { return (float)m_ClipGUI.clip.timeScale; }
  221. }
  222. public override string groupingName
  223. {
  224. get { return k_GroupingName; }
  225. }
  226. public override void RemoveCurves(IEnumerable<EditorCurveBinding> bindings)
  227. {
  228. m_CurvesProxy.RemoveCurves(bindings);
  229. }
  230. public override void ApplyCurveChanges(IEnumerable<CurveWrapper> updatedCurves)
  231. {
  232. m_CurvesProxy.UpdateCurves(updatedCurves);
  233. }
  234. protected override void ConfigureCurveWrapper(CurveWrapper wrapper)
  235. {
  236. m_CurvesProxy.ConfigureCurveWrapper(wrapper);
  237. }
  238. protected override int CreateHashCode()
  239. {
  240. return base.CreateHashCode().CombineHash(m_ClipGUI.clip.GetHashCode());
  241. }
  242. private AnimationClip sourceAnimationClip
  243. {
  244. get
  245. {
  246. if (m_ClipGUI == null || m_ClipGUI.clip == null || m_ClipGUI.clip.curves == null)
  247. return null;
  248. return m_ClipGUI.clip.curves;
  249. }
  250. }
  251. }
  252. class InfiniteClipCurveDataSource : CurveDataSource
  253. {
  254. static readonly string k_GroupingName = L10n.Tr("Animated Values");
  255. readonly AnimationTrack m_AnimationTrack;
  256. public InfiniteClipCurveDataSource(IRowGUI trackGui) : base(trackGui)
  257. {
  258. m_AnimationTrack = trackGui.asset as AnimationTrack;
  259. }
  260. public override AnimationClip animationClip
  261. {
  262. get { return m_AnimationTrack.infiniteClip; }
  263. }
  264. public override float start
  265. {
  266. get { return 0.0f; }
  267. }
  268. public override float timeScale
  269. {
  270. get { return 1.0f; }
  271. }
  272. public override string groupingName
  273. {
  274. get { return k_GroupingName; }
  275. }
  276. public override string ModifyPropertyDisplayName(string path, string propertyName)
  277. {
  278. if (m_AnimationTrack == null || !AnimatedPropertyUtility.IsMaterialProperty(propertyName))
  279. return propertyName;
  280. var binding = m_AnimationTrack.GetBinding(TimelineEditor.inspectedDirector);
  281. if (binding == null)
  282. return propertyName;
  283. var target = binding.transform;
  284. if (!string.IsNullOrEmpty(path))
  285. target = target.Find(path);
  286. if (target == null)
  287. return propertyName;
  288. return AnimatedPropertyUtility.RemapMaterialName(target.gameObject, propertyName);
  289. }
  290. }
  291. class TrackParametersCurveDataSource : CurveDataSource
  292. {
  293. static readonly string k_GroupingName = L10n.Tr("Track Properties");
  294. readonly CurvesProxy m_CurvesProxy;
  295. private int m_TrackDirtyVersion;
  296. public TrackParametersCurveDataSource(IRowGUI trackGui) : base(trackGui)
  297. {
  298. m_CurvesProxy = new CurvesProxy(trackGui.asset);
  299. }
  300. public override AnimationClip animationClip
  301. {
  302. get { return m_CurvesProxy.curves; }
  303. }
  304. public override UInt64 GetClipVersion()
  305. {
  306. return sourceAnimationClip.ClipVersion();
  307. }
  308. public override CurveChangeType UpdateExternalChanges(ref ulong curveVersion)
  309. {
  310. if (m_CurvesProxy.targetTrack == null)
  311. return CurveChangeType.None;
  312. var changeType = sourceAnimationClip.GetChangeType(ref curveVersion);
  313. if (changeType != CurveChangeType.None)
  314. {
  315. m_CurvesProxy.ApplyExternalChangesToProxy();
  316. }
  317. // track property has changed externally, update the curve proxies
  318. else if (m_TrackDirtyVersion != m_CurvesProxy.targetTrack.DirtyIndex)
  319. {
  320. if (changeType == CurveChangeType.None)
  321. changeType = CurveChangeType.CurveModified;
  322. m_CurvesProxy.UpdateProxyCurves();
  323. }
  324. m_TrackDirtyVersion = m_CurvesProxy.targetTrack.DirtyIndex;
  325. return changeType;
  326. }
  327. public override float start
  328. {
  329. get { return 0.0f; }
  330. }
  331. public override float timeScale
  332. {
  333. get { return 1.0f; }
  334. }
  335. public override string groupingName
  336. {
  337. get { return k_GroupingName; }
  338. }
  339. public override void RemoveCurves(IEnumerable<EditorCurveBinding> bindings)
  340. {
  341. m_CurvesProxy.RemoveCurves(bindings);
  342. }
  343. public override void ApplyCurveChanges(IEnumerable<CurveWrapper> updatedCurves)
  344. {
  345. m_CurvesProxy.UpdateCurves(updatedCurves);
  346. }
  347. protected override void ConfigureCurveWrapper(CurveWrapper wrapper)
  348. {
  349. m_CurvesProxy.ConfigureCurveWrapper(wrapper);
  350. }
  351. private AnimationClip sourceAnimationClip
  352. {
  353. get
  354. {
  355. if (m_CurvesProxy.targetTrack == null || m_CurvesProxy.targetTrack.curves == null)
  356. return null;
  357. return m_CurvesProxy.targetTrack.curves;
  358. }
  359. }
  360. }
  361. }