BinaryDataParser.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /**
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2012-2017 DragonBones team and other contributors
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  7. * this software and associated documentation files (the "Software"), to deal in
  8. * the Software without restriction, including without limitation the rights to
  9. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10. * the Software, and to permit persons to whom the Software is furnished to do so,
  11. * subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all
  14. * copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. using System;
  24. using System.IO;
  25. using System.Collections.Generic;
  26. namespace DragonBones
  27. {
  28. /// <internal/>
  29. /// <private/>
  30. public class BinaryDataParser : ObjectDataParser
  31. {
  32. //JsonParse
  33. public delegate object JsonParseDelegate(string json);
  34. public static JsonParseDelegate jsonParseDelegate;
  35. private int _binaryOffset;
  36. private byte[] _binary;
  37. private short[] _intArrayBuffer;
  38. private float[] _floatArrayBuffer;
  39. private short[] _frameIntArrayBuffer;
  40. private float[] _frameFloatArrayBuffer;
  41. private short[] _frameArrayBuffer;
  42. private ushort[] _timelineArrayBuffer;
  43. private TimelineData _ParseBinaryTimeline(TimelineType type, uint offset, TimelineData timelineData = null)
  44. {
  45. var timeline = timelineData != null ? timelineData : BaseObject.BorrowObject<TimelineData>();
  46. timeline.type = type;
  47. timeline.offset = offset;
  48. this._timeline = timeline;
  49. var keyFrameCount = this._timelineArrayBuffer[timeline.offset + (int)BinaryOffset.TimelineKeyFrameCount];
  50. if (keyFrameCount == 1)
  51. {
  52. timeline.frameIndicesOffset = -1;
  53. }
  54. else
  55. {
  56. // One more frame than animation.
  57. var totalFrameCount = this._animation.frameCount + 1;
  58. var frameIndices = this._data.frameIndices;
  59. timeline.frameIndicesOffset = frameIndices.Count;
  60. frameIndices.ResizeList(frameIndices.Count + (int)totalFrameCount);
  61. for (int i = 0, iK = 0, frameStart = 0, frameCount = 0; i < totalFrameCount; ++i)
  62. {
  63. if (frameStart + frameCount <= i && iK < keyFrameCount)
  64. {
  65. frameStart = this._frameArrayBuffer[this._animation.frameOffset + this._timelineArrayBuffer[timeline.offset + (int)BinaryOffset.TimelineFrameOffset + iK]];
  66. if (iK == keyFrameCount - 1)
  67. {
  68. frameCount = (int)this._animation.frameCount - frameStart;
  69. }
  70. else
  71. {
  72. frameCount = this._frameArrayBuffer[this._animation.frameOffset + this._timelineArrayBuffer[timeline.offset + (int)BinaryOffset.TimelineFrameOffset + iK + 1]] - frameStart;
  73. }
  74. iK++;
  75. }
  76. frameIndices[timeline.frameIndicesOffset + i] = (uint)(iK - 1);
  77. }
  78. }
  79. this._timeline = null; //
  80. return timeline;
  81. }
  82. private void _ParseVertices(Dictionary<string, object> rawData, VerticesData vertices)
  83. {
  84. vertices.offset = int.Parse(rawData[DataParser.OFFSET].ToString());
  85. var weightOffset = this._intArrayBuffer[vertices.offset + (int)BinaryOffset.MeshWeightOffset];
  86. if (weightOffset >= 0)
  87. {
  88. var weight = BaseObject.BorrowObject<WeightData>();
  89. var vertexCount = this._intArrayBuffer[vertices.offset + (int)BinaryOffset.MeshVertexCount];
  90. var boneCount = this._intArrayBuffer[weightOffset + (int)BinaryOffset.WeigthBoneCount];
  91. weight.offset = weightOffset;
  92. for (int i = 0; i < boneCount; ++i)
  93. {
  94. var boneIndex = this._intArrayBuffer[weightOffset + (int)BinaryOffset.WeigthBoneIndices + i];
  95. weight.AddBone(this._rawBones[boneIndex]);
  96. }
  97. var boneIndicesOffset = weightOffset + (short)BinaryOffset.WeigthBoneIndices + boneCount;
  98. var weightCount = 0;
  99. for (int i = 0, l = vertexCount; i < l; ++i)
  100. {
  101. var vertexBoneCount = this._intArrayBuffer[boneIndicesOffset++];
  102. weightCount += vertexBoneCount;
  103. boneIndicesOffset += vertexBoneCount;
  104. }
  105. weight.count = weightCount;
  106. vertices.weight = weight;
  107. }
  108. }
  109. protected override void _ParseMesh(Dictionary<string, object> rawData, MeshDisplayData mesh)
  110. {
  111. this._ParseVertices(rawData, mesh.vertices);
  112. }
  113. protected override AnimationData _ParseAnimation(Dictionary<string, object> rawData)
  114. {
  115. var animation = BaseObject.BorrowObject<AnimationData>();
  116. animation.frameCount = (uint)Math.Max(ObjectDataParser._GetNumber(rawData, DataParser.DURATION, 1), 1);
  117. animation.playTimes = (uint)ObjectDataParser._GetNumber(rawData, DataParser.PLAY_TIMES, 1);
  118. animation.duration = (float)animation.frameCount / (float)this._armature.frameRate;//Must float
  119. animation.fadeInTime = ObjectDataParser._GetNumber(rawData, DataParser.FADE_IN_TIME, 0.0f);
  120. animation.scale = ObjectDataParser._GetNumber(rawData, DataParser.SCALE, 1.0f);
  121. animation.name = ObjectDataParser._GetString(rawData, DataParser.NAME, DataParser.DEFAULT_NAME);
  122. if (animation.name.Length == 0)
  123. {
  124. animation.name = DataParser.DEFAULT_NAME;
  125. }
  126. // Offsets.
  127. var offsets = rawData[DataParser.OFFSET] as List<object>;
  128. animation.frameIntOffset = uint.Parse(offsets[0].ToString());
  129. animation.frameFloatOffset = uint.Parse(offsets[1].ToString());
  130. animation.frameOffset = uint.Parse(offsets[2].ToString());
  131. this._animation = animation;
  132. if (rawData.ContainsKey(DataParser.ACTION))
  133. {
  134. animation.actionTimeline = this._ParseBinaryTimeline(TimelineType.Action, uint.Parse(rawData[DataParser.ACTION].ToString()));
  135. }
  136. if (rawData.ContainsKey(DataParser.Z_ORDER))
  137. {
  138. animation.zOrderTimeline = this._ParseBinaryTimeline(TimelineType.ZOrder, uint.Parse(rawData[DataParser.Z_ORDER].ToString()));
  139. }
  140. if (rawData.ContainsKey(DataParser.BONE))
  141. {
  142. var rawTimeliness = rawData[DataParser.BONE] as Dictionary<string, object>;
  143. foreach (var k in rawTimeliness.Keys)
  144. {
  145. var rawTimelines = rawTimeliness[k] as List<object>;
  146. var bone = this._armature.GetBone(k);
  147. if (bone == null)
  148. {
  149. continue;
  150. }
  151. for (int i = 0, l = rawTimelines.Count; i < l; i += 2)
  152. {
  153. var timelineType = int.Parse(rawTimelines[i].ToString());
  154. var timelineOffset = int.Parse(rawTimelines[i + 1].ToString());
  155. var timeline = this._ParseBinaryTimeline((TimelineType)timelineType, (uint)timelineOffset);
  156. this._animation.AddBoneTimeline(bone, timeline);
  157. }
  158. }
  159. }
  160. if (rawData.ContainsKey(DataParser.SLOT))
  161. {
  162. var rawTimeliness = rawData[DataParser.SLOT] as Dictionary<string, object>;
  163. foreach (var k in rawTimeliness.Keys)
  164. {
  165. var rawTimelines = rawTimeliness[k] as List<object>;
  166. var slot = this._armature.GetSlot(k);
  167. if (slot == null)
  168. {
  169. continue;
  170. }
  171. for (int i = 0, l = rawTimelines.Count; i < l; i += 2)
  172. {
  173. var timelineType = int.Parse(rawTimelines[i].ToString());
  174. var timelineOffset = int.Parse(rawTimelines[i + 1].ToString());
  175. var timeline = this._ParseBinaryTimeline((TimelineType)timelineType, (uint)timelineOffset);
  176. this._animation.AddSlotTimeline(slot, timeline);
  177. }
  178. }
  179. }
  180. if (rawData.ContainsKey(DataParser.CONSTRAINT))
  181. {
  182. var rawTimeliness = rawData[DataParser.CONSTRAINT] as Dictionary<string, object>;
  183. foreach (var k in rawTimeliness.Keys)
  184. {
  185. var rawTimelines = rawTimeliness[k] as List<object>;
  186. var constraint = this._armature.GetConstraint(k);
  187. if (constraint == null)
  188. {
  189. continue;
  190. }
  191. for (int i = 0, l = rawTimelines.Count; i < l; i += 2)
  192. {
  193. var timelineType = int.Parse(rawTimelines[i].ToString());
  194. var timelineOffset = int.Parse(rawTimelines[i + 1].ToString());
  195. var timeline = this._ParseBinaryTimeline((TimelineType)timelineType, (uint)timelineOffset);
  196. this._animation.AddConstraintTimeline(constraint, timeline);
  197. }
  198. }
  199. }
  200. this._animation = null;
  201. return animation;
  202. }
  203. protected override void _ParseArray(Dictionary<string, object> rawData)
  204. {
  205. var offsets = rawData[DataParser.OFFSET] as List<object>;
  206. int l0 = int.Parse(offsets[0].ToString());
  207. int l1 = int.Parse(offsets[1].ToString());
  208. int l2 = int.Parse(offsets[3].ToString());
  209. int l3 = int.Parse(offsets[5].ToString());
  210. int l4 = int.Parse(offsets[7].ToString());
  211. int l5 = int.Parse(offsets[9].ToString());
  212. int l6 = int.Parse(offsets[11].ToString());
  213. short[] intArray = { };
  214. float[] floatArray = { };
  215. short[] frameIntArray = { };
  216. float[] frameFloatArray = { };
  217. short[] frameArray = { };
  218. ushort[] timelineArray = { };
  219. using (MemoryStream ms = new MemoryStream(_binary))
  220. using (BinaryDataReader reader = new BinaryDataReader(ms))
  221. {
  222. //ToRead
  223. reader.Seek(this._binaryOffset, SeekOrigin.Begin);
  224. intArray = reader.ReadInt16s(l0, l1 / Helper.INT16_SIZE);
  225. floatArray = reader.ReadSingles(0, l2 / Helper.FLOAT_SIZE);
  226. frameIntArray = reader.ReadInt16s(0, l3 / Helper.INT16_SIZE);
  227. frameFloatArray = reader.ReadSingles(0, l4 / Helper.FLOAT_SIZE);
  228. frameArray = reader.ReadInt16s(0, l5 / Helper.INT16_SIZE);
  229. timelineArray = reader.ReadUInt16s(0, l6 / Helper.UINT16_SIZE);
  230. reader.Close();
  231. ms.Close();
  232. }
  233. this._data.binary = this._binary;
  234. //
  235. this._intArrayBuffer = intArray;
  236. this._floatArrayBuffer = floatArray;
  237. this._frameIntArrayBuffer = frameIntArray;
  238. this._frameFloatArrayBuffer = frameFloatArray;
  239. this._frameArrayBuffer = frameArray;
  240. this._timelineArrayBuffer = timelineArray;
  241. this._data.intArray = this._intArrayBuffer;
  242. this._data.floatArray = this._floatArrayBuffer;
  243. this._data.frameIntArray = this._frameIntArrayBuffer;
  244. this._data.frameFloatArray = this._frameFloatArrayBuffer;
  245. this._data.frameArray = this._frameArrayBuffer;
  246. this._data.timelineArray = this._timelineArrayBuffer;
  247. }
  248. public override DragonBonesData ParseDragonBonesData(object rawObj, float scale = 1)
  249. {
  250. Helper.Assert(rawObj != null && rawObj is byte[], "Data error.");
  251. byte[] bytes = rawObj as byte[];
  252. int headerLength = 0;
  253. object header = DeserializeBinaryJsonData(bytes, out headerLength, jsonParseDelegate);
  254. this._binary = bytes;
  255. this._binaryOffset = 8 + 4 + headerLength;
  256. jsonParseDelegate = null;
  257. return base.ParseDragonBonesData(header, scale);
  258. }
  259. public static Dictionary<string, object> DeserializeBinaryJsonData(byte[] bytes, out int headerLength, BinaryDataParser.JsonParseDelegate jsonParse = null)
  260. {
  261. headerLength = 0;
  262. Dictionary<string, object> result = null;
  263. using (System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes))
  264. using (BinaryDataReader reader = new BinaryDataReader(ms))
  265. {
  266. ms.Position = 0;
  267. byte[] tag = reader.ReadBytes(8);
  268. byte[] array = System.Text.Encoding.ASCII.GetBytes("DBDT");
  269. if (tag[0] != array[0] ||
  270. tag[1] != array[1] ||
  271. tag[2] != array[2] ||
  272. tag[3] != array[3])
  273. {
  274. Helper.Assert(false, "Nonsupport data.");
  275. return null;
  276. }
  277. headerLength = (int)reader.ReadUInt32();
  278. var headerBytes = reader.ReadBytes(headerLength);
  279. var headerString = System.Text.Encoding.UTF8.GetString(headerBytes);
  280. result = jsonParse != null ? jsonParse(headerString) as Dictionary<string, object> : MiniJSON.Json.Deserialize(headerString) as Dictionary<string, object>;
  281. reader.Close();
  282. ms.Dispose();
  283. }
  284. return result;
  285. }
  286. }
  287. }