ArmatureData.cs 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515
  1. using System;
  2. using System.Collections.Generic;
  3. namespace DragonBones
  4. {
  5. /**
  6. * @language zh_CN
  7. * 骨架数据。
  8. * @see DragonBones.Armature
  9. * @version DragonBones 3.0
  10. */
  11. public class ArmatureData : BaseObject
  12. {
  13. private static int _onSortSlots(SlotData a, SlotData b)
  14. {
  15. return a.zOrder > b.zOrder ? 1 : -1;
  16. }
  17. /**
  18. * @language zh_CN
  19. * 动画帧率。
  20. * @version DragonBones 3.0
  21. */
  22. public uint frameRate;
  23. /**
  24. * @private
  25. */
  26. public ArmatureType type;
  27. /**
  28. * @private
  29. */
  30. public uint cacheFrameRate;
  31. /**
  32. * @private
  33. */
  34. public float scale;
  35. /**
  36. * @language zh_CN
  37. * 数据名称。
  38. * @version DragonBones 3.0
  39. */
  40. public string name;
  41. /**
  42. * @private
  43. */
  44. public readonly Rectangle aabb = new Rectangle();
  45. /**
  46. * @language zh_CN
  47. * 所有骨骼数据。
  48. * @see DragonBones.BoneData
  49. * @version DragonBones 3.0
  50. */
  51. public readonly Dictionary<string, BoneData> bones = new Dictionary<string, BoneData>();
  52. /**
  53. * @language zh_CN
  54. * 所有插槽数据。
  55. * @see DragonBones.SlotData
  56. * @version DragonBones 3.0
  57. */
  58. public readonly Dictionary<string, SlotData> slots = new Dictionary<string, SlotData>();
  59. /**
  60. * @language zh_CN
  61. * 所有皮肤数据。
  62. * @see DragonBones.SkinData
  63. * @version DragonBones 3.0
  64. */
  65. public readonly Dictionary<string, SkinData> skins = new Dictionary<string, SkinData>();
  66. /**
  67. * @language zh_CN
  68. * 所有动画数据。
  69. * @see DragonBones.AnimationData
  70. * @version DragonBones 3.0
  71. */
  72. public readonly Dictionary<string, AnimationData> animations = new Dictionary<string, AnimationData>();
  73. /**
  74. * @private
  75. */
  76. public readonly List<ActionData> actions = new List<ActionData>();
  77. /**
  78. * @language zh_CN
  79. * 所属的龙骨数据。
  80. * @see DragonBones.DragonBonesData
  81. * @version DragonBones 4.5
  82. */
  83. public DragonBonesData parent;
  84. /**
  85. * @private
  86. */
  87. public CustomData userData;
  88. private bool _boneDirty;
  89. private bool _slotDirty;
  90. private readonly List<string> _animationNames = new List<string>();
  91. private readonly List<BoneData> _sortedBones = new List<BoneData>();
  92. private readonly List<SlotData> _sortedSlots = new List<SlotData>();
  93. private readonly Dictionary<string, List<BoneData>> _bonesChildren = new Dictionary<string, List<BoneData>>();
  94. private SkinData _defaultSkin;
  95. private AnimationData _defaultAnimation;
  96. /**
  97. * @private
  98. */
  99. public ArmatureData()
  100. {
  101. }
  102. /**
  103. * @private
  104. */
  105. protected override void _onClear()
  106. {
  107. foreach (var pair in bones)
  108. {
  109. pair.Value.ReturnToPool();
  110. }
  111. foreach (var pair in slots)
  112. {
  113. pair.Value.ReturnToPool();
  114. }
  115. foreach (var pair in skins)
  116. {
  117. pair.Value.ReturnToPool();
  118. }
  119. foreach (var pair in animations)
  120. {
  121. pair.Value.ReturnToPool();
  122. }
  123. foreach (var action in actions)
  124. {
  125. action.ReturnToPool();
  126. }
  127. if (userData != null)
  128. {
  129. userData.ReturnToPool();
  130. }
  131. frameRate = 0;
  132. type = ArmatureType.None;
  133. cacheFrameRate = 0;
  134. scale = 1.0f;
  135. name = null;
  136. aabb.Clear();
  137. bones.Clear();
  138. slots.Clear();
  139. skins.Clear();
  140. animations.Clear();
  141. actions.Clear();
  142. parent = null;
  143. _boneDirty = false;
  144. _slotDirty = false;
  145. _animationNames.Clear();
  146. _sortedBones.Clear();
  147. _sortedSlots.Clear();
  148. _bonesChildren.Clear();
  149. _defaultSkin = null;
  150. _defaultAnimation = null;
  151. }
  152. private void _sortBones()
  153. {
  154. var total = _sortedBones.Count;
  155. if (total < 1)
  156. {
  157. return;
  158. }
  159. var sortHelper = _sortedBones.ToArray();
  160. int index = 0;
  161. int count = 0;
  162. _sortedBones.Clear();
  163. while (count < total)
  164. {
  165. var bone = sortHelper[index++];
  166. if (index >= total)
  167. {
  168. index = 0;
  169. }
  170. if (_sortedBones.Contains(bone))
  171. {
  172. continue;
  173. }
  174. if (bone.parent != null && !_sortedBones.Contains(bone.parent))
  175. {
  176. continue;
  177. }
  178. if (bone.ik != null && !_sortedBones.Contains(bone.ik))
  179. {
  180. continue;
  181. }
  182. if (bone.ik != null && bone.chain > 0 && bone.chainIndex == bone.chain)
  183. {
  184. _sortedBones.Insert(_sortedBones.IndexOf(bone.parent) + 1, bone);
  185. }
  186. else
  187. {
  188. _sortedBones.Add(bone);
  189. }
  190. count++;
  191. }
  192. }
  193. private void _sortSlots()
  194. {
  195. _sortedSlots.Sort(ArmatureData._onSortSlots);
  196. }
  197. /**
  198. * @private
  199. */
  200. public void CacheFrames(uint frameRate)
  201. {
  202. if (cacheFrameRate > 0)
  203. {
  204. return;
  205. }
  206. cacheFrameRate = frameRate;
  207. foreach (var animation in animations.Values)
  208. {
  209. animation.CacheFrames(cacheFrameRate);
  210. }
  211. }
  212. /**
  213. * @private
  214. */
  215. public int SetCacheFrame(Matrix globalTransformMatrix, Transform transform)
  216. {
  217. var dataArray = parent.cachedFrames;
  218. var arrayOffset = dataArray.Count;
  219. DragonBones.ResizeList(dataArray, arrayOffset + 10, 0.0f);
  220. dataArray[arrayOffset] = globalTransformMatrix.a;
  221. dataArray[arrayOffset + 1] = globalTransformMatrix.b;
  222. dataArray[arrayOffset + 2] = globalTransformMatrix.c;
  223. dataArray[arrayOffset + 3] = globalTransformMatrix.d;
  224. dataArray[arrayOffset + 4] = globalTransformMatrix.tx;
  225. dataArray[arrayOffset + 5] = globalTransformMatrix.ty;
  226. dataArray[arrayOffset + 6] = transform.skewX;
  227. dataArray[arrayOffset + 7] = transform.skewY;
  228. dataArray[arrayOffset + 8] = transform.scaleX;
  229. dataArray[arrayOffset + 9] = transform.scaleY;
  230. return arrayOffset;
  231. }
  232. /**
  233. * @private
  234. */
  235. public void GetCacheFrame(Matrix globalTransformMatrix, Transform transform, int arrayOffset)
  236. {
  237. var dataArray = parent.cachedFrames;
  238. globalTransformMatrix.a = dataArray[arrayOffset];
  239. globalTransformMatrix.b = dataArray[arrayOffset + 1];
  240. globalTransformMatrix.c = dataArray[arrayOffset + 2];
  241. globalTransformMatrix.d = dataArray[arrayOffset + 3];
  242. globalTransformMatrix.tx = dataArray[arrayOffset + 4];
  243. globalTransformMatrix.ty = dataArray[arrayOffset + 5];
  244. transform.skewX = dataArray[arrayOffset + 6];
  245. transform.skewY = dataArray[arrayOffset + 7];
  246. transform.scaleX = dataArray[arrayOffset + 8];
  247. transform.scaleY = dataArray[arrayOffset + 9];
  248. transform.x = globalTransformMatrix.tx;
  249. transform.y = globalTransformMatrix.ty;
  250. }
  251. /**
  252. * @private
  253. */
  254. public void AddBone(BoneData value, string parentName)
  255. {
  256. if (value != null && !string.IsNullOrEmpty(value.name) && !bones.ContainsKey(value.name))
  257. {
  258. if (parentName != null)
  259. {
  260. var parent = GetBone(parentName);
  261. if (parent != null)
  262. {
  263. value.parent = parent;
  264. }
  265. else
  266. {
  267. (_bonesChildren.ContainsKey(parentName) ?
  268. _bonesChildren[parentName] :
  269. (_bonesChildren[parentName] = new List<BoneData>())).Add(value);
  270. }
  271. }
  272. if (_bonesChildren.ContainsKey(value.name))
  273. {
  274. foreach (var child in _bonesChildren[value.name])
  275. {
  276. child.parent = value;
  277. }
  278. _bonesChildren.Remove(value.name);
  279. }
  280. bones[value.name] = value;
  281. _sortedBones.Add(value);
  282. _boneDirty = true;
  283. }
  284. else
  285. {
  286. DragonBones.Assert(false, DragonBones.ARGUMENT_ERROR);
  287. }
  288. }
  289. /**
  290. * @private
  291. */
  292. public void AddSlot(SlotData value)
  293. {
  294. if (value != null && !string.IsNullOrEmpty(value.name) && !slots.ContainsKey(value.name))
  295. {
  296. slots[value.name] = value;
  297. _sortedSlots.Add(value);
  298. _slotDirty = true;
  299. }
  300. else
  301. {
  302. DragonBones.Assert(false, DragonBones.ARGUMENT_ERROR);
  303. }
  304. }
  305. /**
  306. * @private
  307. */
  308. public void AddSkin(SkinData value)
  309. {
  310. if (value != null && !string.IsNullOrEmpty(value.name) && !skins.ContainsKey(value.name))
  311. {
  312. skins[value.name] = value;
  313. if (_defaultSkin == null)
  314. {
  315. _defaultSkin = value;
  316. }
  317. }
  318. else
  319. {
  320. DragonBones.Assert(false, DragonBones.ARGUMENT_ERROR);
  321. }
  322. }
  323. /**
  324. * @private
  325. */
  326. public void AddAnimation(AnimationData value)
  327. {
  328. if (value != null && !string.IsNullOrEmpty(value.name) && !animations.ContainsKey(value.name))
  329. {
  330. animations[value.name] = value;
  331. _animationNames.Add(value.name);
  332. if (_defaultAnimation == null)
  333. {
  334. _defaultAnimation = value;
  335. }
  336. }
  337. else
  338. {
  339. DragonBones.Assert(false, DragonBones.ARGUMENT_ERROR);
  340. }
  341. }
  342. /**
  343. * @language zh_CN
  344. * 获取指定名称的骨骼数据。
  345. * @param name 骨骼数据名称。
  346. * @see DragonBones.BoneData
  347. * @version DragonBones 3.0
  348. */
  349. public BoneData GetBone(string name)
  350. {
  351. return (!string.IsNullOrEmpty(name) && bones.ContainsKey(name)) ? bones[name] : null;
  352. }
  353. /**
  354. * @language zh_CN
  355. * 获取指定名称的插槽数据。
  356. * @param name 插槽数据名称。
  357. * @see DragonBones.SlotData
  358. * @version DragonBones 3.0
  359. */
  360. public SlotData GetSlot(string name)
  361. {
  362. return (!string.IsNullOrEmpty(name) && slots.ContainsKey(name)) ? slots[name] : null;
  363. }
  364. /**
  365. * @language zh_CN
  366. * 获取指定名称的皮肤数据。
  367. * @param name 皮肤数据名称。
  368. * @see DragonBones.SkinData
  369. * @version DragonBones 3.0
  370. */
  371. public SkinData GetSkin(string name)
  372. {
  373. return !string.IsNullOrEmpty(name) ? (skins.ContainsKey(name) ? skins[name] : null) : _defaultSkin;
  374. }
  375. /**
  376. * @language zh_CN
  377. * 获取指定名称的动画数据。
  378. * @param name 动画数据名称。
  379. * @see DragonBones.AnimationData
  380. * @version DragonBones 3.0
  381. */
  382. public AnimationData GetAnimation(string name)
  383. {
  384. return !string.IsNullOrEmpty(name) ? (animations.ContainsKey(name) ? animations[name] : null) : _defaultAnimation;
  385. }
  386. /**
  387. * @private
  388. */
  389. public List<BoneData> sortedBones
  390. {
  391. get
  392. {
  393. if (_boneDirty)
  394. {
  395. _boneDirty = false;
  396. _sortBones();
  397. }
  398. return _sortedBones;
  399. }
  400. }
  401. /**
  402. * @private
  403. */
  404. public List<SlotData> sortedSlots
  405. {
  406. get
  407. {
  408. if (_slotDirty)
  409. {
  410. _slotDirty = false;
  411. _sortSlots();
  412. }
  413. return _sortedSlots;
  414. }
  415. }
  416. /**
  417. * @language zh_CN
  418. * 所有动画数据名称。
  419. * @see #armatures
  420. * @version DragonBones 3.0
  421. */
  422. public List<string> animationNames
  423. {
  424. get { return _animationNames; }
  425. }
  426. /**
  427. * @language zh_CN
  428. * 获取默认的皮肤数据。
  429. * @see DragonBones.SkinData
  430. * @version DragonBones 4.5
  431. */
  432. public SkinData defaultSkin
  433. {
  434. get { return _defaultSkin; }
  435. }
  436. /**
  437. * @language zh_CN
  438. * 获取默认的动画数据。
  439. * @see DragonBones.AnimationData
  440. * @version DragonBones 4.5
  441. */
  442. public AnimationData defaultAnimation
  443. {
  444. get { return _defaultAnimation; }
  445. }
  446. }
  447. /**
  448. * @language zh_CN
  449. * 骨骼数据。
  450. * @see DragonBones.Bone
  451. * @version DragonBones 3.0
  452. */
  453. public class BoneData : BaseObject
  454. {
  455. /**
  456. * @private
  457. */
  458. public bool inheritTranslation;
  459. /**
  460. * @private
  461. */
  462. public bool inheritRotation;
  463. /**
  464. * @private
  465. */
  466. public bool inheritScale;
  467. /**
  468. * @private
  469. */
  470. public bool bendPositive;
  471. /**
  472. * @private
  473. */
  474. public uint chain;
  475. /**
  476. * @private
  477. */
  478. public int chainIndex;
  479. /**
  480. * @private
  481. */
  482. public float weight;
  483. /**
  484. * @private
  485. */
  486. public float length;
  487. /**
  488. * @language zh_CN
  489. * 数据名称。
  490. * @version DragonBones 3.0
  491. */
  492. public string name;
  493. /**
  494. * @private
  495. */
  496. public readonly Transform transform = new Transform();
  497. /**
  498. * @language zh_CN
  499. * 所属的父骨骼数据。
  500. * @version DragonBones 3.0
  501. */
  502. public BoneData parent;
  503. /**
  504. * @private
  505. */
  506. public BoneData ik;
  507. /**
  508. * @private
  509. */
  510. public CustomData userData;
  511. /**
  512. * @private
  513. */
  514. public BoneData()
  515. {
  516. }
  517. /**
  518. * @private
  519. */
  520. protected override void _onClear()
  521. {
  522. if (userData != null)
  523. {
  524. userData.ReturnToPool();
  525. }
  526. inheritTranslation = false;
  527. inheritRotation = false;
  528. inheritScale = false;
  529. bendPositive = false;
  530. chain = 0;
  531. chainIndex = 0;
  532. weight = 0.0f;
  533. length = 0.0f;
  534. name = null;
  535. transform.Identity();
  536. parent = null;
  537. ik = null;
  538. userData = null;
  539. }
  540. }
  541. /**
  542. * @language zh_CN
  543. * 插槽数据。
  544. * @see DragonBones.Slot
  545. * @version DragonBones 3.0
  546. */
  547. public class SlotData : BaseObject
  548. {
  549. /**
  550. * @private
  551. */
  552. public static readonly ColorTransform DEFAULT_COLOR = new ColorTransform();
  553. /**
  554. * @private
  555. */
  556. public static ColorTransform GenerateColor()
  557. {
  558. return new ColorTransform();
  559. }
  560. /**
  561. * @private
  562. */
  563. public int displayIndex;
  564. /**
  565. * @private
  566. */
  567. public int zOrder;
  568. /**
  569. * @private
  570. */
  571. public BlendMode blendMode;
  572. /**
  573. * @language zh_CN
  574. * 数据名称。
  575. * @version DragonBones 3.0
  576. */
  577. public string name;
  578. /**
  579. * @private
  580. */
  581. public readonly List<ActionData> actions = new List<ActionData>();
  582. /**
  583. * @language zh_CN
  584. * 所属的父骨骼数据。
  585. * @see DragonBones.BoneData
  586. * @version DragonBones 3.0
  587. */
  588. public BoneData parent;
  589. /**
  590. * @private
  591. */
  592. public ColorTransform color;
  593. /**
  594. * @private
  595. */
  596. public CustomData userData;
  597. /**
  598. * @private
  599. */
  600. public SlotData()
  601. {
  602. }
  603. /**
  604. * @private
  605. */
  606. protected override void _onClear()
  607. {
  608. for (int i = 0, l = actions.Count; i < l; ++i)
  609. {
  610. actions[i].ReturnToPool();
  611. }
  612. if (userData != null)
  613. {
  614. userData.ReturnToPool();
  615. }
  616. displayIndex = 0;
  617. zOrder = 0;
  618. blendMode = BlendMode.Normal;
  619. name = null;
  620. actions.Clear();
  621. parent = null;
  622. color = null;
  623. userData = null;
  624. }
  625. }
  626. /**
  627. * @private
  628. */
  629. public class SkinData : BaseObject
  630. {
  631. public string name;
  632. public readonly Dictionary<string, SkinSlotData> slots = new Dictionary<string, SkinSlotData>();
  633. public SkinData()
  634. {
  635. }
  636. protected override void _onClear()
  637. {
  638. foreach (var pair in slots)
  639. {
  640. pair.Value.ReturnToPool();
  641. }
  642. name = null;
  643. slots.Clear();
  644. }
  645. public void AddSlot(SkinSlotData value)
  646. {
  647. if (value != null && value.slot != null && !slots.ContainsKey(value.slot.name))
  648. {
  649. slots[value.slot.name] = value;
  650. }
  651. else
  652. {
  653. DragonBones.Assert(false, DragonBones.ARGUMENT_ERROR);
  654. }
  655. }
  656. public SkinSlotData GetSlot(string name)
  657. {
  658. return slots[name];
  659. }
  660. }
  661. /**
  662. * @private
  663. */
  664. public class SkinSlotData : BaseObject
  665. {
  666. public readonly List<DisplayData> displays = new List<DisplayData>();
  667. public readonly Dictionary<string, MeshData> meshs = new Dictionary<string, MeshData>();
  668. public SlotData slot;
  669. public SkinSlotData()
  670. {
  671. }
  672. protected override void _onClear()
  673. {
  674. for (int i = 0, l = displays.Count; i < l; ++i)
  675. {
  676. displays[i].ReturnToPool();
  677. }
  678. foreach (var mesh in meshs.Values)
  679. {
  680. mesh.ReturnToPool();
  681. }
  682. displays.Clear();
  683. meshs.Clear();
  684. slot = null;
  685. }
  686. public DisplayData GetDisplay(string name)
  687. {
  688. for (int i = 0, l = displays.Count; i < l; ++i)
  689. {
  690. var display = displays[i];
  691. if (display.name == name)
  692. {
  693. return display;
  694. }
  695. }
  696. return null;
  697. }
  698. public void AddMesh(MeshData value)
  699. {
  700. if (value != null && !string.IsNullOrEmpty(value.name) && !meshs.ContainsKey(value.name))
  701. {
  702. meshs[value.name] = value;
  703. }
  704. else
  705. {
  706. DragonBones.Assert(false, DragonBones.ARGUMENT_ERROR);
  707. }
  708. }
  709. public MeshData GetMesh(string name)
  710. {
  711. return meshs[name];
  712. }
  713. }
  714. /**
  715. * @private
  716. */
  717. public class DisplayData : BaseObject
  718. {
  719. public bool isRelativePivot;
  720. public DisplayType type;
  721. public bool inheritAnimation;
  722. public string name;
  723. public string path;
  724. public string share;
  725. public readonly Point pivot = new Point();
  726. public readonly Transform transform = new Transform();
  727. public TextureData texture;
  728. public ArmatureData armature;
  729. public MeshData mesh;
  730. public BoundingBoxData boundingBox;
  731. public DisplayData()
  732. {
  733. }
  734. protected override void _onClear()
  735. {
  736. if (boundingBox != null)
  737. {
  738. boundingBox.ReturnToPool();
  739. }
  740. isRelativePivot = false;
  741. type = DisplayType.Image;
  742. name = null;
  743. path = null;
  744. share = null;
  745. pivot.Clear();
  746. transform.Identity();
  747. texture = null;
  748. armature = null;
  749. mesh = null;
  750. boundingBox = null;
  751. }
  752. }
  753. /**
  754. * @private
  755. */
  756. public class MeshData : BaseObject
  757. {
  758. public bool skinned;
  759. public string name;
  760. public readonly Matrix slotPose = new Matrix();
  761. public readonly List<float> uvs = new List<float>(); // vertices * 2
  762. public readonly List<float> vertices = new List<float>(); // vertices * 2
  763. public readonly List<int> vertexIndices = new List<int>(); // triangles * 3
  764. public readonly List<int[]> boneIndices = new List<int[]>(); // vertices bones
  765. public readonly List<float[]> weights = new List<float[]>(); // vertices bones
  766. public readonly List<float[]> boneVertices = new List<float[]>(); // vertices bones * 2
  767. public readonly List<BoneData> bones = new List<BoneData>(); // bones
  768. public readonly List<Matrix> inverseBindPose = new List<Matrix>(); // bones
  769. public MeshData()
  770. {
  771. }
  772. protected override void _onClear()
  773. {
  774. skinned = false;
  775. name = null;
  776. slotPose.Identity();
  777. uvs.Clear();
  778. vertices.Clear();
  779. vertexIndices.Clear();
  780. boneIndices.Clear();
  781. weights.Clear();
  782. boneVertices.Clear();
  783. bones.Clear();
  784. inverseBindPose.Clear();
  785. }
  786. }
  787. /**
  788. * Cohen–Sutherland algorithm https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm
  789. * ----------------------
  790. * | 0101 | 0100 | 0110 |
  791. * ----------------------
  792. * | 0001 | 0000 | 0010 |
  793. * ----------------------
  794. * | 1001 | 1000 | 1010 |
  795. * ----------------------
  796. */
  797. enum OutCode
  798. {
  799. InSide = 0, // 0000
  800. Left = 1, // 0001
  801. Right = 2, // 0010
  802. Top = 4, // 0100
  803. Bottom = 8 // 1000
  804. }
  805. /**
  806. * @language zh_CN
  807. * 包围盒数据。
  808. * @version DragonBones 5.0
  809. */
  810. public class BoundingBoxData : BaseObject
  811. {
  812. /**
  813. * Compute the bit code for a point (x, y) using the clip rectangle
  814. */
  815. private static OutCode _computeOutCode(float x, float y, float xMin, float yMin, float xMax, float yMax)
  816. {
  817. var code = OutCode.InSide; // initialised as being inside of [[clip window]]
  818. if (x < xMin) // to the left of clip window
  819. {
  820. code |= OutCode.Left;
  821. }
  822. else if (x > xMax) // to the right of clip window
  823. {
  824. code |= OutCode.Right;
  825. }
  826. if (y < yMin) // below the clip window
  827. {
  828. code |= OutCode.Top;
  829. }
  830. else if (y > yMax) // above the clip window
  831. {
  832. code |= OutCode.Bottom;
  833. }
  834. return code;
  835. }
  836. /**
  837. * @private
  838. */
  839. public static int SegmentIntersectsRectangle(
  840. float xA, float yA, float xB, float yB,
  841. float xMin, float yMin, float xMax, float yMax,
  842. Point intersectionPointA = null,
  843. Point intersectionPointB = null,
  844. Point normalRadians = null
  845. )
  846. {
  847. var inSideA = xA > xMin && xA < xMax && yA > yMin && yA < yMax;
  848. var inSideB = xB > xMin && xB < xMax && yB > yMin && yB < yMax;
  849. if (inSideA && inSideB)
  850. {
  851. return -1;
  852. }
  853. int intersectionCount = 0;
  854. var outcode0 = _computeOutCode(xA, yA, xMin, yMin, xMax, yMax);
  855. var outcode1 = _computeOutCode(xB, yB, xMin, yMin, xMax, yMax);
  856. while (true)
  857. {
  858. if ((outcode0 | outcode1) == 0)
  859. { // Bitwise OR is 0. Trivially accept and get out of loop
  860. intersectionCount = 2;
  861. break;
  862. }
  863. else if ((outcode0 & outcode1) != 0)
  864. { // Bitwise AND is not 0. Trivially reject and get out of loop
  865. break;
  866. }
  867. // failed both tests, so calculate the line segment to clip
  868. // from an outside point to an intersection with clip edge
  869. float x = 0.0f;
  870. float y = 0.0f;
  871. float normalRadian = 0.0f;
  872. // At least one endpoint is outside the clip rectangle; pick it.
  873. var outcodeOut = outcode0 != 0 ? outcode0 : outcode1;
  874. // Now find the intersection point;
  875. if ((outcodeOut & OutCode.Top) != 0)
  876. { // point is above the clip rectangle
  877. x = xA + (xB - xA) * (yMin - yA) / (yB - yA);
  878. y = yMin;
  879. if (normalRadians != null)
  880. {
  881. normalRadian = -DragonBones.PI * 0.5f;
  882. }
  883. }
  884. else if ((outcodeOut & OutCode.Bottom) != 0)
  885. { // point is below the clip rectangle
  886. x = xA + (xB - xA) * (yMax - yA) / (yB - yA);
  887. y = yMax;
  888. if (normalRadians != null)
  889. {
  890. normalRadian = DragonBones.PI * 0.5f;
  891. }
  892. }
  893. else if ((outcodeOut & OutCode.Right) != 0)
  894. { // point is to the right of clip rectangle
  895. y = yA + (yB - yA) * (xMax - xA) / (xB - xA);
  896. x = xMax;
  897. if (normalRadians != null)
  898. {
  899. normalRadian = 0.0f;
  900. }
  901. }
  902. else if ((outcodeOut & OutCode.Left) != 0)
  903. { // point is to the left of clip rectangle
  904. y = yA + (yB - yA) * (xMin - xA) / (xB - xA);
  905. x = xMin;
  906. if (normalRadians != null)
  907. {
  908. normalRadian = DragonBones.PI;
  909. }
  910. }
  911. // Now we move outside point to intersection point to clip
  912. // and get ready for next pass.
  913. if (outcodeOut == outcode0)
  914. {
  915. xA = x;
  916. yA = y;
  917. outcode0 = _computeOutCode(xA, yA, xMin, yMin, xMax, yMax);
  918. if (normalRadians != null)
  919. {
  920. normalRadians.x = normalRadian;
  921. }
  922. }
  923. else
  924. {
  925. xB = x;
  926. yB = y;
  927. outcode1 = _computeOutCode(xB, yB, xMin, yMin, xMax, yMax);
  928. if (normalRadians != null)
  929. {
  930. normalRadians.y = normalRadian;
  931. }
  932. }
  933. }
  934. if (intersectionCount > 0)
  935. {
  936. if (inSideA)
  937. {
  938. intersectionCount = 2; // 10
  939. if (intersectionPointA != null)
  940. {
  941. intersectionPointA.x = xB;
  942. intersectionPointA.y = yB;
  943. }
  944. if (intersectionPointB != null)
  945. {
  946. intersectionPointB.x = xB;
  947. intersectionPointB.y = xB;
  948. }
  949. if (normalRadians != null)
  950. {
  951. normalRadians.x = normalRadians.y + DragonBones.PI;
  952. }
  953. }
  954. else if (inSideB)
  955. {
  956. intersectionCount = 1; // 01
  957. if (intersectionPointA != null)
  958. {
  959. intersectionPointA.x = xA;
  960. intersectionPointA.y = yA;
  961. }
  962. if (intersectionPointB != null)
  963. {
  964. intersectionPointB.x = xA;
  965. intersectionPointB.y = yA;
  966. }
  967. if (normalRadians != null)
  968. {
  969. normalRadians.y = normalRadians.x + DragonBones.PI;
  970. }
  971. }
  972. else
  973. {
  974. intersectionCount = 3; // 11
  975. if (intersectionPointA != null)
  976. {
  977. intersectionPointA.x = xA;
  978. intersectionPointA.y = yA;
  979. }
  980. if (intersectionPointB != null)
  981. {
  982. intersectionPointB.x = xB;
  983. intersectionPointB.y = yB;
  984. }
  985. }
  986. }
  987. return intersectionCount;
  988. }
  989. /**
  990. * @private
  991. */
  992. public static int SegmentIntersectsEllipse(
  993. float xA, float yA, float xB, float yB,
  994. float xC, float yC, float widthH, float heightH,
  995. Point intersectionPointA = null,
  996. Point intersectionPointB = null,
  997. Point normalRadians = null
  998. )
  999. {
  1000. var d = widthH / heightH;
  1001. var dd = d * d;
  1002. yA *= d;
  1003. yB *= d;
  1004. var dX = xB - xA;
  1005. var dY = yB - yA;
  1006. var lAB = (float)Math.Sqrt(dX * dX + dY * dY);
  1007. var xD = dX / lAB;
  1008. var yD = dY / lAB;
  1009. var a = (xC - xA) * xD + (yC - yA) * yD;
  1010. var aa = a * a;
  1011. var ee = xA * xA + yA * yA;
  1012. var rr = widthH * widthH;
  1013. var dR = rr - ee + aa;
  1014. int intersectionCount = 0;
  1015. if (dR >= 0)
  1016. {
  1017. var dT = (float)Math.Sqrt(dR);
  1018. var sA = a - dT;
  1019. var sB = a + dT;
  1020. int inSideA = sA < 0.0f ? -1 : (sA <= lAB ? 0 : 1);
  1021. int inSideB = sB < 0.0f ? -1 : (sB <= lAB ? 0 : 1);
  1022. int sideAB = inSideA * inSideB;
  1023. if (sideAB < 0)
  1024. {
  1025. return -1;
  1026. }
  1027. else if (sideAB == 0)
  1028. {
  1029. if (inSideA == -1)
  1030. {
  1031. intersectionCount = 2; // 10
  1032. xB = xA + sB * xD;
  1033. yB = (yA + sB * yD) / d;
  1034. if (intersectionPointA != null)
  1035. {
  1036. intersectionPointA.x = xB;
  1037. intersectionPointA.y = yB;
  1038. }
  1039. if (intersectionPointB != null)
  1040. {
  1041. intersectionPointB.x = xB;
  1042. intersectionPointB.y = yB;
  1043. }
  1044. if (normalRadians != null)
  1045. {
  1046. normalRadians.x = (float)Math.Atan2(yB / rr * dd, xB / rr);
  1047. normalRadians.y = normalRadians.x + DragonBones.PI;
  1048. }
  1049. }
  1050. else if (inSideB == 1)
  1051. {
  1052. intersectionCount = 1; // 01
  1053. xA = xA + sA * xD;
  1054. yA = (yA + sA * yD) / d;
  1055. if (intersectionPointA != null)
  1056. {
  1057. intersectionPointA.x = xA;
  1058. intersectionPointA.y = yA;
  1059. }
  1060. if (intersectionPointB != null)
  1061. {
  1062. intersectionPointB.x = xA;
  1063. intersectionPointB.y = yA;
  1064. }
  1065. if (normalRadians != null)
  1066. {
  1067. normalRadians.x = (float)Math.Atan2(yA / rr * dd, xA / rr);
  1068. normalRadians.y = normalRadians.x + DragonBones.PI;
  1069. }
  1070. }
  1071. else
  1072. {
  1073. intersectionCount = 3; // 11
  1074. if (intersectionPointA != null)
  1075. {
  1076. intersectionPointA.x = xA + sA * xD;
  1077. intersectionPointA.y = (yA + sA * yD) / d;
  1078. if (normalRadians != null)
  1079. {
  1080. normalRadians.x = (float)Math.Atan2(intersectionPointA.y / rr * dd, intersectionPointA.x / rr);
  1081. }
  1082. }
  1083. if (intersectionPointB != null)
  1084. {
  1085. intersectionPointB.x = xA + sB * xD;
  1086. intersectionPointB.y = (yA + sB * yD) / d;
  1087. if (normalRadians != null)
  1088. {
  1089. normalRadians.y = (float)Math.Atan2(intersectionPointB.y / rr * dd, intersectionPointB.x / rr);
  1090. }
  1091. }
  1092. }
  1093. }
  1094. }
  1095. return intersectionCount;
  1096. }
  1097. /**
  1098. * @private
  1099. */
  1100. public static int SegmentIntersectsPolygon(
  1101. float xA, float yA, float xB, float yB,
  1102. List<float> vertices,
  1103. Point intersectionPointA = null,
  1104. Point intersectionPointB = null,
  1105. Point normalRadians = null
  1106. )
  1107. {
  1108. if (xA == xB)
  1109. {
  1110. xA = xB + 0.01f;
  1111. }
  1112. if (yA == yB)
  1113. {
  1114. yA = yB + 0.01f;
  1115. }
  1116. var l = vertices.Count;
  1117. var dXAB = xA - xB;
  1118. var dYAB = yA - yB;
  1119. var llAB = xA * yB - yA * xB;
  1120. int intersectionCount = 0;
  1121. var xC = vertices[l - 2];
  1122. var yC = vertices[l - 1];
  1123. var dMin = 0.0f;
  1124. var dMax = 0.0f;
  1125. var xMin = 0.0f;
  1126. var yMin = 0.0f;
  1127. var xMax = 0.0f;
  1128. var yMax = 0.0f;
  1129. for (int i = 0; i < l; i += 2)
  1130. {
  1131. var xD = vertices[i];
  1132. var yD = vertices[i + 1];
  1133. if (xC == xD)
  1134. {
  1135. xC = xD + 0.01f;
  1136. }
  1137. if (yC == yD)
  1138. {
  1139. yC = yD + 0.01f;
  1140. }
  1141. var dXCD = xC - xD;
  1142. var dYCD = yC - yD;
  1143. var llCD = xC * yD - yC * xD;
  1144. var ll = dXAB * dYCD - dYAB * dXCD;
  1145. var x = (llAB * dXCD - dXAB * llCD) / ll;
  1146. if (((x >= xC && x <= xD) || (x >= xD && x <= xC)) && (dXAB == 0 || (x >= xA && x <= xB) || (x >= xB && x <= xA)))
  1147. {
  1148. var y = (llAB * dYCD - dYAB * llCD) / ll;
  1149. if (((y >= yC && y <= yD) || (y >= yD && y <= yC)) && (dYAB == 0 || (y >= yA && y <= yB) || (y >= yB && y <= yA)))
  1150. {
  1151. if (intersectionPointB != null)
  1152. {
  1153. var d = x - xA;
  1154. if (d < 0.0f)
  1155. {
  1156. d = -d;
  1157. }
  1158. if (intersectionCount == 0)
  1159. {
  1160. dMin = d;
  1161. dMax = d;
  1162. xMin = x;
  1163. yMin = y;
  1164. xMax = x;
  1165. yMax = y;
  1166. if (normalRadians != null)
  1167. {
  1168. normalRadians.x = (float)Math.Atan2(yD - yC, xD - xC) - DragonBones.PI * 0.5f;
  1169. normalRadians.y = normalRadians.x;
  1170. }
  1171. }
  1172. else
  1173. {
  1174. if (d < dMin)
  1175. {
  1176. dMin = d;
  1177. xMin = x;
  1178. yMin = y;
  1179. if (normalRadians != null)
  1180. {
  1181. normalRadians.x = (float)Math.Atan2(yD - yC, xD - xC) - DragonBones.PI * 0.5f;
  1182. }
  1183. }
  1184. if (d > dMax)
  1185. {
  1186. dMax = d;
  1187. xMax = x;
  1188. yMax = y;
  1189. if (normalRadians != null)
  1190. {
  1191. normalRadians.y = (float)Math.Atan2(yD - yC, xD - xC) - DragonBones.PI * 0.5f;
  1192. }
  1193. }
  1194. }
  1195. intersectionCount++;
  1196. }
  1197. else
  1198. {
  1199. xMin = x;
  1200. yMin = y;
  1201. xMax = x;
  1202. yMax = y;
  1203. intersectionCount++;
  1204. if (normalRadians != null)
  1205. {
  1206. normalRadians.x = (float)Math.Atan2(yD - yC, xD - xC) - DragonBones.PI * 0.5f;
  1207. normalRadians.y = normalRadians.x;
  1208. }
  1209. break;
  1210. }
  1211. }
  1212. }
  1213. xC = xD;
  1214. yC = yD;
  1215. }
  1216. if (intersectionCount == 1)
  1217. {
  1218. if (intersectionPointA != null)
  1219. {
  1220. intersectionPointA.x = xMin;
  1221. intersectionPointA.y = yMin;
  1222. }
  1223. if (intersectionPointB != null)
  1224. {
  1225. intersectionPointB.x = xMin;
  1226. intersectionPointB.y = yMin;
  1227. }
  1228. if (normalRadians != null)
  1229. {
  1230. normalRadians.y = normalRadians.x + DragonBones.PI;
  1231. }
  1232. }
  1233. else if (intersectionCount > 1)
  1234. {
  1235. intersectionCount++;
  1236. if (intersectionPointA != null)
  1237. {
  1238. intersectionPointA.x = xMin;
  1239. intersectionPointA.y = yMin;
  1240. }
  1241. if (intersectionPointB != null)
  1242. {
  1243. intersectionPointB.x = xMax;
  1244. intersectionPointB.y = yMax;
  1245. }
  1246. }
  1247. return intersectionCount;
  1248. }
  1249. /**
  1250. * @language zh_CN
  1251. * 包围盒类型。
  1252. * @see DragonBones.BoundingBoxType
  1253. * @version DragonBones 5.0
  1254. */
  1255. public BoundingBoxType type;
  1256. /**
  1257. * @language zh_CN
  1258. * 包围盒颜色。
  1259. * @version DragonBones 5.0
  1260. */
  1261. public uint color;
  1262. public float x;
  1263. public float y;
  1264. public float width;
  1265. public float height;
  1266. /**
  1267. * @language zh_CN
  1268. * 自定义多边形顶点。
  1269. * @version DragonBones 5.0
  1270. */
  1271. public readonly List<float> vertices = new List<float>();
  1272. /**
  1273. * @private
  1274. */
  1275. public BoundingBoxData()
  1276. {
  1277. }
  1278. /**
  1279. * @private
  1280. */
  1281. override protected void _onClear()
  1282. {
  1283. type = BoundingBoxType.None;
  1284. color = 0x000000;
  1285. x = 0.0f;
  1286. y = 0.0f;
  1287. width = 0.0f;
  1288. height = 0.0f;
  1289. vertices.Clear();
  1290. }
  1291. /**
  1292. * @language zh_CN
  1293. * 是否包含点。
  1294. * @version DragonBones 5.0
  1295. */
  1296. public bool ContainsPoint(float pX, float pY)
  1297. {
  1298. var isInSide = false;
  1299. if (type == BoundingBoxType.Polygon)
  1300. {
  1301. if (pX >= x && pX <= width && pY >= y && pY <= height)
  1302. {
  1303. for (int i = 0, l = vertices.Count, prevIndex = l - 2; i < l; i += 2)
  1304. {
  1305. var yA = vertices[prevIndex + 1];
  1306. var yB = vertices[i + 1];
  1307. if ((yB < pY && yA >= pY) || (yA < pY && yB >= pY))
  1308. {
  1309. var xA = vertices[prevIndex];
  1310. var xB = vertices[i];
  1311. if ((pY - yB) * (xA - xB) / (yA - yB) + xB < pX)
  1312. {
  1313. isInSide = !isInSide;
  1314. }
  1315. }
  1316. prevIndex = i;
  1317. }
  1318. }
  1319. }
  1320. else
  1321. {
  1322. var widthH = width * 0.5f;
  1323. if (pX >= -widthH && pX <= widthH)
  1324. {
  1325. var heightH = height * 0.5f;
  1326. if (pY >= -heightH && pY <= heightH)
  1327. {
  1328. if (type == BoundingBoxType.Ellipse)
  1329. {
  1330. pY *= widthH / heightH;
  1331. isInSide = (float)Math.Sqrt(pX * pX + pY * pY) <= widthH;
  1332. }
  1333. else
  1334. {
  1335. isInSide = true;
  1336. }
  1337. }
  1338. }
  1339. }
  1340. return isInSide;
  1341. }
  1342. /**
  1343. * @language zh_CN
  1344. * 是否与线段相交。
  1345. * @version DragonBones 5.0
  1346. */
  1347. public int IntersectsSegment(
  1348. float xA, float yA, float xB, float yB,
  1349. Point intersectionPointA = null,
  1350. Point intersectionPointB = null,
  1351. Point normalRadians = null
  1352. )
  1353. {
  1354. int intersectionCount = 0;
  1355. switch (type)
  1356. {
  1357. case BoundingBoxType.Rectangle:
  1358. var widthH = width * 0.5f;
  1359. var heightH = height * 0.5f;
  1360. intersectionCount = SegmentIntersectsRectangle(
  1361. xA, yA, xB, yB,
  1362. -widthH, -heightH, widthH, heightH,
  1363. intersectionPointA, intersectionPointB, normalRadians
  1364. );
  1365. break;
  1366. case BoundingBoxType.Ellipse:
  1367. intersectionCount = SegmentIntersectsEllipse(
  1368. xA, yA, xB, yB,
  1369. 0.0f, 0.0f, width * 0.5f, height * 0.5f,
  1370. intersectionPointA, intersectionPointB, normalRadians
  1371. );
  1372. break;
  1373. case BoundingBoxType.Polygon:
  1374. if (SegmentIntersectsRectangle(xA, yA, xB, yB, x, y, width, height, null, null) != 0)
  1375. {
  1376. intersectionCount = SegmentIntersectsPolygon(
  1377. xA, yA, xB, yB,
  1378. vertices,
  1379. intersectionPointA, intersectionPointB, normalRadians
  1380. );
  1381. }
  1382. break;
  1383. default:
  1384. break;
  1385. }
  1386. return intersectionCount;
  1387. }
  1388. }
  1389. }