SequenceGroupData.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // SequenceGroupData.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Diagnostics;
  13. using System.Text;
  14. using Microsoft.Xna.Framework;
  15. using Microsoft.Xna.Framework.Content;
  16. using Microsoft.Xna.Framework.Graphics;
  17. #endregion
  18. namespace SceneDataLibrary
  19. {
  20. /// <summary>
  21. /// This class manages the list of pattern groups displayed in a sequence.
  22. /// In Layout, sequence groups correspond to these pattern groups.
  23. /// The Update function sets the time forward and calculates coordinates
  24. /// or color values, and the calculation results are temporarily stored
  25. /// in pattern objects.
  26. /// These results can be used to display other display items by
  27. /// synchronizing them with sequence animations.
  28. /// However, attention is required when creating scenes by Layout, because
  29. /// it is not assumed that the same pattern object data is referred to
  30. /// in the same game scene.
  31. ///
  32. /// シーケンスで表示するパターングループのリストを保持します。
  33. /// Layoutではシーケンスグループに相当します。
  34. /// Update関数で、時刻を進め、座標や色情報の再計算を行います。
  35. /// 計算結果はパターンオブジェクトデータに一時保存されますので、
  36. /// その結果を用いて、他の表示物をシーケンスアニメーションに
  37. /// 同期させて表示させることも可能です。
  38. /// ただし、同じゲームシーン内で同じパターンオブジェクトデータが
  39. /// 参照される状況は想定していないため、
  40. /// Layoutでシーン作成する際は注意が必要です。
  41. /// </summary>
  42. public class SequenceGroupData
  43. {
  44. #region Public Types
  45. //Animation interpolation type
  46. //
  47. //アニメーション補間タイプ
  48. public enum Interpolation
  49. {
  50. None = 0,//No interpolation //補間無し
  51. Linear,//Linear interpolation //線形補間
  52. Spline,//Spline interpolation //スプライン補間
  53. }
  54. public enum PlayStatus
  55. {
  56. Playing = 0,//Playing //再生中
  57. Stop,//Stopped //停止中
  58. LoopEnd,//In loop //ループ中
  59. }
  60. #endregion
  61. #region Fields
  62. private int startFrame = 0;//Start frame for animation movement
  63. private int loopNumber = 0;//Maximum loop count
  64. private TimeSpan timeFrame = new TimeSpan(0, 0, 0);//Current frame
  65. private PlayStatus playStatus = PlayStatus.Stop;//Play status
  66. private long framePerSecond = 60;//The number of frames per second
  67. private int loopCount = 0;//Current loop count
  68. private int drawObjectId = -1;//Base object (Object to be drawn)
  69. private Interpolation interpolationType = Interpolation.None;
  70. private int splineParamT = 0;//Spline curve parameter T
  71. private int splineParamC = 0;//Spline curve parameter C
  72. private int splineParamB = 0;//Spline curve parameter B
  73. private float[] tcbParam = new float[4];//Spline calculation parameter
  74. //List of sequence objects
  75. private List<SequenceObjectData> objectList = new List<SequenceObjectData>();
  76. #endregion
  77. #region Property
  78. /// <summary>
  79. /// Obtains and sets the start frame for animation movement.
  80. ///
  81. /// アニメーション動作の開始フレームを設定取得します。
  82. /// </summary>
  83. public int StartFrame
  84. {
  85. get
  86. {
  87. return startFrame;
  88. }
  89. set
  90. {
  91. startFrame = value;
  92. }
  93. }
  94. /// <summary>
  95. /// Obtains and sets the maximum loop count.
  96. ///
  97. /// ループ数を設定取得します。
  98. /// </summary>
  99. public int LoopNumber
  100. {
  101. get
  102. {
  103. return loopNumber;
  104. }
  105. set
  106. {
  107. loopNumber = value;
  108. }
  109. }
  110. /// <summary>
  111. /// Obtains and sets the animation interpolation type.
  112. /// </summary>
  113. public Interpolation InterpolationType
  114. {
  115. get
  116. {
  117. return interpolationType;
  118. }
  119. set
  120. {
  121. interpolationType = value;
  122. }
  123. }
  124. /// <summary>
  125. /// Obtains and sets the spline curve parameter T.
  126. ///
  127. /// スプライン補間用のパラメータを設定取得します。
  128. /// </summary>
  129. public int SplineParamT
  130. {
  131. get
  132. {
  133. return splineParamT;
  134. }
  135. set
  136. {
  137. splineParamT = value;
  138. }
  139. }
  140. /// <summary>
  141. /// Obtains and sets the spline curve parameter C.
  142. ///
  143. /// スプライン補間用のパラメータを設定取得します。
  144. /// </summary>
  145. public int SplineParamC
  146. {
  147. get
  148. {
  149. return splineParamC;
  150. }
  151. set
  152. {
  153. splineParamC = value;
  154. }
  155. }
  156. /// <summary>
  157. /// Obtains and sets the spline curve parameter B.
  158. ///
  159. /// スプライン補間用のパラメータを設定取得します。
  160. /// </summary>
  161. public int SplineParamB
  162. {
  163. get
  164. {
  165. return splineParamB;
  166. }
  167. set
  168. {
  169. splineParamB = value;
  170. }
  171. }
  172. /// <summary>
  173. /// Obtains the list of sequence objects.
  174. ///
  175. /// スプライン補間用のパラメータを設定取得します。
  176. /// </summary>
  177. public List<SequenceObjectData> SequenceObjectList
  178. {
  179. get { return objectList; }
  180. }
  181. /// <summary>
  182. /// If the sequence is stopped, returns true.
  183. ///
  184. /// シーケンスが停止中ならtrue
  185. /// </summary>
  186. public bool IsStop
  187. {
  188. get
  189. {
  190. return (PlayStatus.Stop == playStatus);
  191. }
  192. }
  193. /// <summary>
  194. /// If the sequence is in a loop, returns true.
  195. ///
  196. /// シーケンスがループ中ならtrue
  197. /// </summary>
  198. public bool IsLoopEnd
  199. {
  200. get
  201. {
  202. return (PlayStatus.LoopEnd == playStatus);
  203. }
  204. }
  205. #endregion
  206. /// <summary>
  207. /// Performs initialization.
  208. /// Converts TCB curve information to runtime format.
  209. ///
  210. /// 初期化します。
  211. /// TCB曲線の情報を実行時の形式に変換します。
  212. /// </summary>
  213. public void Init()
  214. {
  215. //Calculates the parameters for spline interpolation.
  216. //
  217. //スプライン補間用のパラメータの計算
  218. tcbParam[0] = (1.0f - SplineParamT) * (1.0f + SplineParamC) *
  219. (1.0f + SplineParamB);
  220. tcbParam[1] = (1.0f - SplineParamT) * (1.0f - SplineParamC) *
  221. (1.0f - SplineParamB);
  222. tcbParam[2] = (1.0f - SplineParamT) * (1.0f - SplineParamC) *
  223. (1.0f + SplineParamB);
  224. tcbParam[3] = (1.0f - SplineParamT) * (1.0f + SplineParamC) *
  225. (1.0f - SplineParamB);
  226. }
  227. /// <summary>
  228. /// Sets the animation time forward.
  229. /// Updates the current time by adding the difference between
  230. /// the current time and the forwarded time.
  231. /// If the updated time exceeds the play time of the entire animation,
  232. /// consider whether to perform loop processes and determine the frames
  233. /// corrected if necessary.
  234. ///
  235. /// アニメーションの時間を進めます。
  236. /// 現在の時刻にすすめる時間を加算して、現在の時刻を更新します。
  237. /// アニメーション全体の長さより現在の時刻が上回った場合は
  238. /// ループの有無などを検討し、必要であれば補正したフレームを割り出します。
  239. /// </summary>
  240. /// <param name="fPlayFrames">
  241. /// Current time
  242. ///
  243. /// 現在の時間
  244. /// </param>
  245. /// <param name="ElapsedGameTime">
  246. /// Time to be forwarded
  247. ///
  248. /// 進める時間
  249. /// </param>
  250. /// <param name="bReverse">
  251. /// Specifies true in case of reverse play
  252. ///
  253. /// 逆再生の場合true
  254. /// </param>
  255. /// <returns>
  256. /// Returns the time specified in the sequence object to be displayed
  257. ///
  258. /// 表示するシーケンスオブジェクトに設定された時間を返します
  259. /// </returns>
  260. public float Update(float playFrames, TimeSpan elapsedGameTime, bool reverse)
  261. {
  262. //Updates the time.
  263. //
  264. //時間の更新
  265. if (reverse)
  266. timeFrame += elapsedGameTime;
  267. else
  268. timeFrame += elapsedGameTime;
  269. if (TimeSpan.Zero > timeFrame)
  270. timeFrame = TimeSpan.Zero;
  271. //Clears the play status.
  272. //
  273. //再生状態のクリア
  274. playStatus = PlayStatus.Playing;
  275. BEGIN_UPDATE:
  276. //Calculates the length of the entire sequence.
  277. //
  278. //シーケンス全体の長さを計算します。
  279. int total = StartFrame;
  280. int length = StartFrame;
  281. foreach (SequenceObjectData sequenceObject in objectList)
  282. {
  283. length += sequenceObject.Frame;
  284. }
  285. //Checks whether the process proceeds to the end of the sequence.
  286. //
  287. //シーケンスの末端まで進んだかどうか確認します。
  288. if (timeFrame.Ticks * framePerSecond / TimeSpan.TicksPerSecond >= length)
  289. {
  290. //When the process proceeds to the end of the sequence.
  291. //
  292. //末端まで進んでいる場合。
  293. playStatus = PlayStatus.LoopEnd;
  294. //If the maximum loop count is less than 0,
  295. // there is no limitation on the loop count.
  296. //
  297. //ループ規定数が負の場合、無限にループします。
  298. if (0 > LoopNumber)
  299. {
  300. //Sets the status of after-loop.
  301. //
  302. //ループした後の状態について設定します。
  303. if (1 < objectList.Count)
  304. {
  305. timeFrame = new TimeSpan(
  306. (
  307. (timeFrame.Ticks * framePerSecond / TimeSpan.TicksPerSecond)
  308. % length
  309. )
  310. * TimeSpan.TicksPerSecond / framePerSecond);
  311. //Performs recalculation based on the corrected frame.
  312. //
  313. //補正されたフレームを元に再計算する
  314. goto BEGIN_UPDATE;
  315. }
  316. else
  317. {
  318. drawObjectId = 0;
  319. playStatus = PlayStatus.Stop;
  320. playFrames = 0.0f;
  321. }
  322. }
  323. else
  324. {
  325. //Updates the current loop count. //ループした回数を更新します。
  326. loopCount += (int)(
  327. (timeFrame.Ticks * framePerSecond / TimeSpan.TicksPerSecond)
  328. / length);
  329. //Updates the time.
  330. //
  331. //時間の更新
  332. timeFrame -= new TimeSpan(
  333. (
  334. (timeFrame.Ticks * framePerSecond / TimeSpan.TicksPerSecond)
  335. % length)
  336. * TimeSpan.TicksPerSecond / framePerSecond);
  337. if (loopCount < LoopNumber)
  338. {
  339. //Performs recalculation based on the corrected frame.
  340. //
  341. //補正されたフレームを元に再計算する
  342. goto BEGIN_UPDATE;
  343. }
  344. playStatus = PlayStatus.Stop;
  345. }
  346. }
  347. else if (reverse && TimeSpan.Zero == timeFrame)
  348. {
  349. //In reverse play, stops playing when the frame becomes 0.
  350. //
  351. //逆再生で、フレームが0になった場合停止します。
  352. drawObjectId = 0;
  353. playStatus = PlayStatus.Stop;
  354. playFrames = 0.0f;
  355. }
  356. else if (timeFrame.Ticks * framePerSecond / TimeSpan.TicksPerSecond
  357. >= StartFrame)
  358. {
  359. //When the process does not proceed to the end of animation, and
  360. //the frame is not yet 0 in reverse play.
  361. //(In other words, when in normal interpolation display operation.)
  362. //Other than these conditions,
  363. //
  364. //アニメーション末端まで進んでいない場合かつ
  365. //逆再生でフレーム0に至っていない場合。
  366. //つまり、通常の補間表示の場合。
  367. //これ以外の場合でも、
  368. drawObjectId = -1;
  369. int i = 0;
  370. //searches sequence objects to be displayed.
  371. //
  372. //表示対象にするシーケンスオブジェクトを検索します。
  373. foreach (SequenceObjectData data in objectList)
  374. {
  375. total += data.Frame;
  376. if (timeFrame.Ticks * framePerSecond / TimeSpan.TicksPerSecond
  377. < total)
  378. {
  379. //The object to be displayed is found.
  380. //
  381. //表示するオブジェクトを発見
  382. drawObjectId = i;
  383. break;
  384. }
  385. i++;
  386. }
  387. //When the object to be displayed is found.
  388. //
  389. //表示するオブジェクトが見つかった場合
  390. if (0 <= drawObjectId)
  391. {
  392. //Calculates the time in the sequence object to be displayed.
  393. //
  394. //表示するシーケンスオブジェクト内での時間を計算します。
  395. if (0 == objectList[drawObjectId].Frame)
  396. {
  397. playFrames = 0.0f;
  398. }
  399. else
  400. {
  401. playFrames = (
  402. (float)timeFrame.Ticks * (float)framePerSecond /
  403. (float)TimeSpan.TicksPerSecond -
  404. (float)(total - objectList[drawObjectId].Frame))
  405. / (float)objectList[drawObjectId].Frame;
  406. }
  407. }
  408. }
  409. else
  410. {
  411. //Displays nothing.
  412. //
  413. //何も表示しない
  414. drawObjectId = -1;
  415. }
  416. // Once the frame has been set up, performs interpolation
  417. // for conversion information.
  418. //
  419. //フレームが確定したので、変換情報の補間処理を行います。
  420. updateSeq(playFrames);
  421. return playFrames;
  422. }
  423. /// <summary>
  424. /// Performs interpolation based on the provided display frame.
  425. /// Begins by determining the sequence objects to be displayed.
  426. /// Then, if the interpolation type is Linear or Spline, performs
  427. /// conversion interpolation by using the information of neighboring
  428. /// sequence objects as needed.
  429. ///
  430. /// 与えられた表示フレームを元に補間処理を行います。
  431. /// まず、表示すべきシーケンスオブジェクトを求め、
  432. /// 補間タイプが線形、スプラインの場合は、
  433. /// 必要に応じて近隣のシーケンスオブジェクトの情報を用いて
  434. /// 変換の補間を行います。
  435. /// </summary>
  436. /// <param name="fPlayFrames">
  437. /// Time in the current sequence object to be displayed
  438. ///
  439. /// 現在表示すべきシーケンスオブジェクト内での時間
  440. /// </param>
  441. private void updateSeq(float playFrame)
  442. {
  443. //The following objects are needed for interpolation (at a maximum):
  444. //- Base object ...baseObject
  445. //- Previous object (Object before the Base object) ...prevObject
  446. //- Target object (Object after the Base object) ...targetObject
  447. //- Next object (Object after the Target object) ...nextObject
  448. //
  449. //補間に必要なのは、最大で
  450. //・着目オブジェクト...baseObject
  451. //・着目オブジェクトの前のオブジェクト...prevObject
  452. //・着目オブジェクトの次のオブジェクト...targetObject
  453. //・着目オブジェクトの次の次のオブジェクト...nextObject
  454. //になります。
  455. SequenceObjectData prevObject, baseObject, targetObject, nextObject;
  456. //If there is no object to be displayed, returns.
  457. //
  458. //表示するオブジェクトが無いなら戻ります。
  459. if (0 > drawObjectId)
  460. return;
  461. //Sets the objects used for interpolation.
  462. //
  463. //補間のために使用するするオブジェクトを設定します。
  464. //Clears the objects used for interpolation.
  465. //
  466. //補間用のオブジェクトのクリア
  467. nextObject = targetObject = prevObject = baseObject
  468. = objectList[drawObjectId];
  469. //Obtains the Previous object.
  470. //
  471. //直前のオブジェクトの取得
  472. if (0 < drawObjectId)
  473. {
  474. prevObject = objectList[drawObjectId - 1];
  475. }
  476. else if (0 != loopCount)
  477. {
  478. //Otherwise, uses the last object when performing the loop process.
  479. //
  480. //そうでない場合、ループするなら最後のオブジェクトを用いる
  481. prevObject = objectList[objectList.Count - 1];
  482. }
  483. //Obtains the Target object (and sets the Next object in advance).
  484. //
  485. //次のオブジェクトの取得("次の次"もあらかじめ設定)
  486. if (drawObjectId < objectList.Count - 1)
  487. {
  488. //When the Base object is not the last object.
  489. //
  490. //着目オブジェクトがが最後のオブジェクトではない。
  491. nextObject = targetObject = objectList[drawObjectId + 1];
  492. }
  493. else
  494. {
  495. //Sets the first object when performing the loop process.
  496. //
  497. //ループするなら、最初のオブジェクトに設定
  498. if (loopCount < LoopNumber)
  499. {
  500. nextObject = targetObject = objectList[0];
  501. }
  502. }
  503. //Obtains the Next object.
  504. //
  505. //次の次のオブジェクトの取得
  506. if (drawObjectId < objectList.Count - 2)
  507. {
  508. //When the current index + 2 is valid.
  509. //
  510. //2つ先のIndexが有効
  511. nextObject = objectList[drawObjectId + 2];
  512. }
  513. else
  514. {
  515. //Loop process
  516. //
  517. //ループする
  518. if (loopCount < LoopNumber)
  519. {
  520. //When the Next object is the first object.
  521. //
  522. //次の次は最初のオブジェクト。
  523. if (drawObjectId == objectList.Count - 2)
  524. {
  525. nextObject = objectList[0];
  526. }
  527. else
  528. {
  529. //When there are 2 or more objects in total (Index 1 is valid).
  530. //
  531. //全体のオブジェクト数が2つ以上(Index1が有効)
  532. if (1 < objectList.Count)
  533. nextObject = objectList[1];
  534. else
  535. nextObject = objectList[0];
  536. }
  537. }
  538. }
  539. //For each pattern object in the sequence object to be displayed,
  540. //records the interpolated conversion information.
  541. //
  542. //表示するシーケンスオブジェクト内のパターンオブジェクトそれぞれについて
  543. //補間した変換情報を記録していきます。
  544. for (int i = 0; i < baseObject.PatternObjectList.Count; i++)
  545. {
  546. PatternObjectData prevPattern, basePattern;
  547. PatternObjectData targetPattern, nextPattern;
  548. //Sets the interpolation target pattern.
  549. //
  550. //補間対象のパターンを設定します。
  551. prevPattern = basePattern = targetPattern =
  552. nextPattern = baseObject.PatternObjectList[i];
  553. if (targetObject.PatternObjectList.Count > i)
  554. targetPattern = targetObject.PatternObjectList[i];
  555. if (prevObject.PatternObjectList.Count > i)
  556. prevPattern = prevObject.PatternObjectList[i];
  557. if (nextObject.PatternObjectList.Count > i)
  558. nextPattern = nextObject.PatternObjectList[i];
  559. //Calculates conversion values after interpolation.
  560. //
  561. //補間後の変換情報を計算します。
  562. DrawData data = new DrawData();
  563. switch (InterpolationType)
  564. {
  565. case Interpolation.None:
  566. data = basePattern.Data;
  567. break;
  568. case Interpolation.Linear:
  569. PutInfoLinearInterporlation(playFrame, data,
  570. basePattern.Data, targetPattern.Data);
  571. break;
  572. case Interpolation.Spline:
  573. PutInfoTCBSplineInterporlation(playFrame, data,
  574. prevPattern.Data, basePattern.Data,
  575. targetPattern.Data, nextPattern.Data);
  576. break;
  577. }
  578. //Records the data to the pattern object.
  579. //The data recorded here can be used as position information for
  580. //animated patterns.
  581. //
  582. //パターンオブジェクトに記録します。
  583. //ここで記録された情報は、アニメーションされたパターンの
  584. //配置情報として利用することが可能です。
  585. baseObject.PatternObjectList[i].InterpolationDrawData = data;
  586. }
  587. }
  588. /// <summary>
  589. /// Draws the objects by using the conversion information modified
  590. /// by the Update function. The conversion information can be also applied
  591. /// to the entire sequence (as offset).
  592. ///
  593. /// Update関数で更新された変換情報を利用しながら描画します。
  594. /// シーケンス全体に変換を(オフセットとして)適用することも出来ます。
  595. /// </summary>
  596. /// <param name="sb">
  597. /// SpriteBatch
  598. ///
  599. /// スプラインバッチ
  600. /// </param>
  601. /// <param name="fPlayFrames">
  602. /// Frame to be displayed
  603. ///
  604. /// 表示するフレーム
  605. /// </param>
  606. /// <param name="infoPut">
  607. /// Conversion information that affects the entire drawing target
  608. ///
  609. /// 描画対象全体に影響する変換情報
  610. /// </param>
  611. public void Draw(SpriteBatch sb, DrawData baseDrawData)
  612. {
  613. if (0 > drawObjectId)
  614. {
  615. return;
  616. }
  617. //Obtains the current Base object.
  618. //
  619. //現在着目しているシーケンスオブジェクトを取得
  620. SequenceObjectData baseObj = objectList[drawObjectId];
  621. //Referred to by the sequence object.
  622. //
  623. //シーケンスオブジェクトが参照する
  624. for (int i = 0; i < baseObj.PatternObjectList.Count; i++)
  625. {
  626. DrawData sqInfo =
  627. baseObj.PatternObjectList[i].InterpolationDrawData;
  628. baseObj.PatternObjectList[i].Draw(sb, sqInfo, baseDrawData);
  629. }
  630. }
  631. /// <summary>
  632. /// Performs simple linear interpolation.
  633. ///
  634. /// 単純な線形補間をします。
  635. /// </summary>
  636. /// <param name="rate">
  637. /// If the interpolation rate is 1.0, the value will be that of "target".
  638. ///
  639. /// 補間割合1.0ならtargetの値になります。
  640. /// </param>
  641. /// <param name="fTarget">
  642. /// Target value
  643. ///
  644. /// 目的値
  645. /// </param>
  646. /// <param name="fBase">
  647. /// Initial value
  648. ///
  649. /// 初期値
  650. /// </param>
  651. /// <returns>
  652. /// Interpolation results
  653. ///
  654. /// 補間結果
  655. /// </returns>
  656. private static float LinearInterporlation(float rate, float targetValue,
  657. float baseValue)
  658. {
  659. return (targetValue * rate + baseValue * (1f - rate));
  660. }
  661. /// <summary>
  662. /// Performs linear interpolation for the conversion information
  663. /// (position, rotation, scale, center point, and color).
  664. ///
  665. /// 変換情報(位置・回転・スケール・中心点・色)を線形補間します。
  666. /// </summary>
  667. /// <param name="rate">
  668. /// Interpolation rate
  669. ///
  670. /// 補間割合
  671. /// </param>
  672. /// <param name="resultInfo">
  673. /// Calculation results will be stored.
  674. ///
  675. /// 計算結果が入ります。
  676. /// </param>
  677. /// <param name="BaseInfo">
  678. /// Initial value
  679. ///
  680. /// 初期値
  681. /// </param>
  682. /// <param name="targetInfo">
  683. /// Target value
  684. ///
  685. /// 目的値
  686. /// </param>
  687. private static void PutInfoLinearInterporlation(float rate, DrawData resultData,
  688. DrawData baseData, DrawData targetData)
  689. {
  690. resultData.Position = new Point(
  691. (int)LinearInterporlation(rate, targetData.Position.X,
  692. baseData.Position.X),
  693. (int)LinearInterporlation(rate, targetData.Position.Y,
  694. baseData.Position.Y)
  695. );
  696. resultData.Color = new Color(
  697. (byte)LinearInterporlation(rate, targetData.Color.R,
  698. baseData.Color.R),
  699. (byte)LinearInterporlation(rate, targetData.Color.G,
  700. baseData.Color.G),
  701. (byte)LinearInterporlation(rate, targetData.Color.B,
  702. baseData.Color.B),
  703. (byte)LinearInterporlation(rate, targetData.Color.A,
  704. baseData.Color.A)
  705. );
  706. resultData.Scale = new Vector2(
  707. LinearInterporlation(rate, targetData.Scale.X, baseData.Scale.X),
  708. LinearInterporlation(rate, targetData.Scale.Y, baseData.Scale.Y));
  709. resultData.Center = new Point(
  710. (int)LinearInterporlation(rate, targetData.Center.X,
  711. baseData.Center.X),
  712. (int)LinearInterporlation(rate, targetData.Center.Y,
  713. baseData.Center.Y));
  714. resultData.RotateZ = LinearInterporlation(rate, targetData.RotateZ,
  715. baseData.RotateZ);
  716. }
  717. /// <summary>
  718. /// Performs spline interpolation by using TCB curve.
  719. ///
  720. /// TCB曲線を用いたスプライン補間を行います。
  721. /// </summary>
  722. /// <param name="rate">
  723. /// Interpolation rate
  724. ///
  725. /// 補間割合
  726. /// </param>
  727. /// <param name="prevValue">
  728. /// Previous value of the initial value
  729. ///
  730. /// 初期値の前の値
  731. /// </param>
  732. /// <param name="baseValue">
  733. /// Initial value
  734. ///
  735. /// 初期値
  736. /// </param>
  737. /// <param name="targetValue">
  738. /// Target value
  739. ///
  740. /// 目標値
  741. /// </param>
  742. /// <param name="nextValue">
  743. /// Next value of the target value
  744. ///
  745. /// 目標値の次の値
  746. /// </param>
  747. /// <returns>
  748. /// Calculation results
  749. ///
  750. /// 計算結果
  751. /// </returns>
  752. private float CalcSpline(float rate, float prevValue,
  753. float baseValue, float targetValue, float nextValue)
  754. {
  755. float fRate = rate * rate,
  756. fRate2 = fRate * rate;
  757. float fQ0 = tcbParam[0] * (baseValue - prevValue) + tcbParam[1] *
  758. (targetValue - baseValue);
  759. float fQ1 = tcbParam[2] * (targetValue - baseValue) + tcbParam[3] *
  760. (nextValue - targetValue);
  761. return ((2.0f * baseValue - 2.0f * targetValue + fQ0 + fQ1) * fRate2 +
  762. (-3.0f * baseValue + 3.0f * targetValue - 2.0f * fQ0 - fQ1) *
  763. fRate + fQ0 * rate + baseValue);
  764. }
  765. /// <summary>
  766. /// Performs interpolation for the conversion information (position, rotation,
  767. /// scale, center position, color) by using TCB curve.
  768. ///
  769. /// TCB曲線を用いた変換情報(位置・回転・スケール・中心点・色)の補間を行います。
  770. /// </summary>
  771. /// <param name="rate">
  772. /// Interpolation rate
  773. ///
  774. /// 補間割合
  775. /// </param>
  776. /// <param name="resultInfo">
  777. /// Calculation results
  778. ///
  779. /// 計算結果
  780. /// </param>
  781. /// <param name="prevInfo">
  782. /// Previous value of the initial value
  783. ///
  784. /// 初期値の前の値
  785. /// </param>
  786. /// <param name="baseInfo">
  787. /// Initial value
  788. ///
  789. /// 初期値
  790. /// </param>
  791. /// <param name="targetInfo">
  792. /// Target value
  793. ///
  794. /// 目標値
  795. /// </param>
  796. /// <param name="nextInfo">
  797. /// Next value of the target value
  798. ///
  799. /// 目標値の次の値
  800. /// </param>
  801. private void PutInfoTCBSplineInterporlation(float rate,
  802. DrawData resultData, DrawData prevData,
  803. DrawData baseData, DrawData targetData, DrawData nextData)
  804. {
  805. resultData.Position = new Point(
  806. (int)CalcSpline(rate, prevData.Position.X, baseData.Position.X,
  807. targetData.Position.X, nextData.Position.X),
  808. (int)CalcSpline(rate, prevData.Position.Y, baseData.Position.Y,
  809. targetData.Position.Y, nextData.Position.Y));
  810. resultData.Color = new Color(
  811. (byte)CalcSpline(rate, prevData.Color.R, baseData.Color.R,
  812. targetData.Color.R, nextData.Color.R),
  813. (byte)CalcSpline(rate, prevData.Color.G, baseData.Color.G,
  814. targetData.Color.G, nextData.Color.G),
  815. (byte)CalcSpline(rate, prevData.Color.B, baseData.Color.B,
  816. targetData.Color.B, nextData.Color.B),
  817. (byte)CalcSpline(rate, prevData.Color.A, baseData.Color.A,
  818. targetData.Color.A, nextData.Color.A));
  819. resultData.Scale = new Vector2(
  820. CalcSpline(rate, prevData.Scale.X, baseData.Scale.X,
  821. targetData.Scale.X, nextData.Scale.X),
  822. CalcSpline(rate, prevData.Scale.Y, baseData.Scale.Y,
  823. targetData.Scale.Y, nextData.Scale.Y));
  824. resultData.Center = new Point(
  825. (int)CalcSpline(rate, prevData.Center.X, baseData.Center.X,
  826. targetData.Center.X, nextData.Center.X),
  827. (int)CalcSpline(rate, prevData.Center.Y, baseData.Center.Y,
  828. targetData.Center.Y, nextData.Center.Y));
  829. resultData.RotateZ = CalcSpline(rate, prevData.RotateZ,
  830. baseData.RotateZ, targetData.RotateZ, nextData.RotateZ);
  831. }
  832. /// <summary>
  833. /// Resets the frame and plays it from the beginning.
  834. ///
  835. /// フレームをリセットして最初から再生します。
  836. /// </summary>
  837. public void Replay()
  838. {
  839. timeFrame = new TimeSpan();
  840. }
  841. /// <summary>
  842. /// Based on the conversion information obtained and interpolated by the
  843. /// Update function, the sequence group displays pattern objects in the
  844. /// pattern group that is referred to by the current Base sequence object.
  845. /// This function obtains this current Base sequence object.
  846. ///
  847. /// シーケンスグループは、着目しているシーケンスオブジェクトが
  848. /// 参照するパターングループ内のパターンオブジェクトを
  849. /// Update関数で求めた補間された変換情報に基づいて表示します。
  850. /// この、現在着目しているシーケンスオブジェクトを取得する関数です。
  851. /// </summary>
  852. /// <returns>
  853. /// Current sequence object to be displayed
  854. ///
  855. /// 現在表示することになっているシーケンスオブジェクト
  856. /// </returns>
  857. [ContentSerializerIgnore]
  858. public SequenceObjectData CurrentObjectList
  859. {
  860. get
  861. {
  862. return (drawObjectId >= 0) ? objectList[drawObjectId] : objectList[0];
  863. }
  864. }
  865. }
  866. }