SkeletonJson.lua 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. -------------------------------------------------------------------------------
  2. -- Spine Runtimes Software License
  3. -- Version 2.1
  4. --
  5. -- Copyright (c) 2013, Esoteric Software
  6. -- All rights reserved.
  7. --
  8. -- You are granted a perpetual, non-exclusive, non-sublicensable and
  9. -- non-transferable license to install, execute and perform the Spine Runtimes
  10. -- Software (the "Software") solely for internal use. Without the written
  11. -- permission of Esoteric Software (typically granted by licensing Spine), you
  12. -- may not (a) modify, translate, adapt or otherwise create derivative works,
  13. -- improvements of the Software or develop new applications using the Software
  14. -- or (b) remove, delete, alter or obscure any trademarks or any copyright,
  15. -- trademark, patent or other intellectual property or proprietary rights
  16. -- notices on or in the Software, including any copy thereof. Redistributions
  17. -- in binary or source form must include this license and terms.
  18. --
  19. -- THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
  20. -- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. -- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  22. -- EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. -- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. -- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  25. -- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26. -- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  27. -- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  28. -- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. -------------------------------------------------------------------------------
  30. local utils = require "lib/spine-lua/utils"
  31. local SkeletonData = require "lib/spine-lua/SkeletonData"
  32. local BoneData = require "lib/spine-lua/BoneData"
  33. local SlotData = require "lib/spine-lua/SlotData"
  34. local Skin = require "lib/spine-lua/Skin"
  35. local AttachmentLoader = require "lib/spine-lua/AttachmentLoader"
  36. local Animation = require "lib/spine-lua/Animation"
  37. local IkConstraintData = require "lib/spine-lua/IkConstraintData"
  38. local IkConstraint = require "lib/spine-lua/IkConstraint"
  39. local EventData = require "lib/spine-lua/EventData"
  40. local Event = require "lib/spine-lua/Event"
  41. local AttachmentType = require "lib/spine-lua/AttachmentType"
  42. local SkeletonJson = {}
  43. function SkeletonJson.new (attachmentLoader)
  44. if not attachmentLoader then attachmentLoader = AttachmentLoader.new() end
  45. local self = {
  46. attachmentLoader = attachmentLoader,
  47. scale = 1
  48. }
  49. function self:readSkeletonDataFile (fileName, base)
  50. return self:readSkeletonData(utils.readFile(fileName, base))
  51. end
  52. local readAttachment
  53. local readAnimation
  54. local readCurve
  55. local getArray
  56. function self:readSkeletonData (json)
  57. local skeletonData = SkeletonData.new(self.attachmentLoader)
  58. root = json
  59. -- Skeleton.
  60. if root["skeleton"] then
  61. local skeletonMap = root["skeleton"]
  62. skeletonData.hash = skeletonMap["hash"]
  63. skeletonData.version = skeletonMap["spine"]
  64. skeletonData.width = skeletonMap["width"] or 0
  65. skeletonData.height = skeletonMap["height"] or 0
  66. end
  67. -- Bones.
  68. for i,boneMap in ipairs(root["bones"]) do
  69. local boneName = boneMap["name"]
  70. local parent = nil
  71. local parentName = boneMap["parent"]
  72. if parentName then
  73. parent = skeletonData:findBone(parentName)
  74. if not parent then error("Parent bone not found: " .. parentName) end
  75. end
  76. local boneData = BoneData.new(boneName, parent)
  77. boneData.length = (boneMap["length"] or 0) * self.scale
  78. boneData.x = (boneMap["x"] or 0) * self.scale
  79. boneData.y = (boneMap["y"] or 0) * self.scale
  80. boneData.rotation = (boneMap["rotation"] or 0)
  81. if boneMap["scaleX"] ~= nil then
  82. boneData.scaleX = boneMap["scaleX"]
  83. else
  84. boneData.scaleX = 1
  85. end
  86. if boneMap["scaleY"] ~= nil then
  87. boneData.scaleY = boneMap["scaleY"]
  88. else
  89. boneData.scaleY = 1
  90. end
  91. boneData.flipX = boneMap["flipX"] or false
  92. boneData.flipY = boneMap["flipY"] or false
  93. if boneMap["inheritScale"] == false then
  94. boneData.inheritScale = false
  95. else
  96. boneData.inheritScale = true
  97. end
  98. if boneMap["inheritRotation"] == false then
  99. boneData.inheritRotation = false
  100. else
  101. boneData.inheritRotation = true
  102. end
  103. table.insert(skeletonData.bones, boneData)
  104. end
  105. -- IK constraints.
  106. if root["ik"] then
  107. for i,ikMap in ipairs(root["ik"]) do
  108. local ikConstraintData = IkConstraintData.new(ikMap["name"])
  109. for i,boneName in ipairs(ikMap["bones"]) do
  110. local bone = skeletonData:findBone(boneName)
  111. if not bone then error("IK bone not found: " .. boneName) end
  112. table.insert(ikConstraintData.bones, bone)
  113. end
  114. local targetName = ikMap["target"]
  115. ikConstraintData.target = skeletonData:findBone(targetName)
  116. if not ikConstraintData.target then error("Target bone not found: " .. targetName) end
  117. if ikMap["bendPositive"] == false then ikConstraintData.bendDirection = -1 end
  118. if ikMap["mix"] ~= nil then ikConstraintData.mix = ikMap["mix"] end
  119. table.insert(skeletonData.ikConstraints, ikConstraintData)
  120. end
  121. end
  122. -- Slots.
  123. if root["slots"] then
  124. for i,slotMap in ipairs(root["slots"]) do
  125. local slotName = slotMap["name"]
  126. local boneName = slotMap["bone"]
  127. local boneData = skeletonData:findBone(boneName)
  128. if not boneData then error("Slot bone not found: " .. boneName) end
  129. local slotData = SlotData.new(slotName, boneData)
  130. local color = slotMap["color"]
  131. if color then
  132. slotData:setColor(
  133. tonumber(color:sub(1, 2), 16) / 255,
  134. tonumber(color:sub(3, 4), 16) / 255,
  135. tonumber(color:sub(5, 6), 16) / 255,
  136. tonumber(color:sub(7, 8), 16) / 255
  137. )
  138. end
  139. slotData.attachmentName = slotMap["attachment"]
  140. slotData.additiveBlending = slotMap["additive"]
  141. table.insert(skeletonData.slots, slotData)
  142. skeletonData.slotNameIndices[slotData.name] = #skeletonData.slots
  143. end
  144. end
  145. -- Skins.
  146. if root["skins"] then
  147. for skinName,skinMap in pairs(root["skins"]) do
  148. local skin = Skin.new(skinName)
  149. for slotName,slotMap in pairs(skinMap) do
  150. local slotIndex = skeletonData.slotNameIndices[slotName]
  151. for attachmentName,attachmentMap in pairs(slotMap) do
  152. local attachment = readAttachment(attachmentName, attachmentMap)
  153. if attachment then
  154. skin:addAttachment(slotIndex, attachmentName, attachment)
  155. end
  156. end
  157. end
  158. if skin.name == "default" then
  159. skeletonData.defaultSkin = skin
  160. else
  161. table.insert(skeletonData.skins, skin)
  162. end
  163. end
  164. end
  165. -- Events.
  166. if root["events"] then
  167. for eventName,eventMap in pairs(root["events"]) do
  168. local eventData = EventData.new(eventName)
  169. eventData.intValue = eventMap["int"] or 0
  170. eventData.floatValue = eventMap["float"] or 0
  171. eventData.stringValue = eventMap["string"]
  172. table.insert(skeletonData.events, eventData)
  173. end
  174. end
  175. -- Animations.
  176. if root["animations"] then
  177. for animationName,animationMap in pairs(root["animations"]) do
  178. readAnimation(animationName, animationMap, skeletonData)
  179. end
  180. end
  181. return skeletonData
  182. end
  183. readAttachment = function (name, map)
  184. name = map["name"] or name
  185. local type = AttachmentType[map["type"] or "region"]
  186. local path = map["path"] or name
  187. local scale = self.scale
  188. if type == AttachmentType.region then
  189. local region = attachmentLoader:newRegionAttachment(type, name, path)
  190. if not region then return nil end
  191. region.x = (map["x"] or 0) * scale
  192. region.y = (map["y"] or 0) * scale
  193. if map["scaleX"] ~= nil then
  194. region.scaleX = map["scaleX"]
  195. else
  196. region.scaleX = 1
  197. end
  198. if map["scaleY"] ~= nil then
  199. region.scaleY = map["scaleY"]
  200. else
  201. region.scaleY = 1
  202. end
  203. region.rotation = (map["rotation"] or 0)
  204. region.width = map["width"] * scale
  205. region.height = map["height"] * scale
  206. local color = map["color"]
  207. if color then
  208. region.r = tonumber(color:sub(1, 2), 16) / 255
  209. region.g = tonumber(color:sub(3, 4), 16) / 255
  210. region.b = tonumber(color:sub(5, 6), 16) / 255
  211. region.a = tonumber(color:sub(7, 8), 16) / 255
  212. end
  213. region:updateOffset()
  214. return region
  215. elseif type == AttachmentType.mesh then
  216. local mesh = attachmentLoader:newMeshAttachment(skin, name, path)
  217. if not mesh then return null end
  218. mesh.path = path
  219. mesh.vertices = getArray(map, "vertices", scale)
  220. mesh.triangles = getArray(map, "triangles", 1)
  221. mesh.regionUVs = getArray(map, "uvs", 1)
  222. mesh:updateUVs()
  223. local color = map["color"]
  224. if color then
  225. mesh.r = tonumber(color:sub(1, 2), 16) / 255
  226. mesh.g = tonumber(color:sub(3, 4), 16) / 255
  227. mesh.b = tonumber(color:sub(5, 6), 16) / 255
  228. mesh.a = tonumber(color:sub(7, 8), 16) / 255
  229. end
  230. mesh.hullLength = (map["hull"] or 0) * 2
  231. if map["edges"] then mesh.edges = getArray(map, "edges", 1) end
  232. mesh.width = (map["width"] or 0) * scale
  233. mesh.height = (map["height"] or 0) * scale
  234. return mesh
  235. elseif type == AttachmentType.skinnedmesh then
  236. local mesh = self.attachmentLoader.newSkinnedMeshAttachment(skin, name, path)
  237. if not mesh then return null end
  238. mesh.path = path
  239. local uvs = getArray(map, "uvs", 1)
  240. vertices = getArray(map, "vertices", 1)
  241. local weights = {}
  242. local bones = {}
  243. for i = 1, vertices do
  244. local boneCount = vertices[i]
  245. i = i + 1
  246. table.insert(bones, boneCount)
  247. for ii = 1, i + boneCount * 4 do
  248. table.insert(bones, vertices[i])
  249. table.insert(weights, vertices[i + 1] * scale)
  250. table.insert(weights, vertices[i + 2] * scale)
  251. table.insert(weights, vertices[i + 3])
  252. i = i + 4
  253. end
  254. end
  255. mesh.bones = bones
  256. mesh.weights = weights
  257. mesh.triangles = getArray(map, "triangles", 1)
  258. mesh.regionUVs = uvs
  259. mesh:updateUVs()
  260. local color = map["color"]
  261. if color then
  262. mesh.r = tonumber(color:sub(1, 2), 16) / 255
  263. mesh.g = tonumber(color:sub(3, 4), 16) / 255
  264. mesh.b = tonumber(color:sub(5, 6), 16) / 255
  265. mesh.a = tonumber(color:sub(7, 8), 16) / 255
  266. end
  267. mesh.hullLength = (map["hull"] or 0) * 2
  268. if map["edges"] then mesh.edges = getArray(map, "edges", 1) end
  269. mesh.width = (map["width"] or 0) * scale
  270. mesh.height = (map["height"] or 0) * scale
  271. return mesh
  272. elseif type == AttachmentType.boundingbox then
  273. local box = attachmentLoader:newBoundingBoxAttachment(type, name)
  274. if not box then return nil end
  275. local vertices = map["vertices"]
  276. for i,point in ipairs(vertices) do
  277. table.insert(box.vertices, vertices[i] * scale)
  278. end
  279. return box
  280. end
  281. error("Unknown attachment type: " .. type .. " (" .. name .. ")")
  282. end
  283. readAnimation = function (name, map, skeletonData)
  284. local timelines = {}
  285. local duration = 0
  286. local slotsMap = map["slots"]
  287. if slotsMap then
  288. for slotName,timelineMap in pairs(slotsMap) do
  289. local slotIndex = skeletonData.slotNameIndices[slotName]
  290. for timelineName,values in pairs(timelineMap) do
  291. if timelineName == "color" then
  292. local timeline = Animation.ColorTimeline.new()
  293. timeline.slotIndex = slotIndex
  294. local frameIndex = 0
  295. for i,valueMap in ipairs(values) do
  296. local color = valueMap["color"]
  297. timeline:setFrame(
  298. frameIndex, valueMap["time"],
  299. tonumber(color:sub(1, 2), 16) / 255,
  300. tonumber(color:sub(3, 4), 16) / 255,
  301. tonumber(color:sub(5, 6), 16) / 255,
  302. tonumber(color:sub(7, 8), 16) / 255
  303. )
  304. readCurve(timeline, frameIndex, valueMap)
  305. frameIndex = frameIndex + 1
  306. end
  307. table.insert(timelines, timeline)
  308. duration = math.max(duration, timeline:getDuration())
  309. elseif timelineName == "attachment" then
  310. local timeline = Animation.AttachmentTimeline.new()
  311. timeline.slotName = slotName
  312. local frameIndex = 0
  313. for i,valueMap in ipairs(values) do
  314. local attachmentName = valueMap["name"]
  315. if not attachmentName then attachmentName = nil end
  316. timeline:setFrame(frameIndex, valueMap["time"], attachmentName)
  317. frameIndex = frameIndex + 1
  318. end
  319. table.insert(timelines, timeline)
  320. duration = math.max(duration, timeline:getDuration())
  321. else
  322. error("Invalid frame type for a slot: " .. timelineName .. " (" .. slotName .. ")")
  323. end
  324. end
  325. end
  326. end
  327. local bonesMap = map["bones"]
  328. if bonesMap then
  329. for boneName,timelineMap in pairs(bonesMap) do
  330. local boneIndex = skeletonData:findBoneIndex(boneName)
  331. if boneIndex == -1 then error("Bone not found: " .. boneName) end
  332. for timelineName,values in pairs(timelineMap) do
  333. if timelineName == "rotate" then
  334. local timeline = Animation.RotateTimeline.new()
  335. timeline.boneIndex = boneIndex
  336. local frameIndex = 0
  337. for i,valueMap in ipairs(values) do
  338. timeline:setFrame(frameIndex, valueMap["time"], valueMap["angle"])
  339. readCurve(timeline, frameIndex, valueMap)
  340. frameIndex = frameIndex + 1
  341. end
  342. table.insert(timelines, timeline)
  343. duration = math.max(duration, timeline:getDuration())
  344. elseif timelineName == "translate" or timelineName == "scale" then
  345. local timeline
  346. local timelineScale = 1
  347. if timelineName == "scale" then
  348. timeline = Animation.ScaleTimeline.new()
  349. else
  350. timeline = Animation.TranslateTimeline.new()
  351. timelineScale = self.scale
  352. end
  353. timeline.boneIndex = boneIndex
  354. local frameIndex = 0
  355. for i,valueMap in ipairs(values) do
  356. local x = (valueMap["x"] or 0) * timelineScale
  357. local y = (valueMap["y"] or 0) * timelineScale
  358. timeline:setFrame(frameIndex, valueMap["time"], x, y)
  359. readCurve(timeline, frameIndex, valueMap)
  360. frameIndex = frameIndex + 1
  361. end
  362. table.insert(timelines, timeline)
  363. duration = math.max(duration, timeline:getDuration())
  364. elseif timelineName == "flipX" or timelineName == "flipY" then
  365. local x = timelineName == "flipX"
  366. local timeline, field
  367. if x then
  368. timeline = Animation.FlipXTimeline.new()
  369. field = "x"
  370. else
  371. timeline = Animation.FlipYTimeline.new();
  372. field = "y"
  373. end
  374. timeline.boneIndex = boneIndex
  375. local frameIndex = 0
  376. for i,valueMap in ipairs(values) do
  377. timeline:setFrame(frameIndex, valueMap["time"], valueMap[field] or false)
  378. frameIndex = frameIndex + 1
  379. end
  380. table.insert(timelines, timeline)
  381. duration = math.max(duration, timeline:getDuration())
  382. else
  383. error("Invalid timeline type for a bone: " .. timelineName .. " (" .. boneName .. ")")
  384. end
  385. end
  386. end
  387. end
  388. local ik = map["ik"]
  389. if ik then
  390. for ikConstraintName,values in pairs(ik) do
  391. local ikConstraint = skeletonData:findIkConstraint(ikConstraintName)
  392. local timeline = Animation.IkConstraintTimeline.new()
  393. for i,other in pairs(skeletonData.ikConstraints) do
  394. if other == ikConstraint then
  395. timeline.ikConstraintIndex = i
  396. break
  397. end
  398. end
  399. local frameIndex = 0
  400. for i,valueMap in ipairs(values) do
  401. local mix = 1
  402. if valueMap["mix"] ~= nil then mix = valueMap["mix"] end
  403. local bendPositive = 1
  404. if valueMap["bendPositive"] == false then bendPositive = -1 end
  405. timeline:setFrame(frameIndex, valueMap["time"], mix, bendPositive)
  406. readCurve(timeline, frameIndex, valueMap)
  407. frameIndex = frameIndex + 1
  408. end
  409. table.insert(timelines, timeline)
  410. duration = math.max(duration, timeline:getDuration())
  411. end
  412. end
  413. local ffd = map["ffd"]
  414. if ffd then
  415. for skinName,slotMap in pairs(ffd) do
  416. local skin = skeletonData.findSkin(skinName)
  417. for slotName,meshMap in pairs(slotMap) do
  418. local slotIndex = skeletonData.findSlotIndex(slotName)
  419. for meshName,values in pairs(meshMap) do
  420. local timeline = Animation.FfdTimeline.new()
  421. local attachment = skin:getAttachment(slotIndex, meshName)
  422. if not attachment then error("FFD attachment not found: " .. meshName) end
  423. timeline.slotIndex = slotIndex
  424. timeline.attachment = attachment
  425. local isMesh = attachment.type == AttachmentType.mesh
  426. local vertexCount
  427. if isMesh then
  428. vertexCount = attachment.vertices.length
  429. else
  430. vertexCount = attachment.weights.length / 3 * 2
  431. end
  432. local frameIndex = 0
  433. for i,valueMap in ipairs(values) do
  434. local vertices
  435. if not valueMap["vertices"] then
  436. if isMesh then
  437. vertices = attachment.vertices
  438. else
  439. vertices = {}
  440. vertices.length = vertexCount
  441. end
  442. else
  443. local verticesValue = valueMap["vertices"]
  444. local vertices = {}
  445. local start = valueMap["offset"] or 0
  446. if scale == 1 then
  447. for ii = 1, #verticesValue do
  448. vertices[ii + start] = verticesValue[ii]
  449. end
  450. else
  451. for ii = 1, #verticesValue do
  452. vertices[ii + start] = verticesValue[ii] * scale
  453. end
  454. end
  455. if isMesh then
  456. local meshVertices = attachment.vertices
  457. for ii = 1, vertexCount do
  458. vertices[ii] = vertices[ii] + meshVertices[ii]
  459. end
  460. elseif #verticesValue < vertexCount then
  461. vertices[vertexCount] = 0
  462. end
  463. end
  464. timeline:setFrame(frameIndex, valueMap["time"], vertices)
  465. readCurve(timeline, frameIndex, valueMap)
  466. frameIndex = frameIndex + 1
  467. end
  468. table.insert(timelines, timeline)
  469. duration = math.max(duration, timeline:getDuration())
  470. end
  471. end
  472. end
  473. end
  474. local drawOrderValues = map["drawOrder"]
  475. if not drawOrderValues then drawOrderValues = map["draworder"] end
  476. if drawOrderValues then
  477. local timeline = Animation.DrawOrderTimeline.new(#drawOrderValues)
  478. local slotCount = #skeletonData.slots
  479. local frameIndex = 0
  480. for i,drawOrderMap in ipairs(drawOrderValues) do
  481. local drawOrder = nil
  482. local offsets = drawOrderMap["offsets"]
  483. if offsets then
  484. drawOrder = {}
  485. local unchanged = {}
  486. local originalIndex = 1
  487. local unchangedIndex = 1
  488. for ii,offsetMap in ipairs(offsets) do
  489. local slotIndex = skeletonData:findSlotIndex(offsetMap["slot"])
  490. if slotIndex == -1 then error("Slot not found: " .. offsetMap["slot"]) end
  491. -- Collect unchanged items.
  492. while originalIndex ~= slotIndex do
  493. unchanged[unchangedIndex] = originalIndex
  494. unchangedIndex = unchangedIndex + 1
  495. originalIndex = originalIndex + 1
  496. end
  497. -- Set changed items.
  498. drawOrder[originalIndex + offsetMap["offset"]] = originalIndex
  499. originalIndex = originalIndex + 1
  500. end
  501. -- Collect remaining unchanged items.
  502. while originalIndex <= slotCount do
  503. unchanged[unchangedIndex] = originalIndex
  504. unchangedIndex = unchangedIndex + 1
  505. originalIndex = originalIndex + 1
  506. end
  507. -- Fill in unchanged items.
  508. for ii = slotCount, 1, -1 do
  509. if not drawOrder[ii] then
  510. unchangedIndex = unchangedIndex - 1
  511. drawOrder[ii] = unchanged[unchangedIndex]
  512. end
  513. end
  514. end
  515. timeline:setFrame(frameIndex, drawOrderMap["time"], drawOrder)
  516. frameIndex = frameIndex + 1
  517. end
  518. table.insert(timelines, timeline)
  519. duration = math.max(duration, timeline:getDuration())
  520. end
  521. local events = map["events"]
  522. if events then
  523. local timeline = Animation.EventTimeline.new(#events)
  524. local frameIndex = 0
  525. for i,eventMap in ipairs(events) do
  526. local eventData = skeletonData:findEvent(eventMap["name"])
  527. if not eventData then error("Event not found: " .. eventMap["name"]) end
  528. local event = Event.new(eventData)
  529. if eventMap["int"] ~= nil then
  530. event.intValue = eventMap["int"]
  531. else
  532. event.intValue = eventData.intValue
  533. end
  534. if eventMap["float"] ~= nil then
  535. event.floatValue = eventMap["float"]
  536. else
  537. event.floatValue = eventData.floatValue
  538. end
  539. if eventMap["string"] ~= nil then
  540. event.stringValue = eventMap["string"]
  541. else
  542. event.stringValue = eventData.stringValue
  543. end
  544. timeline:setFrame(frameIndex, eventMap["time"], event)
  545. frameIndex = frameIndex + 1
  546. end
  547. table.insert(timelines, timeline)
  548. duration = math.max(duration, timeline:getDuration())
  549. end
  550. table.insert(skeletonData.animations, Animation.new(name, timelines, duration))
  551. end
  552. readCurve = function (timeline, frameIndex, valueMap)
  553. local curve = valueMap["curve"]
  554. if not curve then
  555. timeline:setLinear(frameIndex)
  556. elseif curve == "stepped" then
  557. timeline:setStepped(frameIndex)
  558. else
  559. timeline:setCurve(frameIndex, curve[1], curve[2], curve[3], curve[4])
  560. end
  561. end
  562. getArray = function (map, name, scale)
  563. local list = map[name]
  564. local values = {}
  565. if scale == 1 then
  566. for i = 1, #list do
  567. values[i] = list[i]
  568. end
  569. else
  570. for i = 1, #list do
  571. values[i] = list[i] * scale
  572. end
  573. end
  574. return values
  575. end
  576. return self
  577. end
  578. return SkeletonJson